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