xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/math_brute_force/function_list.cpp (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1 //
2 // Copyright (c) 2017 The Khronos Group Inc.
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 "function_list.h"
18 #include "reference_math.h"
19 #include "test_functions.h"
20 
21 #define FTZ_ON 1
22 #define FTZ_OFF 0
23 #define EXACT 0.0f
24 #define RELAXED_ON 1
25 #define RELAXED_OFF 0
26 
27 #define STRINGIFY(_s) #_s
28 
29 // Only use ulps information in spir test
30 #ifdef FUNCTION_LIST_ULPS_ONLY
31 
32 #define ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type)                       \
33     {                                                                          \
34         STRINGIFY(_name), STRINGIFY(_name), { NULL }, { NULL }, { NULL },      \
35             _ulp, _ulp, _embedded_ulp, INFINITY, INFINITY, _rmode,             \
36             RELAXED_OFF, _type                                                 \
37     }
38 #define ENTRY_EXT(_name, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, _type,     \
39                   _relaxed_embedded_ulp)                                       \
40     {                                                                          \
41         STRINGIFY(_name), STRINGIFY(_name), { NULL }, { NULL }, { NULL },      \
42             _ulp, _ulp, _embedded_ulp, _relaxed_ulp, _relaxed_embedded_ulp,    \
43             _rmode, RELAXED_ON, _type                                          \
44     }
45 #define HALF_ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type)                  \
46     {                                                                          \
47         "half_" STRINGIFY(_name), "half_" STRINGIFY(_name), { NULL },          \
48             { NULL }, { NULL }, _ulp, _ulp, _embedded_ulp, INFINITY, INFINITY, \
49             _rmode, RELAXED_OFF, _type                                         \
50     }
51 #define OPERATOR_ENTRY(_name, _operator, _ulp, _embedded_ulp, _rmode, _type)   \
52     {                                                                          \
53         STRINGIFY(_name), _operator, { NULL }, { NULL }, { NULL }, _ulp, _ulp, \
54             _embedded_ulp, INFINITY, INFINITY, _rmode, RELAXED_OFF, _type      \
55     }
56 
57 #define unaryF NULL
58 #define i_unaryF NULL
59 #define unaryF_u NULL
60 #define macro_unaryF NULL
61 #define binaryF NULL
62 #define binaryOperatorF NULL
63 #define binaryF_i NULL
64 #define macro_binaryF NULL
65 #define ternaryF NULL
66 #define unaryF_two_results NULL
67 #define unaryF_two_results_i NULL
68 #define binaryF_two_results_i NULL
69 #define mad_function NULL
70 
71 #define reference_sqrt NULL
72 #define reference_sqrtl NULL
73 #define reference_divide NULL
74 #define reference_dividel NULL
75 #define reference_relaxed_divide NULL
76 
77 #else // FUNCTION_LIST_ULPS_ONLY
78 
79 #define ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type)                       \
80     {                                                                          \
81         STRINGIFY(_name), STRINGIFY(_name), { (void*)reference_##_name },      \
82             { (void*)reference_##_name##l }, { (void*)reference_##_name },     \
83             _ulp, _ulp, _embedded_ulp, INFINITY, INFINITY, _rmode,             \
84             RELAXED_OFF, _type                                                 \
85     }
86 #define ENTRY_EXT(_name, _ulp, _embedded_ulp, _relaxed_ulp, _rmode, _type,     \
87                   _relaxed_embedded_ulp)                                       \
88     {                                                                          \
89         STRINGIFY(_name), STRINGIFY(_name), { (void*)reference_##_name },      \
90             { (void*)reference_##_name##l },                                   \
91             { (void*)reference_##relaxed_##_name }, _ulp, _ulp, _embedded_ulp, \
92             _relaxed_ulp, _relaxed_embedded_ulp, _rmode, RELAXED_ON, _type     \
93     }
94 #define HALF_ENTRY(_name, _ulp, _embedded_ulp, _rmode, _type)                  \
95     {                                                                          \
96         "half_" STRINGIFY(_name), "half_" STRINGIFY(_name),                    \
97             { (void*)reference_##_name }, { NULL }, { NULL }, _ulp, _ulp,      \
98             _embedded_ulp, INFINITY, INFINITY, _rmode, RELAXED_OFF, _type      \
99     }
100 #define OPERATOR_ENTRY(_name, _operator, _ulp, _embedded_ulp, _rmode, _type)   \
101     {                                                                          \
102         STRINGIFY(_name), _operator, { (void*)reference_##_name },             \
103             { (void*)reference_##_name##l }, { NULL }, _ulp, _ulp,             \
104             _embedded_ulp, INFINITY, INFINITY, _rmode, RELAXED_OFF, _type      \
105     }
106 
107 static constexpr vtbl _unary = {
108     "unary",
109     TestFunc_Float_Float,
110     TestFunc_Double_Double,
111 };
112 
113 static constexpr vtbl _i_unary = {
114     "i_unary",
115     TestFunc_Int_Float,
116     TestFunc_Int_Double,
117 };
118 
119 static constexpr vtbl _unary_u = {
120     "unary_u",
121     TestFunc_Float_UInt,
122     TestFunc_Double_ULong,
123 };
124 
125 static constexpr vtbl _macro_unary = {
126     "macro_unary",
127     TestMacro_Int_Float,
128     TestMacro_Int_Double,
129 };
130 
131 static constexpr vtbl _binary = {
132     "binary",
133     TestFunc_Float_Float_Float,
134     TestFunc_Double_Double_Double,
135 };
136 
137 static constexpr vtbl _binary_operator = {
138     "binaryOperator",
139     TestFunc_Float_Float_Float_Operator,
140     TestFunc_Double_Double_Double_Operator,
141 };
142 
143 static constexpr vtbl _binary_i = {
144     "binary_i",
145     TestFunc_Float_Float_Int,
146     TestFunc_Double_Double_Int,
147 };
148 
149 static constexpr vtbl _macro_binary = {
150     "macro_binary",
151     TestMacro_Int_Float_Float,
152     TestMacro_Int_Double_Double,
153 };
154 
155 static constexpr vtbl _ternary = {
156     "ternary",
157     TestFunc_Float_Float_Float_Float,
158     TestFunc_Double_Double_Double_Double,
159 };
160 
161 static constexpr vtbl _unary_two_results = {
162     "unary_two_results",
163     TestFunc_Float2_Float,
164     TestFunc_Double2_Double,
165 };
166 
167 static constexpr vtbl _unary_two_results_i = {
168     "unary_two_results_i",
169     TestFunc_FloatI_Float,
170     TestFunc_DoubleI_Double,
171 };
172 
173 static constexpr vtbl _binary_two_results_i = {
174     "binary_two_results_i",
175     TestFunc_FloatI_Float_Float,
176     TestFunc_DoubleI_Double_Double,
177 };
178 
179 static constexpr vtbl _mad_tbl = {
180     "ternary",
181     TestFunc_mad_Float,
182     TestFunc_mad_Double,
183 };
184 
185 #define unaryF &_unary
186 #define i_unaryF &_i_unary
187 #define unaryF_u &_unary_u
188 #define macro_unaryF &_macro_unary
189 #define binaryF &_binary
190 #define binaryOperatorF &_binary_operator
191 #define binaryF_i &_binary_i
192 #define macro_binaryF &_macro_binary
193 #define ternaryF &_ternary
194 #define unaryF_two_results &_unary_two_results
195 #define unaryF_two_results_i &_unary_two_results_i
196 #define binaryF_two_results_i &_binary_two_results_i
197 #define mad_function &_mad_tbl
198 
199 #endif // FUNCTION_LIST_ULPS_ONLY
200 
201 const Func functionList[] = {
202     ENTRY_EXT(acos, 4.0f, 4.0f, 4096.0f, FTZ_OFF, unaryF, 4096.0f),
203     ENTRY(acosh, 4.0f, 4.0f, FTZ_OFF, unaryF),
204     ENTRY(acospi, 5.0f, 5.0f, FTZ_OFF, unaryF),
205     ENTRY_EXT(asin, 4.0f, 4.0f, 4096.0f, FTZ_OFF, unaryF, 4096.0f),
206     ENTRY(asinh, 4.0f, 4.0f, FTZ_OFF, unaryF),
207     ENTRY(asinpi, 5.0f, 5.0f, FTZ_OFF, unaryF),
208     ENTRY_EXT(atan, 5.0f, 5.0f, 4096.0f, FTZ_OFF, unaryF, 4096.0f),
209     ENTRY(atanh, 5.0f, 5.0f, FTZ_OFF, unaryF),
210     ENTRY(atanpi, 5.0f, 5.0f, FTZ_OFF, unaryF),
211     ENTRY(atan2, 6.0f, 6.0f, FTZ_OFF, binaryF),
212     ENTRY(atan2pi, 6.0f, 6.0f, FTZ_OFF, binaryF),
213     ENTRY(cbrt, 2.0f, 4.0f, FTZ_OFF, unaryF),
214     ENTRY(ceil, 0.0f, 0.0f, FTZ_OFF, unaryF),
215     ENTRY(copysign, 0.0f, 0.0f, FTZ_OFF, binaryF),
216     ENTRY_EXT(cos, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF,
217               0.00048828125f), // relaxed ulp 2^-11
218     ENTRY(cosh, 4.0f, 4.0f, FTZ_OFF, unaryF),
219     ENTRY_EXT(cospi, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF,
220               0.00048828125f), // relaxed ulp 2^-11
221     //                                  ENTRY( erfc,                  16.0f,
222     //                                  16.0f,         FTZ_OFF,     unaryF),
223     //                                  //disabled for 1.0 due to lack of
224     //                                  reference implementation ENTRY( erf,
225     //                                  16.0f,         16.0f,         FTZ_OFF,
226     //                                  unaryF), //disabled for 1.0 due to lack
227     //                                  of reference implementation
228     ENTRY_EXT(exp, 3.0f, 4.0f, 3.0f, FTZ_OFF, unaryF,
229               4.0f), // relaxed error is actually overwritten in unary.c as it
230                      // is 3+floor(fabs(2*x))
231     ENTRY_EXT(exp2, 3.0f, 4.0f, 3.0f, FTZ_OFF, unaryF,
232               4.0f), // relaxed error is actually overwritten in unary.c as it
233                      // is 3+floor(fabs(2*x))
234     ENTRY_EXT(exp10, 3.0f, 4.0f, 8192.0f, FTZ_OFF, unaryF,
235               8192.0f), // relaxed error is actually overwritten in unary.c as
236                         // it is 3+floor(fabs(2*x)) in derived mode,
237     // in non-derived mode it uses the ulp error for half_exp10.
238     ENTRY(expm1, 3.0f, 4.0f, FTZ_OFF, unaryF),
239     ENTRY(fabs, 0.0f, 0.0f, FTZ_OFF, unaryF),
240     ENTRY(fdim, 0.0f, 0.0f, FTZ_OFF, binaryF),
241     ENTRY(floor, 0.0f, 0.0f, FTZ_OFF, unaryF),
242     ENTRY(fma, 0.0f, 0.0f, FTZ_OFF, ternaryF),
243     ENTRY(fmax, 0.0f, 0.0f, FTZ_OFF, binaryF),
244     ENTRY(fmin, 0.0f, 0.0f, FTZ_OFF, binaryF),
245     ENTRY(fmod, 0.0f, 0.0f, FTZ_OFF, binaryF),
246     ENTRY(fract, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results),
247     ENTRY(frexp, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results_i),
248     ENTRY(hypot, 4.0f, 4.0f, FTZ_OFF, binaryF),
249     ENTRY(ilogb, 0.0f, 0.0f, FTZ_OFF, i_unaryF),
250     ENTRY(isequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
251     ENTRY(isfinite, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
252     ENTRY(isgreater, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
253     ENTRY(isgreaterequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
254     ENTRY(isinf, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
255     ENTRY(isless, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
256     ENTRY(islessequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
257     ENTRY(islessgreater, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
258     ENTRY(isnan, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
259     ENTRY(isnormal, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
260     ENTRY(isnotequal, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
261     ENTRY(isordered, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
262     ENTRY(isunordered, 0.0f, 0.0f, FTZ_OFF, macro_binaryF),
263     ENTRY(ldexp, 0.0f, 0.0f, FTZ_OFF, binaryF_i),
264     ENTRY(lgamma, INFINITY, INFINITY, FTZ_OFF, unaryF),
265     ENTRY(lgamma_r, INFINITY, INFINITY, FTZ_OFF, unaryF_two_results_i),
266     ENTRY_EXT(log, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF,
267               4.76837158203125e-7f), // relaxed ulp 2^-21
268     ENTRY_EXT(log2, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF,
269               4.76837158203125e-7f), // relaxed ulp 2^-21
270     ENTRY_EXT(log10, 3.0f, 4.0f, 4.76837158203125e-7f, FTZ_OFF, unaryF,
271               4.76837158203125e-7f), // relaxed ulp 2^-21
272     ENTRY(log1p, 2.0f, 4.0f, FTZ_OFF, unaryF),
273     ENTRY(logb, 0.0f, 0.0f, FTZ_OFF, unaryF),
274     ENTRY_EXT(mad, INFINITY, INFINITY, INFINITY, FTZ_OFF, mad_function,
275               INFINITY), // in fast-relaxed-math mode it has to be either
276                          // exactly rounded fma or exactly rounded a*b+c
277     ENTRY(maxmag, 0.0f, 0.0f, FTZ_OFF, binaryF),
278     ENTRY(minmag, 0.0f, 0.0f, FTZ_OFF, binaryF),
279     ENTRY(modf, 0.0f, 0.0f, FTZ_OFF, unaryF_two_results),
280     ENTRY(nan, 0.0f, 0.0f, FTZ_OFF, unaryF_u),
281     ENTRY(nextafter, 0.0f, 0.0f, FTZ_OFF, binaryF),
282     ENTRY_EXT(pow, 16.0f, 16.0f, 8192.0f, FTZ_OFF, binaryF,
283               8192.0f), // in derived mode the ulp error is calculated as
284                         // exp2(y*log2(x)) and in non-derived it is the same as
285                         // half_pow
286     ENTRY(pown, 16.0f, 16.0f, FTZ_OFF, binaryF_i),
287     ENTRY(powr, 16.0f, 16.0f, FTZ_OFF, binaryF),
288     //                                  ENTRY( reciprocal,            1.0f,
289     //                                  1.0f,         FTZ_OFF,     unaryF),
290     ENTRY(remainder, 0.0f, 0.0f, FTZ_OFF, binaryF),
291     ENTRY(remquo, 0.0f, 0.0f, FTZ_OFF, binaryF_two_results_i),
292     ENTRY(rint, 0.0f, 0.0f, FTZ_OFF, unaryF),
293     ENTRY(rootn, 16.0f, 16.0f, FTZ_OFF, binaryF_i),
294     ENTRY(round, 0.0f, 0.0f, FTZ_OFF, unaryF),
295     ENTRY(rsqrt, 2.0f, 4.0f, FTZ_OFF, unaryF),
296     ENTRY(signbit, 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
297     ENTRY_EXT(sin, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF,
298               0.00048828125f), // relaxed ulp 2^-11
299     ENTRY_EXT(sincos, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF_two_results,
300               0.00048828125f), // relaxed ulp 2^-11
301     ENTRY(sinh, 4.0f, 4.0f, FTZ_OFF, unaryF),
302     ENTRY_EXT(sinpi, 4.0f, 4.0f, 0.00048828125f, FTZ_OFF, unaryF,
303               0.00048828125f), // relaxed ulp 2^-11
304     { "sqrt",
305       "sqrt",
306       { (void*)reference_sqrt },
307       { (void*)reference_sqrtl },
308       { NULL },
309       3.0f,
310       0.0f,
311       4.0f,
312       INFINITY,
313       INFINITY,
314       FTZ_OFF,
315       RELAXED_OFF,
316       unaryF },
317     { "sqrt_cr",
318       "sqrt",
319       { (void*)reference_sqrt },
320       { (void*)reference_sqrtl },
321       { NULL },
322       0.0f,
323       0.0f,
324       0.0f,
325       INFINITY,
326       INFINITY,
327       FTZ_OFF,
328       RELAXED_OFF,
329       unaryF },
330     ENTRY_EXT(
331         tan, 5.0f, 5.0f, 8192.0f, FTZ_OFF, unaryF,
332         8192.0f), // in derived mode it the ulp error is calculated as sin/cos
333                   // and in non-derived mode it is the same as half_tan.
334     ENTRY(tanh, 5.0f, 5.0f, FTZ_OFF, unaryF),
335     ENTRY(tanpi, 6.0f, 6.0f, FTZ_OFF, unaryF),
336     //                                    ENTRY( tgamma,                 16.0f,
337     //                                    16.0f,         FTZ_OFF,     unaryF),
338     //                                    // Commented this out until we can be
339     //                                    sure this requirement is realistic
340     ENTRY(trunc, 0.0f, 0.0f, FTZ_OFF, unaryF),
341 
342     HALF_ENTRY(cos, 8192.0f, 8192.0f, FTZ_ON, unaryF),
343     HALF_ENTRY(divide, 8192.0f, 8192.0f, FTZ_ON, binaryF),
344     HALF_ENTRY(exp, 8192.0f, 8192.0f, FTZ_ON, unaryF),
345     HALF_ENTRY(exp2, 8192.0f, 8192.0f, FTZ_ON, unaryF),
346     HALF_ENTRY(exp10, 8192.0f, 8192.0f, FTZ_ON, unaryF),
347     HALF_ENTRY(log, 8192.0f, 8192.0f, FTZ_ON, unaryF),
348     HALF_ENTRY(log2, 8192.0f, 8192.0f, FTZ_ON, unaryF),
349     HALF_ENTRY(log10, 8192.0f, 8192.0f, FTZ_ON, unaryF),
350     HALF_ENTRY(powr, 8192.0f, 8192.0f, FTZ_ON, binaryF),
351     HALF_ENTRY(recip, 8192.0f, 8192.0f, FTZ_ON, unaryF),
352     HALF_ENTRY(rsqrt, 8192.0f, 8192.0f, FTZ_ON, unaryF),
353     HALF_ENTRY(sin, 8192.0f, 8192.0f, FTZ_ON, unaryF),
354     HALF_ENTRY(sqrt, 8192.0f, 8192.0f, FTZ_ON, unaryF),
355     HALF_ENTRY(tan, 8192.0f, 8192.0f, FTZ_ON, unaryF),
356 
357     // basic operations
358     OPERATOR_ENTRY(add, "+", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
359     OPERATOR_ENTRY(subtract, "-", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
360     { "divide",
361       "/",
362       { (void*)reference_divide },
363       { (void*)reference_dividel },
364       { (void*)reference_relaxed_divide },
365       2.5f,
366       0.0f,
367       3.0f,
368       2.5f,
369       INFINITY,
370       FTZ_OFF,
371       RELAXED_ON,
372       binaryOperatorF },
373     { "divide_cr",
374       "/",
375       { (void*)reference_divide },
376       { (void*)reference_dividel },
377       { (void*)reference_relaxed_divide },
378       0.0f,
379       0.0f,
380       0.0f,
381       0.f,
382       INFINITY,
383       FTZ_OFF,
384       RELAXED_OFF,
385       binaryOperatorF },
386     OPERATOR_ENTRY(multiply, "*", 0.0f, 0.0f, FTZ_OFF, binaryOperatorF),
387     OPERATOR_ENTRY(assignment, "", 0.0f, 0.0f, FTZ_OFF,
388                    unaryF), // A simple copy operation
389     OPERATOR_ENTRY(not, "!", 0.0f, 0.0f, FTZ_OFF, macro_unaryF),
390 };
391 
392 const size_t functionListCount = sizeof(functionList) / sizeof(functionList[0]);
393