1 /* Copyright 2020 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include <algorithm>
17 #include <cmath>
18 #include <complex>
19 #include <limits>
20
21 #include "tensorflow/core/kernels/mlir_generated/base_ops_test.h"
22 #include "tensorflow/core/kernels/mlir_generated/base_unary_ops_test.h"
23
24 namespace tensorflow {
25 namespace {
26
27 // Test fixture `UnaryOpsTest` that sets the TF device is expected by the TEST
28 // macros below.
29 class UnaryOpsTest : public UnaryOpsTestBase {
30 protected:
SetUp()31 void SetUp() override {
32 std::unique_ptr<tensorflow::Device> device_gpu(
33 tensorflow::DeviceFactory::NewDevice("GPU", {},
34 "/job:a/replica:0/task:0"));
35 SetDevice(tensorflow::DEVICE_GPU, std::move(device_gpu));
36 }
37 };
38
39 /// Test `tf.Abs`.
40
41 template <typename T>
baseline_abs(T x)42 T baseline_abs(T x) {
43 return x >= 0 ? x : -x;
44 }
45
46 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
47 Abs, DT_FLOAT, DT_FLOAT, test::NearZeroAndExtremeInput<float>(), std::abs,
48 test::OpsTestConfig().ExpectStrictlyEqual())
49 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
50 Abs, DT_DOUBLE, DT_DOUBLE, test::NearZeroAndExtremeInput<double>(),
51 std::abs, test::OpsTestConfig().ExpectStrictlyEqual())
52 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
53 Abs, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
54 test::NearZeroAndExtremeInput<Eigen::half>(), std::abs,
55 test::OpsTestConfig().ExpectStrictlyEqual())
56 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
57 Abs, DT_INT64, DT_INT64, test::NearZeroAndExtremeInput<int64_t>(),
58 baseline_abs, test::OpsTestConfig().ExpectStrictlyEqual())
59
60 // These kernels are JIT-compiled.
61 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
62 GENERATE_DEFAULT_TEST(Abs, DT_INT8, DT_INT8, baseline_abs,
63 test::OpsTestConfig().ExpectStrictlyEqual())
64 GENERATE_DEFAULT_TEST(Abs, DT_INT16, DT_INT16, baseline_abs,
65 test::OpsTestConfig().ExpectStrictlyEqual())
66 #endif
67
68 /// Test `tf.Acos`.
69
70 // Test only values in the function domain. The otherwise returned nan value
71 // fails comparison for equality.
GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(Acos,DT_HALF,DT_FLOAT,DT_HALF,DT_FLOAT,test::DefaultInputBetweenZeroAndOne<Eigen::half> (),std::acos,test::OpsTestConfig ())72 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
73 Acos, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
74 test::DefaultInputBetweenZeroAndOne<Eigen::half>(), std::acos,
75 test::OpsTestConfig())
76
77 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
78 Acos, DT_FLOAT, DT_FLOAT, test::DefaultInputBetweenZeroAndOne<float>(),
79 std::acos, test::OpsTestConfig())
80
81 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
82 Acos, DT_DOUBLE, DT_DOUBLE, test::DefaultInputBetweenZeroAndOne<double>(),
83 std::acos, test::OpsTestConfig())
84
85 /// Test `tf.Acosh`.
86
87 // TODO(herhut): Give this better input once TF testing also supports NaN.
88 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
89 Acosh, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
90 test::DefaultInputGreaterEqualOne<Eigen::half>(), std::acosh,
91 test::OpsTestConfig())
92
93 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
94 Acosh, DT_FLOAT, DT_FLOAT, test::DefaultInputGreaterEqualOne<float>(),
95 std::acosh, test::OpsTestConfig())
96
97 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
98 Acosh, DT_DOUBLE, DT_DOUBLE, test::DefaultInputGreaterEqualOne<double>(),
99 std::acosh, test::OpsTestConfig())
100
101 /// Test `tf.Angle`.
102
103 template <typename T>
104 typename T::value_type baseline_angle(T x) {
105 return std::arg(x);
106 }
107
108 GENERATE_DEFAULT_TEST(Angle, DT_COMPLEX64, DT_FLOAT, baseline_angle,
109 test::OpsTestConfig().AddTout().NoBufferReuse())
110
111 GENERATE_DEFAULT_TEST(Angle, DT_COMPLEX128, DT_DOUBLE, baseline_angle,
112 test::OpsTestConfig().AddTout().NoBufferReuse())
113
114 /// Test `tf.Asin`.
115
116 // Test only values in the function domain. The otherwise returned nan value
117 // fails comparison for equality.
118 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
119 Asin, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
120 test::DefaultInputBetweenZeroAndOne<Eigen::half>(), std::asin,
121 test::OpsTestConfig().ExpectStrictlyEqual())
122
123 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
124 Asin, DT_FLOAT, DT_FLOAT, test::DefaultInputBetweenZeroAndOne<float>(),
125 std::asin, test::OpsTestConfig().ExpectStrictlyEqual())
126
127 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
128 Asin, DT_DOUBLE, DT_DOUBLE, test::DefaultInputBetweenZeroAndOne<double>(),
129 std::asin, test::OpsTestConfig().ExpectStrictlyEqual())
130
131 /// Test `tf.Asinh`.
132
GENERATE_DEFAULT_TEST_2(Asinh,DT_HALF,DT_FLOAT,DT_HALF,DT_FLOAT,std::asinh,test::OpsTestConfig ())133 GENERATE_DEFAULT_TEST_2(Asinh, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::asinh,
134 test::OpsTestConfig())
135
136 GENERATE_DEFAULT_TEST(Asinh, DT_FLOAT, DT_FLOAT, std::asinh,
137 test::OpsTestConfig())
138
139 GENERATE_DEFAULT_TEST(Asinh, DT_DOUBLE, DT_DOUBLE, std::asinh,
140 test::OpsTestConfig())
141
142 /// Test `tf.Atan`.
143
144 GENERATE_DEFAULT_TEST_2(Atan, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::atan,
145 test::OpsTestConfig())
146
147 GENERATE_DEFAULT_TEST(Atan, DT_FLOAT, DT_FLOAT, std::atan,
148 test::OpsTestConfig())
149
150 GENERATE_DEFAULT_TEST(Atan, DT_DOUBLE, DT_DOUBLE, std::atan,
151 test::OpsTestConfig())
152
153 /// Test `tf.Atanh`.
154
155 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
156 Atanh, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
157 test::DefaultInputBetweenZeroAndOne<Eigen::half>(), std::atanh,
158 test::OpsTestConfig())
159
160 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
161 Atanh, DT_FLOAT, DT_FLOAT, test::DefaultInputBetweenZeroAndOne<float>(),
162 std::atanh, test::OpsTestConfig())
163
164 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
165 Atanh, DT_DOUBLE, DT_DOUBLE, test::DefaultInputBetweenZeroAndOne<double>(),
166 std::atanh, test::OpsTestConfig())
167
168 /// Test `tf.Cast`.
169
170 template <typename SrcT, typename DstT>
171 DstT baseline_cast(SrcT x) {
172 return static_cast<DstT>(x);
173 }
174
175 template <typename DstT,
176 std::enable_if_t<!llvm::is_one_of<DstT, std::complex<float>,
177 std::complex<double>>::value,
178 bool> = true>
baseline_cast(const std::complex<float> & x)179 DstT baseline_cast(const std::complex<float>& x) {
180 return static_cast<DstT>(x.real());
181 }
182
183 template <typename DstT,
184 std::enable_if_t<!llvm::is_one_of<DstT, std::complex<float>,
185 std::complex<double>>::value,
186 bool> = true>
baseline_cast(const std::complex<double> & x)187 DstT baseline_cast(const std::complex<double>& x) {
188 return static_cast<DstT>(x.real());
189 }
190
191 #define TEST_CAST_FROM_TO(from_type, to_type) \
192 GENERATE_DEFAULT_TEST(Cast, from_type, to_type, baseline_cast, \
193 test::OpsTestConfig() \
194 .AddTout() \
195 .NoBufferReuse() \
196 .ExpectStrictlyEqual() \
197 .InputAttribute("SrcT") \
198 .OutputAttribute("DstT"))
199
200 // Casting from floating point types to unsigned integers has undefined behavior
201 // for negative values <= -1.0
202 #define TEST_NON_NEGATIVE_VALUES_CAST_FROM_TO(from_type, to_type) \
203 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES( \
204 Cast, from_type, to_type, \
205 test::DefaultInputGreaterOrEqualToZero<NativeT>(), baseline_cast, \
206 test::OpsTestConfig() \
207 .AddTout() \
208 .NoBufferReuse() \
209 .ExpectStrictlyEqual() \
210 .InputAttribute("SrcT") \
211 .OutputAttribute("DstT"))
212
213 #define TEST_CAST_TO_NO_UNSIGNED(from_type) \
214 TEST_CAST_FROM_TO(from_type, DT_BOOL) \
215 TEST_CAST_FROM_TO(from_type, DT_INT8) \
216 TEST_CAST_FROM_TO(from_type, DT_INT16) \
217 TEST_CAST_FROM_TO(from_type, DT_INT32) \
218 TEST_CAST_FROM_TO(from_type, DT_INT64) \
219 TEST_CAST_FROM_TO(from_type, DT_FLOAT) \
220 TEST_CAST_FROM_TO(from_type, DT_DOUBLE) \
221 TEST_CAST_FROM_TO(from_type, DT_COMPLEX64) \
222 TEST_CAST_FROM_TO(from_type, DT_COMPLEX128)
223
224 #define TEST_CAST_TO_UNSIGNED(from_type) \
225 TEST_CAST_FROM_TO(from_type, DT_UINT8) \
226 TEST_CAST_FROM_TO(from_type, DT_UINT16) \
227 TEST_CAST_FROM_TO(from_type, DT_UINT32) \
228 TEST_CAST_FROM_TO(from_type, DT_UINT64)
229
230 #define TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED(from_type) \
231 TEST_NON_NEGATIVE_VALUES_CAST_FROM_TO(from_type, DT_UINT8) \
232 TEST_NON_NEGATIVE_VALUES_CAST_FROM_TO(from_type, DT_UINT16) \
233 TEST_NON_NEGATIVE_VALUES_CAST_FROM_TO(from_type, DT_UINT32) \
234 TEST_NON_NEGATIVE_VALUES_CAST_FROM_TO(from_type, DT_UINT64)
235
236 #define TEST_CAST_TO(from_type) \
237 TEST_CAST_TO_NO_UNSIGNED(from_type) TEST_CAST_TO_UNSIGNED(from_type)
238
239 TEST_CAST_TO(DT_BOOL)
TEST_CAST_TO(DT_INT8)240 TEST_CAST_TO(DT_INT8)
241 TEST_CAST_TO(DT_INT16)
242 TEST_CAST_TO(DT_INT32)
243 TEST_CAST_TO(DT_INT64)
244 TEST_CAST_TO(DT_UINT8)
245 TEST_CAST_TO(DT_UINT16)
246 TEST_CAST_TO(DT_UINT32)
247 TEST_CAST_TO(DT_UINT64)
248 TEST_CAST_TO_NO_UNSIGNED(DT_HALF)
249 TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED(DT_HALF)
250 TEST_CAST_TO_NO_UNSIGNED(DT_FLOAT)
251 TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED(DT_FLOAT)
252 TEST_CAST_TO_NO_UNSIGNED(DT_DOUBLE)
253 TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED(DT_DOUBLE)
254 TEST_CAST_TO_NO_UNSIGNED(DT_COMPLEX64)
255 TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED(DT_COMPLEX64)
256 TEST_CAST_TO_NO_UNSIGNED(DT_COMPLEX128)
257 TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED(DT_COMPLEX128)
258
259 #undef TEST_CAST_FROM_TO
260 #undef TEST_NON_NEGATIVE_VALUES_CAST_FROM_TO
261 #undef TEST_CAST_TO_NO_UNSIGNED
262 #undef TEST_CAST_TO_UNSIGNED
263 #undef TEST_NON_NEGATIVE_VALUES_CAST_TO_UNSIGNED
264 #undef TEST_CAST_TO
265
266 /// Test `tf.Ceil`.
267
268 GENERATE_DEFAULT_TEST(Ceil, DT_FLOAT, DT_FLOAT, std::ceil,
269 test::OpsTestConfig().ExpectStrictlyEqual())
270
271 GENERATE_DEFAULT_TEST(Ceil, DT_DOUBLE, DT_DOUBLE, std::ceil,
272 test::OpsTestConfig().ExpectStrictlyEqual())
273
274 GENERATE_DEFAULT_TEST_2(Ceil, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::ceil,
275 test::OpsTestConfig().ExpectStrictlyEqual())
276
277 /// Test `tf.ComplexAbs`.
278
279 template <typename T>
280 typename T::value_type baseline_complex_abs(T x) {
281 return std::abs(x);
282 }
283
284 GENERATE_DEFAULT_TEST(ComplexAbs, DT_COMPLEX64, DT_FLOAT, baseline_complex_abs,
285 test::OpsTestConfig().AddTout().NoBufferReuse())
286
287 GENERATE_DEFAULT_TEST(ComplexAbs, DT_COMPLEX128, DT_DOUBLE,
288 baseline_complex_abs,
289 test::OpsTestConfig().AddTout().NoBufferReuse())
290
291 /// Test `tf.Conj`.
292
293 template <typename T>
baseline_conj(T x)294 T baseline_conj(T x) {
295 return std::conj(x);
296 }
297
298 GENERATE_DEFAULT_TEST(Conj, DT_COMPLEX64, DT_COMPLEX64, baseline_conj,
299 test::OpsTestConfig().NoBufferReuse())
300
301 GENERATE_DEFAULT_TEST(Conj, DT_COMPLEX128, DT_COMPLEX128, baseline_conj,
302 test::OpsTestConfig().NoBufferReuse())
303
304 /// Test `tf.Cos`.
305
GENERATE_DEFAULT_TEST(Cos,DT_FLOAT,DT_FLOAT,std::cos,test::OpsTestConfig ())306 GENERATE_DEFAULT_TEST(Cos, DT_FLOAT, DT_FLOAT, std::cos, test::OpsTestConfig())
307
308 GENERATE_DEFAULT_TEST(Cos, DT_DOUBLE, DT_DOUBLE, std::cos,
309 test::OpsTestConfig())
310
311 GENERATE_DEFAULT_TEST_2(Cos, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::cos,
312 test::OpsTestConfig())
313
314 // These kernels are JIT-compiled.
315 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
316
317 GENERATE_DEFAULT_TEST(Cos, DT_COMPLEX64, DT_COMPLEX64, std::cos,
318 test::OpsTestConfig())
319
320 GENERATE_DEFAULT_TEST(Cos, DT_COMPLEX128, DT_COMPLEX128, std::cos,
321 test::OpsTestConfig())
322
323 #endif
324
325 /// Test `tf.Cosh`.
326
327 GENERATE_DEFAULT_TEST_2(Cosh, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::cosh,
328 test::OpsTestConfig())
329
330 GENERATE_DEFAULT_TEST(Cosh, DT_FLOAT, DT_FLOAT, std::cosh,
331 test::OpsTestConfig())
332
333 GENERATE_DEFAULT_TEST(Cosh, DT_DOUBLE, DT_DOUBLE, std::cosh,
334 test::OpsTestConfig())
335
336 // These kernels are JIT-compiled.
337 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
338
339 GENERATE_DEFAULT_TEST(Cosh, DT_COMPLEX64, DT_COMPLEX64, std::cosh,
340 test::OpsTestConfig())
341
342 GENERATE_DEFAULT_TEST(Cosh, DT_COMPLEX128, DT_COMPLEX128, std::cosh,
343 test::OpsTestConfig())
344
345 #endif
346
347 /// Test `tf.Digamma`.
348
349 /// Reference implementation.
350 double baseline_digamma(double x) {
351 constexpr int kN = 100000;
352 constexpr double kGammaE = 0.5772156649015328606065120900824024;
353 double z = x - 1;
354 double sum = -kGammaE;
355 for (int i = 1; i <= kN; i++) {
356 sum += z / (i * (i + z));
357 }
358 return sum;
359 }
360
361 // Exclude non-positive integer values as `digamma` is undefined for these and
362 // the test framework does not suppot NaN comparisons.
363 constexpr std::initializer_list<double> kDigammaValues = {
364 -18.1, -9.2, -0.7, -0.5, -0.3, -0.2, -0.1, -1e-6,
365 1e-6, 0.1, 0.2, 0.3, 0.5, 0.7, 0.9, 18.0};
366
GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(Digamma,DT_FLOAT,DT_DOUBLE,DT_FLOAT,DT_DOUBLE,test::InputAsVector<float> (kDigammaValues),baseline_digamma,test::OpsTestConfig ())367 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
368 Digamma, DT_FLOAT, DT_DOUBLE, DT_FLOAT, DT_DOUBLE,
369 test::InputAsVector<float>(kDigammaValues), baseline_digamma,
370 test::OpsTestConfig())
371
372 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
373 Digamma, DT_DOUBLE, DT_DOUBLE, test::InputAsVector<double>(kDigammaValues),
374 baseline_digamma, test::OpsTestConfig())
375
376 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
377 Digamma, DT_HALF, DT_DOUBLE, DT_HALF, DT_DOUBLE,
378 test::InputAsVector<Eigen::half>(kDigammaValues), baseline_digamma,
379 test::OpsTestConfig())
380
381 /// Test `tf.Elu`.
382
383 template <typename T>
384 T baseline_elu(T x) {
385 if (x < 0) return std::exp(x) - 1;
386 return x;
387 }
388
389 GENERATE_DEFAULT_TEST(Elu, DT_FLOAT, DT_FLOAT, baseline_elu,
390 test::OpsTestConfig())
391
392 GENERATE_DEFAULT_TEST(Elu, DT_DOUBLE, DT_DOUBLE, baseline_elu,
393 test::OpsTestConfig())
394
395 GENERATE_DEFAULT_TEST_2(Elu, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, baseline_elu,
396 test::OpsTestConfig())
397
398 /// Test `tf.Erf` and `tf.Erfc`.
399
400 // Use specific values to cover the different intervals in the f64 erf and f64
401 // erfc, and f32 erfc approximations.
402 // - (-inf, -sqrt(kMaxlog)]
403 // - [-sqrt(kMaxlog), -8]
404 // - [-8, -1]
405 // - [-1, 0]
406 // - [0, 1]
407 // - [1, 8]
408 // - [8, sqrt(kMaxlog)]
409 // - [sqrt(kMaxlog), inf)
410
411 static constexpr double kSqrtMaxlogF64 = 26.6417;
412 static constexpr std::initializer_list<double> kErfcF64Values = {
413 -1000.0,
414 -27.0,
415 -kSqrtMaxlogF64 - 0.1,
416 -kSqrtMaxlogF64,
417 -kSqrtMaxlogF64 + 0.1,
418 -16.0,
419 -9.0,
420 -8.2,
421 -8.1,
422 -8.0,
423 -7.9,
424 -6.7,
425 -4.5,
426 -2.3,
427 -1.5,
428 -1.2,
429 -1.1,
430 -1.0,
431 -0.9,
432 -0.3,
433 -0.2,
434 -0.1,
435 0.0,
436 0.1,
437 0.2,
438 0.3,
439 0.9,
440 1.0,
441 1.1,
442 1.2,
443 1.5,
444 2.3,
445 4.5,
446 6.7,
447 7.9,
448 8.0,
449 8.1,
450 8.2,
451 9.0,
452 16.0,
453 kSqrtMaxlogF64 - 0.1,
454 kSqrtMaxlogF64,
455 kSqrtMaxlogF64 + 0.1,
456 27.0,
457 1000.0};
458
459 static constexpr float kSqrtMaxlogF32 = 9.41928;
460 static constexpr std::initializer_list<float> kErfcF32Values = {
461 -1000.0,
462 -27.0,
463 -kSqrtMaxlogF32 - 0.1,
464 -kSqrtMaxlogF32,
465 -kSqrtMaxlogF32 + 0.1,
466 -16.0,
467 -9.0,
468 -8.2,
469 -8.1,
470 -8.0,
471 -7.9,
472 -6.7,
473 -4.5,
474 -2.3,
475 -1.5,
476 -1.2,
477 -1.1,
478 -1.0,
479 -0.9,
480 -0.3,
481 -0.2,
482 -0.1,
483 0.0,
484 0.1,
485 0.2,
486 0.3,
487 0.9,
488 1.0,
489 1.1,
490 1.2,
491 1.5,
492 2.3,
493 4.5,
494 6.7,
495 7.9,
496 8.0,
497 8.1,
498 8.2,
499 9.0,
500 16.0,
501 kSqrtMaxlogF32 - 0.1,
502 kSqrtMaxlogF32,
503 kSqrtMaxlogF32 + 0.1,
504 27.0,
505 1000.0};
506
GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(Erf,DT_DOUBLE,DT_DOUBLE,kErfcF64Values,std::erf,test::OpsTestConfig ())507 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(Erf, DT_DOUBLE, DT_DOUBLE,
508 kErfcF64Values, std::erf,
509 test::OpsTestConfig())
510
511 // Use specific values to cover the different intervals of the f32 erf
512 // approximation.
513 // - (-inf, -4]
514 // - [-4, 4]
515 // - [4, inf)
516 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
517 Erf, DT_FLOAT, DT_FLOAT,
518 test::InputAsVector<float>({-100.0, -16.0, -8.9, -6.7, -4.1, -4.0, -3.9,
519 -3.4, -2.3, -1.2, -1.1, -1.0, -0.5, -0.2,
520 -0.1, 0.0, 0.1, 0.2, 0.5, 1.0, 1.1,
521 1.2, 2.3, 3.4, 3.9, 4.0, 4.1, 6.7,
522 8.9, 16.0, 100.0}),
523 std::erf, test::OpsTestConfig())
524
525 GENERATE_DEFAULT_TEST_2(Erf, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::erf,
526 test::OpsTestConfig())
527
528 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
529 Erfc, DT_DOUBLE, DT_DOUBLE, test::InputAsVector<double>(kErfcF64Values),
530 std::erfc, test::OpsTestConfig())
531
532 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
533 Erfc, DT_FLOAT, DT_FLOAT, test::InputAsVector<float>(kErfcF32Values),
534 std::erfc, test::OpsTestConfig())
535
536 GENERATE_DEFAULT_TEST_2(Erfc, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::erfc,
537 test::OpsTestConfig())
538
539 /// Test `tf.Exp`.
540
541 GENERATE_DEFAULT_TEST(Exp, DT_FLOAT, DT_FLOAT, std::exp, test::OpsTestConfig())
542
543 GENERATE_DEFAULT_TEST(Exp, DT_DOUBLE, DT_DOUBLE, std::exp,
544 test::OpsTestConfig())
545
546 GENERATE_DEFAULT_TEST_2(Exp, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::exp,
547 test::OpsTestConfig())
548
549 GENERATE_DEFAULT_TEST(Exp, DT_COMPLEX64, DT_COMPLEX64, std::exp,
550 test::OpsTestConfig())
551
552 GENERATE_DEFAULT_TEST(Exp, DT_COMPLEX128, DT_COMPLEX128, std::exp,
553 test::OpsTestConfig())
554
555 /// Test `tf.Expm1`.
556
557 GENERATE_DEFAULT_TEST(Expm1, DT_FLOAT, DT_FLOAT, std::expm1,
558 test::OpsTestConfig())
559
560 GENERATE_DEFAULT_TEST(Expm1, DT_DOUBLE, DT_DOUBLE, std::expm1,
561 test::OpsTestConfig())
562
563 GENERATE_DEFAULT_TEST_2(Expm1, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::expm1,
564 test::OpsTestConfig())
565
566 /// Test `tf.Floor`.
567
568 GENERATE_DEFAULT_TEST(Floor, DT_FLOAT, DT_FLOAT, std::floor,
569 test::OpsTestConfig().ExpectStrictlyEqual())
570
571 GENERATE_DEFAULT_TEST(Floor, DT_DOUBLE, DT_DOUBLE, std::floor,
572 test::OpsTestConfig().ExpectStrictlyEqual())
573
574 GENERATE_DEFAULT_TEST_2(Floor, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::floor,
575 test::OpsTestConfig().ExpectStrictlyEqual())
576
577 /// Test `tf.Imag`.
578
579 template <typename T>
580 typename T::value_type baseline_imag(T x) {
581 return std::imag(x);
582 }
583
584 GENERATE_DEFAULT_TEST(Imag, DT_COMPLEX64, DT_FLOAT, baseline_imag,
585 test::OpsTestConfig().AddTout().NoBufferReuse())
586
587 GENERATE_DEFAULT_TEST(Imag, DT_COMPLEX128, DT_DOUBLE, baseline_imag,
588 test::OpsTestConfig().AddTout().NoBufferReuse())
589
590 /// Test `tf.Inv`.
591
592 template <typename T>
baseline_inv(T x)593 T baseline_inv(T x) {
594 return T(1) / x;
595 }
596
597 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
598 Inv, DT_INT64, DT_INT64, test::DefaultInputNonZero<int64_t>(), baseline_inv,
599 test::OpsTestConfig().ExpectStrictlyEqual())
600
GENERATE_DEFAULT_TEST(Inv,DT_FLOAT,DT_FLOAT,baseline_inv,test::OpsTestConfig ())601 GENERATE_DEFAULT_TEST(Inv, DT_FLOAT, DT_FLOAT, baseline_inv,
602 test::OpsTestConfig())
603
604 GENERATE_DEFAULT_TEST(Inv, DT_DOUBLE, DT_DOUBLE, baseline_inv,
605 test::OpsTestConfig())
606
607 GENERATE_DEFAULT_TEST_2(Inv, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, baseline_inv,
608 test::OpsTestConfig())
609
610 GENERATE_DEFAULT_TEST(Inv, DT_COMPLEX64, DT_COMPLEX64, baseline_inv,
611 test::OpsTestConfig())
612
613 GENERATE_DEFAULT_TEST(Inv, DT_COMPLEX128, DT_COMPLEX128, baseline_inv,
614 test::OpsTestConfig())
615
616 /// Test `tf.Invert`.
617
618 /// Reference implementation.
619 template <typename T>
620 T baseline_invert(T x) {
621 return ~x;
622 }
623
624 GENERATE_DEFAULT_TEST(Invert, DT_INT8, DT_INT8, baseline_invert,
625 test::OpsTestConfig().ExpectStrictlyEqual())
626
627 GENERATE_DEFAULT_TEST(Invert, DT_UINT8, DT_UINT8, baseline_invert,
628 test::OpsTestConfig().ExpectStrictlyEqual())
629
630 GENERATE_DEFAULT_TEST(Invert, DT_INT16, DT_INT16, baseline_invert,
631 test::OpsTestConfig().ExpectStrictlyEqual())
632
633 GENERATE_DEFAULT_TEST(Invert, DT_UINT16, DT_UINT16, baseline_invert,
634 test::OpsTestConfig().ExpectStrictlyEqual())
635
636 GENERATE_DEFAULT_TEST(Invert, DT_INT32, DT_INT32, baseline_invert,
637 test::OpsTestConfig().ExpectStrictlyEqual())
638
639 GENERATE_DEFAULT_TEST(Invert, DT_UINT32, DT_UINT32, baseline_invert,
640 test::OpsTestConfig().ExpectStrictlyEqual())
641
642 GENERATE_DEFAULT_TEST(Invert, DT_INT64, DT_INT64, baseline_invert,
643 test::OpsTestConfig().ExpectStrictlyEqual())
644
645 GENERATE_DEFAULT_TEST(Invert, DT_UINT64, DT_UINT64, baseline_invert,
646 test::OpsTestConfig().ExpectStrictlyEqual())
647
648 /// Test `tf.IsFinite`.
649
650 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
651 IsFinite, DT_FLOAT, DT_FLOAT, DT_BOOL, DT_BOOL,
652 test::NearZeroAndExtremeInput<float>(), std::isfinite,
653 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
654
655 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
656 IsFinite, DT_DOUBLE, DT_DOUBLE, DT_BOOL, DT_BOOL,
657 test::NearZeroAndExtremeInput<double>(), std::isfinite,
658 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
659
660 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
661 IsFinite, DT_HALF, DT_FLOAT, DT_BOOL, DT_BOOL,
662 test::NearZeroAndExtremeInput<Eigen::half>(), std::isfinite,
663 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
664
665 /// Test `tf.IsInf`.
666
667 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
668 IsInf, DT_FLOAT, DT_FLOAT, DT_BOOL, DT_BOOL,
669 test::NearZeroAndExtremeInput<float>(), std::isinf,
670 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
671
672 // Workaround for gcc bug, it would fail with "unresolved overloaded function
673 // type" if passing std::isinf with type double. So we use type float for
674 // comparing expected values.
675 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
676 IsInf, DT_DOUBLE, DT_FLOAT, DT_BOOL, DT_BOOL,
677 test::NearZeroAndExtremeInput<double>(), std::isinf,
678 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
679
680 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
681 IsInf, DT_HALF, DT_FLOAT, DT_BOOL, DT_BOOL,
682 test::NearZeroAndExtremeInput<Eigen::half>(), std::isinf,
683 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
684
685 /// Test `tf.IsNan`.
686
687 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
688 IsNan, DT_FLOAT, DT_FLOAT, DT_BOOL, DT_BOOL,
689 test::NearZeroInfAndNanInput<float>(), std::isnan,
690 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
691
692 // Workaround for gcc bug, it would fail with "unresolved overloaded function
693 // type" if passing std::isnan with type double. So we use type float for
694 // comparing expected values.
695 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
696 IsNan, DT_DOUBLE, DT_FLOAT, DT_BOOL, DT_BOOL,
697 test::NearZeroInfAndNanInput<double>(), std::isnan,
698 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
699
700 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
701 IsNan, DT_HALF, DT_FLOAT, DT_BOOL, DT_BOOL,
702 test::NearZeroInfAndNanInput<Eigen::half>(), std::isnan,
703 test::OpsTestConfig().ExpectStrictlyEqual().NoBufferReuse());
704
705 /// Test `tf.Lgamma`.
706
707 static constexpr std::initializer_list<double> kLgammaValues = {
708 -std::numeric_limits<double>::infinity(),
709 -9.0,
710 -8.5,
711 -8.3,
712 -2.0,
713 -1.5,
714 -1.3,
715 -1.0,
716 -0.5,
717 -0.3,
718 0.0,
719 0.1,
720 0.2,
721 0.3,
722 0.4,
723 0.5,
724 0.6,
725 0.7,
726 0.8,
727 0.9,
728 1.0,
729 1.5,
730 2.0,
731 3.0,
732 4.0,
733 5.0,
734 100.0,
735 std::numeric_limits<double>::infinity(),
736 };
737
GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(Lgamma,DT_FLOAT,DT_FLOAT,test::InputAsVector<float> (kLgammaValues),std::lgamma,test::OpsTestConfig ())738 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
739 Lgamma, DT_FLOAT, DT_FLOAT, test::InputAsVector<float>(kLgammaValues),
740 std::lgamma, test::OpsTestConfig())
741
742 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
743 Lgamma, DT_DOUBLE, DT_DOUBLE, test::InputAsVector<double>(kLgammaValues),
744 std::lgamma, test::OpsTestConfig())
745
746 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES_2(
747 Lgamma, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
748 test::InputAsVector<Eigen::half>(kLgammaValues), std::lgamma,
749 test::OpsTestConfig())
750
751 /// Test `tf.Log`.
752
753 GENERATE_DEFAULT_TEST(Log, DT_FLOAT, DT_FLOAT, std::log, test::OpsTestConfig())
754
755 GENERATE_DEFAULT_TEST(Log, DT_DOUBLE, DT_DOUBLE, std::log,
756 test::OpsTestConfig())
757
758 GENERATE_DEFAULT_TEST_2(Log, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::log,
759 test::OpsTestConfig())
760
761 /// Test `tf.Log1p`.
762
763 GENERATE_DEFAULT_TEST(Log1p, DT_FLOAT, DT_FLOAT, std::log1p,
764 test::OpsTestConfig())
765
766 GENERATE_DEFAULT_TEST(Log1p, DT_DOUBLE, DT_DOUBLE, std::log1p,
767 test::OpsTestConfig())
768
769 GENERATE_DEFAULT_TEST_2(Log1p, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::log1p,
770 test::OpsTestConfig())
771
772 /// Test `tf.LogicalNot`
773
774 bool baseline_logical_not(bool x) { return !x; }
775
776 GENERATE_DEFAULT_TEST(LogicalNot, DT_BOOL, DT_BOOL, baseline_logical_not,
777 test::OpsTestConfig().ExpectStrictlyEqual().NoT())
778
779 /// Test `tf.Neg`.
780
781 /// Reference implementation.
782 template <typename T>
baseline_neg(T x)783 T baseline_neg(T x) {
784 return -x;
785 }
786
787 GENERATE_DEFAULT_TEST(Neg, DT_FLOAT, DT_FLOAT, baseline_neg,
788 test::OpsTestConfig().ExpectStrictlyEqual())
789
790 GENERATE_DEFAULT_TEST(Neg, DT_DOUBLE, DT_DOUBLE, baseline_neg,
791 test::OpsTestConfig().ExpectStrictlyEqual())
792
GENERATE_DEFAULT_TEST_2(Neg,DT_HALF,DT_FLOAT,DT_HALF,DT_FLOAT,baseline_neg,test::OpsTestConfig ())793 GENERATE_DEFAULT_TEST_2(Neg, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, baseline_neg,
794 test::OpsTestConfig())
795
796 GENERATE_DEFAULT_TEST(Neg, DT_INT8, DT_INT8, baseline_neg,
797 test::OpsTestConfig().ExpectStrictlyEqual())
798
799 GENERATE_DEFAULT_TEST(Neg, DT_INT16, DT_INT16, baseline_neg,
800 test::OpsTestConfig().ExpectStrictlyEqual())
801
802 GENERATE_DEFAULT_TEST(Neg, DT_INT64, DT_INT64, baseline_neg,
803 test::OpsTestConfig().ExpectStrictlyEqual())
804
805 GENERATE_DEFAULT_TEST(Neg, DT_COMPLEX64, DT_COMPLEX64, baseline_neg,
806 test::OpsTestConfig().ExpectStrictlyEqual())
807
808 GENERATE_DEFAULT_TEST(Neg, DT_COMPLEX128, DT_COMPLEX128, baseline_neg,
809 test::OpsTestConfig().ExpectStrictlyEqual())
810
811 /// Test `tf.OnesLike`.
812
813 template <typename T>
814 T baseline_ones_like(T /*inp*/) {
815 return T(1);
816 }
817
818 GENERATE_DEFAULT_TEST(OnesLike, DT_BOOL, DT_BOOL, baseline_ones_like,
819 test::OpsTestConfig().ExpectStrictlyEqual())
820 GENERATE_DEFAULT_TEST(OnesLike, DT_HALF, DT_HALF, baseline_ones_like,
821 test::OpsTestConfig().ExpectStrictlyEqual())
822 GENERATE_DEFAULT_TEST(OnesLike, DT_FLOAT, DT_FLOAT, baseline_ones_like,
823 test::OpsTestConfig().ExpectStrictlyEqual())
824 GENERATE_DEFAULT_TEST(OnesLike, DT_DOUBLE, DT_DOUBLE, baseline_ones_like,
825 test::OpsTestConfig().ExpectStrictlyEqual())
826 GENERATE_DEFAULT_TEST(OnesLike, DT_INT64, DT_INT64, baseline_ones_like,
827 test::OpsTestConfig().ExpectStrictlyEqual())
828 GENERATE_DEFAULT_TEST(OnesLike, DT_COMPLEX64, DT_COMPLEX64, baseline_ones_like,
829 test::OpsTestConfig().ExpectStrictlyEqual())
830 GENERATE_DEFAULT_TEST(OnesLike, DT_COMPLEX128, DT_COMPLEX128,
831 baseline_ones_like,
832 test::OpsTestConfig().ExpectStrictlyEqual())
833
834 // These kernels are JIT-compiled.
835 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
836 GENERATE_DEFAULT_TEST(OnesLike, DT_INT8, DT_INT8, baseline_ones_like,
837 test::OpsTestConfig().ExpectStrictlyEqual())
838 GENERATE_DEFAULT_TEST(OnesLike, DT_INT16, DT_INT16, baseline_ones_like,
839 test::OpsTestConfig().ExpectStrictlyEqual())
840 GENERATE_DEFAULT_TEST(OnesLike, DT_UINT8, DT_UINT8, baseline_ones_like,
841 test::OpsTestConfig().ExpectStrictlyEqual())
842 GENERATE_DEFAULT_TEST(OnesLike, DT_UINT16, DT_UINT16, baseline_ones_like,
843 test::OpsTestConfig().ExpectStrictlyEqual())
844 GENERATE_DEFAULT_TEST(OnesLike, DT_UINT32, DT_UINT32, baseline_ones_like,
845 test::OpsTestConfig().ExpectStrictlyEqual())
846 GENERATE_DEFAULT_TEST(OnesLike, DT_UINT64, DT_UINT64, baseline_ones_like,
847 test::OpsTestConfig().ExpectStrictlyEqual())
848 #endif
849
850 /// Test `tf.Real`.
851
852 template <typename T>
baseline_real(T x)853 typename T::value_type baseline_real(T x) {
854 return std::real(x);
855 }
856
857 GENERATE_DEFAULT_TEST(Real, DT_COMPLEX64, DT_FLOAT, baseline_real,
858 test::OpsTestConfig().AddTout().NoBufferReuse())
859
860 GENERATE_DEFAULT_TEST(Real, DT_COMPLEX128, DT_DOUBLE, baseline_real,
861 test::OpsTestConfig().AddTout().NoBufferReuse())
862
863 /// Test `tf.Reciprocal`.
864
865 template <typename T>
baseline_reciprocal(T x)866 T baseline_reciprocal(T x) {
867 return T(1) / x;
868 }
869
870 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
871 Reciprocal, DT_INT64, DT_INT64, test::DefaultInputNonZero<int64_t>(),
872 baseline_reciprocal, test::OpsTestConfig().ExpectStrictlyEqual())
873
GENERATE_DEFAULT_TEST(Reciprocal,DT_FLOAT,DT_FLOAT,baseline_reciprocal,test::OpsTestConfig ())874 GENERATE_DEFAULT_TEST(Reciprocal, DT_FLOAT, DT_FLOAT, baseline_reciprocal,
875 test::OpsTestConfig())
876
877 GENERATE_DEFAULT_TEST(Reciprocal, DT_DOUBLE, DT_DOUBLE, baseline_reciprocal,
878 test::OpsTestConfig())
879
880 GENERATE_DEFAULT_TEST_2(Reciprocal, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
881 baseline_reciprocal, test::OpsTestConfig())
882
883 GENERATE_DEFAULT_TEST(Reciprocal, DT_COMPLEX64, DT_COMPLEX64,
884 baseline_reciprocal, test::OpsTestConfig())
885
886 GENERATE_DEFAULT_TEST(Reciprocal, DT_COMPLEX128, DT_COMPLEX128,
887 baseline_reciprocal, test::OpsTestConfig())
888
889 /// Test `tf.Relu`.
890
891 template <typename T>
892 T baseline_relu(T x) {
893 return std::max(x, static_cast<T>(0.0));
894 }
895
GENERATE_DEFAULT_TEST(Relu,DT_FLOAT,DT_FLOAT,baseline_relu,test::OpsTestConfig ())896 GENERATE_DEFAULT_TEST(Relu, DT_FLOAT, DT_FLOAT, baseline_relu,
897 test::OpsTestConfig())
898 GENERATE_DEFAULT_TEST(Relu, DT_DOUBLE, DT_DOUBLE, baseline_relu,
899 test::OpsTestConfig())
900 GENERATE_DEFAULT_TEST_2(Relu, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
901 baseline_relu, test::OpsTestConfig())
902
903 // Test the JIT-compiled kernels.
904 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
905 GENERATE_DEFAULT_TEST(Relu, DT_INT8, DT_INT8, baseline_relu,
906 test::OpsTestConfig().ExpectStrictlyEqual())
907 GENERATE_DEFAULT_TEST(Relu, DT_INT16, DT_INT16, baseline_relu,
908 test::OpsTestConfig().ExpectStrictlyEqual())
909 GENERATE_DEFAULT_TEST(Relu, DT_INT64, DT_INT64, baseline_relu,
910 test::OpsTestConfig().ExpectStrictlyEqual())
911 GENERATE_DEFAULT_TEST(Relu, DT_UINT8, DT_UINT8, baseline_relu,
912 test::OpsTestConfig().ExpectStrictlyEqual())
913 GENERATE_DEFAULT_TEST(Relu, DT_UINT16, DT_UINT16, baseline_relu,
914 test::OpsTestConfig().ExpectStrictlyEqual())
915 GENERATE_DEFAULT_TEST(Relu, DT_UINT32, DT_UINT32, baseline_relu,
916 test::OpsTestConfig().ExpectStrictlyEqual())
917 GENERATE_DEFAULT_TEST(Relu, DT_UINT64, DT_UINT64, baseline_relu,
918 test::OpsTestConfig().ExpectStrictlyEqual())
919 #endif
920
921 /// Test `tf.Rint`.
922
923 template <typename T>
924 T baseline_rint(T x) {
925 T y = std::rint(x);
926 return y == T(0) ? T(0) : y;
927 }
928
929 // Test the JIT-compiled kernel.
930 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
931 GENERATE_DEFAULT_TEST_2(Rint, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
932 baseline_rint,
933 test::OpsTestConfig().ExpectStrictlyEqual())
934
TEST_F(UnaryOpsTest,RintWithCache)935 TEST_F(UnaryOpsTest, RintWithCache) {
936 constexpr auto kTFJitCacheDirEnvVar = "TF_JIT_CACHE_DIR";
937 // First try to setup a unique directory for the file cache
938 auto *env = tensorflow::Env::Default();
939 std::string jit_dir;
940 auto max_tries = 5;
941 do {
942 ASSERT_GE(max_tries--, 0);
943 } while (!env->LocalTempFilename(&jit_dir));
944 char* original_env = getenv(kTFJitCacheDirEnvVar);
945 setenv(kTFJitCacheDirEnvVar, jit_dir.c_str(), 1);
946
947 // Run the actual test
948 Test<Eigen::half, float, Eigen::half, float>(
949 "Rint", test::DefaultInputShape(), test::DefaultInput<Eigen::half>(),
950 baseline_rint, test::OpsTestConfig().ExpectStrictlyEqual());
951
952 // Test that the file cache is not empty after compiling
953 std::vector<std::string> children;
954 TF_ASSERT_OK(env->GetChildren(jit_dir, &children));
955 ASSERT_EQ(1, children.size());
956
957 if (original_env != nullptr) setenv(kTFJitCacheDirEnvVar, original_env, 1);
958 }
959 #endif
960
961 GENERATE_DEFAULT_TEST(Rint, DT_FLOAT, DT_FLOAT, baseline_rint,
962 test::OpsTestConfig().ExpectStrictlyEqual())
963 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
964 Rint, DT_DOUBLE, DT_DOUBLE,
965 test::InputAsVector<double>({-1.7, -1.5, -0.2, -0.0, 0.0, 0.2, 0.5000001,
966 1.5, 1.7, 2.0}),
967 baseline_rint, test::OpsTestConfig().ExpectStrictlyEqual())
968
969 /// Test `tf.Round`.
970
971 /// `tf.Round` is the same as `std::rint` and different from `std::round`. It
972 /// rounds to the nearest even integer, not towards zero.
973
974 GENERATE_DEFAULT_TEST_WITH_SPECIFIC_INPUT_VALUES(
975 Round, DT_DOUBLE, DT_DOUBLE,
976 test::InputAsVector<double>({-1.7, -1.5, -0.2, -0.0, 0.0, 0.2, 0.5000001,
977 1.5, 1.7, 2.0}),
978 baseline_rint, test::OpsTestConfig().ExpectStrictlyEqual())
979
980 GENERATE_DEFAULT_TEST(Round, DT_FLOAT, DT_FLOAT, baseline_rint,
981 test::OpsTestConfig().ExpectStrictlyEqual())
982
983 GENERATE_DEFAULT_TEST_2(Round, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
984 baseline_rint,
985 test::OpsTestConfig().ExpectStrictlyEqual())
986
987 GENERATE_DEFAULT_TEST(Round, DT_INT32, DT_INT32, baseline_rint,
988 test::OpsTestConfig().ExpectStrictlyEqual())
989
990 GENERATE_DEFAULT_TEST(Round, DT_INT64, DT_INT64, baseline_rint,
991 test::OpsTestConfig().ExpectStrictlyEqual())
992
993 /// Test `tf.Rsqrt`.
994
995 /// Reference implementation.
996 template <typename T>
baseline_rsqrt(T x)997 T baseline_rsqrt(T x) {
998 return 1.0 / std::sqrt(x);
999 }
1000
GENERATE_DEFAULT_TEST(Rsqrt,DT_FLOAT,DT_FLOAT,baseline_rsqrt,test::OpsTestConfig ())1001 GENERATE_DEFAULT_TEST(Rsqrt, DT_FLOAT, DT_FLOAT, baseline_rsqrt,
1002 test::OpsTestConfig())
1003
1004 GENERATE_DEFAULT_TEST(Rsqrt, DT_DOUBLE, DT_DOUBLE, baseline_rsqrt,
1005 test::OpsTestConfig())
1006
1007 GENERATE_DEFAULT_TEST_2(Rsqrt, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
1008 baseline_rsqrt, test::OpsTestConfig())
1009
1010 /// Test `tf.Selu`.
1011
1012 template <typename T>
1013 T baseline_selu(T x) {
1014 const double scale = 1.0507009873554804934193349852946;
1015 if (x > 0) return scale * x;
1016
1017 const double scaled_alpha = 1.7580993408473768599402175208123;
1018 return scaled_alpha * (std::exp(x) - 1);
1019 }
1020
GENERATE_DEFAULT_TEST(Selu,DT_FLOAT,DT_FLOAT,baseline_selu,test::OpsTestConfig ())1021 GENERATE_DEFAULT_TEST(Selu, DT_FLOAT, DT_FLOAT, baseline_selu,
1022 test::OpsTestConfig())
1023
1024 GENERATE_DEFAULT_TEST(Selu, DT_DOUBLE, DT_DOUBLE, baseline_selu,
1025 test::OpsTestConfig())
1026
1027 GENERATE_DEFAULT_TEST_2(Selu, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
1028 baseline_selu, test::OpsTestConfig())
1029
1030 /// Test `tf.Sigmoid`.
1031
1032 // Reference implementation
1033 template <typename T>
1034 T baseline_sigmoid(T x) {
1035 return 1.0 / (1 + std::exp(-x));
1036 }
1037
GENERATE_DEFAULT_TEST(Sigmoid,DT_FLOAT,DT_FLOAT,baseline_sigmoid,test::OpsTestConfig ())1038 GENERATE_DEFAULT_TEST(Sigmoid, DT_FLOAT, DT_FLOAT, baseline_sigmoid,
1039 test::OpsTestConfig())
1040
1041 GENERATE_DEFAULT_TEST(Sigmoid, DT_DOUBLE, DT_DOUBLE, baseline_sigmoid,
1042 test::OpsTestConfig())
1043
1044 GENERATE_DEFAULT_TEST_2(Sigmoid, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
1045 baseline_sigmoid, test::OpsTestConfig())
1046
1047 /// Test `tf.Sign`.
1048
1049 // Reference implementation
1050 template <typename T>
1051 T baseline_sign(T x) {
1052 if (std::isnan(x)) return x;
1053 if (x == 0) return 0;
1054 if (x < 0) return -1;
1055 return 1;
1056 }
1057
1058 template <>
baseline_sign(std::complex<double> x)1059 std::complex<double> baseline_sign(std::complex<double> x) {
1060 double abs_x = std::abs(x);
1061 if (abs_x == 0) return std::complex<double>(0);
1062 double abs_x_inverse = 1 / abs_x;
1063 return std::complex<double>(x.real() * abs_x_inverse,
1064 x.imag() * abs_x_inverse);
1065 }
1066
1067 GENERATE_DEFAULT_TEST(Sign, DT_FLOAT, DT_FLOAT, baseline_sign,
1068 test::OpsTestConfig().ExpectStrictlyEqual())
1069 GENERATE_DEFAULT_TEST(Sign, DT_DOUBLE, DT_DOUBLE, baseline_sign,
1070 test::OpsTestConfig().ExpectStrictlyEqual())
1071 // TODO(b/162577610): We should actually use ExpectStrictlyEqual()
1072 // here. This requires returning 0.0 for input -0.0.
GENERATE_DEFAULT_TEST_2(Sign,DT_HALF,DT_FLOAT,DT_HALF,DT_FLOAT,baseline_sign,test::OpsTestConfig ())1073 GENERATE_DEFAULT_TEST_2(Sign, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
1074 baseline_sign, test::OpsTestConfig())
1075 GENERATE_DEFAULT_TEST(Sign, DT_INT64, DT_INT64, baseline_sign,
1076 test::OpsTestConfig().ExpectStrictlyEqual())
1077 GENERATE_DEFAULT_TEST_2(Sign, DT_COMPLEX64, DT_COMPLEX128, DT_COMPLEX64,
1078 DT_COMPLEX128, baseline_sign,
1079 test::OpsTestConfig().ExpectStrictlyEqual())
1080 GENERATE_DEFAULT_TEST(Sign, DT_COMPLEX128, DT_COMPLEX128, baseline_sign,
1081 test::OpsTestConfig().ExpectStrictlyEqual())
1082
1083 // These kernels are JIT-compiled.
1084 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
1085 GENERATE_DEFAULT_TEST(Sign, DT_INT8, DT_INT8, baseline_sign,
1086 test::OpsTestConfig().ExpectStrictlyEqual())
1087 GENERATE_DEFAULT_TEST(Sign, DT_INT16, DT_INT16, baseline_sign,
1088 test::OpsTestConfig().ExpectStrictlyEqual())
1089 #endif
1090
1091 /// Test `tf.Sin`.
1092
1093 GENERATE_DEFAULT_TEST(Sin, DT_FLOAT, DT_FLOAT, std::sin, test::OpsTestConfig())
1094
1095 GENERATE_DEFAULT_TEST(Sin, DT_DOUBLE, DT_DOUBLE, std::sin,
1096 test::OpsTestConfig())
1097
1098 GENERATE_DEFAULT_TEST_2(Sin, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::sin,
1099 test::OpsTestConfig())
1100
1101 // These kernels are JIT-compiled.
1102 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
1103
1104 GENERATE_DEFAULT_TEST(Sin, DT_COMPLEX64, DT_COMPLEX64, std::sin,
1105 test::OpsTestConfig())
1106
1107 GENERATE_DEFAULT_TEST(Sin, DT_COMPLEX128, DT_COMPLEX128, std::sin,
1108 test::OpsTestConfig())
1109
1110 #endif
1111
1112 /// Test `tf.Sinh`.
1113
1114 GENERATE_DEFAULT_TEST_2(Sinh, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::sinh,
1115 test::OpsTestConfig())
1116
1117 GENERATE_DEFAULT_TEST(Sinh, DT_FLOAT, DT_FLOAT, std::sinh,
1118 test::OpsTestConfig())
1119
1120 GENERATE_DEFAULT_TEST(Sinh, DT_DOUBLE, DT_DOUBLE, std::sinh,
1121 test::OpsTestConfig())
1122
1123 // These kernels are JIT-compiled.
1124 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
1125
1126 GENERATE_DEFAULT_TEST(Sinh, DT_COMPLEX64, DT_COMPLEX64, std::sinh,
1127 test::OpsTestConfig())
1128
1129 GENERATE_DEFAULT_TEST(Sinh, DT_COMPLEX128, DT_COMPLEX128, std::sinh,
1130 test::OpsTestConfig())
1131
1132 #endif
1133
1134 /// Test `tf.Softplus`.
1135
1136 // Reference implementation
1137 template <typename T>
1138 T baseline_softplus(T x) {
1139 T epsilon = std::numeric_limits<T>::epsilon();
1140 T threshold = 2 + std::log(epsilon);
1141 if (x > -threshold && x < threshold) {
1142 return std::exp(x);
1143 }
1144 return std::log1p(std::exp(x));
1145 }
1146
GENERATE_DEFAULT_TEST_2(Softplus,DT_HALF,DT_FLOAT,DT_HALF,DT_FLOAT,baseline_softplus,test::OpsTestConfig ())1147 GENERATE_DEFAULT_TEST_2(Softplus, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
1148 baseline_softplus, test::OpsTestConfig())
1149
1150 GENERATE_DEFAULT_TEST(Softplus, DT_FLOAT, DT_FLOAT, baseline_softplus,
1151 test::OpsTestConfig())
1152
1153 GENERATE_DEFAULT_TEST(Softplus, DT_DOUBLE, DT_DOUBLE, baseline_softplus,
1154 test::OpsTestConfig())
1155
1156 /// Test `tf.Softsign`.
1157
1158 // Reference implementation
1159 template <typename T>
1160 T baseline_softsign(T x) {
1161 return x / (std::abs(x) + 1);
1162 }
1163
GENERATE_DEFAULT_TEST_2(Softsign,DT_HALF,DT_FLOAT,DT_HALF,DT_FLOAT,baseline_softsign,test::OpsTestConfig ())1164 GENERATE_DEFAULT_TEST_2(Softsign, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT,
1165 baseline_softsign, test::OpsTestConfig())
1166
1167 GENERATE_DEFAULT_TEST(Softsign, DT_FLOAT, DT_FLOAT, baseline_softsign,
1168 test::OpsTestConfig())
1169
1170 GENERATE_DEFAULT_TEST(Softsign, DT_DOUBLE, DT_DOUBLE, baseline_softsign,
1171 test::OpsTestConfig())
1172
1173 /// Test `tf.Sqrt`.
1174
1175 GENERATE_DEFAULT_TEST(Sqrt, DT_FLOAT, DT_FLOAT, std::sqrt,
1176 test::OpsTestConfig())
1177
1178 GENERATE_DEFAULT_TEST(Sqrt, DT_DOUBLE, DT_DOUBLE, std::sqrt,
1179 test::OpsTestConfig())
1180
1181 GENERATE_DEFAULT_TEST_2(Sqrt, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::sqrt,
1182 test::OpsTestConfig())
1183
1184 /// Test `tf.Tan`.
1185
1186 GENERATE_DEFAULT_TEST(Tan, DT_FLOAT, DT_FLOAT, std::tan, test::OpsTestConfig())
1187
1188 GENERATE_DEFAULT_TEST(Tan, DT_DOUBLE, DT_DOUBLE, std::tan,
1189 test::OpsTestConfig())
1190
1191 GENERATE_DEFAULT_TEST_2(Tan, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::tan,
1192 test::OpsTestConfig())
1193
1194 // These kernels are JIT-compiled.
1195 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
1196
1197 GENERATE_DEFAULT_TEST(Tan, DT_COMPLEX64, DT_COMPLEX64, std::tan,
1198 test::OpsTestConfig())
1199
1200 GENERATE_DEFAULT_TEST(Tan, DT_COMPLEX128, DT_COMPLEX128, std::tan,
1201 test::OpsTestConfig())
1202
1203 #endif
1204
1205 /// Test `tf.Tanh`.
1206
1207 GENERATE_DEFAULT_TEST(Tanh, DT_FLOAT, DT_FLOAT, std::tanh,
1208 test::OpsTestConfig())
1209
1210 GENERATE_DEFAULT_TEST(Tanh, DT_DOUBLE, DT_DOUBLE, std::tanh,
1211 test::OpsTestConfig())
1212
1213 GENERATE_DEFAULT_TEST_2(Tanh, DT_HALF, DT_FLOAT, DT_HALF, DT_FLOAT, std::tanh,
1214 test::OpsTestConfig())
1215
1216 // Test small/large input values to be approximated as constant -1/1.
1217 template <typename T>
1218 T baseline_tanh_limits(T x) {
1219 assert((x < -10 || x > 10) &&
1220 "baseline_tanh_limits is only applicable to small/large values");
1221 return x < 0.0 ? -1.0 : 1.0;
1222 }
TEST_F(UnaryOpsTest,TanhSmallAndLarge)1223 TEST_F(UnaryOpsTest, TanhSmallAndLarge) {
1224 Test<float, float, float, float>(
1225 "Tanh", test::DefaultInputShape(),
1226 test::InputAsVector<float>({-100.0, -10.5, 12.0, 123.0, 10000.0}),
1227 baseline_tanh_limits,
1228 test::OpsTestConfig().ExpectStrictlyEqual().SuppressTolerance());
1229 }
1230
TEST_F(UnaryOpsTest,TanhNaN)1231 TEST_F(UnaryOpsTest, TanhNaN) {
1232 Test<float, float, float, float>(
1233 "Tanh", test::DefaultInputShape(),
1234 test::InputAsVector<float>({std::numeric_limits<float>::quiet_NaN()}),
1235 std::tanh, test::OpsTestConfig().ExpectStrictlyEqual());
1236 }
1237
1238 /// Test `tf.Square`.
1239
1240 template <typename T>
baseline_square(T x)1241 T baseline_square(T x) {
1242 return x * x;
1243 }
1244
GENERATE_DEFAULT_TEST(Square,DT_HALF,DT_HALF,baseline_square,test::OpsTestConfig ())1245 GENERATE_DEFAULT_TEST(Square, DT_HALF, DT_HALF, baseline_square,
1246 test::OpsTestConfig())
1247 GENERATE_DEFAULT_TEST(Square, DT_FLOAT, DT_FLOAT, baseline_square,
1248 test::OpsTestConfig())
1249 GENERATE_DEFAULT_TEST(Square, DT_DOUBLE, DT_DOUBLE, baseline_square,
1250 test::OpsTestConfig())
1251 GENERATE_DEFAULT_TEST(Square, DT_INT64, DT_INT64, baseline_square,
1252 test::OpsTestConfig().ExpectStrictlyEqual())
1253
1254 // These kernels are JIT-compiled.
1255 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
1256 GENERATE_DEFAULT_TEST(Square, DT_INT8, DT_INT8, baseline_square,
1257 test::OpsTestConfig().ExpectStrictlyEqual())
1258 GENERATE_DEFAULT_TEST(Square, DT_INT16, DT_INT16, baseline_square,
1259 test::OpsTestConfig().ExpectStrictlyEqual())
1260 GENERATE_DEFAULT_TEST(Square, DT_UINT8, DT_UINT8, baseline_square,
1261 test::OpsTestConfig().ExpectStrictlyEqual())
1262 GENERATE_DEFAULT_TEST(Square, DT_UINT16, DT_UINT16, baseline_square,
1263 test::OpsTestConfig().ExpectStrictlyEqual())
1264 GENERATE_DEFAULT_TEST(Square, DT_UINT32, DT_UINT32, baseline_square,
1265 test::OpsTestConfig().ExpectStrictlyEqual())
1266 GENERATE_DEFAULT_TEST(Square, DT_UINT64, DT_UINT64, baseline_square,
1267 test::OpsTestConfig().ExpectStrictlyEqual())
1268 #endif
1269
1270 /// Test `tf.ZerosLike`.
1271
1272 template <typename T>
1273 T baseline_zeros_like(T /*inp*/) {
1274 return T(0);
1275 }
1276
1277 GENERATE_DEFAULT_TEST(ZerosLike, DT_BOOL, DT_BOOL, baseline_zeros_like,
1278 test::OpsTestConfig().ExpectStrictlyEqual())
1279 GENERATE_DEFAULT_TEST(ZerosLike, DT_HALF, DT_HALF, baseline_zeros_like,
1280 test::OpsTestConfig().ExpectStrictlyEqual())
1281 GENERATE_DEFAULT_TEST(ZerosLike, DT_FLOAT, DT_FLOAT, baseline_zeros_like,
1282 test::OpsTestConfig().ExpectStrictlyEqual())
1283 GENERATE_DEFAULT_TEST(ZerosLike, DT_DOUBLE, DT_DOUBLE, baseline_zeros_like,
1284 test::OpsTestConfig().ExpectStrictlyEqual())
1285 GENERATE_DEFAULT_TEST(ZerosLike, DT_INT64, DT_INT64, baseline_zeros_like,
1286 test::OpsTestConfig().ExpectStrictlyEqual())
1287 GENERATE_DEFAULT_TEST(ZerosLike, DT_COMPLEX64, DT_COMPLEX64,
1288 baseline_zeros_like,
1289 test::OpsTestConfig().ExpectStrictlyEqual())
1290 GENERATE_DEFAULT_TEST(ZerosLike, DT_COMPLEX128, DT_COMPLEX128,
1291 baseline_zeros_like,
1292 test::OpsTestConfig().ExpectStrictlyEqual())
1293
1294 // These kernels are JIT-compiled.
1295 #if defined(MLIR_GENERATED_GPU_KERNELS_ENABLED)
1296 GENERATE_DEFAULT_TEST(ZerosLike, DT_INT8, DT_INT8, baseline_zeros_like,
1297 test::OpsTestConfig().ExpectStrictlyEqual())
1298 GENERATE_DEFAULT_TEST(ZerosLike, DT_INT16, DT_INT16, baseline_zeros_like,
1299 test::OpsTestConfig().ExpectStrictlyEqual())
1300 GENERATE_DEFAULT_TEST(ZerosLike, DT_UINT8, DT_UINT8, baseline_zeros_like,
1301 test::OpsTestConfig().ExpectStrictlyEqual())
1302 GENERATE_DEFAULT_TEST(ZerosLike, DT_UINT16, DT_UINT16, baseline_zeros_like,
1303 test::OpsTestConfig().ExpectStrictlyEqual())
1304 GENERATE_DEFAULT_TEST(ZerosLike, DT_UINT32, DT_UINT32, baseline_zeros_like,
1305 test::OpsTestConfig().ExpectStrictlyEqual())
1306 GENERATE_DEFAULT_TEST(ZerosLike, DT_UINT64, DT_UINT64, baseline_zeros_like,
1307 test::OpsTestConfig().ExpectStrictlyEqual())
1308 #endif
1309
1310 } // namespace
1311 } // namespace tensorflow
1312