diff --git a/sycl/include/sycl/ext/intel/esimd/math.hpp b/sycl/include/sycl/ext/intel/esimd/math.hpp index 40e20d3ec17ab..6f0188111e534 100644 --- a/sycl/include/sycl/ext/intel/esimd/math.hpp +++ b/sycl/include/sycl/ext/intel/esimd/math.hpp @@ -98,9 +98,12 @@ template ESIMD_NODEBUG ESIMD_INLINE simd __esimd_abs_common_internal(simd src0) { simd Result; - if constexpr (detail::is_generic_floating_point_v) - Result = simd(__spirv_ocl_fabs(src0.data())); - else + if constexpr (detail::is_generic_floating_point_v) { + using CppT = __ESIMD_DNS::element_type_traits::EnclosingCppT; + Result = + __ESIMD_DNS::convert_vector(__spirv_ocl_fabs( + __ESIMD_DNS::convert_vector(src0.data()))); + } else Result = simd(__spirv_ocl_s_abs(src0.data())); return convert(Result); } @@ -184,8 +187,12 @@ template __ESIMD_API simd(max)(simd src0, simd src1, Sat sat = {}) { constexpr bool is_sat = std::is_same_v; - if constexpr (std::is_floating_point::value) { - auto Result = __spirv_ocl_fmax(src0.data(), src1.data()); + if constexpr (detail::is_generic_floating_point_v) { + using CppT = __ESIMD_DNS::element_type_traits::EnclosingCppT; + auto Result = + __ESIMD_DNS::convert_vector(__spirv_ocl_fmax( + __ESIMD_DNS::convert_vector(src0.data()), + __ESIMD_DNS::convert_vector(src1.data()))); if constexpr (is_sat) Result = __esimd_sat(Result); return simd(Result); @@ -269,8 +276,12 @@ template __ESIMD_API simd(min)(simd src0, simd src1, Sat sat = {}) { constexpr bool is_sat = std::is_same_v; - if constexpr (std::is_floating_point::value) { - auto Result = __spirv_ocl_fmin(src0.data(), src1.data()); + if constexpr (detail::is_generic_floating_point_v) { + using CppT = __ESIMD_DNS::element_type_traits::EnclosingCppT; + auto Result = + __ESIMD_DNS::convert_vector(__spirv_ocl_fmin( + __ESIMD_DNS::convert_vector(src0.data()), + __ESIMD_DNS::convert_vector(src1.data()))); if constexpr (is_sat) Result = __esimd_sat(Result); return simd(Result); @@ -1465,8 +1476,12 @@ template struct esimd_apply_prod { template struct esimd_apply_reduced_max { template simd operator()(simd v1, simd v2) { - if constexpr (std::is_floating_point::value) { - return __spirv_ocl_fmax(v1.data(), v2.data()); + if constexpr (detail::is_generic_floating_point_v) { + using CppT = __ESIMD_DNS::element_type_traits::EnclosingCppT; + return __ESIMD_DNS::convert_vector( + __spirv_ocl_fmax( + __ESIMD_DNS::convert_vector(v1.data()), + __ESIMD_DNS::convert_vector(v2.data()))); } else if constexpr (std::is_unsigned::value) { return __esimd_umax(v1.data(), v2.data()); } else { @@ -1478,8 +1493,13 @@ template struct esimd_apply_reduced_max { template struct esimd_apply_reduced_min { template simd operator()(simd v1, simd v2) { - if constexpr (std::is_floating_point::value) { - return __spirv_ocl_fmin(v1.data(), v2.data()); + + if constexpr (detail::is_generic_floating_point_v) { + using CppT = __ESIMD_DNS::element_type_traits::EnclosingCppT; + return __ESIMD_DNS::convert_vector( + __spirv_ocl_fmin( + __ESIMD_DNS::convert_vector(v1.data()), + __ESIMD_DNS::convert_vector(v2.data()))); } else if constexpr (std::is_unsigned::value) { return __esimd_umin(v1.data(), v2.data()); } else { diff --git a/sycl/test-e2e/ESIMD/spirv_fp_test.cpp b/sycl/test-e2e/ESIMD/spirv_fp_test.cpp new file mode 100644 index 0000000000000..9b71768a665c5 --- /dev/null +++ b/sycl/test-e2e/ESIMD/spirv_fp_test.cpp @@ -0,0 +1,92 @@ +//==- spirv_fp_test.cpp - Test for abs function -==// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// REQUIRES: arch-intel_gpu_pvc +// RUN: %{build} -o %t.out +// RUN: %{run} %t.out + +#include +#include + +#include +#include + +using namespace sycl; +using namespace sycl::ext::intel::esimd; +using bf16 = sycl::ext::oneapi::bfloat16; +using tfloat32 = sycl::ext::intel::experimental::esimd::tfloat32; + +template +using shared_allocator = sycl::usm_allocator; +template +using shared_vector = std::vector>; + +template +bool test(sycl::queue &Queue, T testValue1, T testValue2) { + shared_allocator Allocator(Queue); + + shared_vector OutputAbs(N, 0, Allocator); + shared_vector OutputMin(N, 0, Allocator); + shared_vector OutputMax(N, 0, Allocator); + + auto *OutputAbsPtr = OutputAbs.data(); + auto *OutputMinPtr = OutputMin.data(); + auto *OutputMaxPtr = OutputMax.data(); + + Queue.submit([&](sycl::handler &cgh) { + auto Kernel = ([=]() SYCL_ESIMD_KERNEL { + simd Input1 = testValue1; + simd Input2 = testValue2; + simd ResultAbs = __ESIMD_NS::abs(Input1); + simd ResultMin = __ESIMD_NS::min(Input1, Input2); + simd ResultMax = __ESIMD_NS::max(Input1, Input2); + ResultAbs.copy_to(OutputAbsPtr); + ResultMin.copy_to(OutputMinPtr); + ResultMax.copy_to(OutputMaxPtr); + }); + cgh.single_task(Kernel); + }); + Queue.wait(); + + for (int I = 0; I < N; I++) { + if (std::abs(testValue1) != OutputAbs[I]) { + std::cout << "Incorrect value for abs at index " << I << " " + << std::abs(testValue1) << " != " << OutputAbs[I] << std::endl; + return false; + } + if (std::min(testValue1, testValue2) != OutputMin[I]) { + std::cout << "Incorrect value for min at index " << I << " " + << std::min(testValue1, testValue2) << " != " << OutputMin[I] + << std::endl; + return false; + } + + if (std::max(testValue1, testValue2) != OutputMax[I]) { + std::cout << "Incorrect value for max at index " << I << " " + << std::max(testValue1, testValue2) << " != " << OutputMax[I] + << std::endl; + return false; + } + } + + return true; +} + +int main() { + + bool Pass = true; + sycl::queue Q; + Pass &= test(Q, -1, -2); + Pass &= test(Q, -1, -2); + + if (Pass) + std::cout << "Pass" << std::endl; + else + std::cout << "Fail" << std::endl; + + return !Pass; +}