|
| 1 | +//==----------- builtins_common.cpp - SYCL built-in common functions -------==// |
| 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 | + |
| 9 | +// This file defines the host versions of functions defined |
| 10 | +// in SYCL SPEC section - 4.13.5 Common functions. |
| 11 | + |
| 12 | +// Define _USE_MATH_DEFINES to enforce math defines of macros like M_PI in |
| 13 | +// <cmath>. _USE_MATH_DEFINES is defined here before includes of SYCL header |
| 14 | +// files to avoid include of <cmath> via those SYCL headers with unset |
| 15 | +// _USE_MATH_DEFINES. |
| 16 | +#define _USE_MATH_DEFINES |
| 17 | + |
| 18 | +#include "builtins_helper.hpp" |
| 19 | + |
| 20 | +#include <cmath> |
| 21 | + |
| 22 | +namespace s = cl::sycl; |
| 23 | +namespace d = s::detail; |
| 24 | + |
| 25 | +namespace cl { |
| 26 | +namespace __host_std { |
| 27 | +namespace { |
| 28 | + |
| 29 | +template <typename T> inline T __fclamp(T x, T minval, T maxval) { |
| 30 | + return std::fmin(std::fmax(x, minval), maxval); |
| 31 | +} |
| 32 | + |
| 33 | +template <typename T> inline T __degrees(T radians) { |
| 34 | + return (180 / M_PI) * radians; |
| 35 | +} |
| 36 | + |
| 37 | +template <typename T> inline T __mix(T x, T y, T a) { return x + (y - x) * a; } |
| 38 | + |
| 39 | +template <typename T> inline T __radians(T degrees) { |
| 40 | + return (M_PI / 180) * degrees; |
| 41 | +} |
| 42 | + |
| 43 | +template <typename T> inline T __step(T edge, T x) { |
| 44 | + return (x < edge) ? 0.0 : 1.0; |
| 45 | +} |
| 46 | + |
| 47 | +template <typename T> inline T __smoothstep(T edge0, T edge1, T x) { |
| 48 | + T t; |
| 49 | + T v = (x - edge0) / (edge1 - edge0); |
| 50 | + t = __fclamp(v, T(0), T(1)); |
| 51 | + return t * t * (3 - 2 * t); |
| 52 | +} |
| 53 | + |
| 54 | +template <typename T> inline T __sign(T x) { |
| 55 | + if (std::isnan(x)) |
| 56 | + return T(0.0); |
| 57 | + if (x > 0) |
| 58 | + return T(1.0); |
| 59 | + if (x < 0) |
| 60 | + return T(-1.0); |
| 61 | + /* x is +0.0 or -0.0 */ |
| 62 | + return x; |
| 63 | +} |
| 64 | + |
| 65 | +} // namespace |
| 66 | + |
| 67 | +// --------------- 4.13.5 Common functions. Host implementations --------------- |
| 68 | +// fclamp |
| 69 | +cl_float fclamp(s::cl_float x, s::cl_float minval, s::cl_float maxval) __NOEXC { |
| 70 | + return __fclamp(x, minval, maxval); |
| 71 | +} |
| 72 | +cl_double fclamp(s::cl_double x, s::cl_double minval, |
| 73 | + s::cl_double maxval) __NOEXC { |
| 74 | + return __fclamp(x, minval, maxval); |
| 75 | +} |
| 76 | +cl_half fclamp(s::cl_half x, s::cl_half minval, s::cl_half maxval) __NOEXC { |
| 77 | + return __fclamp(x, minval, maxval); |
| 78 | +} |
| 79 | +MAKE_1V_2V_3V(fclamp, s::cl_float, s::cl_float, s::cl_float, s::cl_float) |
| 80 | +MAKE_1V_2V_3V(fclamp, s::cl_double, s::cl_double, s::cl_double, s::cl_double) |
| 81 | +MAKE_1V_2V_3V(fclamp, s::cl_half, s::cl_half, s::cl_half, s::cl_half) |
| 82 | + |
| 83 | +// degrees |
| 84 | +cl_float degrees(s::cl_float radians) __NOEXC { return __degrees(radians); } |
| 85 | +cl_double degrees(s::cl_double radians) __NOEXC { return __degrees(radians); } |
| 86 | +cl_half degrees(s::cl_half radians) __NOEXC { return __degrees(radians); } |
| 87 | +MAKE_1V(degrees, s::cl_float, s::cl_float) |
| 88 | +MAKE_1V(degrees, s::cl_double, s::cl_double) |
| 89 | +MAKE_1V(degrees, s::cl_half, s::cl_half) |
| 90 | + |
| 91 | +// fmin_common |
| 92 | +cl_float fmin_common(s::cl_float x, s::cl_float y) __NOEXC { |
| 93 | + return std::fmin(x, y); |
| 94 | +} |
| 95 | +cl_double fmin_common(s::cl_double x, s::cl_double y) __NOEXC { |
| 96 | + return std::fmin(x, y); |
| 97 | +} |
| 98 | +cl_half fmin_common(s::cl_half x, s::cl_half y) __NOEXC { |
| 99 | + return std::fmin(x, y); |
| 100 | +} |
| 101 | +MAKE_1V_2V(fmin_common, s::cl_float, s::cl_float, s::cl_float) |
| 102 | +MAKE_1V_2V(fmin_common, s::cl_double, s::cl_double, s::cl_double) |
| 103 | +MAKE_1V_2V(fmin_common, s::cl_half, s::cl_half, s::cl_half) |
| 104 | + |
| 105 | +// fmax_common |
| 106 | +cl_float fmax_common(s::cl_float x, s::cl_float y) __NOEXC { |
| 107 | + return std::fmax(x, y); |
| 108 | +} |
| 109 | +cl_double fmax_common(s::cl_double x, s::cl_double y) __NOEXC { |
| 110 | + return std::fmax(x, y); |
| 111 | +} |
| 112 | +cl_half fmax_common(s::cl_half x, s::cl_half y) __NOEXC { |
| 113 | + return std::fmax(x, y); |
| 114 | +} |
| 115 | +MAKE_1V_2V(fmax_common, s::cl_float, s::cl_float, s::cl_float) |
| 116 | +MAKE_1V_2V(fmax_common, s::cl_double, s::cl_double, s::cl_double) |
| 117 | +MAKE_1V_2V(fmax_common, s::cl_half, s::cl_half, s::cl_half) |
| 118 | + |
| 119 | +// mix |
| 120 | +cl_float mix(s::cl_float x, s::cl_float y, s::cl_float a) __NOEXC { |
| 121 | + return __mix(x, y, a); |
| 122 | +} |
| 123 | +cl_double mix(s::cl_double x, s::cl_double y, s::cl_double a) __NOEXC { |
| 124 | + return __mix(x, y, a); |
| 125 | +} |
| 126 | +cl_half mix(s::cl_half x, s::cl_half y, s::cl_half a) __NOEXC { |
| 127 | + return __mix(x, y, a); |
| 128 | +} |
| 129 | +MAKE_1V_2V_3V(mix, s::cl_float, s::cl_float, s::cl_float, s::cl_float) |
| 130 | +MAKE_1V_2V_3V(mix, s::cl_double, s::cl_double, s::cl_double, s::cl_double) |
| 131 | +MAKE_1V_2V_3V(mix, s::cl_half, s::cl_half, s::cl_half, s::cl_half) |
| 132 | + |
| 133 | +// radians |
| 134 | +cl_float radians(s::cl_float degrees) __NOEXC { return __radians(degrees); } |
| 135 | +cl_double radians(s::cl_double degrees) __NOEXC { return __radians(degrees); } |
| 136 | +cl_half radians(s::cl_half degrees) __NOEXC { return __radians(degrees); } |
| 137 | +MAKE_1V(radians, s::cl_float, s::cl_float) |
| 138 | +MAKE_1V(radians, s::cl_double, s::cl_double) |
| 139 | +MAKE_1V(radians, s::cl_half, s::cl_half) |
| 140 | + |
| 141 | +// step |
| 142 | +cl_float step(s::cl_float edge, s::cl_float x) __NOEXC { |
| 143 | + return __step(edge, x); |
| 144 | +} |
| 145 | +cl_double step(s::cl_double edge, s::cl_double x) __NOEXC { |
| 146 | + return __step(edge, x); |
| 147 | +} |
| 148 | +cl_half step(s::cl_half edge, s::cl_half x) __NOEXC { return __step(edge, x); } |
| 149 | +MAKE_1V_2V(step, s::cl_float, s::cl_float, s::cl_float) |
| 150 | +MAKE_1V_2V(step, s::cl_double, s::cl_double, s::cl_double) |
| 151 | +MAKE_1V_2V(step, s::cl_half, s::cl_half, s::cl_half) |
| 152 | + |
| 153 | +// smoothstep |
| 154 | +cl_float smoothstep(s::cl_float edge0, s::cl_float edge1, |
| 155 | + s::cl_float x) __NOEXC { |
| 156 | + return __smoothstep(edge0, edge1, x); |
| 157 | +} |
| 158 | +cl_double smoothstep(s::cl_double edge0, s::cl_double edge1, |
| 159 | + s::cl_double x) __NOEXC { |
| 160 | + return __smoothstep(edge0, edge1, x); |
| 161 | +} |
| 162 | +cl_half smoothstep(s::cl_half edge0, s::cl_half edge1, s::cl_half x) __NOEXC { |
| 163 | + return __smoothstep(edge0, edge1, x); |
| 164 | +} |
| 165 | +MAKE_1V_2V_3V(smoothstep, s::cl_float, s::cl_float, s::cl_float, s::cl_float) |
| 166 | +MAKE_1V_2V_3V(smoothstep, s::cl_double, s::cl_double, s::cl_double, |
| 167 | + s::cl_double) |
| 168 | +MAKE_1V_2V_3V(smoothstep, s::cl_half, s::cl_half, s::cl_half, s::cl_half) |
| 169 | + |
| 170 | +// sign |
| 171 | +cl_float sign(s::cl_float x) __NOEXC { return __sign(x); } |
| 172 | +cl_double sign(s::cl_double x) __NOEXC { return __sign(x); } |
| 173 | +cl_half sign(s::cl_half x) __NOEXC { return __sign(x); } |
| 174 | +MAKE_1V(sign, s::cl_float, s::cl_float) |
| 175 | +MAKE_1V(sign, s::cl_double, s::cl_double) |
| 176 | +MAKE_1V(sign, s::cl_half, s::cl_half) |
| 177 | + |
| 178 | +} // namespace __host_std |
| 179 | +} // namespace cl |
0 commit comments