Clang Project

clang_source_code/lib/Headers/__clang_cuda_cmath.h
1/*===---- __clang_cuda_cmath.h - Device-side CUDA cmath support ------------===
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a copy
4 * of this software and associated documentation files (the "Software"), to deal
5 * in the Software without restriction, including without limitation the rights
6 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 * copies of the Software, and to permit persons to whom the Software is
8 * furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 * THE SOFTWARE.
20 *
21 *===-----------------------------------------------------------------------===
22 */
23#ifndef __CLANG_CUDA_CMATH_H__
24#define __CLANG_CUDA_CMATH_H__
25#ifndef __CUDA__
26#error "This file is for CUDA compilation only."
27#endif
28
29#include <limits>
30
31// CUDA lets us use various std math functions on the device side.  This file
32// works in concert with __clang_cuda_math_forward_declares.h to make this work.
33//
34// Specifically, the forward-declares header declares __device__ overloads for
35// these functions in the global namespace, then pulls them into namespace std
36// with 'using' statements.  Then this file implements those functions, after
37// their implementations have been pulled in.
38//
39// It's important that we declare the functions in the global namespace and pull
40// them into namespace std with using statements, as opposed to simply declaring
41// these functions in namespace std, because our device functions need to
42// overload the standard library functions, which may be declared in the global
43// namespace or in std, depending on the degree of conformance of the stdlib
44// implementation.  Declaring in the global namespace and pulling into namespace
45// std covers all of the known knowns.
46
47#define __DEVICE__ static __device__ __inline__ __attribute__((always_inline))
48
49__DEVICE__ long long abs(long long __n) { return ::llabs(__n); }
50__DEVICE__ long abs(long __n) { return ::labs(__n); }
51__DEVICE__ float abs(float __x) { return ::fabsf(__x); }
52__DEVICE__ double abs(double __x) { return ::fabs(__x); }
53__DEVICE__ float acos(float __x) { return ::acosf(__x); }
54__DEVICE__ float asin(float __x) { return ::asinf(__x); }
55__DEVICE__ float atan(float __x) { return ::atanf(__x); }
56__DEVICE__ float atan2(float __x, float __y) { return ::atan2f(__x, __y); }
57__DEVICE__ float ceil(float __x) { return ::ceilf(__x); }
58__DEVICE__ float cos(float __x) { return ::cosf(__x); }
59__DEVICE__ float cosh(float __x) { return ::coshf(__x); }
60__DEVICE__ float exp(float __x) { return ::expf(__x); }
61__DEVICE__ float fabs(float __x) { return ::fabsf(__x); }
62__DEVICE__ float floor(float __x) { return ::floorf(__x); }
63__DEVICE__ float fmod(float __x, float __y) { return ::fmodf(__x, __y); }
64__DEVICE__ int fpclassify(float __x) {
65  return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
66                              FP_ZERO, __x);
67}
68__DEVICE__ int fpclassify(double __x) {
69  return __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_NORMAL, FP_SUBNORMAL,
70                              FP_ZERO, __x);
71}
72__DEVICE__ float frexp(float __arg, int *__exp) {
73  return ::frexpf(__arg, __exp);
74}
75
76// For inscrutable reasons, the CUDA headers define these functions for us on
77// Windows.
78#ifndef _MSC_VER
79__DEVICE__ bool isinf(float __x) { return ::__isinff(__x); }
80__DEVICE__ bool isinf(double __x) { return ::__isinf(__x); }
81__DEVICE__ bool isfinite(float __x) { return ::__finitef(__x); }
82// For inscrutable reasons, __finite(), the double-precision version of
83// __finitef, does not exist when compiling for MacOS.  __isfinited is available
84// everywhere and is just as good.
85__DEVICE__ bool isfinite(double __x) { return ::__isfinited(__x); }
86__DEVICE__ bool isnan(float __x) { return ::__isnanf(__x); }
87__DEVICE__ bool isnan(double __x) { return ::__isnan(__x); }
88#endif
89
90__DEVICE__ bool isgreater(float __x, float __y) {
91  return __builtin_isgreater(__x, __y);
92}
93__DEVICE__ bool isgreater(double __x, double __y) {
94  return __builtin_isgreater(__x, __y);
95}
96__DEVICE__ bool isgreaterequal(float __x, float __y) {
97  return __builtin_isgreaterequal(__x, __y);
98}
99__DEVICE__ bool isgreaterequal(double __x, double __y) {
100  return __builtin_isgreaterequal(__x, __y);
101}
102__DEVICE__ bool isless(float __x, float __y) {
103  return __builtin_isless(__x, __y);
104}
105__DEVICE__ bool isless(double __x, double __y) {
106  return __builtin_isless(__x, __y);
107}
108__DEVICE__ bool islessequal(float __x, float __y) {
109  return __builtin_islessequal(__x, __y);
110}
111__DEVICE__ bool islessequal(double __x, double __y) {
112  return __builtin_islessequal(__x, __y);
113}
114__DEVICE__ bool islessgreater(float __x, float __y) {
115  return __builtin_islessgreater(__x, __y);
116}
117__DEVICE__ bool islessgreater(double __x, double __y) {
118  return __builtin_islessgreater(__x, __y);
119}
120__DEVICE__ bool isnormal(float __x) { return __builtin_isnormal(__x); }
121__DEVICE__ bool isnormal(double __x) { return __builtin_isnormal(__x); }
122__DEVICE__ bool isunordered(float __x, float __y) {
123  return __builtin_isunordered(__x, __y);
124}
125__DEVICE__ bool isunordered(double __x, double __y) {
126  return __builtin_isunordered(__x, __y);
127}
128__DEVICE__ float ldexp(float __arg, int __exp) {
129  return ::ldexpf(__arg, __exp);
130}
131__DEVICE__ float log(float __x) { return ::logf(__x); }
132__DEVICE__ float log10(float __x) { return ::log10f(__x); }
133__DEVICE__ float modf(float __x, float *__iptr) { return ::modff(__x, __iptr); }
134__DEVICE__ float pow(float __base, float __exp) {
135  return ::powf(__base, __exp);
136}
137__DEVICE__ float pow(float __base, int __iexp) {
138  return ::powif(__base, __iexp);
139}
140__DEVICE__ double pow(double __base, int __iexp) {
141  return ::powi(__base, __iexp);
142}
143__DEVICE__ bool signbit(float __x) { return ::__signbitf(__x); }
144__DEVICE__ bool signbit(double __x) { return ::__signbitd(__x); }
145__DEVICE__ float sin(float __x) { return ::sinf(__x); }
146__DEVICE__ float sinh(float __x) { return ::sinhf(__x); }
147__DEVICE__ float sqrt(float __x) { return ::sqrtf(__x); }
148__DEVICE__ float tan(float __x) { return ::tanf(__x); }
149__DEVICE__ float tanh(float __x) { return ::tanhf(__x); }
150
151// Notably missing above is nexttoward.  We omit it because
152// libdevice doesn't provide an implementation, and we don't want to be in the
153// business of implementing tricky libm functions in this header.
154
155// Now we've defined everything we promised we'd define in
156// __clang_cuda_math_forward_declares.h.  We need to do two additional things to
157// fix up our math functions.
158//
159// 1) Define __device__ overloads for e.g. sin(int).  The CUDA headers define
160//    only sin(float) and sin(double), which means that e.g. sin(0) is
161//    ambiguous.
162//
163// 2) Pull the __device__ overloads of "foobarf" math functions into namespace
164//    std.  These are defined in the CUDA headers in the global namespace,
165//    independent of everything else we've done here.
166
167// We can't use std::enable_if, because we want to be pre-C++11 compatible.  But
168// we go ahead and unconditionally define functions that are only available when
169// compiling for C++11 to match the behavior of the CUDA headers.
170template<bool __B, class __T = void>
171struct __clang_cuda_enable_if {};
172
173template <class __T> struct __clang_cuda_enable_if<true, __T> {
174  typedef __T type;
175};
176
177// Defines an overload of __fn that accepts one integral argument, calls
178// __fn((double)x), and returns __retty.
179#define __CUDA_CLANG_FN_INTEGER_OVERLOAD_1(__retty, __fn)                      \
180  template <typename __T>                                                      \
181  __DEVICE__                                                                   \
182      typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,    \
183                                      __retty>::type                           \
184      __fn(__T __x) {                                                          \
185    return ::__fn((double)__x);                                                \
186  }
187
188// Defines an overload of __fn that accepts one two arithmetic arguments, calls
189// __fn((double)x, (double)y), and returns a double.
190//
191// Note this is different from OVERLOAD_1, which generates an overload that
192// accepts only *integral* arguments.
193#define __CUDA_CLANG_FN_INTEGER_OVERLOAD_2(__retty, __fn)                      \
194  template <typename __T1, typename __T2>                                      \
195  __DEVICE__ typename __clang_cuda_enable_if<                                  \
196      std::numeric_limits<__T1>::is_specialized &&                             \
197          std::numeric_limits<__T2>::is_specialized,                           \
198      __retty>::type                                                           \
199  __fn(__T1 __x, __T2 __y) {                                                   \
200    return __fn((double)__x, (double)__y);                                     \
201  }
202
203__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, acos)
204__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, acosh)
205__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, asin)
206__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, asinh)
207__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, atan)
208__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, atan2);
209__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, atanh)
210__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cbrt)
211__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, ceil)
212__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, copysign);
213__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cos)
214__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, cosh)
215__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, erf)
216__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, erfc)
217__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, exp)
218__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, exp2)
219__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, expm1)
220__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, fabs)
221__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fdim);
222__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, floor)
223__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmax);
224__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmin);
225__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, fmod);
226__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(int, fpclassify)
227__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, hypot);
228__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(int, ilogb)
229__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isfinite)
230__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isgreater);
231__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isgreaterequal);
232__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isinf);
233__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isless);
234__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, islessequal);
235__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, islessgreater);
236__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isnan);
237__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, isnormal)
238__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(bool, isunordered);
239__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, lgamma)
240__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log)
241__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log10)
242__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log1p)
243__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, log2)
244__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, logb)
245__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long long, llrint)
246__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long long, llround)
247__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long, lrint)
248__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(long, lround)
249__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, nearbyint);
250__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, nextafter);
251__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, pow);
252__CUDA_CLANG_FN_INTEGER_OVERLOAD_2(double, remainder);
253__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, rint);
254__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, round);
255__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(bool, signbit)
256__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sin)
257__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sinh)
258__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, sqrt)
259__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tan)
260__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tanh)
261__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, tgamma)
262__CUDA_CLANG_FN_INTEGER_OVERLOAD_1(double, trunc);
263
264#undef __CUDA_CLANG_FN_INTEGER_OVERLOAD_1
265#undef __CUDA_CLANG_FN_INTEGER_OVERLOAD_2
266
267// Overloads for functions that don't match the patterns expected by
268// __CUDA_CLANG_FN_INTEGER_OVERLOAD_{1,2}.
269template <typename __T1, typename __T2, typename __T3>
270__DEVICE__ typename __clang_cuda_enable_if<
271    std::numeric_limits<__T1>::is_specialized &&
272        std::numeric_limits<__T2>::is_specialized &&
273        std::numeric_limits<__T3>::is_specialized,
274    double>::type
275fma(__T1 __x, __T2 __y, __T3 __z) {
276  return std::fma((double)__x, (double)__y, (double)__z);
277}
278
279template <typename __T>
280__DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
281                                           double>::type
282frexp(__T __x, int *__exp) {
283  return std::frexp((double)__x, __exp);
284}
285
286template <typename __T>
287__DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
288                                           double>::type
289ldexp(__T __x, int __exp) {
290  return std::ldexp((double)__x, __exp);
291}
292
293template <typename __T1, typename __T2>
294__DEVICE__ typename __clang_cuda_enable_if<
295    std::numeric_limits<__T1>::is_specialized &&
296        std::numeric_limits<__T2>::is_specialized,
297    double>::type
298remquo(__T1 __x, __T2 __y, int *__quo) {
299  return std::remquo((double)__x, (double)__y, __quo);
300}
301
302template <typename __T>
303__DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
304                                           double>::type
305scalbln(__T __x, long __exp) {
306  return std::scalbln((double)__x, __exp);
307}
308
309template <typename __T>
310__DEVICE__ typename __clang_cuda_enable_if<std::numeric_limits<__T>::is_integer,
311                                           double>::type
312scalbn(__T __x, int __exp) {
313  return std::scalbn((double)__x, __exp);
314}
315
316// We need to define these overloads in exactly the namespace our standard
317// library uses (including the right inline namespace), otherwise they won't be
318// picked up by other functions in the standard library (e.g. functions in
319// <complex>).  Thus the ugliness below.
320#ifdef _LIBCPP_BEGIN_NAMESPACE_STD
321_LIBCPP_BEGIN_NAMESPACE_STD
322#else
323namespace std {
324#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
325_GLIBCXX_BEGIN_NAMESPACE_VERSION
326#endif
327#endif
328
329// Pull the new overloads we defined above into namespace std.
330using ::acos;
331using ::acosh;
332using ::asin;
333using ::asinh;
334using ::atan;
335using ::atan2;
336using ::atanh;
337using ::cbrt;
338using ::ceil;
339using ::copysign;
340using ::cos;
341using ::cosh;
342using ::erf;
343using ::erfc;
344using ::exp;
345using ::exp2;
346using ::expm1;
347using ::fabs;
348using ::fdim;
349using ::floor;
350using ::fma;
351using ::fmax;
352using ::fmin;
353using ::fmod;
354using ::fpclassify;
355using ::frexp;
356using ::hypot;
357using ::ilogb;
358using ::isfinite;
359using ::isgreater;
360using ::isgreaterequal;
361using ::isless;
362using ::islessequal;
363using ::islessgreater;
364using ::isnormal;
365using ::isunordered;
366using ::ldexp;
367using ::lgamma;
368using ::llrint;
369using ::llround;
370using ::log;
371using ::log10;
372using ::log1p;
373using ::log2;
374using ::logb;
375using ::lrint;
376using ::lround;
377using ::nearbyint;
378using ::nextafter;
379using ::pow;
380using ::remainder;
381using ::remquo;
382using ::rint;
383using ::round;
384using ::scalbln;
385using ::scalbn;
386using ::signbit;
387using ::sin;
388using ::sinh;
389using ::sqrt;
390using ::tan;
391using ::tanh;
392using ::tgamma;
393using ::trunc;
394
395// Well this is fun: We need to pull these symbols in for libc++, but we can't
396// pull them in with libstdc++, because its ::isinf and ::isnan are different
397// than its std::isinf and std::isnan.
398#ifndef __GLIBCXX__
399using ::isinf;
400using ::isnan;
401#endif
402
403// Finally, pull the "foobarf" functions that CUDA defines in its headers into
404// namespace std.
405using ::acosf;
406using ::acoshf;
407using ::asinf;
408using ::asinhf;
409using ::atan2f;
410using ::atanf;
411using ::atanhf;
412using ::cbrtf;
413using ::ceilf;
414using ::copysignf;
415using ::cosf;
416using ::coshf;
417using ::erfcf;
418using ::erff;
419using ::exp2f;
420using ::expf;
421using ::expm1f;
422using ::fabsf;
423using ::fdimf;
424using ::floorf;
425using ::fmaf;
426using ::fmaxf;
427using ::fminf;
428using ::fmodf;
429using ::frexpf;
430using ::hypotf;
431using ::ilogbf;
432using ::ldexpf;
433using ::lgammaf;
434using ::llrintf;
435using ::llroundf;
436using ::log10f;
437using ::log1pf;
438using ::log2f;
439using ::logbf;
440using ::logf;
441using ::lrintf;
442using ::lroundf;
443using ::modff;
444using ::nearbyintf;
445using ::nextafterf;
446using ::powf;
447using ::remainderf;
448using ::remquof;
449using ::rintf;
450using ::roundf;
451using ::scalblnf;
452using ::scalbnf;
453using ::sinf;
454using ::sinhf;
455using ::sqrtf;
456using ::tanf;
457using ::tanhf;
458using ::tgammaf;
459using ::truncf;
460
461#ifdef _LIBCPP_END_NAMESPACE_STD
462_LIBCPP_END_NAMESPACE_STD
463#else
464#ifdef _GLIBCXX_BEGIN_NAMESPACE_VERSION
465_GLIBCXX_END_NAMESPACE_VERSION
466#endif
467// namespace std
468#endif
469
470#undef __DEVICE__
471
472#endif
473