Merge branch 'blender-v2.90-release'
[blender.git] / intern / cycles / test / util_avxf_test.h
1 /*
2  * Copyright 2011-2016 Blender Foundation
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 "testing/testing.h"
18 #include "util/util_system.h"
19 #include "util/util_types.h"
20
21 CCL_NAMESPACE_BEGIN
22
23 bool validate_cpu_capabilities()
24 {
25
26 #ifdef __KERNEL_AVX2__
27   return system_cpu_support_avx2();
28 #else
29 #  ifdef __KERNEL_AVX__
30   return system_cpu_support_avx();
31 #  endif
32 #endif
33 }
34
35 #define VALIDATECPU \
36   if (!validate_cpu_capabilities()) \
37     return;
38
39 #define compare_vector_scalar(a, b) \
40   for (size_t index = 0; index < a.size; index++) \
41     EXPECT_FLOAT_EQ(a[index], b);
42
43 #define compare_vector_vector(a, b) \
44   for (size_t index = 0; index < a.size; index++) \
45     EXPECT_FLOAT_EQ(a[index], b[index]);
46
47 #define compare_vector_vector_near(a, b, abserror) \
48   for (size_t index = 0; index < a.size; index++) \
49     EXPECT_NEAR(a[index], b[index], abserror);
50
51 #define basic_test_vv(a, b, op) \
52   VALIDATECPU \
53   avxf c = a op b; \
54   for (size_t i = 0; i < a.size; i++) \
55     EXPECT_FLOAT_EQ(c[i], a[i] op b[i]);
56
57 /* vector op float tests */
58 #define basic_test_vf(a, b, op) \
59   VALIDATECPU \
60   avxf c = a op b; \
61   for (size_t i = 0; i < a.size; i++) \
62     EXPECT_FLOAT_EQ(c[i], a[i] op b);
63
64 const avxf avxf_a(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f);
65 const avxf avxf_b(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f);
66 const avxf avxf_c(1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f);
67 const float float_b = 1.5f;
68
69 TEST(util_avx, avxf_add_vv){basic_test_vv(avxf_a, avxf_b, +)} TEST(util_avx, avxf_sub_vv){
70     basic_test_vv(avxf_a, avxf_b, -)} TEST(util_avx, avxf_mul_vv){
71     basic_test_vv(avxf_a, avxf_b, *)} TEST(util_avx, avxf_div_vv){
72     basic_test_vv(avxf_a, avxf_b, /)} TEST(util_avx, avxf_add_vf){
73     basic_test_vf(avxf_a, float_b, +)} TEST(util_avx, avxf_sub_vf){
74     basic_test_vf(avxf_a, float_b, -)} TEST(util_avx, avxf_mul_vf){
75     basic_test_vf(avxf_a, float_b, *)} TEST(util_avx,
76                                             avxf_div_vf){basic_test_vf(avxf_a, float_b, /)}
77
78 TEST(util_avx, avxf_ctor)
79 {
80   VALIDATECPU
81   compare_vector_scalar(avxf(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f),
82                         static_cast<float>(index));
83   compare_vector_scalar(avxf(1.0f), 1.0f);
84   compare_vector_vector(avxf(1.0f, 2.0f), avxf(1.0f, 1.0f, 1.0f, 1.0f, 2.0f, 2.0f, 2.0f, 2.0f));
85   compare_vector_vector(avxf(1.0f, 2.0f, 3.0f, 4.0f),
86                         avxf(1.0f, 2.0f, 3.0f, 4.0f, 1.0f, 2.0f, 3.0f, 4.0f));
87   compare_vector_vector(avxf(make_float3(1.0f, 2.0f, 3.0f)),
88                         avxf(0.0f, 3.0f, 2.0f, 1.0f, 0.0f, 3.0f, 2.0f, 1.0f));
89 }
90
91 TEST(util_avx, avxf_sqrt)
92 {
93   VALIDATECPU
94   compare_vector_vector(mm256_sqrt(avxf(1.0f, 4.0f, 9.0f, 16.0f, 25.0f, 36.0f, 49.0f, 64.0f)),
95                         avxf(1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f));
96 }
97
98 TEST(util_avx, avxf_min_max)
99 {
100   VALIDATECPU
101   compare_vector_vector(min(avxf_a, avxf_b), avxf_a);
102   compare_vector_vector(max(avxf_a, avxf_b), avxf_b);
103 }
104
105 TEST(util_avx, avxf_set_sign)
106 {
107   VALIDATECPU
108   avxf res = set_sign_bit<1, 0, 0, 0, 0, 0, 0, 0>(avxf_a);
109   compare_vector_vector(res, avxf(0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, -0.8f));
110 }
111
112 TEST(util_avx, avxf_msub)
113 {
114   VALIDATECPU
115   avxf res = msub(avxf_a, avxf_b, avxf_c);
116   avxf exp = avxf((avxf_a[7] * avxf_b[7]) - avxf_c[7],
117                   (avxf_a[6] * avxf_b[6]) - avxf_c[6],
118                   (avxf_a[5] * avxf_b[5]) - avxf_c[5],
119                   (avxf_a[4] * avxf_b[4]) - avxf_c[4],
120                   (avxf_a[3] * avxf_b[3]) - avxf_c[3],
121                   (avxf_a[2] * avxf_b[2]) - avxf_c[2],
122                   (avxf_a[1] * avxf_b[1]) - avxf_c[1],
123                   (avxf_a[0] * avxf_b[0]) - avxf_c[0]);
124   compare_vector_vector(res, exp);
125 }
126
127 TEST(util_avx, avxf_madd)
128 {
129   VALIDATECPU
130   avxf res = madd(avxf_a, avxf_b, avxf_c);
131   avxf exp = avxf((avxf_a[7] * avxf_b[7]) + avxf_c[7],
132                   (avxf_a[6] * avxf_b[6]) + avxf_c[6],
133                   (avxf_a[5] * avxf_b[5]) + avxf_c[5],
134                   (avxf_a[4] * avxf_b[4]) + avxf_c[4],
135                   (avxf_a[3] * avxf_b[3]) + avxf_c[3],
136                   (avxf_a[2] * avxf_b[2]) + avxf_c[2],
137                   (avxf_a[1] * avxf_b[1]) + avxf_c[1],
138                   (avxf_a[0] * avxf_b[0]) + avxf_c[0]);
139   compare_vector_vector(res, exp);
140 }
141
142 TEST(util_avx, avxf_nmadd)
143 {
144   VALIDATECPU
145   avxf res = nmadd(avxf_a, avxf_b, avxf_c);
146   avxf exp = avxf(avxf_c[7] - (avxf_a[7] * avxf_b[7]),
147                   avxf_c[6] - (avxf_a[6] * avxf_b[6]),
148                   avxf_c[5] - (avxf_a[5] * avxf_b[5]),
149                   avxf_c[4] - (avxf_a[4] * avxf_b[4]),
150                   avxf_c[3] - (avxf_a[3] * avxf_b[3]),
151                   avxf_c[2] - (avxf_a[2] * avxf_b[2]),
152                   avxf_c[1] - (avxf_a[1] * avxf_b[1]),
153                   avxf_c[0] - (avxf_a[0] * avxf_b[0]));
154   compare_vector_vector(res, exp);
155 }
156
157 TEST(util_avx, avxf_compare)
158 {
159   VALIDATECPU
160   avxf a(0.0f, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f);
161   avxf b(7.0f, 6.0f, 5.0f, 4.0f, 3.0f, 2.0f, 1.0f, 0.0f);
162   avxb res = a <= b;
163   int exp[8] = {
164       a[0] <= b[0] ? -1 : 0,
165       a[1] <= b[1] ? -1 : 0,
166       a[2] <= b[2] ? -1 : 0,
167       a[3] <= b[3] ? -1 : 0,
168       a[4] <= b[4] ? -1 : 0,
169       a[5] <= b[5] ? -1 : 0,
170       a[6] <= b[6] ? -1 : 0,
171       a[7] <= b[7] ? -1 : 0,
172   };
173   compare_vector_vector(res, exp);
174 }
175
176 TEST(util_avx, avxf_permute)
177 {
178   VALIDATECPU
179   avxf res = permute<3, 0, 1, 7, 6, 5, 2, 4>(avxf_b);
180   compare_vector_vector(res, avxf(4.0f, 6.0f, 3.0f, 2.0f, 1.0f, 7.0f, 8.0f, 5.0f));
181 }
182
183 TEST(util_avx, avxf_blend)
184 {
185   VALIDATECPU
186   avxf res = blend<0, 0, 1, 0, 1, 0, 1, 0>(avxf_a, avxf_b);
187   compare_vector_vector(res, avxf(0.1f, 0.2f, 3.0f, 0.4f, 5.0f, 0.6f, 7.0f, 0.8f));
188 }
189
190 TEST(util_avx, avxf_shuffle)
191 {
192   VALIDATECPU
193   avxf res = shuffle<0, 1, 2, 3, 1, 3, 2, 0>(avxf_a);
194   compare_vector_vector(res, avxf(0.4f, 0.2f, 0.1f, 0.3f, 0.5f, 0.6f, 0.7f, 0.8f));
195 }
196
197 TEST(util_avx, avxf_cross)
198 {
199   VALIDATECPU
200   avxf res = cross(avxf_b, avxf_c);
201   compare_vector_vector_near(res,
202                              avxf(0.0f,
203                                   -9.5367432e-07f,
204                                   0.0f,
205                                   4.7683716e-07f,
206                                   0.0f,
207                                   -3.8146973e-06f,
208                                   3.8146973e-06f,
209                                   3.8146973e-06f),
210                              0.000002000f);
211 }
212
213 TEST(util_avx, avxf_dot3)
214 {
215   VALIDATECPU
216   float den, den2;
217   dot3(avxf_a, avxf_b, den, den2);
218   EXPECT_FLOAT_EQ(den, 14.9f);
219   EXPECT_FLOAT_EQ(den2, 2.9f);
220 }
221
222 CCL_NAMESPACE_END