|
| 1 | +// RUN: %{build} -fsycl-device-code-split=per_kernel -o %t.out |
| 2 | +// RUN: %{run} %t.out |
| 3 | + |
| 4 | +// Tests NVVM intrinsics for sin and cos approximations |
| 5 | + |
| 6 | +#include <cassert> |
| 7 | +#include <cmath> |
| 8 | +#include <sycl/detail/core.hpp> |
| 9 | + |
| 10 | +// Forward declarations of NVVM intrinsics |
| 11 | +extern "C" { |
| 12 | +float __nvvm_sin_approx_f(float); |
| 13 | +float __nvvm_sin_approx_ftz_f(float); |
| 14 | +float __nvvm_cos_approx_f(float); |
| 15 | +float __nvvm_cos_approx_ftz_f(float); |
| 16 | +} |
| 17 | + |
| 18 | +constexpr float TOLERANCE = 0.01f; // 1% tolerance for approximations |
| 19 | + |
| 20 | +template <typename Func> |
| 21 | +void test_approx(sycl::queue &q, Func intrinsic_func, const char *name, |
| 22 | + float input, float expected) { |
| 23 | + float result = 0.0f; |
| 24 | + |
| 25 | + { |
| 26 | + sycl::buffer<float, 1> buf_result(&result, sycl::range<1>(1)); |
| 27 | + q.submit([&](sycl::handler &cgh) { |
| 28 | + auto acc_result = |
| 29 | + buf_result.template get_access<sycl::access::mode::write>(cgh); |
| 30 | + cgh.single_task([=]() { acc_result[0] = intrinsic_func(input); }); |
| 31 | + }).wait(); |
| 32 | + } |
| 33 | + |
| 34 | + float error = std::abs(result - expected); |
| 35 | + assert(error < TOLERANCE && name && " approximation out of tolerance"); |
| 36 | +} |
| 37 | + |
| 38 | +int main() { |
| 39 | + sycl::queue q; |
| 40 | + |
| 41 | + // Test values |
| 42 | + const float pi = 3.14159265f; |
| 43 | + const float test_values[] = {0.0f, pi / 6.0f, pi / 4.0f, pi / 3.0f, |
| 44 | + pi / 2.0f, pi, 2.0f * pi}; |
| 45 | + |
| 46 | + // Expected sin values |
| 47 | + const float expected_sin[] = {0.0f, 0.5f, 0.707107f, 0.866025f, |
| 48 | + 1.0f, 0.0f, 0.0f}; |
| 49 | + |
| 50 | + // Expected cos values |
| 51 | + const float expected_cos[] = {1.0f, 0.866025f, 0.707107f, 0.5f, |
| 52 | + 0.0f, -1.0f, 1.0f}; |
| 53 | + |
| 54 | + // Test __nvvm_sin_approx_f |
| 55 | + for (size_t i = 0; i < sizeof(test_values) / sizeof(test_values[0]); ++i) { |
| 56 | + test_approx(q, __nvvm_sin_approx_f, "sin", test_values[i], expected_sin[i]); |
| 57 | + } |
| 58 | + |
| 59 | + // Test __nvvm_sin_approx_ftz_f |
| 60 | + for (size_t i = 0; i < sizeof(test_values) / sizeof(test_values[0]); ++i) { |
| 61 | + test_approx(q, __nvvm_sin_approx_ftz_f, "sin_ftz", test_values[i], |
| 62 | + expected_sin[i]); |
| 63 | + } |
| 64 | + |
| 65 | + // Test __nvvm_cos_approx_f |
| 66 | + for (size_t i = 0; i < sizeof(test_values) / sizeof(test_values[0]); ++i) { |
| 67 | + test_approx(q, __nvvm_cos_approx_f, "cos", test_values[i], expected_cos[i]); |
| 68 | + } |
| 69 | + |
| 70 | + // Test __nvvm_cos_approx_ftz_f |
| 71 | + for (size_t i = 0; i < sizeof(test_values) / sizeof(test_values[0]); ++i) { |
| 72 | + test_approx(q, __nvvm_cos_approx_ftz_f, "cos_ftz", test_values[i], |
| 73 | + expected_cos[i]); |
| 74 | + } |
| 75 | + |
| 76 | + return 0; |
| 77 | +} |
0 commit comments