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