1/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "shared.rsh"
18//#pragma rs_fp_relaxed
19
20volatile float x = 0.0f;
21volatile float y = 0.0f;
22volatile float result_add = 0.0f;
23volatile float result_sub = 0.0f;
24volatile float result_mul = 0.0f;
25volatile float result_div = 0.0f;
26
27#define DECLARE_INPUT_SET(type, abbrev)         \
28volatile type    rand_##abbrev##1_0, rand_##abbrev##1_1; \
29volatile type##2 rand_##abbrev##2_0, rand_##abbrev##2_1; \
30volatile type##3 rand_##abbrev##3_0, rand_##abbrev##3_1; \
31volatile type##4 rand_##abbrev##4_0, rand_##abbrev##4_1;
32
33#define DECLARE_ALL_INPUT_SETS()    \
34DECLARE_INPUT_SET(float, f);        \
35DECLARE_INPUT_SET(char, sc);        \
36DECLARE_INPUT_SET(uchar, uc);       \
37DECLARE_INPUT_SET(short, ss);       \
38DECLARE_INPUT_SET(ushort, us);      \
39DECLARE_INPUT_SET(int, si);         \
40DECLARE_INPUT_SET(uint, ui);        \
41DECLARE_INPUT_SET(long, sl);        \
42DECLARE_INPUT_SET(ulong, ul);
43
44DECLARE_ALL_INPUT_SETS();
45
46#define DECLARE_REFERENCE_SET_VEC_VEC(type, abbrev, func)   \
47volatile type    func##_rand_##abbrev##1_##abbrev##1;                \
48volatile type##2 func##_rand_##abbrev##2_##abbrev##2;                \
49volatile type##3 func##_rand_##abbrev##3_##abbrev##3;                \
50volatile type##4 func##_rand_##abbrev##4_##abbrev##4;
51#define DECLARE_REFERENCE_SET_VEC_SCL(type, abbrev, func)   \
52volatile type##2 func##_rand_##abbrev##2_##abbrev##1;                \
53volatile type##3 func##_rand_##abbrev##3_##abbrev##1;                \
54volatile type##4 func##_rand_##abbrev##4_##abbrev##1;
55
56#define DECLARE_ALL_REFERENCE_SETS_VEC_VEC(func)    \
57DECLARE_REFERENCE_SET_VEC_VEC(float, f, func);      \
58DECLARE_REFERENCE_SET_VEC_VEC(char, sc, func);      \
59DECLARE_REFERENCE_SET_VEC_VEC(uchar, uc, func);     \
60DECLARE_REFERENCE_SET_VEC_VEC(short, ss, func);     \
61DECLARE_REFERENCE_SET_VEC_VEC(ushort, us, func);    \
62DECLARE_REFERENCE_SET_VEC_VEC(int, si, func);       \
63DECLARE_REFERENCE_SET_VEC_VEC(uint, ui, func);      \
64DECLARE_REFERENCE_SET_VEC_VEC(long, sl, func);      \
65DECLARE_REFERENCE_SET_VEC_VEC(ulong, ul, func);
66
67DECLARE_ALL_REFERENCE_SETS_VEC_VEC(min);
68DECLARE_ALL_REFERENCE_SETS_VEC_VEC(max);
69DECLARE_REFERENCE_SET_VEC_VEC(float, f, fmin);
70DECLARE_REFERENCE_SET_VEC_SCL(float, f, fmin);
71DECLARE_REFERENCE_SET_VEC_VEC(float, f, fmax);
72DECLARE_REFERENCE_SET_VEC_SCL(float, f, fmax);
73
74static void fail_f1(float v1, float v2, float actual, float expected, char *op_name) {
75    int dist = float_dist(actual, expected);
76    rsDebug("float operation did not match!", op_name);
77    rsDebug("v1", v1);
78    rsDebug("v2", v2);
79    rsDebug("Dalvik result", expected);
80    rsDebug("Renderscript result", actual);
81    rsDebug("ULP difference", dist);
82}
83
84static void fail_f2(float2 v1, float2 v2, float2 actual, float2 expected, char *op_name) {
85    int2 dist;
86    dist.x = float_dist(actual.x, expected.x);
87    dist.y = float_dist(actual.y, expected.y);
88    rsDebug("float2 operation did not match!", op_name);
89    rsDebug("v1.x", v1.x);
90    rsDebug("v1.y", v1.y);
91    rsDebug("v2.x", v2.x);
92    rsDebug("v2.y", v2.y);
93    rsDebug("Dalvik result .x", expected.x);
94    rsDebug("Dalvik result .y", expected.y);
95    rsDebug("Renderscript result .x", actual.x);
96    rsDebug("Renderscript result .y", actual.y);
97    rsDebug("ULP difference .x", dist.x);
98    rsDebug("ULP difference .y", dist.y);
99}
100
101static void fail_f3(float3 v1, float3 v2, float3 actual, float3 expected, char *op_name) {
102    int3 dist;
103    dist.x = float_dist(actual.x, expected.x);
104    dist.y = float_dist(actual.y, expected.y);
105    dist.z = float_dist(actual.z, expected.z);
106    rsDebug("float3 operation did not match!", op_name);
107    rsDebug("v1.x", v1.x);
108    rsDebug("v1.y", v1.y);
109    rsDebug("v1.z", v1.z);
110    rsDebug("v2.x", v2.x);
111    rsDebug("v2.y", v2.y);
112    rsDebug("v2.z", v2.z);
113    rsDebug("Dalvik result .x", expected.x);
114    rsDebug("Dalvik result .y", expected.y);
115    rsDebug("Dalvik result .z", expected.z);
116    rsDebug("Renderscript result .x", actual.x);
117    rsDebug("Renderscript result .y", actual.y);
118    rsDebug("Renderscript result .z", actual.z);
119    rsDebug("ULP difference .x", dist.x);
120    rsDebug("ULP difference .y", dist.y);
121    rsDebug("ULP difference .z", dist.z);
122}
123
124static void fail_f4(float4 v1, float4 v2, float4 actual, float4 expected, char *op_name) {
125    int4 dist;
126    dist.x = float_dist(actual.x, expected.x);
127    dist.y = float_dist(actual.y, expected.y);
128    dist.z = float_dist(actual.z, expected.z);
129    dist.w = float_dist(actual.w, expected.w);
130    rsDebug("float4 operation did not match!", op_name);
131    rsDebug("v1.x", v1.x);
132    rsDebug("v1.y", v1.y);
133    rsDebug("v1.z", v1.z);
134    rsDebug("v1.w", v1.w);
135    rsDebug("v2.x", v2.x);
136    rsDebug("v2.y", v2.y);
137    rsDebug("v2.z", v2.z);
138    rsDebug("v2.w", v2.w);
139    rsDebug("Dalvik result .x", expected.x);
140    rsDebug("Dalvik result .y", expected.y);
141    rsDebug("Dalvik result .z", expected.z);
142    rsDebug("Dalvik result .w", expected.w);
143    rsDebug("Renderscript result .x", actual.x);
144    rsDebug("Renderscript result .y", actual.y);
145    rsDebug("Renderscript result .z", actual.z);
146    rsDebug("Renderscript result .w", actual.w);
147    rsDebug("ULP difference .x", dist.x);
148    rsDebug("ULP difference .y", dist.y);
149    rsDebug("ULP difference .z", dist.z);
150    rsDebug("ULP difference .w", dist.w);
151}
152
153static bool f1_almost_equal(float a, float b) {
154    return float_almost_equal(a, b);
155}
156
157static bool f2_almost_equal(float2 a, float2 b) {
158    return float_almost_equal(a.x, b.x) && float_almost_equal(a.y, b.y);
159}
160
161
162static bool f3_almost_equal(float3 a, float3 b) {
163    return float_almost_equal(a.x, b.x) && float_almost_equal(a.y, b.y)
164            && float_almost_equal(a.z, b.z);
165}
166
167static bool f4_almost_equal(float4 a, float4 b) {
168    return float_almost_equal(a.x, b.x) && float_almost_equal(a.y, b.y)
169            && float_almost_equal(a.z, b.z) && float_almost_equal(a.w, b.w);
170}
171
172#define TEST_BASIC_FLOAT_OP(op, opName)                 \
173temp_f1 = x op y;                                       \
174if (! float_almost_equal(temp_f1, result_##opName)) {   \
175    fail_f1(x, y , temp_f1, result_##opName, #opName);  \
176    failed = true;                                      \
177}
178
179#define TEST_FN_FN(func, size)                                                  \
180temp_f##size = func(rand_f##size##_0, rand_f##size##_1);                        \
181if (! f##size##_almost_equal(temp_f##size , func##_rand_f##size##_f##size)) {   \
182    fail_f##size (x, y , temp_f##size, func##_rand_f##size##_f##size, #func);   \
183    failed = true;                                                              \
184}
185#define TEST_FN_F(func, size)                                               \
186temp_f##size = func(rand_f##size##_0, rand_f1_1);                           \
187if (! f##size##_almost_equal(temp_f##size , func##_rand_f##size##_f1)) {    \
188    fail_f##size (x, y , temp_f##size, func##_rand_f##size##_f1 , #func);   \
189    failed = true;                                                          \
190}
191
192#define TEST_FN_FN_ALL(func)    \
193TEST_FN_FN(func, 1)             \
194TEST_FN_FN(func, 2)             \
195TEST_FN_FN(func, 3)             \
196TEST_FN_FN(func, 4)
197#define TEST_FN_F_ALL(func) \
198TEST_FN_F(func, 2)          \
199TEST_FN_F(func, 3)          \
200TEST_FN_F(func, 4)
201
202#define TEST_VEC1_VEC1(func, type)                              \
203temp_##type##1 = func( rand_##type##1_0, rand_##type##1_1 );    \
204if (temp_##type##1 != func##_rand_##type##1_##type##1) {        \
205    rsDebug(#func " " #type "1 operation did not match!", 0);   \
206    rsDebug("v1", rand_##type##1_0);                            \
207    rsDebug("v2", rand_##type##1_1);                            \
208    rsDebug("Dalvik result", func##_rand_##type##1_##type##1);  \
209    rsDebug("Renderscript result", temp_##type##1);             \
210    failed = true;                                              \
211}
212#define TEST_VEC2_VEC2(func, type)                                      \
213temp_##type##2 = func( rand_##type##2_0, rand_##type##2_1 );            \
214if (temp_##type##2 .x != func##_rand_##type##2_##type##2 .x             \
215        || temp_##type##2 .y != func##_rand_##type##2_##type##2 .y) {   \
216    rsDebug(#func " " #type "2 operation did not match!", 0);           \
217    rsDebug("v1.x", rand_##type##2_0 .x);                               \
218    rsDebug("v1.y", rand_##type##2_0 .y);                               \
219    rsDebug("v2.x", rand_##type##2_1 .x);                               \
220    rsDebug("v2.y", rand_##type##2_1 .y);                               \
221    rsDebug("Dalvik result .x", func##_rand_##type##2_##type##2 .x);    \
222    rsDebug("Dalvik result .y", func##_rand_##type##2_##type##2 .y);    \
223    rsDebug("Renderscript result .x", temp_##type##2 .x);               \
224    rsDebug("Renderscript result .y", temp_##type##2 .y);               \
225    failed = true;                                                      \
226}
227#define TEST_VEC3_VEC3(func, type)                                      \
228temp_##type##3 = func( rand_##type##3_0, rand_##type##3_1 );            \
229if (temp_##type##3 .x != func##_rand_##type##3_##type##3 .x             \
230        || temp_##type##3 .y != func##_rand_##type##3_##type##3 .y      \
231        || temp_##type##3 .z != func##_rand_##type##3_##type##3 .z) {   \
232    rsDebug(#func " " #type "3 operation did not match!", 0);           \
233    rsDebug("v1.x", rand_##type##3_0 .x);                               \
234    rsDebug("v1.y", rand_##type##3_0 .y);                               \
235    rsDebug("v1.z", rand_##type##3_0 .z);                               \
236    rsDebug("v2.x", rand_##type##3_1 .x);                               \
237    rsDebug("v2.y", rand_##type##3_1 .y);                               \
238    rsDebug("v2.z", rand_##type##3_1 .z);                               \
239    rsDebug("Dalvik result .x", func##_rand_##type##3_##type##3 .x);    \
240    rsDebug("Dalvik result .y", func##_rand_##type##3_##type##3 .y);    \
241    rsDebug("Dalvik result .z", func##_rand_##type##3_##type##3 .z);    \
242    rsDebug("Renderscript result .x", temp_##type##3 .x);               \
243    rsDebug("Renderscript result .y", temp_##type##3 .y);               \
244    rsDebug("Renderscript result .z", temp_##type##3 .z);               \
245    failed = true;                                                      \
246}
247#define TEST_VEC4_VEC4(func, type)                                      \
248temp_##type##4 = func( rand_##type##4_0, rand_##type##4_1 );            \
249if (temp_##type##4 .x != func##_rand_##type##4_##type##4 .x             \
250        || temp_##type##4 .y != func##_rand_##type##4_##type##4 .y      \
251        || temp_##type##4 .z != func##_rand_##type##4_##type##4 .z      \
252        || temp_##type##4 .w != func##_rand_##type##4_##type##4 .w) {   \
253    rsDebug(#func " " #type "4 operation did not match!", 0);           \
254    rsDebug("v1.x", rand_##type##4_0 .x);                               \
255    rsDebug("v1.y", rand_##type##4_0 .y);                               \
256    rsDebug("v1.z", rand_##type##4_0 .z);                               \
257    rsDebug("v1.w", rand_##type##4_0 .w);                               \
258    rsDebug("v2.x", rand_##type##4_1 .x);                               \
259    rsDebug("v2.y", rand_##type##4_1 .y);                               \
260    rsDebug("v2.z", rand_##type##4_1 .z);                               \
261    rsDebug("v2.w", rand_##type##4_1 .w);                               \
262    rsDebug("Dalvik result .x", func##_rand_##type##4_##type##4 .x);    \
263    rsDebug("Dalvik result .y", func##_rand_##type##4_##type##4 .y);    \
264    rsDebug("Dalvik result .z", func##_rand_##type##4_##type##4 .z);    \
265    rsDebug("Dalvik result .w", func##_rand_##type##4_##type##4 .w);    \
266    rsDebug("Renderscript result .x", temp_##type##4 .x);               \
267    rsDebug("Renderscript result .y", temp_##type##4 .y);               \
268    rsDebug("Renderscript result .z", temp_##type##4 .z);               \
269    rsDebug("Renderscript result .w", temp_##type##4 .w);               \
270    failed = true;                                                      \
271}
272
273#define TEST_SC1_SC1(func)  TEST_VEC1_VEC1(func, sc)
274#define TEST_SC2_SC2(func)  TEST_VEC2_VEC2(func, sc)
275#define TEST_SC3_SC3(func)  TEST_VEC3_VEC3(func, sc)
276#define TEST_SC4_SC4(func)  TEST_VEC4_VEC4(func, sc)
277
278#define TEST_UC1_UC1(func)  TEST_VEC1_VEC1(func, uc)
279#define TEST_UC2_UC2(func)  TEST_VEC2_VEC2(func, uc)
280#define TEST_UC3_UC3(func)  TEST_VEC3_VEC3(func, uc)
281#define TEST_UC4_UC4(func)  TEST_VEC4_VEC4(func, uc)
282
283#define TEST_SS1_SS1(func)  TEST_VEC1_VEC1(func, ss)
284#define TEST_SS2_SS2(func)  TEST_VEC2_VEC2(func, ss)
285#define TEST_SS3_SS3(func)  TEST_VEC3_VEC3(func, ss)
286#define TEST_SS4_SS4(func)  TEST_VEC4_VEC4(func, ss)
287
288#define TEST_US1_US1(func)  TEST_VEC1_VEC1(func, us)
289#define TEST_US2_US2(func)  TEST_VEC2_VEC2(func, us)
290#define TEST_US3_US3(func)  TEST_VEC3_VEC3(func, us)
291#define TEST_US4_US4(func)  TEST_VEC4_VEC4(func, us)
292
293#define TEST_SI1_SI1(func)  TEST_VEC1_VEC1(func, si)
294#define TEST_SI2_SI2(func)  TEST_VEC2_VEC2(func, si)
295#define TEST_SI3_SI3(func)  TEST_VEC3_VEC3(func, si)
296#define TEST_SI4_SI4(func)  TEST_VEC4_VEC4(func, si)
297
298#define TEST_UI1_UI1(func)  TEST_VEC1_VEC1(func, ui)
299#define TEST_UI2_UI2(func)  TEST_VEC2_VEC2(func, ui)
300#define TEST_UI3_UI3(func)  TEST_VEC3_VEC3(func, ui)
301#define TEST_UI4_UI4(func)  TEST_VEC4_VEC4(func, ui)
302
303#define TEST_SL1_SL1(func)  TEST_VEC1_VEC1(func, sl)
304#define TEST_SL2_SL2(func)  TEST_VEC2_VEC2(func, sl)
305#define TEST_SL3_SL3(func)  TEST_VEC3_VEC3(func, sl)
306#define TEST_SL4_SL4(func)  TEST_VEC4_VEC4(func, sl)
307
308#define TEST_UL1_UL1(func)  TEST_VEC1_VEC1(func, ul)
309#define TEST_UL2_UL2(func)  TEST_VEC2_VEC2(func, ul)
310#define TEST_UL3_UL3(func)  TEST_VEC3_VEC3(func, ul)
311#define TEST_UL4_UL4(func)  TEST_VEC4_VEC4(func, ul)
312
313#define TEST_SC_SC_ALL(func)    \
314TEST_SC1_SC1(func)              \
315TEST_SC2_SC2(func)              \
316TEST_SC3_SC3(func)              \
317TEST_SC4_SC4(func)
318#define TEST_UC_UC_ALL(func)    \
319TEST_UC1_UC1(func)              \
320TEST_UC2_UC2(func)              \
321TEST_UC3_UC3(func)              \
322TEST_UC4_UC4(func)
323
324#define TEST_SS_SS_ALL(func)    \
325TEST_SS1_SS1(func)              \
326TEST_SS2_SS2(func)              \
327TEST_SS3_SS3(func)              \
328TEST_SS4_SS4(func)
329#define TEST_US_US_ALL(func)    \
330TEST_US1_US1(func)              \
331TEST_US2_US2(func)              \
332TEST_US3_US3(func)              \
333TEST_US4_US4(func)
334#define TEST_SI_SI_ALL(func)    \
335TEST_SI1_SI1(func)              \
336TEST_SI2_SI2(func)              \
337TEST_SI3_SI3(func)              \
338TEST_SI4_SI4(func)
339#define TEST_UI_UI_ALL(func)    \
340TEST_UI1_UI1(func)              \
341TEST_UI2_UI2(func)              \
342TEST_UI3_UI3(func)              \
343TEST_UI4_UI4(func)
344#define TEST_SL_SL_ALL(func)    \
345TEST_SL1_SL1(func)              \
346TEST_SL2_SL2(func)              \
347TEST_SL3_SL3(func)              \
348TEST_SL4_SL4(func)
349#define TEST_UL_UL_ALL(func)    \
350TEST_UL1_UL1(func)              \
351TEST_UL2_UL2(func)              \
352TEST_UL3_UL3(func)              \
353TEST_UL4_UL4(func)
354
355#define TEST_VEC_VEC_ALL(func)  \
356TEST_FN_FN_ALL(func)            \
357TEST_SC_SC_ALL(func)            \
358TEST_UC_UC_ALL(func)            \
359TEST_SS_SS_ALL(func)            \
360TEST_US_US_ALL(func)            \
361TEST_SI_SI_ALL(func)            \
362TEST_UI_UI_ALL(func)            \
363TEST_SL_SL_ALL(func)            \
364TEST_UL_UL_ALL(func)
365
366#define DECLARE_TEMP_SET(type, abbrev)  \
367volatile type    temp_##abbrev##1;               \
368volatile type##2 temp_##abbrev##2;               \
369volatile type##3 temp_##abbrev##3;               \
370volatile type##4 temp_##abbrev##4;
371
372#define DECLARE_ALL_TEMP_SETS() \
373DECLARE_TEMP_SET(float, f);     \
374DECLARE_TEMP_SET(char, sc);     \
375DECLARE_TEMP_SET(uchar, uc);    \
376DECLARE_TEMP_SET(short, ss);    \
377DECLARE_TEMP_SET(ushort, us);   \
378DECLARE_TEMP_SET(int, si);      \
379DECLARE_TEMP_SET(uint, ui);     \
380DECLARE_TEMP_SET(long, sl);     \
381DECLARE_TEMP_SET(ulong, ul);
382
383static bool test_math_agree() {
384    bool failed = false;
385
386    DECLARE_ALL_TEMP_SETS();
387
388    TEST_BASIC_FLOAT_OP(+, add);
389    TEST_BASIC_FLOAT_OP(-, sub);
390    TEST_BASIC_FLOAT_OP(*, mul);
391    TEST_BASIC_FLOAT_OP(/, div);
392
393    TEST_VEC_VEC_ALL(min);
394    TEST_VEC_VEC_ALL(max);
395    TEST_FN_FN_ALL(fmin);
396    TEST_FN_F_ALL(fmin);
397    TEST_FN_FN_ALL(fmax);
398    TEST_FN_F_ALL(fmax);
399
400    if (failed) {
401        rsDebug("test_math_agree FAILED", 0);
402    }
403    else {
404        rsDebug("test_math_agree PASSED", 0);
405    }
406
407    return failed;
408}
409
410void math_agree_test() {
411    bool failed = false;
412    failed |= test_math_agree();
413
414    if (failed) {
415        rsSendToClientBlocking(RS_MSG_TEST_FAILED);
416    }
417    else {
418        rsSendToClientBlocking(RS_MSG_TEST_PASSED);
419    }
420}
421