Skip to content

Commit 830916a

Browse files
authored
[SYCL] Add sycl cpp header for imf libdevice API (#6487)
We added some imf(intel math) APIs in libdevice: #5999, #6327, those APIs are C interface which means we don't expect users to call them directly in SYCL kernel since SYCL programming uses cpp. This PR will provide cpp wrapper for those imf APIs which users can call directly in source, the approach is similar to STL , std math functions will call corresponding C math functions or compiler math builtins. The user scenario should be following: cpp #include <sycl/ext/intel/math.hpp> ... float x, y, z; z = sycl::ext::intel::math::copysign(x, y); ... ``
1 parent e4423ef commit 830916a

File tree

1 file changed

+68
-0
lines changed

1 file changed

+68
-0
lines changed

sycl/include/sycl/ext/intel/math.hpp

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//==------------- math.hpp - Intel specific math API -----------------------==//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
// The main header of Intel specific math API
9+
//===----------------------------------------------------------------------===//
10+
11+
#pragma once
12+
#include <sycl/half_type.hpp>
13+
#include <type_traits>
14+
15+
// _iml_half_internal is internal representation for fp16 type used in intel
16+
// math device library. The definition here should align with definition in
17+
// https://github.com/intel/llvm/blob/sycl/libdevice/imf_half.hpp
18+
#if defined(__SPIR__)
19+
using _iml_half_internal = _Float16;
20+
#else
21+
using _iml_half_internal = uint16_t;
22+
#endif
23+
24+
extern "C" {
25+
float __imf_saturatef(float);
26+
float __imf_copysignf(float, float);
27+
double __imf_copysign(double, double);
28+
_iml_half_internal __imf_copysignf16(_iml_half_internal, _iml_half_internal);
29+
};
30+
31+
namespace sycl {
32+
__SYCL_INLINE_VER_NAMESPACE(_V1) {
33+
namespace ext {
34+
namespace intel {
35+
namespace math {
36+
37+
#if __cplusplus >= 201703L
38+
template <typename Tp>
39+
std::enable_if_t<std::is_same_v<Tp, float>, float> saturate(Tp x) {
40+
return __imf_saturatef(x);
41+
}
42+
43+
template <typename Tp>
44+
std::enable_if_t<std::is_same_v<Tp, float>, float> copysign(Tp x, Tp y) {
45+
return __imf_copysignf(x, y);
46+
}
47+
48+
template <typename Tp>
49+
std::enable_if_t<std::is_same_v<Tp, double>, double> copysign(Tp x, Tp y) {
50+
return __imf_copysign(x, y);
51+
}
52+
53+
template <typename Tp>
54+
std::enable_if_t<std::is_same_v<Tp, sycl::half>, sycl::half> copysign(Tp x,
55+
Tp y) {
56+
static_assert(sizeof(sycl::half) == sizeof(_iml_half_internal),
57+
"sycl::half is not compatible with _iml_half_internal.");
58+
_iml_half_internal xi = __builtin_bit_cast(_iml_half_internal, x);
59+
_iml_half_internal yi = __builtin_bit_cast(_iml_half_internal, y);
60+
return __builtin_bit_cast(sycl::half, __imf_copysignf16(xi, yi));
61+
}
62+
63+
#endif
64+
} // namespace math
65+
} // namespace intel
66+
} // namespace ext
67+
} // __SYCL_INLINE_VER_NAMESPACE(_V1)
68+
} // namespace sycl

0 commit comments

Comments
 (0)