1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © Microsoft Corporation
3bf215546Sopenharmony_ci *
4bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
5bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
6bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
7bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
9bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
10bf215546Sopenharmony_ci *
11bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
12bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
13bf215546Sopenharmony_ci * Software.
14bf215546Sopenharmony_ci *
15bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16bf215546Sopenharmony_ci * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17bf215546Sopenharmony_ci * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18bf215546Sopenharmony_ci * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19bf215546Sopenharmony_ci * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20bf215546Sopenharmony_ci * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21bf215546Sopenharmony_ci * IN THE SOFTWARE.
22bf215546Sopenharmony_ci */
23bf215546Sopenharmony_ci
24bf215546Sopenharmony_ci#include <cmath>
25bf215546Sopenharmony_ci#include <stdio.h>
26bf215546Sopenharmony_ci#include <stdint.h>
27bf215546Sopenharmony_ci#include <stdexcept>
28bf215546Sopenharmony_ci#include <vector>
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#include <unknwn.h>
31bf215546Sopenharmony_ci#include <directx/d3d12.h>
32bf215546Sopenharmony_ci#include <dxgi1_4.h>
33bf215546Sopenharmony_ci#include <gtest/gtest.h>
34bf215546Sopenharmony_ci#include <wrl.h>
35bf215546Sopenharmony_ci#include <dxguids/dxguids.h>
36bf215546Sopenharmony_ci
37bf215546Sopenharmony_ci#include "compute_test.h"
38bf215546Sopenharmony_ci
39bf215546Sopenharmony_ciusing std::vector;
40bf215546Sopenharmony_ci
41bf215546Sopenharmony_ciTEST_F(ComputeTest, runtime_memcpy)
42bf215546Sopenharmony_ci{
43bf215546Sopenharmony_ci   struct shift { uint8_t val; uint8_t shift; uint16_t ret; };
44bf215546Sopenharmony_ci   const char *kernel_source =
45bf215546Sopenharmony_ci   "struct shift { uchar val; uchar shift; ushort ret; };\n\
46bf215546Sopenharmony_ci   __kernel void main_test(__global struct shift *inout)\n\
47bf215546Sopenharmony_ci   {\n\
48bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
49bf215546Sopenharmony_ci      uint id2 = id + get_global_id(1);\n\
50bf215546Sopenharmony_ci      struct shift lc[4] = { { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }};\n\
51bf215546Sopenharmony_ci      lc[id] = inout[id];\n\
52bf215546Sopenharmony_ci      inout[id2].ret = (ushort) lc[id2].val << (ushort) lc[id2].shift;\n\
53bf215546Sopenharmony_ci   }\n";
54bf215546Sopenharmony_ci
55bf215546Sopenharmony_ci   auto inout = ShaderArg<struct shift>({
56bf215546Sopenharmony_ci         { 0x10, 1, 0xffff },
57bf215546Sopenharmony_ci         { 0x20, 2, 0xffff },
58bf215546Sopenharmony_ci         { 0x30, 3, 0xffff },
59bf215546Sopenharmony_ci         { 0x40, 4, 0xffff },
60bf215546Sopenharmony_ci      },
61bf215546Sopenharmony_ci      SHADER_ARG_INOUT);
62bf215546Sopenharmony_ci   const uint16_t expected[] = { 0x20, 0x80, 0x180, 0x400 };
63bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
64bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
65bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].ret, expected[i]);
66bf215546Sopenharmony_ci}
67bf215546Sopenharmony_ci
68bf215546Sopenharmony_ciTEST_F(ComputeTest, two_global_arrays)
69bf215546Sopenharmony_ci{
70bf215546Sopenharmony_ci   const char *kernel_source =
71bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *g1, __global uint *g2)\n\
72bf215546Sopenharmony_ci   {\n\
73bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
74bf215546Sopenharmony_ci       g1[idx] -= g2[idx];\n\
75bf215546Sopenharmony_ci   }\n";
76bf215546Sopenharmony_ci   auto g1 = ShaderArg<uint32_t>({ 10, 20, 30, 40 }, SHADER_ARG_INOUT);
77bf215546Sopenharmony_ci   auto g2 = ShaderArg<uint32_t>({ 1, 2, 3, 4 }, SHADER_ARG_INPUT);
78bf215546Sopenharmony_ci   const uint32_t expected[] = {
79bf215546Sopenharmony_ci      9, 18, 27, 36
80bf215546Sopenharmony_ci   };
81bf215546Sopenharmony_ci
82bf215546Sopenharmony_ci   run_shader(kernel_source, g1.size(), 1, 1, g1, g2);
83bf215546Sopenharmony_ci   for (int i = 0; i < g1.size(); ++i)
84bf215546Sopenharmony_ci      EXPECT_EQ(g1[i], expected[i]);
85bf215546Sopenharmony_ci}
86bf215546Sopenharmony_ci
87bf215546Sopenharmony_ci/* Disabled until saturated conversions from f32->i64 fixed (mesa/mesa#3824) */
88bf215546Sopenharmony_ciTEST_F(ComputeTest, DISABLED_i64tof32)
89bf215546Sopenharmony_ci{
90bf215546Sopenharmony_ci   const char *kernel_source =
91bf215546Sopenharmony_ci   "__kernel void main_test(__global long *out, __constant long *in)\n\
92bf215546Sopenharmony_ci   {\n\
93bf215546Sopenharmony_ci       __local float tmp[12];\n\
94bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
95bf215546Sopenharmony_ci       tmp[idx] = in[idx];\n\
96bf215546Sopenharmony_ci       barrier(CLK_LOCAL_MEM_FENCE);\n\
97bf215546Sopenharmony_ci       out[idx] = tmp[idx + get_global_id(1)];\n\
98bf215546Sopenharmony_ci   }\n";
99bf215546Sopenharmony_ci   auto in = ShaderArg<int64_t>({ 0x100000000LL,
100bf215546Sopenharmony_ci                                  -0x100000000LL,
101bf215546Sopenharmony_ci                                  0x7fffffffffffffffLL,
102bf215546Sopenharmony_ci                                  0x4000004000000000LL,
103bf215546Sopenharmony_ci                                  0x4000003fffffffffLL,
104bf215546Sopenharmony_ci                                  0x4000004000000001LL,
105bf215546Sopenharmony_ci                                  -1,
106bf215546Sopenharmony_ci                                  -0x4000004000000000LL,
107bf215546Sopenharmony_ci                                  -0x4000003fffffffffLL,
108bf215546Sopenharmony_ci                                  -0x4000004000000001LL,
109bf215546Sopenharmony_ci                                  0,
110bf215546Sopenharmony_ci                                  INT64_MIN },
111bf215546Sopenharmony_ci                                SHADER_ARG_INPUT);
112bf215546Sopenharmony_ci   auto out = ShaderArg<int64_t>(std::vector<int64_t>(12, 0xdeadbeed), SHADER_ARG_OUTPUT);
113bf215546Sopenharmony_ci   const int64_t expected[] = {
114bf215546Sopenharmony_ci      0x100000000LL,
115bf215546Sopenharmony_ci      -0x100000000LL,
116bf215546Sopenharmony_ci      0x7fffffffffffffffLL,
117bf215546Sopenharmony_ci      0x4000000000000000LL,
118bf215546Sopenharmony_ci      0x4000000000000000LL,
119bf215546Sopenharmony_ci      0x4000008000000000LL,
120bf215546Sopenharmony_ci      -1,
121bf215546Sopenharmony_ci      -0x4000000000000000LL,
122bf215546Sopenharmony_ci      -0x4000000000000000LL,
123bf215546Sopenharmony_ci      -0x4000008000000000LL,
124bf215546Sopenharmony_ci      0,
125bf215546Sopenharmony_ci      INT64_MIN,
126bf215546Sopenharmony_ci   };
127bf215546Sopenharmony_ci
128bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
129bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
130bf215546Sopenharmony_ci      EXPECT_EQ((int64_t)out[i], expected[i]);
131bf215546Sopenharmony_ci   }
132bf215546Sopenharmony_ci}
133bf215546Sopenharmony_ciTEST_F(ComputeTest, two_constant_arrays)
134bf215546Sopenharmony_ci{
135bf215546Sopenharmony_ci   const char *kernel_source =
136bf215546Sopenharmony_ci   "__kernel void main_test(__constant uint *c1, __global uint *g1, __constant uint *c2)\n\
137bf215546Sopenharmony_ci   {\n\
138bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
139bf215546Sopenharmony_ci       g1[idx] -= c1[idx] + c2[idx];\n\
140bf215546Sopenharmony_ci   }\n";
141bf215546Sopenharmony_ci   auto g1 = ShaderArg<uint32_t>({ 10, 20, 30, 40 }, SHADER_ARG_INOUT);
142bf215546Sopenharmony_ci   auto c1 = ShaderArg<uint32_t>({ 1, 2, 3, 4 }, SHADER_ARG_INPUT);
143bf215546Sopenharmony_ci   auto c2 = ShaderArg<uint32_t>(std::vector<uint32_t>(16384, 5), SHADER_ARG_INPUT);
144bf215546Sopenharmony_ci   const uint32_t expected[] = {
145bf215546Sopenharmony_ci      4, 13, 22, 31
146bf215546Sopenharmony_ci   };
147bf215546Sopenharmony_ci
148bf215546Sopenharmony_ci   run_shader(kernel_source, g1.size(), 1, 1, c1, g1, c2);
149bf215546Sopenharmony_ci   for (int i = 0; i < g1.size(); ++i)
150bf215546Sopenharmony_ci      EXPECT_EQ(g1[i], expected[i]);
151bf215546Sopenharmony_ci}
152bf215546Sopenharmony_ci
153bf215546Sopenharmony_ciTEST_F(ComputeTest, null_constant_ptr)
154bf215546Sopenharmony_ci{
155bf215546Sopenharmony_ci   const char *kernel_source =
156bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *g1, __constant uint *c1)\n\
157bf215546Sopenharmony_ci   {\n\
158bf215546Sopenharmony_ci       __constant uint fallback[] = {2, 3, 4, 5};\n\
159bf215546Sopenharmony_ci       __constant uint *c = c1 ? c1 : fallback;\n\
160bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
161bf215546Sopenharmony_ci       g1[idx] -= c[idx];\n\
162bf215546Sopenharmony_ci   }\n";
163bf215546Sopenharmony_ci   auto g1 = ShaderArg<uint32_t>({ 10, 20, 30, 40 }, SHADER_ARG_INOUT);
164bf215546Sopenharmony_ci   auto c1 = ShaderArg<uint32_t>({ 1, 2, 3, 4 }, SHADER_ARG_INPUT);
165bf215546Sopenharmony_ci   const uint32_t expected1[] = {
166bf215546Sopenharmony_ci      9, 18, 27, 36
167bf215546Sopenharmony_ci   };
168bf215546Sopenharmony_ci
169bf215546Sopenharmony_ci   run_shader(kernel_source, g1.size(), 1, 1, g1, c1);
170bf215546Sopenharmony_ci   for (int i = 0; i < g1.size(); ++i)
171bf215546Sopenharmony_ci      EXPECT_EQ(g1[i], expected1[i]);
172bf215546Sopenharmony_ci
173bf215546Sopenharmony_ci   const uint32_t expected2[] = {
174bf215546Sopenharmony_ci      8, 17, 26, 35
175bf215546Sopenharmony_ci   };
176bf215546Sopenharmony_ci
177bf215546Sopenharmony_ci   g1 = ShaderArg<uint32_t>({ 10, 20, 30, 40 }, SHADER_ARG_INOUT);
178bf215546Sopenharmony_ci   auto c2 = NullShaderArg();
179bf215546Sopenharmony_ci   run_shader(kernel_source, g1.size(), 1, 1, g1, c2);
180bf215546Sopenharmony_ci   for (int i = 0; i < g1.size(); ++i)
181bf215546Sopenharmony_ci      EXPECT_EQ(g1[i], expected2[i]);
182bf215546Sopenharmony_ci}
183bf215546Sopenharmony_ci
184bf215546Sopenharmony_ciTEST_F(ComputeTest, null_global_ptr)
185bf215546Sopenharmony_ci{
186bf215546Sopenharmony_ci   const char *kernel_source =
187bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *g1, __global uint *g2)\n\
188bf215546Sopenharmony_ci   {\n\
189bf215546Sopenharmony_ci       __constant uint fallback[] = {2, 3, 4, 5};\n\
190bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
191bf215546Sopenharmony_ci       g1[idx] -= g2 ? g2[idx] : fallback[idx];\n\
192bf215546Sopenharmony_ci   }\n";
193bf215546Sopenharmony_ci   auto g1 = ShaderArg<uint32_t>({ 10, 20, 30, 40 }, SHADER_ARG_INOUT);
194bf215546Sopenharmony_ci   auto g2 = ShaderArg<uint32_t>({ 1, 2, 3, 4 }, SHADER_ARG_INPUT);
195bf215546Sopenharmony_ci   const uint32_t expected1[] = {
196bf215546Sopenharmony_ci      9, 18, 27, 36
197bf215546Sopenharmony_ci   };
198bf215546Sopenharmony_ci
199bf215546Sopenharmony_ci   run_shader(kernel_source, g1.size(), 1, 1, g1, g2);
200bf215546Sopenharmony_ci   for (int i = 0; i < g1.size(); ++i)
201bf215546Sopenharmony_ci      EXPECT_EQ(g1[i], expected1[i]);
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci   const uint32_t expected2[] = {
204bf215546Sopenharmony_ci      8, 17, 26, 35
205bf215546Sopenharmony_ci   };
206bf215546Sopenharmony_ci
207bf215546Sopenharmony_ci   g1 = ShaderArg<uint32_t>({ 10, 20, 30, 40 }, SHADER_ARG_INOUT);
208bf215546Sopenharmony_ci   auto g2null = NullShaderArg();
209bf215546Sopenharmony_ci   run_shader(kernel_source, g1.size(), 1, 1, g1, g2null);
210bf215546Sopenharmony_ci   for (int i = 0; i < g1.size(); ++i)
211bf215546Sopenharmony_ci      EXPECT_EQ(g1[i], expected2[i]);
212bf215546Sopenharmony_ci}
213bf215546Sopenharmony_ci
214bf215546Sopenharmony_ciTEST_F(ComputeTest, ret_constant_ptr)
215bf215546Sopenharmony_ci{
216bf215546Sopenharmony_ci   struct s { uint64_t ptr; uint32_t val; };
217bf215546Sopenharmony_ci   const char *kernel_source =
218bf215546Sopenharmony_ci   "struct s { __constant uint *ptr; uint val; };\n\
219bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out, __constant uint *in)\n\
220bf215546Sopenharmony_ci   {\n\
221bf215546Sopenharmony_ci       __constant uint foo[] = { 1, 2 };\n\
222bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
223bf215546Sopenharmony_ci       if (idx == 0)\n\
224bf215546Sopenharmony_ci          out[idx].ptr = foo;\n\
225bf215546Sopenharmony_ci       else\n\
226bf215546Sopenharmony_ci          out[idx].ptr = in;\n\
227bf215546Sopenharmony_ci       out[idx].val = out[idx].ptr[idx];\n\
228bf215546Sopenharmony_ci   }\n";
229bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>(std::vector<struct s>(2, {0xdeadbeefdeadbeef, 0}), SHADER_ARG_OUTPUT);
230bf215546Sopenharmony_ci   auto in = ShaderArg<uint32_t>({ 3, 4 }, SHADER_ARG_INPUT);
231bf215546Sopenharmony_ci   const uint32_t expected_val[] = {
232bf215546Sopenharmony_ci      1, 4
233bf215546Sopenharmony_ci   };
234bf215546Sopenharmony_ci   const uint64_t expected_ptr[] = {
235bf215546Sopenharmony_ci      2ull << 32, 1ull << 32
236bf215546Sopenharmony_ci   };
237bf215546Sopenharmony_ci
238bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
239bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
240bf215546Sopenharmony_ci      EXPECT_EQ(out[i].val, expected_val[i]);
241bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ptr, expected_ptr[i]);
242bf215546Sopenharmony_ci   }
243bf215546Sopenharmony_ci}
244bf215546Sopenharmony_ci
245bf215546Sopenharmony_ciTEST_F(ComputeTest, ret_global_ptr)
246bf215546Sopenharmony_ci{
247bf215546Sopenharmony_ci   struct s { uint64_t ptr; uint32_t val; };
248bf215546Sopenharmony_ci   const char *kernel_source =
249bf215546Sopenharmony_ci   "struct s { __global uint *ptr; uint val; };\n\
250bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out, __global uint *in1, __global uint *in2)\n\
251bf215546Sopenharmony_ci   {\n\
252bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
253bf215546Sopenharmony_ci       out[idx].ptr = idx ? in2 : in1;\n\
254bf215546Sopenharmony_ci       out[idx].val = out[idx].ptr[idx];\n\
255bf215546Sopenharmony_ci   }\n";
256bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>(std::vector<struct s>(2, {0xdeadbeefdeadbeef, 0}), SHADER_ARG_OUTPUT);
257bf215546Sopenharmony_ci   auto in1 = ShaderArg<uint32_t>({ 1, 2 }, SHADER_ARG_INPUT);
258bf215546Sopenharmony_ci   auto in2 = ShaderArg<uint32_t>({ 3, 4 }, SHADER_ARG_INPUT);
259bf215546Sopenharmony_ci   const uint32_t expected_val[] = {
260bf215546Sopenharmony_ci      1, 4
261bf215546Sopenharmony_ci   };
262bf215546Sopenharmony_ci   const uint64_t expected_ptr[] = {
263bf215546Sopenharmony_ci      1ull << 32, 2ull << 32
264bf215546Sopenharmony_ci   };
265bf215546Sopenharmony_ci
266bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in1, in2);
267bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
268bf215546Sopenharmony_ci      EXPECT_EQ(out[i].val, expected_val[i]);
269bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ptr, expected_ptr[i]);
270bf215546Sopenharmony_ci   }
271bf215546Sopenharmony_ci}
272bf215546Sopenharmony_ci
273bf215546Sopenharmony_ciTEST_F(ComputeTest, ret_local_ptr)
274bf215546Sopenharmony_ci{
275bf215546Sopenharmony_ci   struct s { uint64_t ptr; };
276bf215546Sopenharmony_ci   const char *kernel_source =
277bf215546Sopenharmony_ci   "struct s { __local uint *ptr; };\n\
278bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out)\n\
279bf215546Sopenharmony_ci   {\n\
280bf215546Sopenharmony_ci       __local uint tmp[2];\n\
281bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
282bf215546Sopenharmony_ci       tmp[idx] = idx;\n\
283bf215546Sopenharmony_ci       out[idx].ptr = &tmp[idx];\n\
284bf215546Sopenharmony_ci   }\n";
285bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>(std::vector<struct s>(2, { 0xdeadbeefdeadbeef }), SHADER_ARG_OUTPUT);
286bf215546Sopenharmony_ci   const uint64_t expected_ptr[] = {
287bf215546Sopenharmony_ci      0, 4,
288bf215546Sopenharmony_ci   };
289bf215546Sopenharmony_ci
290bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out);
291bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
292bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ptr, expected_ptr[i]);
293bf215546Sopenharmony_ci   }
294bf215546Sopenharmony_ci}
295bf215546Sopenharmony_ci
296bf215546Sopenharmony_ciTEST_F(ComputeTest, ret_private_ptr)
297bf215546Sopenharmony_ci{
298bf215546Sopenharmony_ci   struct s { uint64_t ptr; uint32_t value; };
299bf215546Sopenharmony_ci   const char *kernel_source =
300bf215546Sopenharmony_ci   "struct s { __private uint *ptr; uint value; };\n\
301bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out)\n\
302bf215546Sopenharmony_ci   {\n\
303bf215546Sopenharmony_ci       uint tmp[2] = {1, 2};\n\
304bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
305bf215546Sopenharmony_ci       out[idx].ptr = &tmp[idx];\n\
306bf215546Sopenharmony_ci       out[idx].value = *out[idx].ptr;\n\
307bf215546Sopenharmony_ci   }\n";
308bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>(std::vector<struct s>(2, { 0xdeadbeefdeadbeef }), SHADER_ARG_OUTPUT);
309bf215546Sopenharmony_ci   const uint64_t expected_ptr[] = {
310bf215546Sopenharmony_ci      0, 4,
311bf215546Sopenharmony_ci   };
312bf215546Sopenharmony_ci   const uint32_t expected_value[] = {
313bf215546Sopenharmony_ci      1, 2
314bf215546Sopenharmony_ci   };
315bf215546Sopenharmony_ci
316bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out);
317bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
318bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ptr, expected_ptr[i]);
319bf215546Sopenharmony_ci   }
320bf215546Sopenharmony_ci}
321bf215546Sopenharmony_ci
322bf215546Sopenharmony_ciTEST_F(ComputeTest, globals_8bit)
323bf215546Sopenharmony_ci{
324bf215546Sopenharmony_ci   const char *kernel_source =
325bf215546Sopenharmony_ci   "__kernel void main_test(__global unsigned char *inout)\n\
326bf215546Sopenharmony_ci   {\n\
327bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
328bf215546Sopenharmony_ci       inout[idx] = inout[idx] + 1;\n\
329bf215546Sopenharmony_ci   }\n";
330bf215546Sopenharmony_ci   auto inout = ShaderArg<uint8_t> ({ 100, 110, 120, 130 }, SHADER_ARG_INOUT);
331bf215546Sopenharmony_ci   const uint8_t expected[] = {
332bf215546Sopenharmony_ci      101, 111, 121, 131
333bf215546Sopenharmony_ci   };
334bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
335bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
336bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
337bf215546Sopenharmony_ci}
338bf215546Sopenharmony_ci
339bf215546Sopenharmony_ciTEST_F(ComputeTest, globals_16bit)
340bf215546Sopenharmony_ci{
341bf215546Sopenharmony_ci   const char *kernel_source =
342bf215546Sopenharmony_ci   "__kernel void main_test(__global unsigned short *inout)\n\
343bf215546Sopenharmony_ci   {\n\
344bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
345bf215546Sopenharmony_ci       inout[idx] = inout[idx] + 1;\n\
346bf215546Sopenharmony_ci   }\n";
347bf215546Sopenharmony_ci   auto inout = ShaderArg<uint16_t> ({ 10000, 10010, 10020, 10030 }, SHADER_ARG_INOUT);
348bf215546Sopenharmony_ci   const uint16_t expected[] = {
349bf215546Sopenharmony_ci      10001, 10011, 10021, 10031
350bf215546Sopenharmony_ci   };
351bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
352bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
353bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
354bf215546Sopenharmony_ci}
355bf215546Sopenharmony_ci
356bf215546Sopenharmony_ciTEST_F(ComputeTest, globals_64bit)
357bf215546Sopenharmony_ci{
358bf215546Sopenharmony_ci   const char *kernel_source =
359bf215546Sopenharmony_ci   "__kernel void main_test(__global unsigned long *inout)\n\
360bf215546Sopenharmony_ci   {\n\
361bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
362bf215546Sopenharmony_ci       inout[idx] = inout[idx] + 1;\n\
363bf215546Sopenharmony_ci   }\n";
364bf215546Sopenharmony_ci   uint64_t base = 1ull << 50;
365bf215546Sopenharmony_ci   auto inout = ShaderArg<uint64_t>({ base, base + 10, base + 20, base + 30 },
366bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
367bf215546Sopenharmony_ci   const uint64_t expected[] = {
368bf215546Sopenharmony_ci      base + 1, base + 11, base + 21, base + 31
369bf215546Sopenharmony_ci   };
370bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
371bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
372bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
373bf215546Sopenharmony_ci}
374bf215546Sopenharmony_ci
375bf215546Sopenharmony_ciTEST_F(ComputeTest, built_ins_global_id)
376bf215546Sopenharmony_ci{
377bf215546Sopenharmony_ci   const char *kernel_source =
378bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
379bf215546Sopenharmony_ci   {\n\
380bf215546Sopenharmony_ci       output[get_global_id(0)] = get_global_id(0);\n\
381bf215546Sopenharmony_ci   }\n";
382bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
383bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
384bf215546Sopenharmony_ci   const uint32_t expected[] = {
385bf215546Sopenharmony_ci      0, 1, 2, 3
386bf215546Sopenharmony_ci   };
387bf215546Sopenharmony_ci
388bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
389bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
390bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
391bf215546Sopenharmony_ci}
392bf215546Sopenharmony_ci
393bf215546Sopenharmony_ciTEST_F(ComputeTest, built_ins_global_id_rmw)
394bf215546Sopenharmony_ci{
395bf215546Sopenharmony_ci   const char *kernel_source =
396bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
397bf215546Sopenharmony_ci   {\n\
398bf215546Sopenharmony_ci       uint id = get_global_id(0);\n\
399bf215546Sopenharmony_ci       output[id] = output[id] * (id + 1);\n\
400bf215546Sopenharmony_ci   }\n";
401bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({0x00000001, 0x10000001, 0x00020002, 0x04010203},
402bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
403bf215546Sopenharmony_ci   const uint32_t expected[] = {
404bf215546Sopenharmony_ci      0x00000001, 0x20000002, 0x00060006, 0x1004080c
405bf215546Sopenharmony_ci   };
406bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
407bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
408bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
409bf215546Sopenharmony_ci}
410bf215546Sopenharmony_ci
411bf215546Sopenharmony_ciTEST_F(ComputeTest, types_float_basics)
412bf215546Sopenharmony_ci{
413bf215546Sopenharmony_ci   const char *kernel_source =
414bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
415bf215546Sopenharmony_ci   {\n\
416bf215546Sopenharmony_ci       output[get_global_id(0)] = (uint)((float)get_global_id(0) + 1.5f);\n\
417bf215546Sopenharmony_ci   }\n";
418bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
419bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
420bf215546Sopenharmony_ci   const uint32_t expected[] = {
421bf215546Sopenharmony_ci      1, 2, 3, 4
422bf215546Sopenharmony_ci   };
423bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
424bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
425bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
426bf215546Sopenharmony_ci}
427bf215546Sopenharmony_ci
428bf215546Sopenharmony_ciTEST_F(ComputeTest, DISABLED_types_double_basics)
429bf215546Sopenharmony_ci{
430bf215546Sopenharmony_ci   /* Disabled because doubles are unsupported */
431bf215546Sopenharmony_ci   const char *kernel_source =
432bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
433bf215546Sopenharmony_ci   {\n\
434bf215546Sopenharmony_ci       output[get_global_id(0)] = (uint)((double)get_global_id(0) + 1.5);\n\
435bf215546Sopenharmony_ci   }\n";
436bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
437bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
438bf215546Sopenharmony_ci   const uint32_t expected[] = {
439bf215546Sopenharmony_ci      1, 2, 3, 4
440bf215546Sopenharmony_ci   };
441bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
442bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
443bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
444bf215546Sopenharmony_ci}
445bf215546Sopenharmony_ci
446bf215546Sopenharmony_ciTEST_F(ComputeTest, types_short_basics)
447bf215546Sopenharmony_ci{
448bf215546Sopenharmony_ci   const char *kernel_source =
449bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
450bf215546Sopenharmony_ci   {\n\
451bf215546Sopenharmony_ci       output[get_global_id(0)] = (uint)((short)get_global_id(0) + (short)1);\n\
452bf215546Sopenharmony_ci   }\n";
453bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
454bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
455bf215546Sopenharmony_ci   const uint32_t expected[] = {
456bf215546Sopenharmony_ci      1, 2, 3, 4
457bf215546Sopenharmony_ci   };
458bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
459bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
460bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
461bf215546Sopenharmony_ci}
462bf215546Sopenharmony_ci
463bf215546Sopenharmony_ciTEST_F(ComputeTest, types_char_basics)
464bf215546Sopenharmony_ci{
465bf215546Sopenharmony_ci   const char *kernel_source =
466bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
467bf215546Sopenharmony_ci   {\n\
468bf215546Sopenharmony_ci       output[get_global_id(0)] = (uint)((char)get_global_id(0) + (char)1);\n\
469bf215546Sopenharmony_ci   }\n";
470bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
471bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
472bf215546Sopenharmony_ci   const uint32_t expected[] = {
473bf215546Sopenharmony_ci      1, 2, 3, 4
474bf215546Sopenharmony_ci   };
475bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
476bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
477bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
478bf215546Sopenharmony_ci}
479bf215546Sopenharmony_ci
480bf215546Sopenharmony_ciTEST_F(ComputeTest, types_if_statement)
481bf215546Sopenharmony_ci{
482bf215546Sopenharmony_ci   const char *kernel_source =
483bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
484bf215546Sopenharmony_ci   {\n\
485bf215546Sopenharmony_ci       int idx = get_global_id(0);\n\
486bf215546Sopenharmony_ci       if (idx > 0)\n\
487bf215546Sopenharmony_ci           output[idx] = ~idx;\n\
488bf215546Sopenharmony_ci       else\n\
489bf215546Sopenharmony_ci           output[0] = 0xff;\n\
490bf215546Sopenharmony_ci   }\n";
491bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
492bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
493bf215546Sopenharmony_ci   const uint32_t expected[] = {
494bf215546Sopenharmony_ci      0xff, ~1u, ~2u, ~3u
495bf215546Sopenharmony_ci   };
496bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
497bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
498bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
499bf215546Sopenharmony_ci}
500bf215546Sopenharmony_ci
501bf215546Sopenharmony_ciTEST_F(ComputeTest, types_do_while_loop)
502bf215546Sopenharmony_ci{
503bf215546Sopenharmony_ci   const char *kernel_source =
504bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
505bf215546Sopenharmony_ci   {\n\
506bf215546Sopenharmony_ci       int value = 1;\n\
507bf215546Sopenharmony_ci       int i = 1, n = get_global_id(0);\n\
508bf215546Sopenharmony_ci       do {\n\
509bf215546Sopenharmony_ci          value *= i++;\n\
510bf215546Sopenharmony_ci       } while (i <= n);\n\
511bf215546Sopenharmony_ci       output[n] = value;\n\
512bf215546Sopenharmony_ci   }\n";
513bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(5, 0xdeadbeef),
514bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
515bf215546Sopenharmony_ci   const uint32_t expected[] = {
516bf215546Sopenharmony_ci      1, 1, 1*2, 1*2*3, 1*2*3*4
517bf215546Sopenharmony_ci   };
518bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
519bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
520bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
521bf215546Sopenharmony_ci}
522bf215546Sopenharmony_ci
523bf215546Sopenharmony_ciTEST_F(ComputeTest, types_for_loop)
524bf215546Sopenharmony_ci{
525bf215546Sopenharmony_ci   const char *kernel_source =
526bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
527bf215546Sopenharmony_ci   {\n\
528bf215546Sopenharmony_ci       int value = 1;\n\
529bf215546Sopenharmony_ci       int n = get_global_id(0);\n\
530bf215546Sopenharmony_ci       for (int i = 1; i <= n; ++i)\n\
531bf215546Sopenharmony_ci          value *= i;\n\
532bf215546Sopenharmony_ci       output[n] = value;\n\
533bf215546Sopenharmony_ci   }\n";
534bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(5, 0xdeadbeef),
535bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
536bf215546Sopenharmony_ci   const uint32_t expected[] = {
537bf215546Sopenharmony_ci      1, 1, 1*2, 1*2*3, 1*2*3*4
538bf215546Sopenharmony_ci   };
539bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
540bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
541bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
542bf215546Sopenharmony_ci}
543bf215546Sopenharmony_ci
544bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_local_array_long)
545bf215546Sopenharmony_ci{
546bf215546Sopenharmony_ci   const char *kernel_source =
547bf215546Sopenharmony_ci   "__kernel void main_test(__global ulong *inout)\n\
548bf215546Sopenharmony_ci   {\n\
549bf215546Sopenharmony_ci      ulong tmp[] = {\n\
550bf215546Sopenharmony_ci         get_global_id(1) + 0x00000000,\n\
551bf215546Sopenharmony_ci         get_global_id(1) + 0x10000001,\n\
552bf215546Sopenharmony_ci         get_global_id(1) + 0x20000020,\n\
553bf215546Sopenharmony_ci         get_global_id(1) + 0x30000300,\n\
554bf215546Sopenharmony_ci      };\n\
555bf215546Sopenharmony_ci      uint idx = get_global_id(0);\n\
556bf215546Sopenharmony_ci      inout[idx] = tmp[idx];\n\
557bf215546Sopenharmony_ci   }\n";
558bf215546Sopenharmony_ci   auto inout = ShaderArg<uint64_t>({ 0, 0, 0, 0 }, SHADER_ARG_INOUT);
559bf215546Sopenharmony_ci   const uint64_t expected[] = {
560bf215546Sopenharmony_ci      0x00000000, 0x10000001, 0x20000020, 0x30000300,
561bf215546Sopenharmony_ci   };
562bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
563bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
564bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
565bf215546Sopenharmony_ci}
566bf215546Sopenharmony_ci
567bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_local_array_short)
568bf215546Sopenharmony_ci{
569bf215546Sopenharmony_ci   const char *kernel_source =
570bf215546Sopenharmony_ci   "__kernel void main_test(__global ushort *inout)\n\
571bf215546Sopenharmony_ci   {\n\
572bf215546Sopenharmony_ci      ushort tmp[] = {\n\
573bf215546Sopenharmony_ci         get_global_id(1) + 0x00,\n\
574bf215546Sopenharmony_ci         get_global_id(1) + 0x10,\n\
575bf215546Sopenharmony_ci         get_global_id(1) + 0x20,\n\
576bf215546Sopenharmony_ci         get_global_id(1) + 0x30,\n\
577bf215546Sopenharmony_ci      };\n\
578bf215546Sopenharmony_ci      uint idx = get_global_id(0);\n\
579bf215546Sopenharmony_ci      inout[idx] = tmp[idx];\n\
580bf215546Sopenharmony_ci   }\n";
581bf215546Sopenharmony_ci   auto inout = ShaderArg<uint16_t>({ 0, 0, 0, 0 }, SHADER_ARG_INOUT);
582bf215546Sopenharmony_ci   const uint16_t expected[] = {
583bf215546Sopenharmony_ci      0x00, 0x10, 0x20, 0x30,
584bf215546Sopenharmony_ci   };
585bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
586bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
587bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
588bf215546Sopenharmony_ci}
589bf215546Sopenharmony_ci
590bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_local_array_struct_vec_float_misaligned)
591bf215546Sopenharmony_ci{
592bf215546Sopenharmony_ci   const char *kernel_source =
593bf215546Sopenharmony_ci   "struct has_vecs { uchar c; ushort s; float2 f; };\n\
594bf215546Sopenharmony_ci   __kernel void main_test(__global uint *inout)\n\
595bf215546Sopenharmony_ci   {\n\
596bf215546Sopenharmony_ci      struct has_vecs tmp[] = {\n\
597bf215546Sopenharmony_ci         { 10 + get_global_id(0), get_global_id(1), { 10.0f, 1.0f } },\n\
598bf215546Sopenharmony_ci         { 19 + get_global_id(0), get_global_id(1), { 20.0f, 4.0f } },\n\
599bf215546Sopenharmony_ci         { 28 + get_global_id(0), get_global_id(1), { 30.0f, 9.0f } },\n\
600bf215546Sopenharmony_ci         { 37 + get_global_id(0), get_global_id(1), { 40.0f, 16.0f } },\n\
601bf215546Sopenharmony_ci      };\n\
602bf215546Sopenharmony_ci      uint idx = get_global_id(0);\n\
603bf215546Sopenharmony_ci      uint mul = (tmp[idx].c + tmp[idx].s) * trunc(tmp[idx].f[0]);\n\
604bf215546Sopenharmony_ci      inout[idx] = mul + trunc(tmp[idx].f[1]);\n\
605bf215546Sopenharmony_ci   }\n";
606bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 0, 0, 0 }, SHADER_ARG_INOUT);
607bf215546Sopenharmony_ci   const uint16_t expected[] = { 101, 404, 909, 1616 };
608bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
609bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
610bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
611bf215546Sopenharmony_ci}
612bf215546Sopenharmony_ci
613bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_local_array)
614bf215546Sopenharmony_ci{
615bf215546Sopenharmony_ci   const char *kernel_source =
616bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
617bf215546Sopenharmony_ci   {\n\
618bf215546Sopenharmony_ci      uint tmp[] = {\n\
619bf215546Sopenharmony_ci         get_global_id(1) + 0x00,\n\
620bf215546Sopenharmony_ci         get_global_id(1) + 0x10,\n\
621bf215546Sopenharmony_ci         get_global_id(1) + 0x20,\n\
622bf215546Sopenharmony_ci         get_global_id(1) + 0x30,\n\
623bf215546Sopenharmony_ci      };\n\
624bf215546Sopenharmony_ci      uint idx = get_global_id(0);\n\
625bf215546Sopenharmony_ci      inout[idx] = tmp[idx];\n\
626bf215546Sopenharmony_ci   }\n";
627bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 0, 0, 0 }, SHADER_ARG_INOUT);
628bf215546Sopenharmony_ci   const uint32_t expected[] = {
629bf215546Sopenharmony_ci      0x00, 0x10, 0x20, 0x30,
630bf215546Sopenharmony_ci   };
631bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
632bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
633bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
634bf215546Sopenharmony_ci}
635bf215546Sopenharmony_ci
636bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_global_struct_array)
637bf215546Sopenharmony_ci{
638bf215546Sopenharmony_ci   struct two_vals { uint32_t add; uint32_t mul; };
639bf215546Sopenharmony_ci   const char *kernel_source =
640bf215546Sopenharmony_ci   "struct two_vals { uint add; uint mul; };\n\
641bf215546Sopenharmony_ci   __kernel void main_test(__global struct two_vals *in_out)\n\
642bf215546Sopenharmony_ci   {\n\
643bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
644bf215546Sopenharmony_ci      in_out[id].add = in_out[id].add + id;\n\
645bf215546Sopenharmony_ci      in_out[id].mul = in_out[id].mul * id;\n\
646bf215546Sopenharmony_ci   }\n";
647bf215546Sopenharmony_ci   auto inout = ShaderArg<struct two_vals>({ { 8, 8 }, { 16, 16 }, { 64, 64 }, { 65536, 65536 } },
648bf215546Sopenharmony_ci                                           SHADER_ARG_INOUT);
649bf215546Sopenharmony_ci   const struct two_vals expected[] = {
650bf215546Sopenharmony_ci      { 8 + 0, 8 * 0 },
651bf215546Sopenharmony_ci      { 16 + 1, 16 * 1 },
652bf215546Sopenharmony_ci      { 64 + 2, 64 * 2 },
653bf215546Sopenharmony_ci      { 65536 + 3, 65536 * 3 }
654bf215546Sopenharmony_ci   };
655bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
656bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
657bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].add, expected[i].add);
658bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].mul, expected[i].mul);
659bf215546Sopenharmony_ci   }
660bf215546Sopenharmony_ci}
661bf215546Sopenharmony_ci
662bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_global_uint2)
663bf215546Sopenharmony_ci{
664bf215546Sopenharmony_ci   struct uint2 { uint32_t x; uint32_t y; };
665bf215546Sopenharmony_ci   const char *kernel_source =
666bf215546Sopenharmony_ci   "__kernel void main_test(__global uint2 *inout)\n\
667bf215546Sopenharmony_ci   {\n\
668bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
669bf215546Sopenharmony_ci      inout[id].x = inout[id].x + id;\n\
670bf215546Sopenharmony_ci      inout[id].y = inout[id].y * id;\n\
671bf215546Sopenharmony_ci   }\n";
672bf215546Sopenharmony_ci   auto inout = ShaderArg<struct uint2>({ { 8, 8 }, { 16, 16 }, { 64, 64 }, { 65536, 65536 } },
673bf215546Sopenharmony_ci                                        SHADER_ARG_INOUT);
674bf215546Sopenharmony_ci   const struct uint2 expected[] = {
675bf215546Sopenharmony_ci      { 8 + 0, 8 * 0 },
676bf215546Sopenharmony_ci      { 16 + 1, 16 * 1 },
677bf215546Sopenharmony_ci      { 64 + 2, 64 * 2 },
678bf215546Sopenharmony_ci      { 65536 + 3, 65536 * 3 }
679bf215546Sopenharmony_ci   };
680bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
681bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
682bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].x, expected[i].x);
683bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].y, expected[i].y);
684bf215546Sopenharmony_ci   }
685bf215546Sopenharmony_ci}
686bf215546Sopenharmony_ci
687bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_global_ushort2)
688bf215546Sopenharmony_ci{
689bf215546Sopenharmony_ci   struct ushort2 { uint16_t x; uint16_t y; };
690bf215546Sopenharmony_ci   const char *kernel_source =
691bf215546Sopenharmony_ci   "__kernel void main_test(__global ushort2 *inout)\n\
692bf215546Sopenharmony_ci   {\n\
693bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
694bf215546Sopenharmony_ci      inout[id].x = inout[id].x + id;\n\
695bf215546Sopenharmony_ci      inout[id].y = inout[id].y * id;\n\
696bf215546Sopenharmony_ci   }\n";
697bf215546Sopenharmony_ci   auto inout = ShaderArg<struct ushort2>({ { 8, 8 }, { 16, 16 }, { 64, 64 },
698bf215546Sopenharmony_ci                                            { (uint16_t)65536, (uint16_t)65536 } },
699bf215546Sopenharmony_ci                                          SHADER_ARG_INOUT);
700bf215546Sopenharmony_ci   const struct ushort2 expected[] = {
701bf215546Sopenharmony_ci      { 8 + 0, 8 * 0 },
702bf215546Sopenharmony_ci      { 16 + 1, 16 * 1 },
703bf215546Sopenharmony_ci      { 64 + 2, 64 * 2 },
704bf215546Sopenharmony_ci      { (uint16_t)(65536 + 3), (uint16_t)(65536 * 3) }
705bf215546Sopenharmony_ci   };
706bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
707bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
708bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].x, expected[i].x);
709bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].y, expected[i].y);
710bf215546Sopenharmony_ci   }
711bf215546Sopenharmony_ci}
712bf215546Sopenharmony_ci
713bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_global_uchar3)
714bf215546Sopenharmony_ci{
715bf215546Sopenharmony_ci   struct uchar3 { uint8_t x; uint8_t y; uint8_t z; uint8_t pad; };
716bf215546Sopenharmony_ci   const char *kernel_source =
717bf215546Sopenharmony_ci   "__kernel void main_test(__global uchar3 *inout)\n\
718bf215546Sopenharmony_ci   {\n\
719bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
720bf215546Sopenharmony_ci      inout[id].x = inout[id].x + id;\n\
721bf215546Sopenharmony_ci      inout[id].y = inout[id].y * id;\n\
722bf215546Sopenharmony_ci      inout[id].z = inout[id].y + inout[id].x;\n\
723bf215546Sopenharmony_ci   }\n";
724bf215546Sopenharmony_ci   auto inout = ShaderArg<struct uchar3>({ { 8, 8, 8 }, { 16, 16, 16 }, { 64, 64, 64 }, { 255, 255, 255 } },
725bf215546Sopenharmony_ci                                         SHADER_ARG_INOUT);
726bf215546Sopenharmony_ci   const struct uchar3 expected[] = {
727bf215546Sopenharmony_ci      { 8 + 0, 8 * 0, (8 + 0) + (8 * 0) },
728bf215546Sopenharmony_ci      { 16 + 1, 16 * 1, (16 + 1) + (16 * 1) },
729bf215546Sopenharmony_ci      { 64 + 2, 64 * 2, (64 + 2) + (64 * 2) },
730bf215546Sopenharmony_ci      { (uint8_t)(255 + 3), (uint8_t)(255 * 3), (uint8_t)((255 + 3) + (255 * 3)) }
731bf215546Sopenharmony_ci   };
732bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
733bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
734bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].x, expected[i].x);
735bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].y, expected[i].y);
736bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].z, expected[i].z);
737bf215546Sopenharmony_ci   }
738bf215546Sopenharmony_ci}
739bf215546Sopenharmony_ci
740bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_constant_uchar3)
741bf215546Sopenharmony_ci{
742bf215546Sopenharmony_ci   struct uchar3 { uint8_t x; uint8_t y; uint8_t z; uint8_t pad; };
743bf215546Sopenharmony_ci   const char *kernel_source =
744bf215546Sopenharmony_ci   "__kernel void main_test(__global uchar3 *out, __constant uchar3 *in)\n\
745bf215546Sopenharmony_ci   {\n\
746bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
747bf215546Sopenharmony_ci      out[id].x = in[id].x + id;\n\
748bf215546Sopenharmony_ci      out[id].y = in[id].y * id;\n\
749bf215546Sopenharmony_ci      out[id].z = out[id].y + out[id].x;\n\
750bf215546Sopenharmony_ci   }\n";
751bf215546Sopenharmony_ci   auto in = ShaderArg<struct uchar3>({ { 8, 8, 8 }, { 16, 16, 16 }, { 64, 64, 64 }, { 255, 255, 255 } },
752bf215546Sopenharmony_ci                                      SHADER_ARG_INPUT);
753bf215546Sopenharmony_ci   auto out = ShaderArg<struct uchar3>(std::vector<struct uchar3>(4, { 0xff, 0xff, 0xff }),
754bf215546Sopenharmony_ci                                      SHADER_ARG_OUTPUT);
755bf215546Sopenharmony_ci   const struct uchar3 expected[] = {
756bf215546Sopenharmony_ci      { 8 + 0, 8 * 0, (8 + 0) + (8 * 0) },
757bf215546Sopenharmony_ci      { 16 + 1, 16 * 1, (16 + 1) + (16 * 1) },
758bf215546Sopenharmony_ci      { 64 + 2, 64 * 2, (64 + 2) + (64 * 2) },
759bf215546Sopenharmony_ci      { (uint8_t)(255 + 3), (uint8_t)(255 * 3), (uint8_t)((255 + 3) + (255 * 3)) }
760bf215546Sopenharmony_ci   };
761bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
762bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
763bf215546Sopenharmony_ci      EXPECT_EQ(out[i].x, expected[i].x);
764bf215546Sopenharmony_ci      EXPECT_EQ(out[i].y, expected[i].y);
765bf215546Sopenharmony_ci      EXPECT_EQ(out[i].z, expected[i].z);
766bf215546Sopenharmony_ci   }
767bf215546Sopenharmony_ci}
768bf215546Sopenharmony_ci
769bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_global_uint8)
770bf215546Sopenharmony_ci{
771bf215546Sopenharmony_ci   struct uint8 {
772bf215546Sopenharmony_ci      uint32_t s0; uint32_t s1; uint32_t s2; uint32_t s3;
773bf215546Sopenharmony_ci      uint32_t s4; uint32_t s5; uint32_t s6; uint32_t s7;
774bf215546Sopenharmony_ci   };
775bf215546Sopenharmony_ci   const char *kernel_source =
776bf215546Sopenharmony_ci   "__kernel void main_test(__global uint8 *inout)\n\
777bf215546Sopenharmony_ci   {\n\
778bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
779bf215546Sopenharmony_ci      inout[id].s01234567 = inout[id].s01234567 * 2;\n\
780bf215546Sopenharmony_ci   }\n";
781bf215546Sopenharmony_ci   auto inout = ShaderArg<struct uint8>({ { 1, 2, 3, 4, 5, 6, 7, 8 } },
782bf215546Sopenharmony_ci                                        SHADER_ARG_INOUT);
783bf215546Sopenharmony_ci   const struct uint8 expected[] = {
784bf215546Sopenharmony_ci      { 2, 4, 6, 8, 10, 12, 14, 16 }
785bf215546Sopenharmony_ci   };
786bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
787bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
788bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s0, expected[i].s0);
789bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s1, expected[i].s1);
790bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s2, expected[i].s2);
791bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s3, expected[i].s3);
792bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s4, expected[i].s4);
793bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s5, expected[i].s5);
794bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s6, expected[i].s6);
795bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].s7, expected[i].s7);
796bf215546Sopenharmony_ci   }
797bf215546Sopenharmony_ci}
798bf215546Sopenharmony_ci
799bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_local_ulong16)
800bf215546Sopenharmony_ci{
801bf215546Sopenharmony_ci   struct ulong16 {
802bf215546Sopenharmony_ci      uint64_t values[16];
803bf215546Sopenharmony_ci   };
804bf215546Sopenharmony_ci   const char *kernel_source =
805bf215546Sopenharmony_ci   R"(__kernel void main_test(__global ulong16 *inout)
806bf215546Sopenharmony_ci   {
807bf215546Sopenharmony_ci      __local ulong16 local_array[2];
808bf215546Sopenharmony_ci      uint id = get_global_id(0);
809bf215546Sopenharmony_ci      local_array[id] = inout[id];
810bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);
811bf215546Sopenharmony_ci      inout[id] = local_array[0] * 2;
812bf215546Sopenharmony_ci   })";
813bf215546Sopenharmony_ci   auto inout = ShaderArg<struct ulong16>({ { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
814bf215546Sopenharmony_ci                                        SHADER_ARG_INOUT);
815bf215546Sopenharmony_ci   const struct ulong16 expected[] = {
816bf215546Sopenharmony_ci      { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30 }
817bf215546Sopenharmony_ci   };
818bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
819bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
820bf215546Sopenharmony_ci      for (int j = 0; j < 16; ++j) {
821bf215546Sopenharmony_ci         EXPECT_EQ(inout[i].values[j], expected[i].values[j]);
822bf215546Sopenharmony_ci      }
823bf215546Sopenharmony_ci   }
824bf215546Sopenharmony_ci}
825bf215546Sopenharmony_ci
826bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_constant_uint8)
827bf215546Sopenharmony_ci{
828bf215546Sopenharmony_ci   struct uint8 {
829bf215546Sopenharmony_ci      uint32_t s0; uint32_t s1; uint32_t s2; uint32_t s3;
830bf215546Sopenharmony_ci      uint32_t s4; uint32_t s5; uint32_t s6; uint32_t s7;
831bf215546Sopenharmony_ci   };
832bf215546Sopenharmony_ci   const char *kernel_source =
833bf215546Sopenharmony_ci   "__kernel void main_test(__global uint8 *out, __constant uint8 *in)\n\
834bf215546Sopenharmony_ci   {\n\
835bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
836bf215546Sopenharmony_ci      out[id].s01234567 = in[id].s01234567 * 2;\n\
837bf215546Sopenharmony_ci   }\n";
838bf215546Sopenharmony_ci   auto in = ShaderArg<struct uint8>({ { 1, 2, 3, 4, 5, 6, 7, 8 } },
839bf215546Sopenharmony_ci                                     SHADER_ARG_INPUT);
840bf215546Sopenharmony_ci   auto out = ShaderArg<struct uint8>({ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } },
841bf215546Sopenharmony_ci                                      SHADER_ARG_INOUT);
842bf215546Sopenharmony_ci   const struct uint8 expected[] = {
843bf215546Sopenharmony_ci      { 2, 4, 6, 8, 10, 12, 14, 16 }
844bf215546Sopenharmony_ci   };
845bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
846bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
847bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s0, expected[i].s0);
848bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s1, expected[i].s1);
849bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s2, expected[i].s2);
850bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s3, expected[i].s3);
851bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s4, expected[i].s4);
852bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s5, expected[i].s5);
853bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s6, expected[i].s6);
854bf215546Sopenharmony_ci      EXPECT_EQ(out[i].s7, expected[i].s7);
855bf215546Sopenharmony_ci   }
856bf215546Sopenharmony_ci}
857bf215546Sopenharmony_ci
858bf215546Sopenharmony_ciTEST_F(ComputeTest, complex_types_const_array)
859bf215546Sopenharmony_ci{
860bf215546Sopenharmony_ci   const char *kernel_source =
861bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
862bf215546Sopenharmony_ci   {\n\
863bf215546Sopenharmony_ci       const uint foo[] = { 100, 101, 102, 103 };\n\
864bf215546Sopenharmony_ci       output[get_global_id(0)] = foo[get_global_id(0) % 4];\n\
865bf215546Sopenharmony_ci   }\n";
866bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
867bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
868bf215546Sopenharmony_ci   const uint32_t expected[] = {
869bf215546Sopenharmony_ci      100, 101, 102, 103
870bf215546Sopenharmony_ci   };
871bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
872bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
873bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
874bf215546Sopenharmony_ci}
875bf215546Sopenharmony_ci
876bf215546Sopenharmony_ciTEST_F(ComputeTest, mem_access_load_store_ordering)
877bf215546Sopenharmony_ci{
878bf215546Sopenharmony_ci   const char *kernel_source =
879bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
880bf215546Sopenharmony_ci   {\n\
881bf215546Sopenharmony_ci       uint foo[4];\n\
882bf215546Sopenharmony_ci       foo[0] = 0x11111111;\n\
883bf215546Sopenharmony_ci       foo[1] = 0x22222222;\n\
884bf215546Sopenharmony_ci       foo[2] = 0x44444444;\n\
885bf215546Sopenharmony_ci       foo[3] = 0x88888888;\n\
886bf215546Sopenharmony_ci       foo[get_global_id(1)] -= 0x11111111; // foo[0] = 0 \n\
887bf215546Sopenharmony_ci       foo[0] += get_global_id(0); // foo[0] = tid\n\
888bf215546Sopenharmony_ci       foo[foo[get_global_id(1)]] = get_global_id(0); // foo[tid] = tid\n\
889bf215546Sopenharmony_ci       output[get_global_id(0)] = foo[get_global_id(0)]; // output[tid] = tid\n\
890bf215546Sopenharmony_ci   }\n";
891bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
892bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
893bf215546Sopenharmony_ci   const uint16_t expected[] = {
894bf215546Sopenharmony_ci      0, 1, 2, 3
895bf215546Sopenharmony_ci   };
896bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
897bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
898bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
899bf215546Sopenharmony_ci}
900bf215546Sopenharmony_ci
901bf215546Sopenharmony_ciTEST_F(ComputeTest, two_const_arrays)
902bf215546Sopenharmony_ci{
903bf215546Sopenharmony_ci   const char *kernel_source =
904bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *output)\n\
905bf215546Sopenharmony_ci   {\n\
906bf215546Sopenharmony_ci      uint id = get_global_id(0);\n\
907bf215546Sopenharmony_ci      uint foo[4] = {100, 101, 102, 103};\n\
908bf215546Sopenharmony_ci      uint bar[4] = {1, 2, 3, 4};\n\
909bf215546Sopenharmony_ci      output[id] = foo[id] * bar[id];\n\
910bf215546Sopenharmony_ci   }\n";
911bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
912bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
913bf215546Sopenharmony_ci   const uint32_t expected[] = {
914bf215546Sopenharmony_ci      100, 202, 306, 412
915bf215546Sopenharmony_ci   };
916bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
917bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
918bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
919bf215546Sopenharmony_ci}
920bf215546Sopenharmony_ci
921bf215546Sopenharmony_ciTEST_F(ComputeTest, imod_pos)
922bf215546Sopenharmony_ci{
923bf215546Sopenharmony_ci   const char *kernel_source =
924bf215546Sopenharmony_ci   "__kernel void main_test(__global int *inout)\n\
925bf215546Sopenharmony_ci   {\n\
926bf215546Sopenharmony_ci       inout[get_global_id(0)] = inout[get_global_id(0)] % 3;\n\
927bf215546Sopenharmony_ci   }\n";
928bf215546Sopenharmony_ci   auto inout = ShaderArg<int32_t>({ -4, -3, -2, -1, 0, 1, 2, 3, 4 },
929bf215546Sopenharmony_ci                                   SHADER_ARG_INOUT);
930bf215546Sopenharmony_ci   const int32_t expected[] = {
931bf215546Sopenharmony_ci      -1, 0, -2, -1,  0, 1, 2, 0, 1
932bf215546Sopenharmony_ci   };
933bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
934bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
935bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
936bf215546Sopenharmony_ci}
937bf215546Sopenharmony_ci
938bf215546Sopenharmony_ciTEST_F(ComputeTest, imod_neg)
939bf215546Sopenharmony_ci{
940bf215546Sopenharmony_ci   const char *kernel_source =
941bf215546Sopenharmony_ci   "__kernel void main_test(__global int *inout)\n\
942bf215546Sopenharmony_ci   {\n\
943bf215546Sopenharmony_ci       inout[get_global_id(0)] = inout[get_global_id(0)] % -3;\n\
944bf215546Sopenharmony_ci   }\n";
945bf215546Sopenharmony_ci   auto inout = ShaderArg<int32_t>({ -4, -3, -2, -1, 0, 1, 2, 3, 4 },
946bf215546Sopenharmony_ci                                   SHADER_ARG_INOUT);
947bf215546Sopenharmony_ci   const int32_t expected[] = {
948bf215546Sopenharmony_ci      -1, 0, -2, -1,  0, 1, 2, 0, 1
949bf215546Sopenharmony_ci   };
950bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
951bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
952bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
953bf215546Sopenharmony_ci}
954bf215546Sopenharmony_ci
955bf215546Sopenharmony_ciTEST_F(ComputeTest, umod)
956bf215546Sopenharmony_ci{
957bf215546Sopenharmony_ci   const char *kernel_source =
958bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
959bf215546Sopenharmony_ci   {\n\
960bf215546Sopenharmony_ci       inout[get_global_id(0)] = inout[get_global_id(0)] % 0xfffffffc;\n\
961bf215546Sopenharmony_ci   }\n";
962bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0xfffffffa, 0xfffffffb, 0xfffffffc, 0xfffffffd, 0xfffffffe },
963bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
964bf215546Sopenharmony_ci   const uint32_t expected[] = {
965bf215546Sopenharmony_ci      0xfffffffa, 0xfffffffb, 0, 1, 2
966bf215546Sopenharmony_ci   };
967bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
968bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
969bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
970bf215546Sopenharmony_ci}
971bf215546Sopenharmony_ci
972bf215546Sopenharmony_ciTEST_F(ComputeTest, rotate)
973bf215546Sopenharmony_ci{
974bf215546Sopenharmony_ci   const char *kernel_source =
975bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
976bf215546Sopenharmony_ci   {\n\
977bf215546Sopenharmony_ci       inout[get_global_id(0)] = rotate(inout[get_global_id(0)], (uint)get_global_id(0) * 4);\n\
978bf215546Sopenharmony_ci   }\n";
979bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
980bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
981bf215546Sopenharmony_ci   const uint32_t expected[] = {
982bf215546Sopenharmony_ci      0xdeadbeef, 0xeadbeefd, 0xadbeefde, 0xdbeefdea
983bf215546Sopenharmony_ci   };
984bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
985bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
986bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
987bf215546Sopenharmony_ci}
988bf215546Sopenharmony_ci
989bf215546Sopenharmony_ciTEST_F(ComputeTest, popcount)
990bf215546Sopenharmony_ci{
991bf215546Sopenharmony_ci   const char *kernel_source =
992bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
993bf215546Sopenharmony_ci   {\n\
994bf215546Sopenharmony_ci       inout[get_global_id(0)] = popcount(inout[get_global_id(0)]);\n\
995bf215546Sopenharmony_ci   }\n";
996bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 0x1, 0x3, 0x101, 0x110011, ~0u },
997bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
998bf215546Sopenharmony_ci   const uint32_t expected[] = {
999bf215546Sopenharmony_ci      0, 1, 2, 2, 4, 32
1000bf215546Sopenharmony_ci   };
1001bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1002bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1003bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1004bf215546Sopenharmony_ci}
1005bf215546Sopenharmony_ci
1006bf215546Sopenharmony_ciTEST_F(ComputeTest, hadd)
1007bf215546Sopenharmony_ci{
1008bf215546Sopenharmony_ci   const char *kernel_source =
1009bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
1010bf215546Sopenharmony_ci   {\n\
1011bf215546Sopenharmony_ci       inout[get_global_id(0)] = hadd(inout[get_global_id(0)], 1u << 31);\n\
1012bf215546Sopenharmony_ci   }\n";
1013bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 1, 2, 3, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xffffffff },
1014bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
1015bf215546Sopenharmony_ci   const uint32_t expected[] = {
1016bf215546Sopenharmony_ci      (1u << 31) >> 1,
1017bf215546Sopenharmony_ci      ((1u << 31) + 1) >> 1,
1018bf215546Sopenharmony_ci      ((1u << 31) + 2) >> 1,
1019bf215546Sopenharmony_ci      ((1u << 31) + 3) >> 1,
1020bf215546Sopenharmony_ci      ((1ull << 31) + 0xfffffffc) >> 1,
1021bf215546Sopenharmony_ci      ((1ull << 31) + 0xfffffffd) >> 1,
1022bf215546Sopenharmony_ci      ((1ull << 31) + 0xfffffffe) >> 1,
1023bf215546Sopenharmony_ci      ((1ull << 31) + 0xffffffff) >> 1,
1024bf215546Sopenharmony_ci   };
1025bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1026bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1027bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1028bf215546Sopenharmony_ci}
1029bf215546Sopenharmony_ci
1030bf215546Sopenharmony_ciTEST_F(ComputeTest, rhadd)
1031bf215546Sopenharmony_ci{
1032bf215546Sopenharmony_ci   const char *kernel_source =
1033bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
1034bf215546Sopenharmony_ci   {\n\
1035bf215546Sopenharmony_ci       inout[get_global_id(0)] = rhadd(inout[get_global_id(0)], 1u << 31);\n\
1036bf215546Sopenharmony_ci   }\n";
1037bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 1, 2, 3, 0xfffffffc, 0xfffffffd, 0xfffffffe, 0xffffffff },
1038bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
1039bf215546Sopenharmony_ci   const uint32_t expected[] = {
1040bf215546Sopenharmony_ci      ((1u << 31) + 1) >> 1,
1041bf215546Sopenharmony_ci      ((1u << 31) + 2) >> 1,
1042bf215546Sopenharmony_ci      ((1u << 31) + 3) >> 1,
1043bf215546Sopenharmony_ci      ((1u << 31) + 4) >> 1,
1044bf215546Sopenharmony_ci      ((1ull << 31) + 0xfffffffd) >> 1,
1045bf215546Sopenharmony_ci      ((1ull << 31) + 0xfffffffe) >> 1,
1046bf215546Sopenharmony_ci      ((1ull << 31) + 0xffffffff) >> 1,
1047bf215546Sopenharmony_ci      ((1ull << 31) + (1ull << 32)) >> 1,
1048bf215546Sopenharmony_ci   };
1049bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1050bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1051bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1052bf215546Sopenharmony_ci}
1053bf215546Sopenharmony_ci
1054bf215546Sopenharmony_ciTEST_F(ComputeTest, add_sat)
1055bf215546Sopenharmony_ci{
1056bf215546Sopenharmony_ci   const char *kernel_source =
1057bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
1058bf215546Sopenharmony_ci   {\n\
1059bf215546Sopenharmony_ci       inout[get_global_id(0)] = add_sat(inout[get_global_id(0)], 2u);\n\
1060bf215546Sopenharmony_ci   }\n";
1061bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0xffffffff - 3, 0xffffffff - 2, 0xffffffff - 1, 0xffffffff },
1062bf215546Sopenharmony_ci                                    SHADER_ARG_INOUT);
1063bf215546Sopenharmony_ci   const uint32_t expected[] = {
1064bf215546Sopenharmony_ci      0xffffffff - 1, 0xffffffff, 0xffffffff, 0xffffffff
1065bf215546Sopenharmony_ci   };
1066bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1067bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1068bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1069bf215546Sopenharmony_ci}
1070bf215546Sopenharmony_ci
1071bf215546Sopenharmony_ciTEST_F(ComputeTest, sub_sat)
1072bf215546Sopenharmony_ci{
1073bf215546Sopenharmony_ci   const char *kernel_source =
1074bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
1075bf215546Sopenharmony_ci   {\n\
1076bf215546Sopenharmony_ci       inout[get_global_id(0)] = sub_sat(inout[get_global_id(0)], 2u);\n\
1077bf215546Sopenharmony_ci   }\n";
1078bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 1, 2, 3 }, SHADER_ARG_INOUT);
1079bf215546Sopenharmony_ci   const uint32_t expected[] = {
1080bf215546Sopenharmony_ci      0, 0, 0, 1
1081bf215546Sopenharmony_ci   };
1082bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1083bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1084bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1085bf215546Sopenharmony_ci}
1086bf215546Sopenharmony_ci
1087bf215546Sopenharmony_ciTEST_F(ComputeTest, mul_hi)
1088bf215546Sopenharmony_ci{
1089bf215546Sopenharmony_ci   const char *kernel_source =
1090bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
1091bf215546Sopenharmony_ci   {\n\
1092bf215546Sopenharmony_ci       inout[get_global_id(0)] = mul_hi(inout[get_global_id(0)], 1u << 31);\n\
1093bf215546Sopenharmony_ci   }\n";
1094bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 1, 2, 3, (1u << 31) }, SHADER_ARG_INOUT);
1095bf215546Sopenharmony_ci   const uint32_t expected[] = {
1096bf215546Sopenharmony_ci      0, 0, 1, 1, (1u << 30)
1097bf215546Sopenharmony_ci   };
1098bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1099bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1100bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1101bf215546Sopenharmony_ci}
1102bf215546Sopenharmony_ci
1103bf215546Sopenharmony_ciTEST_F(ComputeTest, ldexp_x)
1104bf215546Sopenharmony_ci{
1105bf215546Sopenharmony_ci   const char *kernel_source =
1106bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1107bf215546Sopenharmony_ci   {\n\
1108bf215546Sopenharmony_ci       inout[get_global_id(0)] = ldexp(inout[get_global_id(0)], 5);\n\
1109bf215546Sopenharmony_ci   }\n";
1110bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 0.5f, 1.0f, 2.0f }, SHADER_ARG_INOUT);
1111bf215546Sopenharmony_ci   const float expected[] = {
1112bf215546Sopenharmony_ci      ldexp(0.0f, 5), ldexp(0.5f, 5), ldexp(1.0f, 5), ldexp(2.0f, 5)
1113bf215546Sopenharmony_ci   };
1114bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1115bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1116bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1117bf215546Sopenharmony_ci}
1118bf215546Sopenharmony_ci
1119bf215546Sopenharmony_ciTEST_F(ComputeTest, ldexp_y)
1120bf215546Sopenharmony_ci{
1121bf215546Sopenharmony_ci   const char *kernel_source =
1122bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1123bf215546Sopenharmony_ci   {\n\
1124bf215546Sopenharmony_ci       inout[get_global_id(0)] = ldexp(inout[get_global_id(0)], get_global_id(0));\n\
1125bf215546Sopenharmony_ci   }\n";
1126bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.25f, 0.5f, 0.75f, 1.0f }, SHADER_ARG_INOUT);
1127bf215546Sopenharmony_ci   const float expected[] = {
1128bf215546Sopenharmony_ci      ldexp(0.25f, 0), ldexp(0.5f, 1), ldexp(0.75f, 2), ldexp(1.0f, 3)
1129bf215546Sopenharmony_ci   };
1130bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1131bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1132bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1133bf215546Sopenharmony_ci}
1134bf215546Sopenharmony_ci
1135bf215546Sopenharmony_ciTEST_F(ComputeTest, frexp_ret)
1136bf215546Sopenharmony_ci{
1137bf215546Sopenharmony_ci   const char *kernel_source =
1138bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1139bf215546Sopenharmony_ci   {\n\
1140bf215546Sopenharmony_ci       int exp;\n\
1141bf215546Sopenharmony_ci       inout[get_global_id(0)] = frexp(inout[get_global_id(0)], &exp);\n\
1142bf215546Sopenharmony_ci   }\n";
1143bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 0.5f, 1.0f, 3.0f }, SHADER_ARG_INOUT);
1144bf215546Sopenharmony_ci   const float expected[] = {
1145bf215546Sopenharmony_ci      0.0f, 0.5f, 0.5f, 0.75f
1146bf215546Sopenharmony_ci   };
1147bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1148bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1149bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1150bf215546Sopenharmony_ci}
1151bf215546Sopenharmony_ci
1152bf215546Sopenharmony_ciTEST_F(ComputeTest, frexp_exp)
1153bf215546Sopenharmony_ci{
1154bf215546Sopenharmony_ci   const char *kernel_source =
1155bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1156bf215546Sopenharmony_ci   {\n\
1157bf215546Sopenharmony_ci       int exp;\n\
1158bf215546Sopenharmony_ci       frexp(inout[get_global_id(0)], &exp);\n\
1159bf215546Sopenharmony_ci       inout[get_global_id(0)] = (float)exp;\n\
1160bf215546Sopenharmony_ci   }\n";
1161bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 0.5f, 1.0f, 3.0f }, SHADER_ARG_INOUT);
1162bf215546Sopenharmony_ci   const float expected[] = {
1163bf215546Sopenharmony_ci      0.0f, 0.0f, 1.0f, 2.0f
1164bf215546Sopenharmony_ci   };
1165bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1166bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1167bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1168bf215546Sopenharmony_ci}
1169bf215546Sopenharmony_ci
1170bf215546Sopenharmony_ciTEST_F(ComputeTest, clz)
1171bf215546Sopenharmony_ci{
1172bf215546Sopenharmony_ci   const char *kernel_source =
1173bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout)\n\
1174bf215546Sopenharmony_ci   {\n\
1175bf215546Sopenharmony_ci       inout[get_global_id(0)] = clz(inout[get_global_id(0)]);\n\
1176bf215546Sopenharmony_ci   }\n";
1177bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0, 1, 0xffff,  (1u << 30), (1u << 31) }, SHADER_ARG_INOUT);
1178bf215546Sopenharmony_ci   const uint32_t expected[] = {
1179bf215546Sopenharmony_ci      32, 31, 16, 1, 0
1180bf215546Sopenharmony_ci   };
1181bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1182bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1183bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1184bf215546Sopenharmony_ci}
1185bf215546Sopenharmony_ci
1186bf215546Sopenharmony_ciTEST_F(ComputeTest, sin)
1187bf215546Sopenharmony_ci{
1188bf215546Sopenharmony_ci   struct sin_vals { float in; float clc; float native; };
1189bf215546Sopenharmony_ci   const char *kernel_source =
1190bf215546Sopenharmony_ci   "struct sin_vals { float in; float clc; float native; };\n\
1191bf215546Sopenharmony_ci   __kernel void main_test(__global struct sin_vals *inout)\n\
1192bf215546Sopenharmony_ci   {\n\
1193bf215546Sopenharmony_ci       inout[get_global_id(0)].clc = sin(inout[get_global_id(0)].in);\n\
1194bf215546Sopenharmony_ci       inout[get_global_id(0)].native = native_sin(inout[get_global_id(0)].in);\n\
1195bf215546Sopenharmony_ci   }\n";
1196bf215546Sopenharmony_ci   const vector<sin_vals> input = {
1197bf215546Sopenharmony_ci      { 0.0f, 0.0f, 0.0f },
1198bf215546Sopenharmony_ci      { 1.0f, 0.0f, 0.0f },
1199bf215546Sopenharmony_ci      { 2.0f, 0.0f, 0.0f },
1200bf215546Sopenharmony_ci      { 3.0f, 0.0f, 0.0f },
1201bf215546Sopenharmony_ci   };
1202bf215546Sopenharmony_ci   auto inout = ShaderArg<sin_vals>(input, SHADER_ARG_INOUT);
1203bf215546Sopenharmony_ci   const struct sin_vals expected[] = {
1204bf215546Sopenharmony_ci      { 0.0f, 0.0f,       0.0f       },
1205bf215546Sopenharmony_ci      { 1.0f, sin(1.0f), sin(1.0f) },
1206bf215546Sopenharmony_ci      { 2.0f, sin(2.0f), sin(2.0f) },
1207bf215546Sopenharmony_ci      { 3.0f, sin(3.0f), sin(3.0f) },
1208bf215546Sopenharmony_ci   };
1209bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1210bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
1211bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i].in, inout[i].in);
1212bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i].clc, inout[i].clc);
1213bf215546Sopenharmony_ci      EXPECT_NEAR(inout[i].clc, inout[i].native, 0.008f); // range from DXIL spec
1214bf215546Sopenharmony_ci   }
1215bf215546Sopenharmony_ci}
1216bf215546Sopenharmony_ci
1217bf215546Sopenharmony_ciTEST_F(ComputeTest, cosh)
1218bf215546Sopenharmony_ci{
1219bf215546Sopenharmony_ci   const char *kernel_source =
1220bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1221bf215546Sopenharmony_ci   {\n\
1222bf215546Sopenharmony_ci       inout[get_global_id(0)] = cosh(inout[get_global_id(0)]);\n\
1223bf215546Sopenharmony_ci   }\n";
1224bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1225bf215546Sopenharmony_ci   const float expected[] = {
1226bf215546Sopenharmony_ci      cosh(0.0f), cosh(1.0f), cosh(2.0f), cosh(3.0f)
1227bf215546Sopenharmony_ci   };
1228bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1229bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1230bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1231bf215546Sopenharmony_ci}
1232bf215546Sopenharmony_ci
1233bf215546Sopenharmony_ciTEST_F(ComputeTest, exp)
1234bf215546Sopenharmony_ci{
1235bf215546Sopenharmony_ci   const char *kernel_source =
1236bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1237bf215546Sopenharmony_ci   {\n\
1238bf215546Sopenharmony_ci       inout[get_global_id(0)] = native_exp(inout[get_global_id(0)]);\n\
1239bf215546Sopenharmony_ci   }\n";
1240bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1241bf215546Sopenharmony_ci   const float expected[] = {
1242bf215546Sopenharmony_ci      exp(0.0f), exp(1.0f), exp(2.0f), exp(3.0f)
1243bf215546Sopenharmony_ci   };
1244bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1245bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1246bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1247bf215546Sopenharmony_ci}
1248bf215546Sopenharmony_ci
1249bf215546Sopenharmony_ciTEST_F(ComputeTest, exp10)
1250bf215546Sopenharmony_ci{
1251bf215546Sopenharmony_ci   const char *kernel_source =
1252bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1253bf215546Sopenharmony_ci   {\n\
1254bf215546Sopenharmony_ci       inout[get_global_id(0)] = native_exp10(inout[get_global_id(0)]);\n\
1255bf215546Sopenharmony_ci   }\n";
1256bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1257bf215546Sopenharmony_ci   const float expected[] = {
1258bf215546Sopenharmony_ci      pow(10.0f, 0.0f), pow(10.0f, 1.0f), pow(10.0f, 2.0f), pow(10.0f, 3.0f)
1259bf215546Sopenharmony_ci   };
1260bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1261bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1262bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1263bf215546Sopenharmony_ci}
1264bf215546Sopenharmony_ci
1265bf215546Sopenharmony_ciTEST_F(ComputeTest, exp2)
1266bf215546Sopenharmony_ci{
1267bf215546Sopenharmony_ci   const char *kernel_source =
1268bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1269bf215546Sopenharmony_ci   {\n\
1270bf215546Sopenharmony_ci       inout[get_global_id(0)] = native_exp2(inout[get_global_id(0)]);\n\
1271bf215546Sopenharmony_ci   }\n";
1272bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1273bf215546Sopenharmony_ci   const float expected[] = {
1274bf215546Sopenharmony_ci      pow(2.0f, 0.0f), pow(2.0f, 1.0f), pow(2.0f, 2.0f), pow(2.0f, 3.0f)
1275bf215546Sopenharmony_ci   };
1276bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1277bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1278bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1279bf215546Sopenharmony_ci}
1280bf215546Sopenharmony_ci
1281bf215546Sopenharmony_ciTEST_F(ComputeTest, log)
1282bf215546Sopenharmony_ci{
1283bf215546Sopenharmony_ci   const char *kernel_source =
1284bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1285bf215546Sopenharmony_ci   {\n\
1286bf215546Sopenharmony_ci       inout[get_global_id(0)] = native_log(inout[get_global_id(0)]);\n\
1287bf215546Sopenharmony_ci   }\n";
1288bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1289bf215546Sopenharmony_ci   const float expected[] = {
1290bf215546Sopenharmony_ci      log(0.0f), log(1.0f), log(2.0f), log(3.0f)
1291bf215546Sopenharmony_ci   };
1292bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1293bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1294bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1295bf215546Sopenharmony_ci}
1296bf215546Sopenharmony_ci
1297bf215546Sopenharmony_ciTEST_F(ComputeTest, log10)
1298bf215546Sopenharmony_ci{
1299bf215546Sopenharmony_ci   const char *kernel_source =
1300bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1301bf215546Sopenharmony_ci   {\n\
1302bf215546Sopenharmony_ci       inout[get_global_id(0)] = native_log10(inout[get_global_id(0)]);\n\
1303bf215546Sopenharmony_ci   }\n";
1304bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1305bf215546Sopenharmony_ci   const float expected[] = {
1306bf215546Sopenharmony_ci      log10(0.0f), log10(1.0f), log10(2.0f), log10(3.0f)
1307bf215546Sopenharmony_ci   };
1308bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1309bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1310bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1311bf215546Sopenharmony_ci}
1312bf215546Sopenharmony_ci
1313bf215546Sopenharmony_ciTEST_F(ComputeTest, log2)
1314bf215546Sopenharmony_ci{
1315bf215546Sopenharmony_ci   const char *kernel_source =
1316bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1317bf215546Sopenharmony_ci   {\n\
1318bf215546Sopenharmony_ci       inout[get_global_id(0)] = native_log2(inout[get_global_id(0)]);\n\
1319bf215546Sopenharmony_ci   }\n";
1320bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.0f, 1.0f, 2.0f, 3.0f }, SHADER_ARG_INOUT);
1321bf215546Sopenharmony_ci   const float expected[] = {
1322bf215546Sopenharmony_ci      log(0.0f) / log(2.0f), log(1.0f) / log(2.0f), log(2.0f) / log(2.0f), log(3.0f) / log(2.0f)
1323bf215546Sopenharmony_ci   };
1324bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1325bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1326bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1327bf215546Sopenharmony_ci}
1328bf215546Sopenharmony_ci
1329bf215546Sopenharmony_ciTEST_F(ComputeTest, rint)
1330bf215546Sopenharmony_ci{
1331bf215546Sopenharmony_ci   const char *kernel_source =
1332bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1333bf215546Sopenharmony_ci   {\n\
1334bf215546Sopenharmony_ci      inout[get_global_id(0)] = rint(inout[get_global_id(0)]);\n\
1335bf215546Sopenharmony_ci   }\n";
1336bf215546Sopenharmony_ci
1337bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0.5f, 1.5f, -0.5f, -1.5f, 1.4f }, SHADER_ARG_INOUT);
1338bf215546Sopenharmony_ci   const float expected[] = {
1339bf215546Sopenharmony_ci      0.0f, 2.0f, 0.0f, -2.0f, 1.0f,
1340bf215546Sopenharmony_ci   };
1341bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1342bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1343bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1344bf215546Sopenharmony_ci}
1345bf215546Sopenharmony_ci
1346bf215546Sopenharmony_ciTEST_F(ComputeTest, round)
1347bf215546Sopenharmony_ci{
1348bf215546Sopenharmony_ci   const char *kernel_source =
1349bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1350bf215546Sopenharmony_ci   {\n\
1351bf215546Sopenharmony_ci       inout[get_global_id(0)] = round(inout[get_global_id(0)]);\n\
1352bf215546Sopenharmony_ci   }\n";
1353bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0, 0.3f, -0.3f, 0.5f, -0.5f, 1.1f, -1.1f },
1354bf215546Sopenharmony_ci                                 SHADER_ARG_INOUT);
1355bf215546Sopenharmony_ci   const float expected[] = {
1356bf215546Sopenharmony_ci      0.0f, 0.0f, -0.0f, 1.0f, -1.0f, 1.0f, -1.0f
1357bf215546Sopenharmony_ci   };
1358bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1359bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1360bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1361bf215546Sopenharmony_ci}
1362bf215546Sopenharmony_ci
1363bf215546Sopenharmony_ciTEST_F(ComputeTest, arg_by_val)
1364bf215546Sopenharmony_ci{
1365bf215546Sopenharmony_ci   const char *kernel_source =
1366bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout, float mul)\n\
1367bf215546Sopenharmony_ci   {\n\
1368bf215546Sopenharmony_ci       inout[get_global_id(0)] = inout[get_global_id(0)] * mul;\n\
1369bf215546Sopenharmony_ci   }\n";
1370bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0, 0.3f, -0.3f, 0.5f, -0.5f, 1.1f, -1.1f },
1371bf215546Sopenharmony_ci                                 SHADER_ARG_INOUT);
1372bf215546Sopenharmony_ci   auto mul = ShaderArg<float>(10.0f, SHADER_ARG_INPUT);
1373bf215546Sopenharmony_ci   const float expected[] = {
1374bf215546Sopenharmony_ci      0.0f, 3.0f, -3.0f, 5.0f, -5.0f, 11.0f, -11.0f
1375bf215546Sopenharmony_ci   };
1376bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, mul);
1377bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1378bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1379bf215546Sopenharmony_ci}
1380bf215546Sopenharmony_ci
1381bf215546Sopenharmony_ciTEST_F(ComputeTest, uint8_by_val)
1382bf215546Sopenharmony_ci{
1383bf215546Sopenharmony_ci   struct uint8 {
1384bf215546Sopenharmony_ci      uint32_t s0; uint32_t s1; uint32_t s2; uint32_t s3;
1385bf215546Sopenharmony_ci      uint32_t s4; uint32_t s5; uint32_t s6; uint32_t s7;
1386bf215546Sopenharmony_ci   };
1387bf215546Sopenharmony_ci   const char *kernel_source =
1388bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *out, uint8 val)\n\
1389bf215546Sopenharmony_ci   {\n\
1390bf215546Sopenharmony_ci       out[get_global_id(0)] = val.s0 + val.s1 + val.s2 + val.s3 +\n\
1391bf215546Sopenharmony_ci                               val.s4 + val.s5 + val.s6 + val.s7;\n\
1392bf215546Sopenharmony_ci   }\n";
1393bf215546Sopenharmony_ci   auto out = ShaderArg<uint32_t>({ 0 }, SHADER_ARG_OUTPUT);
1394bf215546Sopenharmony_ci   auto val = ShaderArg<struct uint8>({ {0, 1, 2, 3, 4, 5, 6, 7 }}, SHADER_ARG_INPUT);
1395bf215546Sopenharmony_ci   const uint32_t expected[] = { 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 };
1396bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, val);
1397bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i)
1398bf215546Sopenharmony_ci      EXPECT_EQ(out[i], expected[i]);
1399bf215546Sopenharmony_ci}
1400bf215546Sopenharmony_ci
1401bf215546Sopenharmony_ciTEST_F(ComputeTest, link)
1402bf215546Sopenharmony_ci{
1403bf215546Sopenharmony_ci   const char *foo_src =
1404bf215546Sopenharmony_ci   "float foo(float in)\n\
1405bf215546Sopenharmony_ci   {\n\
1406bf215546Sopenharmony_ci       return in * in;\n\
1407bf215546Sopenharmony_ci   }\n";
1408bf215546Sopenharmony_ci   const char *kernel_source =
1409bf215546Sopenharmony_ci   "float foo(float in);\n\
1410bf215546Sopenharmony_ci   __kernel void main_test(__global float *inout)\n\
1411bf215546Sopenharmony_ci   {\n\
1412bf215546Sopenharmony_ci       inout[get_global_id(0)] = foo(inout[get_global_id(0)]);\n\
1413bf215546Sopenharmony_ci   }\n";
1414bf215546Sopenharmony_ci   std::vector<const char *> srcs = { foo_src, kernel_source };
1415bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 2.0f }, SHADER_ARG_INOUT);
1416bf215546Sopenharmony_ci   const float expected[] = {
1417bf215546Sopenharmony_ci      4.0f,
1418bf215546Sopenharmony_ci   };
1419bf215546Sopenharmony_ci   run_shader(srcs, inout.size(), 1, 1, inout);
1420bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1421bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1422bf215546Sopenharmony_ci}
1423bf215546Sopenharmony_ci
1424bf215546Sopenharmony_ciTEST_F(ComputeTest, link_library)
1425bf215546Sopenharmony_ci{
1426bf215546Sopenharmony_ci   const char *bar_src =
1427bf215546Sopenharmony_ci   "float bar(float in)\n\
1428bf215546Sopenharmony_ci   {\n\
1429bf215546Sopenharmony_ci      return in * 5;\n\
1430bf215546Sopenharmony_ci   }\n";
1431bf215546Sopenharmony_ci   const char *foo_src =
1432bf215546Sopenharmony_ci   "float bar(float in);\n\
1433bf215546Sopenharmony_ci   float foo(float in)\n\
1434bf215546Sopenharmony_ci   {\n\
1435bf215546Sopenharmony_ci       return in * bar(in);\n\
1436bf215546Sopenharmony_ci   }\n";
1437bf215546Sopenharmony_ci   const char *kernel_source =
1438bf215546Sopenharmony_ci   "float foo(float in);\n\
1439bf215546Sopenharmony_ci   __kernel void main_test(__global float *inout)\n\
1440bf215546Sopenharmony_ci   {\n\
1441bf215546Sopenharmony_ci       inout[get_global_id(0)] = foo(inout[get_global_id(0)]);\n\
1442bf215546Sopenharmony_ci   }\n";
1443bf215546Sopenharmony_ci   std::vector<Shader> libraries = {
1444bf215546Sopenharmony_ci      compile({ bar_src, kernel_source }, {}, true),
1445bf215546Sopenharmony_ci      compile({ foo_src }, {}, true)
1446bf215546Sopenharmony_ci   };
1447bf215546Sopenharmony_ci   Shader exe = link(libraries);
1448bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 2.0f }, SHADER_ARG_INOUT);
1449bf215546Sopenharmony_ci   const float expected[] = {
1450bf215546Sopenharmony_ci      20.0f,
1451bf215546Sopenharmony_ci   };
1452bf215546Sopenharmony_ci   run_shader(exe, { (unsigned)inout.size(), 1, 1 }, inout);
1453bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1454bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1455bf215546Sopenharmony_ci}
1456bf215546Sopenharmony_ci
1457bf215546Sopenharmony_ciTEST_F(ComputeTest, localvar)
1458bf215546Sopenharmony_ci{
1459bf215546Sopenharmony_ci   const char *kernel_source =
1460bf215546Sopenharmony_ci   "__kernel __attribute__((reqd_work_group_size(2, 1, 1)))\n\
1461bf215546Sopenharmony_ci   void main_test(__global float *inout)\n\
1462bf215546Sopenharmony_ci   {\n\
1463bf215546Sopenharmony_ci      __local float2 tmp[2];\n\
1464bf215546Sopenharmony_ci      tmp[get_local_id(0)].x = inout[get_global_id(0)] + 1;\n\
1465bf215546Sopenharmony_ci      tmp[get_local_id(0)].y = inout[get_global_id(0)] - 1;\n\
1466bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1467bf215546Sopenharmony_ci      inout[get_global_id(0)] = tmp[get_local_id(0) % 2].x * tmp[(get_local_id(0) + 1) % 2].y;\n\
1468bf215546Sopenharmony_ci   }\n";
1469bf215546Sopenharmony_ci
1470bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 2.0f, 4.0f }, SHADER_ARG_INOUT);
1471bf215546Sopenharmony_ci   const float expected[] = {
1472bf215546Sopenharmony_ci      9.0f, 5.0f
1473bf215546Sopenharmony_ci   };
1474bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1475bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1476bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1477bf215546Sopenharmony_ci}
1478bf215546Sopenharmony_ci
1479bf215546Sopenharmony_ciTEST_F(ComputeTest, localvar_uchar2)
1480bf215546Sopenharmony_ci{
1481bf215546Sopenharmony_ci   const char *kernel_source =
1482bf215546Sopenharmony_ci   "__attribute__((reqd_work_group_size(2, 1, 1)))\n\
1483bf215546Sopenharmony_ci   __kernel void main_test(__global uchar *inout)\n\
1484bf215546Sopenharmony_ci   {\n\
1485bf215546Sopenharmony_ci      __local uchar2 tmp[2];\n\
1486bf215546Sopenharmony_ci      tmp[get_local_id(0)].x = inout[get_global_id(0)] + 1;\n\
1487bf215546Sopenharmony_ci      tmp[get_local_id(0)].y = inout[get_global_id(0)] - 1;\n\
1488bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1489bf215546Sopenharmony_ci      inout[get_global_id(0)] = tmp[get_local_id(0) % 2].x * tmp[(get_local_id(0) + 1) % 2].y;\n\
1490bf215546Sopenharmony_ci   }\n";
1491bf215546Sopenharmony_ci
1492bf215546Sopenharmony_ci   auto inout = ShaderArg<uint8_t>({ 2, 4 }, SHADER_ARG_INOUT);
1493bf215546Sopenharmony_ci   const uint8_t expected[] = { 9, 5 };
1494bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1495bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1496bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1497bf215546Sopenharmony_ci}
1498bf215546Sopenharmony_ci
1499bf215546Sopenharmony_ciTEST_F(ComputeTest, work_group_size_hint)
1500bf215546Sopenharmony_ci{
1501bf215546Sopenharmony_ci   const char *kernel_source =
1502bf215546Sopenharmony_ci   "__attribute__((work_group_size_hint(2, 1, 1)))\n\
1503bf215546Sopenharmony_ci   __kernel void main_test(__global uint *output)\n\
1504bf215546Sopenharmony_ci   {\n\
1505bf215546Sopenharmony_ci       output[get_global_id(0)] = get_local_id(0);\n\
1506bf215546Sopenharmony_ci   }\n";
1507bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
1508bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
1509bf215546Sopenharmony_ci   const uint32_t expected[] = {
1510bf215546Sopenharmony_ci      0, 1, 2, 3
1511bf215546Sopenharmony_ci   };
1512bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
1513bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
1514bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
1515bf215546Sopenharmony_ci}
1516bf215546Sopenharmony_ci
1517bf215546Sopenharmony_ciTEST_F(ComputeTest, reqd_work_group_size)
1518bf215546Sopenharmony_ci{
1519bf215546Sopenharmony_ci   const char *kernel_source =
1520bf215546Sopenharmony_ci   "__attribute__((reqd_work_group_size(2, 1, 1)))\n\
1521bf215546Sopenharmony_ci   __kernel void main_test(__global uint *output)\n\
1522bf215546Sopenharmony_ci   {\n\
1523bf215546Sopenharmony_ci       output[get_global_id(0)] = get_local_id(0);\n\
1524bf215546Sopenharmony_ci   }\n";
1525bf215546Sopenharmony_ci   auto output = ShaderArg<uint32_t>(std::vector<uint32_t>(4, 0xdeadbeef),
1526bf215546Sopenharmony_ci                                     SHADER_ARG_OUTPUT);
1527bf215546Sopenharmony_ci   const uint32_t expected[] = {
1528bf215546Sopenharmony_ci      0, 1, 0, 1
1529bf215546Sopenharmony_ci   };
1530bf215546Sopenharmony_ci   run_shader(kernel_source, output.size(), 1, 1, output);
1531bf215546Sopenharmony_ci   for (int i = 0; i < output.size(); ++i)
1532bf215546Sopenharmony_ci      EXPECT_EQ(output[i], expected[i]);
1533bf215546Sopenharmony_ci}
1534bf215546Sopenharmony_ci
1535bf215546Sopenharmony_ciTEST_F(ComputeTest, image)
1536bf215546Sopenharmony_ci{
1537bf215546Sopenharmony_ci   const char* kernel_source =
1538bf215546Sopenharmony_ci   "__kernel void main_test(read_only image2d_t input, write_only image2d_t output)\n\
1539bf215546Sopenharmony_ci   {\n\
1540bf215546Sopenharmony_ci      int2 coords = (int2)(get_global_id(0), get_global_id(1));\n\
1541bf215546Sopenharmony_ci      write_imagef(output, coords, read_imagef(input, coords));\n\
1542bf215546Sopenharmony_ci   }\n";
1543bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1544bf215546Sopenharmony_ci   validate(shader);
1545bf215546Sopenharmony_ci}
1546bf215546Sopenharmony_ci
1547bf215546Sopenharmony_ciTEST_F(ComputeTest, image_two_reads)
1548bf215546Sopenharmony_ci{
1549bf215546Sopenharmony_ci   const char* kernel_source =
1550bf215546Sopenharmony_ci   "__kernel void main_test(image2d_t image, int is_float, __global float* output)\n\
1551bf215546Sopenharmony_ci   {\n\
1552bf215546Sopenharmony_ci      if (is_float)\n\
1553bf215546Sopenharmony_ci         output[get_global_id(0)] = read_imagef(image, (int2)(0, 0)).x;\n\
1554bf215546Sopenharmony_ci      else \n\
1555bf215546Sopenharmony_ci         output[get_global_id(0)] = (float)read_imagei(image, (int2)(0, 0)).x;\n\
1556bf215546Sopenharmony_ci   }\n";
1557bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1558bf215546Sopenharmony_ci   validate(shader);
1559bf215546Sopenharmony_ci}
1560bf215546Sopenharmony_ci
1561bf215546Sopenharmony_ciTEST_F(ComputeTest, image_unused)
1562bf215546Sopenharmony_ci{
1563bf215546Sopenharmony_ci   const char* kernel_source =
1564bf215546Sopenharmony_ci   "__kernel void main_test(read_only image2d_t input, write_only image2d_t output)\n\
1565bf215546Sopenharmony_ci   {\n\
1566bf215546Sopenharmony_ci   }\n";
1567bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1568bf215546Sopenharmony_ci   validate(shader);
1569bf215546Sopenharmony_ci}
1570bf215546Sopenharmony_ci
1571bf215546Sopenharmony_ciTEST_F(ComputeTest, image_read_write)
1572bf215546Sopenharmony_ci{
1573bf215546Sopenharmony_ci   const char *kernel_source =
1574bf215546Sopenharmony_ci   R"(__kernel void main_test(read_write image2d_t image)
1575bf215546Sopenharmony_ci   {
1576bf215546Sopenharmony_ci      int2 coords = (int2)(get_global_id(0), get_global_id(1));
1577bf215546Sopenharmony_ci      write_imagef(image, coords, read_imagef(image, coords) + (float4)(1.0f, 1.0f, 1.0f, 1.0f));
1578bf215546Sopenharmony_ci   })";
1579bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }), { "-cl-std=cl3.0" });
1580bf215546Sopenharmony_ci   validate(shader);
1581bf215546Sopenharmony_ci}
1582bf215546Sopenharmony_ci
1583bf215546Sopenharmony_ciTEST_F(ComputeTest, sampler)
1584bf215546Sopenharmony_ci{
1585bf215546Sopenharmony_ci   const char* kernel_source =
1586bf215546Sopenharmony_ci   "__kernel void main_test(image2d_t image, sampler_t sampler, __global float* output)\n\
1587bf215546Sopenharmony_ci   {\n\
1588bf215546Sopenharmony_ci      output[get_global_id(0)] = read_imagef(image, sampler, (int2)(0, 0)).x;\n\
1589bf215546Sopenharmony_ci   }\n";
1590bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1591bf215546Sopenharmony_ci   validate(shader);
1592bf215546Sopenharmony_ci}
1593bf215546Sopenharmony_ci
1594bf215546Sopenharmony_ciTEST_F(ComputeTest, image_dims)
1595bf215546Sopenharmony_ci{
1596bf215546Sopenharmony_ci   const char* kernel_source =
1597bf215546Sopenharmony_ci   "__kernel void main_test(image2d_t roimage, write_only image2d_t woimage, __global uint* output)\n\
1598bf215546Sopenharmony_ci   {\n\
1599bf215546Sopenharmony_ci      output[get_global_id(0)] = get_image_width(roimage);\n\
1600bf215546Sopenharmony_ci      output[get_global_id(0) + 1] = get_image_width(woimage);\n\
1601bf215546Sopenharmony_ci   }\n";
1602bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1603bf215546Sopenharmony_ci   validate(shader);
1604bf215546Sopenharmony_ci}
1605bf215546Sopenharmony_ci
1606bf215546Sopenharmony_ciTEST_F(ComputeTest, image_format)
1607bf215546Sopenharmony_ci{
1608bf215546Sopenharmony_ci   const char* kernel_source =
1609bf215546Sopenharmony_ci   "__kernel void main_test(image2d_t roimage, write_only image2d_t woimage, __global uint* output)\n\
1610bf215546Sopenharmony_ci   {\n\
1611bf215546Sopenharmony_ci      output[get_global_id(0)] = get_image_channel_data_type(roimage);\n\
1612bf215546Sopenharmony_ci      output[get_global_id(0) + 1] = get_image_channel_order(woimage);\n\
1613bf215546Sopenharmony_ci   }\n";
1614bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1615bf215546Sopenharmony_ci   validate(shader);
1616bf215546Sopenharmony_ci}
1617bf215546Sopenharmony_ci
1618bf215546Sopenharmony_ciTEST_F(ComputeTest, image1d_buffer_t)
1619bf215546Sopenharmony_ci{
1620bf215546Sopenharmony_ci   const char* kernel_source =
1621bf215546Sopenharmony_ci   "__kernel void main_test(read_only image1d_buffer_t input, write_only image1d_buffer_t output)\n\
1622bf215546Sopenharmony_ci   {\n\
1623bf215546Sopenharmony_ci      write_imageui(output, get_global_id(0), read_imageui(input, get_global_id(0)));\n\
1624bf215546Sopenharmony_ci   }\n";
1625bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1626bf215546Sopenharmony_ci   validate(shader);
1627bf215546Sopenharmony_ci}
1628bf215546Sopenharmony_ci
1629bf215546Sopenharmony_ciTEST_F(ComputeTest, local_ptr)
1630bf215546Sopenharmony_ci{
1631bf215546Sopenharmony_ci   struct uint2 { uint32_t x, y; };
1632bf215546Sopenharmony_ci   const char *kernel_source =
1633bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout, __local uint2 *tmp)\n\
1634bf215546Sopenharmony_ci   {\n\
1635bf215546Sopenharmony_ci      tmp[get_local_id(0)].x = inout[get_global_id(0)] + 1;\n\
1636bf215546Sopenharmony_ci      tmp[get_local_id(0)].y = inout[get_global_id(0)] - 1;\n\
1637bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1638bf215546Sopenharmony_ci      inout[get_global_id(0)] = tmp[get_local_id(0) % 2].x * tmp[(get_local_id(0) + 1) % 2].y;\n\
1639bf215546Sopenharmony_ci   }\n";
1640bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 2, 4 }, SHADER_ARG_INOUT);
1641bf215546Sopenharmony_ci   auto tmp = ShaderArg<struct uint2>(std::vector<struct uint2>(4096), SHADER_ARG_INPUT);
1642bf215546Sopenharmony_ci   const uint8_t expected[] = { 9, 5 };
1643bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, tmp);
1644bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1645bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1646bf215546Sopenharmony_ci}
1647bf215546Sopenharmony_ci
1648bf215546Sopenharmony_ciTEST_F(ComputeTest, two_local_ptrs)
1649bf215546Sopenharmony_ci{
1650bf215546Sopenharmony_ci   struct uint2 { uint32_t x, y; };
1651bf215546Sopenharmony_ci   const char *kernel_source =
1652bf215546Sopenharmony_ci   "__kernel void main_test(__global uint *inout, __local uint2 *tmp, __local uint *tmp2)\n\
1653bf215546Sopenharmony_ci   {\n\
1654bf215546Sopenharmony_ci      tmp[get_local_id(0)].x = inout[get_global_id(0)] + 1;\n\
1655bf215546Sopenharmony_ci      tmp[get_local_id(0)].y = inout[get_global_id(0)] - 1;\n\
1656bf215546Sopenharmony_ci      tmp2[get_local_id(0)] = get_global_id(0);\n\
1657bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1658bf215546Sopenharmony_ci      inout[get_global_id(0)] = tmp[get_local_id(0) % 2].x * tmp[(get_local_id(0) + 1) % 2].y + tmp2[get_local_id(0) % 2];\n\
1659bf215546Sopenharmony_ci   }\n";
1660bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 2, 4 }, SHADER_ARG_INOUT);
1661bf215546Sopenharmony_ci   auto tmp = ShaderArg<struct uint2>(std::vector<struct uint2>(1024), SHADER_ARG_INPUT);
1662bf215546Sopenharmony_ci   auto tmp2 = ShaderArg<uint32_t>(std::vector<uint32_t>(1024), SHADER_ARG_INPUT);
1663bf215546Sopenharmony_ci   const uint8_t expected[] = { 9, 6 };
1664bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, tmp, tmp2);
1665bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1666bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1667bf215546Sopenharmony_ci}
1668bf215546Sopenharmony_ci
1669bf215546Sopenharmony_ciTEST_F(ComputeTest, int8_to_float)
1670bf215546Sopenharmony_ci{
1671bf215546Sopenharmony_ci   const char *kernel_source =
1672bf215546Sopenharmony_ci   "__kernel void main_test(__global char* in, __global float* out)\n\
1673bf215546Sopenharmony_ci   {\n\
1674bf215546Sopenharmony_ci      uint pos = get_global_id(0);\n\
1675bf215546Sopenharmony_ci      out[pos] = in[pos] / 100.0f;\n\
1676bf215546Sopenharmony_ci   }";
1677bf215546Sopenharmony_ci   auto in = ShaderArg<char>({ 10, 20, 30, 40 }, SHADER_ARG_INPUT);
1678bf215546Sopenharmony_ci   auto out = ShaderArg<float>(std::vector<float>(4, std::numeric_limits<float>::infinity()), SHADER_ARG_OUTPUT);
1679bf215546Sopenharmony_ci   const float expected[] = { 0.1f, 0.2f, 0.3f, 0.4f };
1680bf215546Sopenharmony_ci   run_shader(kernel_source, in.size(), 1, 1, in, out);
1681bf215546Sopenharmony_ci   for (int i = 0; i < in.size(); ++i)
1682bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(out[i], expected[i]);
1683bf215546Sopenharmony_ci}
1684bf215546Sopenharmony_ci
1685bf215546Sopenharmony_ciTEST_F(ComputeTest, vec_hint_float4)
1686bf215546Sopenharmony_ci{
1687bf215546Sopenharmony_ci   const char *kernel_source =
1688bf215546Sopenharmony_ci   "__kernel __attribute__((vec_type_hint(float4))) void main_test(__global float *inout)\n\
1689bf215546Sopenharmony_ci   {\n\
1690bf215546Sopenharmony_ci      inout[get_global_id(0)] *= inout[get_global_id(1)];\n\
1691bf215546Sopenharmony_ci   }";
1692bf215546Sopenharmony_ci   Shader shader = compile({ kernel_source });
1693bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].vec_hint_size, 4);
1694bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].vec_hint_type, CLC_VEC_HINT_TYPE_FLOAT);
1695bf215546Sopenharmony_ci}
1696bf215546Sopenharmony_ci
1697bf215546Sopenharmony_ciTEST_F(ComputeTest, vec_hint_uchar2)
1698bf215546Sopenharmony_ci{
1699bf215546Sopenharmony_ci   const char *kernel_source =
1700bf215546Sopenharmony_ci   "__kernel __attribute__((vec_type_hint(uchar2))) void main_test(__global float *inout)\n\
1701bf215546Sopenharmony_ci   {\n\
1702bf215546Sopenharmony_ci      inout[get_global_id(0)] *= inout[get_global_id(1)];\n\
1703bf215546Sopenharmony_ci   }";
1704bf215546Sopenharmony_ci   Shader shader = compile({ kernel_source });
1705bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].vec_hint_size, 2);
1706bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].vec_hint_type, CLC_VEC_HINT_TYPE_CHAR);
1707bf215546Sopenharmony_ci}
1708bf215546Sopenharmony_ci
1709bf215546Sopenharmony_ciTEST_F(ComputeTest, vec_hint_none)
1710bf215546Sopenharmony_ci{
1711bf215546Sopenharmony_ci   const char *kernel_source =
1712bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout)\n\
1713bf215546Sopenharmony_ci   {\n\
1714bf215546Sopenharmony_ci      inout[get_global_id(0)] *= inout[get_global_id(1)];\n\
1715bf215546Sopenharmony_ci   }";
1716bf215546Sopenharmony_ci   Shader shader = compile({ kernel_source });
1717bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].vec_hint_size, 0);
1718bf215546Sopenharmony_ci}
1719bf215546Sopenharmony_ci
1720bf215546Sopenharmony_ciTEST_F(ComputeTest, DISABLED_debug_layer_failure)
1721bf215546Sopenharmony_ci{
1722bf215546Sopenharmony_ci   /* This is a negative test case, it intentionally triggers a failure to validate the mechanism
1723bf215546Sopenharmony_ci    * is in place, so other tests will fail if they produce debug messages
1724bf215546Sopenharmony_ci    */
1725bf215546Sopenharmony_ci   const char *kernel_source =
1726bf215546Sopenharmony_ci   "__kernel void main_test(__global float *inout, float mul)\n\
1727bf215546Sopenharmony_ci   {\n\
1728bf215546Sopenharmony_ci       inout[get_global_id(0)] = inout[get_global_id(0)] * mul;\n\
1729bf215546Sopenharmony_ci   }\n";
1730bf215546Sopenharmony_ci   auto inout = ShaderArg<float>({ 0, 0.3f, -0.3f, 0.5f, -0.5f, 1.1f, -1.1f },
1731bf215546Sopenharmony_ci                                 SHADER_ARG_INOUT);
1732bf215546Sopenharmony_ci   auto mul = ShaderArg<float>(10.0f, SHADER_ARG_INPUT);
1733bf215546Sopenharmony_ci   const float expected[] = {
1734bf215546Sopenharmony_ci      0.0f, 3.0f, -3.0f, 5.0f, -5.0f, 11.0f, -11.0f
1735bf215546Sopenharmony_ci   };
1736bf215546Sopenharmony_ci   ComPtr<ID3D12InfoQueue> info_queue;
1737bf215546Sopenharmony_ci   dev->QueryInterface(info_queue.ReleaseAndGetAddressOf());
1738bf215546Sopenharmony_ci   if (!info_queue) {
1739bf215546Sopenharmony_ci      GTEST_SKIP() << "No info queue";
1740bf215546Sopenharmony_ci      return;
1741bf215546Sopenharmony_ci   }
1742bf215546Sopenharmony_ci
1743bf215546Sopenharmony_ci   info_queue->AddApplicationMessage(D3D12_MESSAGE_SEVERITY_ERROR, "This should cause the test to fail");
1744bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, mul);
1745bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1746bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(inout[i], expected[i]);
1747bf215546Sopenharmony_ci}
1748bf215546Sopenharmony_ci
1749bf215546Sopenharmony_ciTEST_F(ComputeTest, compiler_defines)
1750bf215546Sopenharmony_ci{
1751bf215546Sopenharmony_ci   const char *kernel_source =
1752bf215546Sopenharmony_ci      "__kernel void main_test(__global int* out)\n\
1753bf215546Sopenharmony_ci   {\n\
1754bf215546Sopenharmony_ci      out[0] = OUT_VAL0;\n\
1755bf215546Sopenharmony_ci      out[1] = __OPENCL_C_VERSION__;\n\
1756bf215546Sopenharmony_ci   }";
1757bf215546Sopenharmony_ci   auto out = ShaderArg<int>(std::vector<int>(2, 0), SHADER_ARG_OUTPUT);
1758bf215546Sopenharmony_ci   CompileArgs compile_args = { 1, 1, 1 };
1759bf215546Sopenharmony_ci   compile_args.compiler_command_line = { "-DOUT_VAL0=5", "-cl-std=cl" };
1760bf215546Sopenharmony_ci   std::vector<RawShaderArg *> raw_args = { &out };
1761bf215546Sopenharmony_ci   run_shader({ kernel_source }, compile_args, out);
1762bf215546Sopenharmony_ci   EXPECT_EQ(out[0], 5);
1763bf215546Sopenharmony_ci   EXPECT_EQ(out[1], 100);
1764bf215546Sopenharmony_ci}
1765bf215546Sopenharmony_ci
1766bf215546Sopenharmony_ciTEST_F(ComputeTest, global_atomic_add)
1767bf215546Sopenharmony_ci{
1768bf215546Sopenharmony_ci   const char *kernel_source =
1769bf215546Sopenharmony_ci   "__kernel void main_test(__global int *inout, __global int *old)\n\
1770bf215546Sopenharmony_ci   {\n\
1771bf215546Sopenharmony_ci      old[get_global_id(0)] = atomic_add(inout + get_global_id(0), 3);\n\
1772bf215546Sopenharmony_ci   }\n";
1773bf215546Sopenharmony_ci   auto inout = ShaderArg<int32_t>({ 2, 4 }, SHADER_ARG_INOUT);
1774bf215546Sopenharmony_ci   auto old = ShaderArg<int32_t>(std::vector<int32_t>(2, 0xdeadbeef), SHADER_ARG_OUTPUT);
1775bf215546Sopenharmony_ci   const int32_t expected_inout[] = { 5, 7 };
1776bf215546Sopenharmony_ci   const int32_t expected_old[] = { 2, 4 };
1777bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, old);
1778bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
1779bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected_inout[i]);
1780bf215546Sopenharmony_ci      EXPECT_EQ(old[i], expected_old[i]);
1781bf215546Sopenharmony_ci   }
1782bf215546Sopenharmony_ci}
1783bf215546Sopenharmony_ci
1784bf215546Sopenharmony_ciTEST_F(ComputeTest, global_atomic_imin)
1785bf215546Sopenharmony_ci{
1786bf215546Sopenharmony_ci   const char *kernel_source =
1787bf215546Sopenharmony_ci   "__kernel void main_test(__global int *inout, __global int *old)\n\
1788bf215546Sopenharmony_ci   {\n\
1789bf215546Sopenharmony_ci      old[get_global_id(0)] = atomic_min(inout + get_global_id(0), 1);\n\
1790bf215546Sopenharmony_ci   }\n";
1791bf215546Sopenharmony_ci   auto inout = ShaderArg<int32_t>({ 0, 2, -1 }, SHADER_ARG_INOUT);
1792bf215546Sopenharmony_ci   auto old = ShaderArg<int32_t>(std::vector<int32_t>(3, 0xdeadbeef), SHADER_ARG_OUTPUT);
1793bf215546Sopenharmony_ci   const int32_t expected_inout[] = { 0, 1, -1 };
1794bf215546Sopenharmony_ci   const int32_t expected_old[] = { 0, 2, -1 };
1795bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, old);
1796bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
1797bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected_inout[i]);
1798bf215546Sopenharmony_ci      EXPECT_EQ(old[i], expected_old[i]);
1799bf215546Sopenharmony_ci   }
1800bf215546Sopenharmony_ci}
1801bf215546Sopenharmony_ci
1802bf215546Sopenharmony_ciTEST_F(ComputeTest, global_atomic_and_or)
1803bf215546Sopenharmony_ci{
1804bf215546Sopenharmony_ci   const char *kernel_source =
1805bf215546Sopenharmony_ci   "__attribute__((reqd_work_group_size(3, 1, 1)))\n\
1806bf215546Sopenharmony_ci   __kernel void main_test(__global int *inout)\n\
1807bf215546Sopenharmony_ci   {\n\
1808bf215546Sopenharmony_ci      atomic_and(inout, ~(1 << get_global_id(0)));\n\
1809bf215546Sopenharmony_ci      atomic_or(inout, (1 << (get_global_id(0) + 4)));\n\
1810bf215546Sopenharmony_ci   }\n";
1811bf215546Sopenharmony_ci   auto inout = ShaderArg<int32_t>(0xf, SHADER_ARG_INOUT);
1812bf215546Sopenharmony_ci   const int32_t expected[] = { 0x78 };
1813bf215546Sopenharmony_ci   run_shader(kernel_source, 3, 1, 1, inout);
1814bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1815bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1816bf215546Sopenharmony_ci}
1817bf215546Sopenharmony_ci
1818bf215546Sopenharmony_ciTEST_F(ComputeTest, global_atomic_cmpxchg)
1819bf215546Sopenharmony_ci{
1820bf215546Sopenharmony_ci   const char *kernel_source =
1821bf215546Sopenharmony_ci   "__attribute__((reqd_work_group_size(2, 1, 1)))\n\
1822bf215546Sopenharmony_ci   __kernel void main_test(__global int *inout)\n\
1823bf215546Sopenharmony_ci   {\n\
1824bf215546Sopenharmony_ci      while (atomic_cmpxchg(inout, get_global_id(0), get_global_id(0) + 1) != get_global_id(0))\n\
1825bf215546Sopenharmony_ci         ;\n\
1826bf215546Sopenharmony_ci   }\n";
1827bf215546Sopenharmony_ci   auto inout = ShaderArg<int32_t>(0, SHADER_ARG_INOUT);
1828bf215546Sopenharmony_ci   const int32_t expected_inout[] = { 2 };
1829bf215546Sopenharmony_ci   run_shader(kernel_source, 2, 1, 1, inout);
1830bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1831bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected_inout[i]);
1832bf215546Sopenharmony_ci}
1833bf215546Sopenharmony_ci
1834bf215546Sopenharmony_ciTEST_F(ComputeTest, local_atomic_and_or)
1835bf215546Sopenharmony_ci{
1836bf215546Sopenharmony_ci   const char *kernel_source =
1837bf215546Sopenharmony_ci   "__attribute__((reqd_work_group_size(2, 1, 1)))\n\
1838bf215546Sopenharmony_ci   __kernel void main_test(__global ushort *inout)\n\
1839bf215546Sopenharmony_ci   {\n\
1840bf215546Sopenharmony_ci      __local ushort tmp;\n\
1841bf215546Sopenharmony_ci      atomic_and(&tmp, ~(0xff << (get_global_id(0) * 8)));\n\
1842bf215546Sopenharmony_ci      atomic_or(&tmp, inout[get_global_id(0)] << (get_global_id(0) * 8));\n\
1843bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1844bf215546Sopenharmony_ci      inout[get_global_id(0)] = tmp;\n\
1845bf215546Sopenharmony_ci   }\n";
1846bf215546Sopenharmony_ci   auto inout = ShaderArg<uint16_t>({ 2, 4 }, SHADER_ARG_INOUT);
1847bf215546Sopenharmony_ci   const uint16_t expected[] = { 0x402, 0x402 };
1848bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout);
1849bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
1850bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
1851bf215546Sopenharmony_ci}
1852bf215546Sopenharmony_ci
1853bf215546Sopenharmony_ciTEST_F(ComputeTest, local_atomic_cmpxchg)
1854bf215546Sopenharmony_ci{
1855bf215546Sopenharmony_ci   const char *kernel_source =
1856bf215546Sopenharmony_ci   "__attribute__((reqd_work_group_size(2, 1, 1)))\n\
1857bf215546Sopenharmony_ci   __kernel void main_test(__global int *out)\n\
1858bf215546Sopenharmony_ci   {\n\
1859bf215546Sopenharmony_ci      __local uint tmp;\n\
1860bf215546Sopenharmony_ci      tmp = 0;\n\
1861bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1862bf215546Sopenharmony_ci      while (atomic_cmpxchg(&tmp, get_global_id(0), get_global_id(0) + 1) != get_global_id(0))\n\
1863bf215546Sopenharmony_ci         ;\n\
1864bf215546Sopenharmony_ci      barrier(CLK_LOCAL_MEM_FENCE);\n\
1865bf215546Sopenharmony_ci      out[0] = tmp;\n\
1866bf215546Sopenharmony_ci   }\n";
1867bf215546Sopenharmony_ci
1868bf215546Sopenharmony_ci   auto out = ShaderArg<uint32_t>(0xdeadbeef, SHADER_ARG_OUTPUT);
1869bf215546Sopenharmony_ci   const uint16_t expected[] = { 2 };
1870bf215546Sopenharmony_ci   run_shader(kernel_source, 2, 1, 1, out);
1871bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i)
1872bf215546Sopenharmony_ci      EXPECT_EQ(out[i], expected[i]);
1873bf215546Sopenharmony_ci}
1874bf215546Sopenharmony_ci
1875bf215546Sopenharmony_ciTEST_F(ComputeTest, constant_sampler)
1876bf215546Sopenharmony_ci{
1877bf215546Sopenharmony_ci   const char* kernel_source =
1878bf215546Sopenharmony_ci   "__constant sampler_t sampler = CLK_NORMALIZED_COORDS_FALSE | CLK_ADDRESS_CLAMP | CLK_FILTER_LINEAR;\n\
1879bf215546Sopenharmony_ci   __kernel void main_test(read_only image2d_t input, write_only image2d_t output)\n\
1880bf215546Sopenharmony_ci   {\n\
1881bf215546Sopenharmony_ci      int2 coordsi = (int2)(get_global_id(0), get_global_id(1));\n\
1882bf215546Sopenharmony_ci      float2 coordsf = (float2)((float)coordsi.x / get_image_width(input), (float)coordsi.y / get_image_height(input));\n\
1883bf215546Sopenharmony_ci      write_imagef(output, coordsi, \n\
1884bf215546Sopenharmony_ci         read_imagef(input, sampler, coordsf) + \n\
1885bf215546Sopenharmony_ci         read_imagef(input, sampler, coordsf + (float2)(0.1, 0.1)));\n\
1886bf215546Sopenharmony_ci   }\n";
1887bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1888bf215546Sopenharmony_ci   validate(shader);
1889bf215546Sopenharmony_ci   EXPECT_EQ(shader.dxil->metadata.num_const_samplers, 1);
1890bf215546Sopenharmony_ci}
1891bf215546Sopenharmony_ci
1892bf215546Sopenharmony_ciTEST_F(ComputeTest, hi)
1893bf215546Sopenharmony_ci{
1894bf215546Sopenharmony_ci   const char *kernel_source = R"(
1895bf215546Sopenharmony_ci   __kernel void main_test(__global char3 *srcA, __global char2 *dst)
1896bf215546Sopenharmony_ci   {
1897bf215546Sopenharmony_ci       int  tid = get_global_id(0);
1898bf215546Sopenharmony_ci
1899bf215546Sopenharmony_ci       char2 tmp = srcA[tid].hi;
1900bf215546Sopenharmony_ci       dst[tid] = tmp;
1901bf215546Sopenharmony_ci   })";
1902bf215546Sopenharmony_ci   Shader shader = compile(std::vector<const char*>({ kernel_source }));
1903bf215546Sopenharmony_ci   validate(shader);
1904bf215546Sopenharmony_ci}
1905bf215546Sopenharmony_ci
1906bf215546Sopenharmony_ciTEST_F(ComputeTest, system_values)
1907bf215546Sopenharmony_ci{
1908bf215546Sopenharmony_ci   const char *kernel_source =
1909bf215546Sopenharmony_ci   "__kernel void main_test(__global uint* outputs)\n\
1910bf215546Sopenharmony_ci   {\n\
1911bf215546Sopenharmony_ci      outputs[0] = get_work_dim();\n\
1912bf215546Sopenharmony_ci      outputs[1] = get_global_size(0);\n\
1913bf215546Sopenharmony_ci      outputs[2] = get_local_size(0);\n\
1914bf215546Sopenharmony_ci      outputs[3] = get_num_groups(0);\n\
1915bf215546Sopenharmony_ci      outputs[4] = get_group_id(0);\n\
1916bf215546Sopenharmony_ci      outputs[5] = get_global_offset(0);\n\
1917bf215546Sopenharmony_ci      outputs[6] = get_global_id(0);\n\
1918bf215546Sopenharmony_ci   }\n";
1919bf215546Sopenharmony_ci   auto out = ShaderArg<uint32_t>(std::vector<uint32_t>(6, 0xdeadbeef), SHADER_ARG_OUTPUT);
1920bf215546Sopenharmony_ci   const uint16_t expected[] = { 3, 1, 1, 1, 0, 0, 0, };
1921bf215546Sopenharmony_ci   CompileArgs args = { 1, 1, 1 };
1922bf215546Sopenharmony_ci   Shader shader = compile({ kernel_source });
1923bf215546Sopenharmony_ci   run_shader(shader, args, out);
1924bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i)
1925bf215546Sopenharmony_ci      EXPECT_EQ(out[i], expected[i]);
1926bf215546Sopenharmony_ci
1927bf215546Sopenharmony_ci   args.work_props.work_dim = 2;
1928bf215546Sopenharmony_ci   args.work_props.global_offset_x = 100;
1929bf215546Sopenharmony_ci   args.work_props.group_id_offset_x = 2;
1930bf215546Sopenharmony_ci   args.work_props.group_count_total_x = 5;
1931bf215546Sopenharmony_ci   const uint32_t expected_withoffsets[] = { 2, 5, 1, 5, 2, 100, 102 };
1932bf215546Sopenharmony_ci   run_shader(shader, args, out);
1933bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i)
1934bf215546Sopenharmony_ci      EXPECT_EQ(out[i], expected_withoffsets[i]);
1935bf215546Sopenharmony_ci}
1936bf215546Sopenharmony_ci
1937bf215546Sopenharmony_ciTEST_F(ComputeTest, convert_round_sat)
1938bf215546Sopenharmony_ci{
1939bf215546Sopenharmony_ci   const char *kernel_source =
1940bf215546Sopenharmony_ci   "__kernel void main_test(__global float *f, __global uchar *u)\n\
1941bf215546Sopenharmony_ci   {\n\
1942bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
1943bf215546Sopenharmony_ci       u[idx] = convert_uchar_sat_rtp(f[idx]);\n\
1944bf215546Sopenharmony_ci   }\n";
1945bf215546Sopenharmony_ci   auto f = ShaderArg<float>({ -1.0f, 1.1f, 20.0f, 255.5f }, SHADER_ARG_INPUT);
1946bf215546Sopenharmony_ci   auto u = ShaderArg<uint8_t>({ 255, 0, 0, 0 }, SHADER_ARG_OUTPUT);
1947bf215546Sopenharmony_ci   const uint8_t expected[] = {
1948bf215546Sopenharmony_ci      0, 2, 20, 255
1949bf215546Sopenharmony_ci   };
1950bf215546Sopenharmony_ci
1951bf215546Sopenharmony_ci   run_shader(kernel_source, f.size(), 1, 1, f, u);
1952bf215546Sopenharmony_ci   for (int i = 0; i < u.size(); ++i)
1953bf215546Sopenharmony_ci      EXPECT_EQ(u[i], expected[i]);
1954bf215546Sopenharmony_ci}
1955bf215546Sopenharmony_ci
1956bf215546Sopenharmony_ciTEST_F(ComputeTest, convert_round_sat_vec)
1957bf215546Sopenharmony_ci{
1958bf215546Sopenharmony_ci   const char *kernel_source =
1959bf215546Sopenharmony_ci   "__kernel void main_test(__global float16 *f, __global uchar16 *u)\n\
1960bf215546Sopenharmony_ci   {\n\
1961bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
1962bf215546Sopenharmony_ci       u[idx] = convert_uchar16_sat_rtp(f[idx]);\n\
1963bf215546Sopenharmony_ci   }\n";
1964bf215546Sopenharmony_ci   auto f = ShaderArg<float>({
1965bf215546Sopenharmony_ci      -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f,
1966bf215546Sopenharmony_ci      -0.5f, 1.9f, 20.0f, 254.5f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f,
1967bf215546Sopenharmony_ci       0.0f, 1.3f, 20.0f, 255.1f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f,
1968bf215546Sopenharmony_ci      -0.0f, 1.5555f, 20.0f, 254.9f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f, -1.0f, 1.1f, 20.0f, 255.5f,
1969bf215546Sopenharmony_ci   }, SHADER_ARG_INPUT);
1970bf215546Sopenharmony_ci   auto u = ShaderArg<uint8_t>({
1971bf215546Sopenharmony_ci      255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0,
1972bf215546Sopenharmony_ci      255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0,
1973bf215546Sopenharmony_ci      255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0,
1974bf215546Sopenharmony_ci      255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0, 255, 0, 0, 0,
1975bf215546Sopenharmony_ci   }, SHADER_ARG_OUTPUT);
1976bf215546Sopenharmony_ci   const uint8_t expected[] = {
1977bf215546Sopenharmony_ci      0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255,
1978bf215546Sopenharmony_ci      0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255,
1979bf215546Sopenharmony_ci      0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255,
1980bf215546Sopenharmony_ci      0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255, 0, 2, 20, 255,
1981bf215546Sopenharmony_ci   };
1982bf215546Sopenharmony_ci
1983bf215546Sopenharmony_ci   run_shader(kernel_source, 4, 1, 1, f, u);
1984bf215546Sopenharmony_ci   for (int i = 0; i < u.size(); ++i)
1985bf215546Sopenharmony_ci      EXPECT_EQ(u[i], expected[i]);
1986bf215546Sopenharmony_ci}
1987bf215546Sopenharmony_ci
1988bf215546Sopenharmony_ciTEST_F(ComputeTest, convert_char2_uchar2)
1989bf215546Sopenharmony_ci{
1990bf215546Sopenharmony_ci   const char *kernel_source =
1991bf215546Sopenharmony_ci   "__kernel void main_test( __global char2 *src, __global uchar2 *dest )\n\
1992bf215546Sopenharmony_ci   {\n\
1993bf215546Sopenharmony_ci      size_t i = get_global_id(0);\n\
1994bf215546Sopenharmony_ci      dest[i] = convert_uchar2_sat( src[i] );\n\
1995bf215546Sopenharmony_ci   }\n";
1996bf215546Sopenharmony_ci
1997bf215546Sopenharmony_ci   auto c = ShaderArg<int8_t>({ -127, -4, 0, 4, 126, 127, 16, 32 }, SHADER_ARG_INPUT);
1998bf215546Sopenharmony_ci   auto u = ShaderArg<uint8_t>({ 99, 99, 99, 99, 99, 99, 99, 99 }, SHADER_ARG_OUTPUT);
1999bf215546Sopenharmony_ci   const uint8_t expected[] = { 0, 0, 0, 4, 126, 127, 16, 32 };
2000bf215546Sopenharmony_ci   run_shader(kernel_source, 4, 1, 1, c, u);
2001bf215546Sopenharmony_ci   for (int i = 0; i < u.size(); i++)
2002bf215546Sopenharmony_ci      EXPECT_EQ(u[i], expected[i]);
2003bf215546Sopenharmony_ci}
2004bf215546Sopenharmony_ci
2005bf215546Sopenharmony_ciTEST_F(ComputeTest, async_copy)
2006bf215546Sopenharmony_ci{
2007bf215546Sopenharmony_ci   const char *kernel_source = R"(
2008bf215546Sopenharmony_ci   __kernel void main_test( const __global char *src, __global char *dst, __local char *localBuffer, int copiesPerWorkgroup, int copiesPerWorkItem )
2009bf215546Sopenharmony_ci   {
2010bf215546Sopenharmony_ci    int i;
2011bf215546Sopenharmony_ci    for(i=0; i<copiesPerWorkItem; i++)
2012bf215546Sopenharmony_ci        localBuffer[ get_local_id( 0 )*copiesPerWorkItem+i ] = (char)(char)0;
2013bf215546Sopenharmony_ci       barrier( CLK_LOCAL_MEM_FENCE );
2014bf215546Sopenharmony_ci       event_t event;
2015bf215546Sopenharmony_ci       event = async_work_group_copy( (__local char*)localBuffer, (__global const char*)(src+copiesPerWorkgroup*get_group_id(0)), (size_t)copiesPerWorkgroup, 0 );
2016bf215546Sopenharmony_ci       wait_group_events( 1, &event );
2017bf215546Sopenharmony_ci    for(i=0; i<copiesPerWorkItem; i++)
2018bf215546Sopenharmony_ci     dst[ get_global_id( 0 )*copiesPerWorkItem+i ] = localBuffer[ get_local_id( 0 )*copiesPerWorkItem+i ];
2019bf215546Sopenharmony_ci   })";
2020bf215546Sopenharmony_ci   Shader shader = compile({ kernel_source });
2021bf215546Sopenharmony_ci   validate(shader);
2022bf215546Sopenharmony_ci}
2023bf215546Sopenharmony_ci
2024bf215546Sopenharmony_ciTEST_F(ComputeTest, packed_struct_global)
2025bf215546Sopenharmony_ci{
2026bf215546Sopenharmony_ci#pragma pack(push, 1)
2027bf215546Sopenharmony_ci   struct s { uint8_t uc; uint64_t ul; uint16_t us; };
2028bf215546Sopenharmony_ci#pragma pack(pop)
2029bf215546Sopenharmony_ci
2030bf215546Sopenharmony_ci   const char *kernel_source =
2031bf215546Sopenharmony_ci   "struct __attribute__((packed)) s {uchar uc; ulong ul; ushort us; };\n\
2032bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *inout, global uint *size)\n\
2033bf215546Sopenharmony_ci   {\n\
2034bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
2035bf215546Sopenharmony_ci       inout[idx].uc = idx + 1;\n\
2036bf215546Sopenharmony_ci       inout[idx].ul = ((ulong)(idx + 1 + 0xfbfcfdfe) << 32) | 0x12345678;\n\
2037bf215546Sopenharmony_ci       inout[idx].us = ((ulong)(idx + 1 + 0xa0) << 8) | 0x12;\n\
2038bf215546Sopenharmony_ci       *size = sizeof(struct s);\n\
2039bf215546Sopenharmony_ci   }\n";
2040bf215546Sopenharmony_ci   auto inout = ShaderArg<struct s>({0, 0, 0}, SHADER_ARG_OUTPUT);
2041bf215546Sopenharmony_ci   auto size = ShaderArg<uint32_t>(0, SHADER_ARG_OUTPUT);
2042bf215546Sopenharmony_ci   const struct s expected[] = {
2043bf215546Sopenharmony_ci      { 1, 0xfbfcfdff12345678, 0xa112 }
2044bf215546Sopenharmony_ci   };
2045bf215546Sopenharmony_ci
2046bf215546Sopenharmony_ci   run_shader(kernel_source, inout.size(), 1, 1, inout, size);
2047bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i) {
2048bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].uc, expected[i].uc);
2049bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].ul, expected[i].ul);
2050bf215546Sopenharmony_ci      EXPECT_EQ(inout[i].us, expected[i].us);
2051bf215546Sopenharmony_ci   }
2052bf215546Sopenharmony_ci   EXPECT_EQ(size, sizeof(struct s));
2053bf215546Sopenharmony_ci}
2054bf215546Sopenharmony_ci
2055bf215546Sopenharmony_ciTEST_F(ComputeTest, packed_struct_arg)
2056bf215546Sopenharmony_ci{
2057bf215546Sopenharmony_ci#pragma pack(push, 1)
2058bf215546Sopenharmony_ci   struct s { uint8_t uc; uint64_t ul; uint16_t us; };
2059bf215546Sopenharmony_ci#pragma pack(pop)
2060bf215546Sopenharmony_ci
2061bf215546Sopenharmony_ci   const char *kernel_source =
2062bf215546Sopenharmony_ci   "struct __attribute__((packed)) s {uchar uc; ulong ul; ushort us; };\n\
2063bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out, struct s in)\n\
2064bf215546Sopenharmony_ci   {\n\
2065bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
2066bf215546Sopenharmony_ci       out[idx].uc = in.uc + 0x12;\n\
2067bf215546Sopenharmony_ci       out[idx].ul = in.ul + 0x123456789abcdef;\n\
2068bf215546Sopenharmony_ci       out[idx].us = in.us + 0x1234;\n\
2069bf215546Sopenharmony_ci   }\n";
2070bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>({0, 0, 0}, SHADER_ARG_OUTPUT);
2071bf215546Sopenharmony_ci   auto in = ShaderArg<struct s>({1, 2, 3}, SHADER_ARG_INPUT);
2072bf215546Sopenharmony_ci   const struct s expected[] = {
2073bf215546Sopenharmony_ci      { 0x12 + 1, 0x123456789abcdef + 2, 0x1234 + 3 }
2074bf215546Sopenharmony_ci   };
2075bf215546Sopenharmony_ci
2076bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
2077bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
2078bf215546Sopenharmony_ci      EXPECT_EQ(out[i].uc, expected[i].uc);
2079bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ul, expected[i].ul);
2080bf215546Sopenharmony_ci      EXPECT_EQ(out[i].us, expected[i].us);
2081bf215546Sopenharmony_ci   }
2082bf215546Sopenharmony_ci}
2083bf215546Sopenharmony_ci
2084bf215546Sopenharmony_ciTEST_F(ComputeTest, packed_struct_local)
2085bf215546Sopenharmony_ci{
2086bf215546Sopenharmony_ci#pragma pack(push, 1)
2087bf215546Sopenharmony_ci   struct s { uint8_t uc; uint64_t ul; uint16_t us; };
2088bf215546Sopenharmony_ci#pragma pack(pop)
2089bf215546Sopenharmony_ci
2090bf215546Sopenharmony_ci   const char *kernel_source =
2091bf215546Sopenharmony_ci   "struct __attribute__((packed)) s {uchar uc; ulong ul; ushort us; };\n\
2092bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out, __constant struct s *in)\n\
2093bf215546Sopenharmony_ci   {\n\
2094bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
2095bf215546Sopenharmony_ci       __local struct s tmp[2];\n\
2096bf215546Sopenharmony_ci       tmp[get_local_id(0)] = in[idx];\n\
2097bf215546Sopenharmony_ci       barrier(CLK_LOCAL_MEM_FENCE);\n\
2098bf215546Sopenharmony_ci       out[idx] = tmp[(get_local_id(0) + 1) % 2];\n\
2099bf215546Sopenharmony_ci   }\n";
2100bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>({{0, 0, 0}, {0, 0, 0}}, SHADER_ARG_OUTPUT);
2101bf215546Sopenharmony_ci   auto in = ShaderArg<struct s>({{1, 2, 3}, {0x12, 0x123456789abcdef, 0x1234} }, SHADER_ARG_INPUT);
2102bf215546Sopenharmony_ci   const struct s expected[] = {
2103bf215546Sopenharmony_ci      { 0x12, 0x123456789abcdef, 0x1234 },
2104bf215546Sopenharmony_ci      { 1, 2, 3 },
2105bf215546Sopenharmony_ci   };
2106bf215546Sopenharmony_ci
2107bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
2108bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
2109bf215546Sopenharmony_ci      EXPECT_EQ(out[i].uc, expected[i].uc);
2110bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ul, expected[i].ul);
2111bf215546Sopenharmony_ci      EXPECT_EQ(out[i].us, expected[i].us);
2112bf215546Sopenharmony_ci   }
2113bf215546Sopenharmony_ci}
2114bf215546Sopenharmony_ci
2115bf215546Sopenharmony_ciTEST_F(ComputeTest, DISABLED_packed_struct_const)
2116bf215546Sopenharmony_ci{
2117bf215546Sopenharmony_ci#pragma pack(push, 1)
2118bf215546Sopenharmony_ci   struct s { uint8_t uc; uint64_t ul; uint16_t us; };
2119bf215546Sopenharmony_ci#pragma pack(pop)
2120bf215546Sopenharmony_ci
2121bf215546Sopenharmony_ci   const char *kernel_source =
2122bf215546Sopenharmony_ci   "struct __attribute__((packed)) s {uchar uc; ulong ul; ushort us; };\n\
2123bf215546Sopenharmony_ci   __kernel void main_test(__global struct s *out, struct s in)\n\
2124bf215546Sopenharmony_ci   {\n\
2125bf215546Sopenharmony_ci       __constant struct s base[] = {\n\
2126bf215546Sopenharmony_ci          {0x12, 0x123456789abcdef, 0x1234},\n\
2127bf215546Sopenharmony_ci          {0x11, 0x123456789abcdee, 0x1233},\n\
2128bf215546Sopenharmony_ci       };\n\
2129bf215546Sopenharmony_ci       uint idx = get_global_id(0);\n\
2130bf215546Sopenharmony_ci       out[idx].uc = base[idx % 2].uc + in.uc;\n\
2131bf215546Sopenharmony_ci       out[idx].ul = base[idx % 2].ul + in.ul;\n\
2132bf215546Sopenharmony_ci       out[idx].us = base[idx % 2].us + in.us;\n\
2133bf215546Sopenharmony_ci   }\n";
2134bf215546Sopenharmony_ci   auto out = ShaderArg<struct s>(std::vector<struct s>(2, {0, 0, 0}), SHADER_ARG_OUTPUT);
2135bf215546Sopenharmony_ci   auto in = ShaderArg<struct s>({1, 2, 3}, SHADER_ARG_INPUT);
2136bf215546Sopenharmony_ci   const struct s expected[] = {
2137bf215546Sopenharmony_ci      { 0x12 + 1, 0x123456789abcdef + 2, 0x1234 + 3 },
2138bf215546Sopenharmony_ci      { 0x11 + 1, 0x123456789abcdee + 2, 0x1233 + 3 },
2139bf215546Sopenharmony_ci   };
2140bf215546Sopenharmony_ci
2141bf215546Sopenharmony_ci   run_shader(kernel_source, out.size(), 1, 1, out, in);
2142bf215546Sopenharmony_ci   for (int i = 0; i < out.size(); ++i) {
2143bf215546Sopenharmony_ci      EXPECT_EQ(out[i].uc, expected[i].uc);
2144bf215546Sopenharmony_ci      EXPECT_EQ(out[i].ul, expected[i].ul);
2145bf215546Sopenharmony_ci      EXPECT_EQ(out[i].us, expected[i].us);
2146bf215546Sopenharmony_ci   }
2147bf215546Sopenharmony_ci}
2148bf215546Sopenharmony_ci
2149bf215546Sopenharmony_ciTEST_F(ComputeTest, printf)
2150bf215546Sopenharmony_ci{
2151bf215546Sopenharmony_ci   const char *kernel_source = R"(
2152bf215546Sopenharmony_ci   __kernel void main_test(__global float *src, __global uint *dest)
2153bf215546Sopenharmony_ci   {
2154bf215546Sopenharmony_ci      *dest = printf("%s: %f", "Test", src[0]);
2155bf215546Sopenharmony_ci   })";
2156bf215546Sopenharmony_ci
2157bf215546Sopenharmony_ci   auto src = ShaderArg<float>({ 1.0f }, SHADER_ARG_INPUT);
2158bf215546Sopenharmony_ci   auto dest = ShaderArg<uint32_t>({ 0xdeadbeef }, SHADER_ARG_OUTPUT);
2159bf215546Sopenharmony_ci   run_shader(kernel_source, 1, 1, 1, src, dest);
2160bf215546Sopenharmony_ci   EXPECT_EQ(dest[0], 0);
2161bf215546Sopenharmony_ci}
2162bf215546Sopenharmony_ci
2163bf215546Sopenharmony_ciTEST_F(ComputeTest, vload_half)
2164bf215546Sopenharmony_ci{
2165bf215546Sopenharmony_ci   const char *kernel_source = R"(
2166bf215546Sopenharmony_ci   __kernel void main_test(__global half *src, __global float4 *dest)
2167bf215546Sopenharmony_ci   {
2168bf215546Sopenharmony_ci      int offset = get_global_id(0);
2169bf215546Sopenharmony_ci      dest[offset] = vload_half4(offset, src);
2170bf215546Sopenharmony_ci   })";
2171bf215546Sopenharmony_ci   auto src = ShaderArg<uint16_t>({ 0x3c00, 0x4000, 0x4200, 0x4400,
2172bf215546Sopenharmony_ci                                    0x4500, 0x4600, 0x4700, 0x4800 }, SHADER_ARG_INPUT);
2173bf215546Sopenharmony_ci   auto dest = ShaderArg<float>({ FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX,
2174bf215546Sopenharmony_ci                                  FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX }, SHADER_ARG_OUTPUT);
2175bf215546Sopenharmony_ci   run_shader(kernel_source, 2, 1, 1, src, dest);
2176bf215546Sopenharmony_ci   for (unsigned i = 0; i < 8; ++i)
2177bf215546Sopenharmony_ci      EXPECT_FLOAT_EQ(dest[i], (float)(i + 1));
2178bf215546Sopenharmony_ci}
2179bf215546Sopenharmony_ci
2180bf215546Sopenharmony_ciTEST_F(ComputeTest, vstore_half)
2181bf215546Sopenharmony_ci{
2182bf215546Sopenharmony_ci   const char *kernel_source = R"(
2183bf215546Sopenharmony_ci   __kernel void main_test(__global half *dst, __global float4 *src)
2184bf215546Sopenharmony_ci   {
2185bf215546Sopenharmony_ci      int offset = get_global_id(0);
2186bf215546Sopenharmony_ci      vstore_half4(src[offset], offset, dst);
2187bf215546Sopenharmony_ci   })";
2188bf215546Sopenharmony_ci   auto dest = ShaderArg<uint16_t>({0xdead, 0xdead, 0xdead, 0xdead,
2189bf215546Sopenharmony_ci                                   0xdead, 0xdead, 0xdead, 0xdead}, SHADER_ARG_OUTPUT);
2190bf215546Sopenharmony_ci   auto src = ShaderArg<float>({ 1.0, 2.0, 3.0, 4.0,
2191bf215546Sopenharmony_ci                                  5.0, 6.0, 7.0, 8.0 }, SHADER_ARG_INPUT);
2192bf215546Sopenharmony_ci   run_shader(kernel_source, 2, 1, 1, dest, src);
2193bf215546Sopenharmony_ci   const uint16_t expected[] = { 0x3c00, 0x4000, 0x4200, 0x4400,
2194bf215546Sopenharmony_ci                                 0x4500, 0x4600, 0x4700, 0x4800 };
2195bf215546Sopenharmony_ci   for (unsigned i = 0; i < 8; ++i)
2196bf215546Sopenharmony_ci      EXPECT_EQ(dest[i], expected[i]);
2197bf215546Sopenharmony_ci}
2198bf215546Sopenharmony_ci
2199bf215546Sopenharmony_ciTEST_F(ComputeTest, inline_function)
2200bf215546Sopenharmony_ci{
2201bf215546Sopenharmony_ci   const char *kernel_source = R"(
2202bf215546Sopenharmony_ci   inline float helper(float foo)
2203bf215546Sopenharmony_ci   {
2204bf215546Sopenharmony_ci      return foo * 2;
2205bf215546Sopenharmony_ci   }
2206bf215546Sopenharmony_ci
2207bf215546Sopenharmony_ci   __kernel void main_test(__global float *dst, __global float *src)
2208bf215546Sopenharmony_ci   {
2209bf215546Sopenharmony_ci      *dst = helper(*src);
2210bf215546Sopenharmony_ci   })";
2211bf215546Sopenharmony_ci   auto dest = ShaderArg<float>({ NAN }, SHADER_ARG_OUTPUT);
2212bf215546Sopenharmony_ci   auto src = ShaderArg<float>({ 1.0f }, SHADER_ARG_INPUT);
2213bf215546Sopenharmony_ci   run_shader(kernel_source, 1, 1, 1, dest, src);
2214bf215546Sopenharmony_ci   EXPECT_EQ(dest[0], 2.0f);
2215bf215546Sopenharmony_ci}
2216bf215546Sopenharmony_ci
2217bf215546Sopenharmony_ciTEST_F(ComputeTest, unused_arg)
2218bf215546Sopenharmony_ci{
2219bf215546Sopenharmony_ci   const char *kernel_source = R"(
2220bf215546Sopenharmony_ci   __kernel void main_test(__global int *dst, __global int *unused, __global int *src)
2221bf215546Sopenharmony_ci   {
2222bf215546Sopenharmony_ci      int i = get_global_id(0);
2223bf215546Sopenharmony_ci      dst[i] = src[i];
2224bf215546Sopenharmony_ci   })";
2225bf215546Sopenharmony_ci   auto dest = ShaderArg<int>({ -1, -1, -1, -1 }, SHADER_ARG_OUTPUT);
2226bf215546Sopenharmony_ci   auto src = ShaderArg<int>({ 1, 2, 3, 4 }, SHADER_ARG_INPUT);
2227bf215546Sopenharmony_ci   auto unused = ShaderArg<int>({ -1, -1, -1, -1 }, SHADER_ARG_INPUT);
2228bf215546Sopenharmony_ci   run_shader(kernel_source, 4, 1, 1, dest, unused, src);
2229bf215546Sopenharmony_ci   for (int i = 0; i < 4; ++i)
2230bf215546Sopenharmony_ci      EXPECT_EQ(dest[i], i + 1);
2231bf215546Sopenharmony_ci}
2232bf215546Sopenharmony_ci
2233bf215546Sopenharmony_ciTEST_F(ComputeTest, spec_constant)
2234bf215546Sopenharmony_ci{
2235bf215546Sopenharmony_ci   const char *spirv_asm = R"(
2236bf215546Sopenharmony_ci               OpCapability Addresses
2237bf215546Sopenharmony_ci               OpCapability Kernel
2238bf215546Sopenharmony_ci               OpCapability Int64
2239bf215546Sopenharmony_ci          %1 = OpExtInstImport "OpenCL.std"
2240bf215546Sopenharmony_ci               OpMemoryModel Physical64 OpenCL
2241bf215546Sopenharmony_ci               OpEntryPoint Kernel %2 "main_test" %__spirv_BuiltInGlobalInvocationId
2242bf215546Sopenharmony_ci          %4 = OpString "kernel_arg_type.main_test.uint*,"
2243bf215546Sopenharmony_ci               OpSource OpenCL_C 102000
2244bf215546Sopenharmony_ci               OpName %__spirv_BuiltInGlobalInvocationId "__spirv_BuiltInGlobalInvocationId"
2245bf215546Sopenharmony_ci               OpName %output "output"
2246bf215546Sopenharmony_ci               OpName %entry "entry"
2247bf215546Sopenharmony_ci               OpName %output_addr "output.addr"
2248bf215546Sopenharmony_ci               OpName %id "id"
2249bf215546Sopenharmony_ci               OpName %call "call"
2250bf215546Sopenharmony_ci               OpName %conv "conv"
2251bf215546Sopenharmony_ci               OpName %idxprom "idxprom"
2252bf215546Sopenharmony_ci               OpName %arrayidx "arrayidx"
2253bf215546Sopenharmony_ci               OpName %add "add"
2254bf215546Sopenharmony_ci               OpName %mul "mul"
2255bf215546Sopenharmony_ci               OpName %idxprom1 "idxprom1"
2256bf215546Sopenharmony_ci               OpName %arrayidx2 "arrayidx2"
2257bf215546Sopenharmony_ci               OpDecorate %__spirv_BuiltInGlobalInvocationId BuiltIn GlobalInvocationId
2258bf215546Sopenharmony_ci               OpDecorate %__spirv_BuiltInGlobalInvocationId Constant
2259bf215546Sopenharmony_ci               OpDecorate %id Alignment 4
2260bf215546Sopenharmony_ci               OpDecorate %output_addr Alignment 8
2261bf215546Sopenharmony_ci               OpDecorate %uint_1 SpecId 1
2262bf215546Sopenharmony_ci      %ulong = OpTypeInt 64 0
2263bf215546Sopenharmony_ci       %uint = OpTypeInt 32 0
2264bf215546Sopenharmony_ci     %uint_1 = OpSpecConstant %uint 1
2265bf215546Sopenharmony_ci    %v3ulong = OpTypeVector %ulong 3
2266bf215546Sopenharmony_ci%_ptr_Input_v3ulong = OpTypePointer Input %v3ulong
2267bf215546Sopenharmony_ci       %void = OpTypeVoid
2268bf215546Sopenharmony_ci%_ptr_CrossWorkgroup_uint = OpTypePointer CrossWorkgroup %uint
2269bf215546Sopenharmony_ci         %24 = OpTypeFunction %void %_ptr_CrossWorkgroup_uint
2270bf215546Sopenharmony_ci%_ptr_Function__ptr_CrossWorkgroup_uint = OpTypePointer Function %_ptr_CrossWorkgroup_uint
2271bf215546Sopenharmony_ci%_ptr_Function_uint = OpTypePointer Function %uint
2272bf215546Sopenharmony_ci%__spirv_BuiltInGlobalInvocationId = OpVariable %_ptr_Input_v3ulong Input
2273bf215546Sopenharmony_ci          %2 = OpFunction %void DontInline %24
2274bf215546Sopenharmony_ci     %output = OpFunctionParameter %_ptr_CrossWorkgroup_uint
2275bf215546Sopenharmony_ci      %entry = OpLabel
2276bf215546Sopenharmony_ci%output_addr = OpVariable %_ptr_Function__ptr_CrossWorkgroup_uint Function
2277bf215546Sopenharmony_ci         %id = OpVariable %_ptr_Function_uint Function
2278bf215546Sopenharmony_ci               OpStore %output_addr %output Aligned 8
2279bf215546Sopenharmony_ci         %27 = OpLoad %v3ulong %__spirv_BuiltInGlobalInvocationId Aligned 32
2280bf215546Sopenharmony_ci       %call = OpCompositeExtract %ulong %27 0
2281bf215546Sopenharmony_ci       %conv = OpUConvert %uint %call
2282bf215546Sopenharmony_ci               OpStore %id %conv Aligned 4
2283bf215546Sopenharmony_ci         %28 = OpLoad %_ptr_CrossWorkgroup_uint %output_addr Aligned 8
2284bf215546Sopenharmony_ci         %29 = OpLoad %uint %id Aligned 4
2285bf215546Sopenharmony_ci    %idxprom = OpUConvert %ulong %29
2286bf215546Sopenharmony_ci   %arrayidx = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %28 %idxprom
2287bf215546Sopenharmony_ci         %30 = OpLoad %uint %arrayidx Aligned 4
2288bf215546Sopenharmony_ci         %31 = OpLoad %uint %id Aligned 4
2289bf215546Sopenharmony_ci        %add = OpIAdd %uint %31 %uint_1
2290bf215546Sopenharmony_ci        %mul = OpIMul %uint %30 %add
2291bf215546Sopenharmony_ci         %32 = OpLoad %_ptr_CrossWorkgroup_uint %output_addr Aligned 8
2292bf215546Sopenharmony_ci         %33 = OpLoad %uint %id Aligned 4
2293bf215546Sopenharmony_ci   %idxprom1 = OpUConvert %ulong %33
2294bf215546Sopenharmony_ci  %arrayidx2 = OpInBoundsPtrAccessChain %_ptr_CrossWorkgroup_uint %32 %idxprom1
2295bf215546Sopenharmony_ci               OpStore %arrayidx2 %mul Aligned 4
2296bf215546Sopenharmony_ci               OpReturn
2297bf215546Sopenharmony_ci               OpFunctionEnd)";
2298bf215546Sopenharmony_ci   Shader shader = assemble(spirv_asm);
2299bf215546Sopenharmony_ci   Shader spec_shader = specialize(shader, 1, 5);
2300bf215546Sopenharmony_ci
2301bf215546Sopenharmony_ci   auto inout = ShaderArg<uint32_t>({ 0x00000001, 0x10000001, 0x00020002, 0x04010203 },
2302bf215546Sopenharmony_ci      SHADER_ARG_INOUT);
2303bf215546Sopenharmony_ci   const uint32_t expected[] = {
2304bf215546Sopenharmony_ci      0x00000005, 0x60000006, 0x000e000e, 0x20081018
2305bf215546Sopenharmony_ci   };
2306bf215546Sopenharmony_ci   CompileArgs args = { (unsigned)inout.size(), 1, 1 };
2307bf215546Sopenharmony_ci   run_shader(spec_shader, args, inout);
2308bf215546Sopenharmony_ci   for (int i = 0; i < inout.size(); ++i)
2309bf215546Sopenharmony_ci      EXPECT_EQ(inout[i], expected[i]);
2310bf215546Sopenharmony_ci}
2311bf215546Sopenharmony_ci
2312bf215546Sopenharmony_ciTEST_F(ComputeTest, arg_metadata)
2313bf215546Sopenharmony_ci{
2314bf215546Sopenharmony_ci   const char *kernel_source = R"(
2315bf215546Sopenharmony_ci   __kernel void main_test(
2316bf215546Sopenharmony_ci      __global int *undec_ptr,
2317bf215546Sopenharmony_ci      __global volatile int *vol_ptr,
2318bf215546Sopenharmony_ci      __global const int *const_ptr,
2319bf215546Sopenharmony_ci      __global int *restrict restr_ptr,
2320bf215546Sopenharmony_ci      __global const int *restrict const_restr_ptr,
2321bf215546Sopenharmony_ci      __constant int *const_ptr2)
2322bf215546Sopenharmony_ci   {
2323bf215546Sopenharmony_ci   })";
2324bf215546Sopenharmony_ci   Shader shader = compile({ kernel_source });
2325bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[0].address_qualifier, CLC_KERNEL_ARG_ADDRESS_GLOBAL);
2326bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[0].type_qualifier, 0);
2327bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[1].address_qualifier, CLC_KERNEL_ARG_ADDRESS_GLOBAL);
2328bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[1].type_qualifier, CLC_KERNEL_ARG_TYPE_VOLATILE);
2329bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[2].address_qualifier, CLC_KERNEL_ARG_ADDRESS_GLOBAL);
2330bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[2].type_qualifier, CLC_KERNEL_ARG_TYPE_CONST);
2331bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[3].address_qualifier, CLC_KERNEL_ARG_ADDRESS_GLOBAL);
2332bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[3].type_qualifier, CLC_KERNEL_ARG_TYPE_RESTRICT);
2333bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[4].address_qualifier, CLC_KERNEL_ARG_ADDRESS_GLOBAL);
2334bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[4].type_qualifier, CLC_KERNEL_ARG_TYPE_RESTRICT | CLC_KERNEL_ARG_TYPE_CONST);
2335bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[5].address_qualifier, CLC_KERNEL_ARG_ADDRESS_CONSTANT);
2336bf215546Sopenharmony_ci   EXPECT_EQ(shader.metadata->kernels[0].args[5].type_qualifier, CLC_KERNEL_ARG_TYPE_CONST);
2337bf215546Sopenharmony_ci}
2338