xref: /aosp_15_r20/external/OpenCL-CTS/test_conformance/relationals/test_comparisons_fp.h (revision 6467f958c7de8070b317fc65bcb0f6472e388d82)
1 //
2 // Copyright (c) 2022 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 #ifndef TEST_COMPARISONS_FP_H
18 #define TEST_COMPARISONS_FP_H
19 
20 #include <map>
21 #include <memory>
22 #include <string>
23 #include <vector>
24 
25 #include <CL/cl_half.h>
26 
27 #include "testBase.h"
28 
29 #define HALF_NAN 0x7e00
30 template <typename T> using VerifyFunc = bool (*)(const T &, const T &);
31 
32 struct RelTestBase
33 {
RelTestBaseRelTestBase34     explicit RelTestBase(const ExplicitTypes &dt): dataType(dt) {}
35     virtual ~RelTestBase() = default;
36     ExplicitTypes dataType;
37 };
38 
39 template <typename T> struct RelTestParams : public RelTestBase
40 {
RelTestParamsRelTestParams41     RelTestParams(const VerifyFunc<T> &vfn, const ExplicitTypes &dt,
42                   const T &nan_)
43         : RelTestBase(dt), verifyFn(vfn), nan(nan_)
44     {}
45 
46     VerifyFunc<T> verifyFn;
47     T nan;
48 };
49 
50 struct RelationalsFPTest
51 {
52     RelationalsFPTest(cl_context context, cl_device_id device,
53                       cl_command_queue queue, const char *fn, const char *op);
54 
55     virtual cl_int SetUp(int elements);
56 
57     // Test body returning an OpenCL error code
58     virtual cl_int Run();
59 
60     template <typename T>
61     void generate_equiv_test_data(T *, unsigned int, bool,
62                                   const RelTestParams<T> &, const MTdata &);
63 
64     template <typename T, typename U>
65     void verify_equiv_values(unsigned int, const T *const, const T *const,
66                              U *const, const VerifyFunc<T> &);
67 
68     template <typename T>
69     int test_equiv_kernel(unsigned int vecSize, const RelTestParams<T> &param,
70                           const MTdata &d);
71 
72     template <typename T>
73     int test_relational(int numElements, const RelTestParams<T> &param);
74 
75 protected:
76     cl_context context;
77     cl_device_id device;
78     cl_command_queue queue;
79 
80     std::string fnName;
81     std::string opName;
82 
83     std::vector<std::unique_ptr<RelTestBase>> params;
84     std::map<ExplicitTypes, std::string> eqTypeNames;
85     size_t num_elements;
86 
87     int halfFlushDenormsToZero;
88 };
89 
90 struct IsEqualFPTest : public RelationalsFPTest
91 {
IsEqualFPTestIsEqualFPTest92     IsEqualFPTest(cl_device_id d, cl_context c, cl_command_queue q)
93         : RelationalsFPTest(c, d, q, "isequal", "==")
94     {}
95     cl_int SetUp(int elements) override;
96 
97     // for correct handling nan/inf we need fp value
98     struct half_equals_to
99     {
operatorIsEqualFPTest::half_equals_to100         bool operator()(const cl_half &lhs, const cl_half &rhs) const
101         {
102             return cl_half_to_float(lhs) == cl_half_to_float(rhs);
103         }
104     };
105 };
106 
107 struct IsNotEqualFPTest : public RelationalsFPTest
108 {
IsNotEqualFPTestIsNotEqualFPTest109     IsNotEqualFPTest(cl_device_id d, cl_context c, cl_command_queue q)
110         : RelationalsFPTest(c, d, q, "isnotequal", "!=")
111     {}
112     cl_int SetUp(int elements) override;
113 
114     // for correct handling nan/inf we need fp value
115     struct half_not_equals_to
116     {
operatorIsNotEqualFPTest::half_not_equals_to117         bool operator()(const cl_half &lhs, const cl_half &rhs) const
118         {
119             return cl_half_to_float(lhs) != cl_half_to_float(rhs);
120         }
121     };
122 };
123 
124 struct IsGreaterFPTest : public RelationalsFPTest
125 {
IsGreaterFPTestIsGreaterFPTest126     IsGreaterFPTest(cl_device_id d, cl_context c, cl_command_queue q)
127         : RelationalsFPTest(c, d, q, "isgreater", ">")
128     {}
129     cl_int SetUp(int elements) override;
130 
131     struct half_greater
132     {
operatorIsGreaterFPTest::half_greater133         bool operator()(const cl_half &lhs, const cl_half &rhs) const
134         {
135             return cl_half_to_float(lhs) > cl_half_to_float(rhs);
136         }
137     };
138 };
139 
140 struct IsGreaterEqualFPTest : public RelationalsFPTest
141 {
IsGreaterEqualFPTestIsGreaterEqualFPTest142     IsGreaterEqualFPTest(cl_device_id d, cl_context c, cl_command_queue q)
143         : RelationalsFPTest(c, d, q, "isgreaterequal", ">=")
144     {}
145     cl_int SetUp(int elements) override;
146 
147     struct half_greater_equal
148     {
operatorIsGreaterEqualFPTest::half_greater_equal149         bool operator()(const cl_half &lhs, const cl_half &rhs) const
150         {
151             return cl_half_to_float(lhs) >= cl_half_to_float(rhs);
152         }
153     };
154 };
155 
156 struct IsLessFPTest : public RelationalsFPTest
157 {
IsLessFPTestIsLessFPTest158     IsLessFPTest(cl_device_id d, cl_context c, cl_command_queue q)
159         : RelationalsFPTest(c, d, q, "isless", "<")
160     {}
161     cl_int SetUp(int elements) override;
162 
163     struct half_less
164     {
operatorIsLessFPTest::half_less165         bool operator()(const cl_half &lhs, const cl_half &rhs) const
166         {
167             return cl_half_to_float(lhs) < cl_half_to_float(rhs);
168         }
169     };
170 };
171 
172 struct IsLessEqualFPTest : public RelationalsFPTest
173 {
IsLessEqualFPTestIsLessEqualFPTest174     IsLessEqualFPTest(cl_device_id d, cl_context c, cl_command_queue q)
175         : RelationalsFPTest(c, d, q, "islessequal", "<=")
176     {}
177     cl_int SetUp(int elements) override;
178 
179     struct half_less_equal
180     {
operatorIsLessEqualFPTest::half_less_equal181         bool operator()(const cl_half &lhs, const cl_half &rhs) const
182         {
183             return cl_half_to_float(lhs) <= cl_half_to_float(rhs);
184         }
185     };
186 };
187 
188 struct IsLessGreaterFPTest : public RelationalsFPTest
189 {
IsLessGreaterFPTestIsLessGreaterFPTest190     IsLessGreaterFPTest(cl_device_id d, cl_context c, cl_command_queue q)
191         : RelationalsFPTest(c, d, q, "islessgreater", "<>")
192     {}
193     cl_int SetUp(int elements) override;
194 
195     struct half_less_greater
196     {
operatorIsLessGreaterFPTest::half_less_greater197         bool operator()(const cl_half &lhs, const cl_half &rhs) const
198         {
199             float flhs = cl_half_to_float(lhs), frhs = cl_half_to_float(rhs);
200             return (flhs < frhs) || (flhs > frhs);
201         }
202     };
203 
204     template <typename T> struct less_greater
205     {
operatorIsLessGreaterFPTest::less_greater206         bool operator()(const T &lhs, const T &rhs) const
207         {
208             return (lhs < rhs) || (lhs > rhs);
209         }
210     };
211 };
212 
213 template <class T>
MakeAndRunTest(cl_device_id device,cl_context context,cl_command_queue queue,int num_elements)214 int MakeAndRunTest(cl_device_id device, cl_context context,
215                    cl_command_queue queue, int num_elements)
216 {
217     auto test_fixture = T(device, context, queue);
218 
219     cl_int error = test_fixture.SetUp(num_elements);
220     test_error_ret(error, "Error in test initialization", TEST_FAIL);
221 
222     error = test_fixture.Run();
223     test_error_ret(error, "Test Failed", TEST_FAIL);
224 
225     return TEST_PASS;
226 }
227 
228 #endif // TEST_COMPARISONS_FP_H
229