1*bed243d3SAndroid Build Coastguard Worker/*===---- complex - CUDA wrapper for <complex> ------------------------------=== 2*bed243d3SAndroid Build Coastguard Worker * 3*bed243d3SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a copy 4*bed243d3SAndroid Build Coastguard Worker * of this software and associated documentation files (the "Software"), to deal 5*bed243d3SAndroid Build Coastguard Worker * in the Software without restriction, including without limitation the rights 6*bed243d3SAndroid Build Coastguard Worker * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7*bed243d3SAndroid Build Coastguard Worker * copies of the Software, and to permit persons to whom the Software is 8*bed243d3SAndroid Build Coastguard Worker * furnished to do so, subject to the following conditions: 9*bed243d3SAndroid Build Coastguard Worker * 10*bed243d3SAndroid Build Coastguard Worker * The above copyright notice and this permission notice shall be included in 11*bed243d3SAndroid Build Coastguard Worker * all copies or substantial portions of the Software. 12*bed243d3SAndroid Build Coastguard Worker * 13*bed243d3SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14*bed243d3SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15*bed243d3SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16*bed243d3SAndroid Build Coastguard Worker * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17*bed243d3SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18*bed243d3SAndroid Build Coastguard Worker * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19*bed243d3SAndroid Build Coastguard Worker * THE SOFTWARE. 20*bed243d3SAndroid Build Coastguard Worker * 21*bed243d3SAndroid Build Coastguard Worker *===-----------------------------------------------------------------------=== 22*bed243d3SAndroid Build Coastguard Worker */ 23*bed243d3SAndroid Build Coastguard Worker 24*bed243d3SAndroid Build Coastguard Worker#ifndef __CLANG_CUDA_WRAPPERS_COMPLEX 25*bed243d3SAndroid Build Coastguard Worker#define __CLANG_CUDA_WRAPPERS_COMPLEX 26*bed243d3SAndroid Build Coastguard Worker 27*bed243d3SAndroid Build Coastguard Worker// Wrapper around <complex> that forces its functions to be __host__ 28*bed243d3SAndroid Build Coastguard Worker// __device__. 29*bed243d3SAndroid Build Coastguard Worker 30*bed243d3SAndroid Build Coastguard Worker// First, include host-only headers we think are likely to be included by 31*bed243d3SAndroid Build Coastguard Worker// <complex>, so that the pragma below only applies to <complex> itself. 32*bed243d3SAndroid Build Coastguard Worker#if __cplusplus >= 201103L 33*bed243d3SAndroid Build Coastguard Worker#include <type_traits> 34*bed243d3SAndroid Build Coastguard Worker#endif 35*bed243d3SAndroid Build Coastguard Worker#include <stdexcept> 36*bed243d3SAndroid Build Coastguard Worker#include <cmath> 37*bed243d3SAndroid Build Coastguard Worker#include <sstream> 38*bed243d3SAndroid Build Coastguard Worker 39*bed243d3SAndroid Build Coastguard Worker// Next, include our <algorithm> wrapper, to ensure that device overloads of 40*bed243d3SAndroid Build Coastguard Worker// std::min/max are available. 41*bed243d3SAndroid Build Coastguard Worker#include <algorithm> 42*bed243d3SAndroid Build Coastguard Worker 43*bed243d3SAndroid Build Coastguard Worker#pragma clang force_cuda_host_device begin 44*bed243d3SAndroid Build Coastguard Worker 45*bed243d3SAndroid Build Coastguard Worker// When compiling for device, ask libstdc++ to use its own implements of 46*bed243d3SAndroid Build Coastguard Worker// complex functions, rather than calling builtins (which resolve to library 47*bed243d3SAndroid Build Coastguard Worker// functions that don't exist when compiling CUDA device code). 48*bed243d3SAndroid Build Coastguard Worker// 49*bed243d3SAndroid Build Coastguard Worker// This is a little dicey, because it causes libstdc++ to define a different 50*bed243d3SAndroid Build Coastguard Worker// set of overloads on host and device. 51*bed243d3SAndroid Build Coastguard Worker// 52*bed243d3SAndroid Build Coastguard Worker// // Present only when compiling for host. 53*bed243d3SAndroid Build Coastguard Worker// __host__ __device__ void complex<float> sin(const complex<float>& x) { 54*bed243d3SAndroid Build Coastguard Worker// return __builtin_csinf(x); 55*bed243d3SAndroid Build Coastguard Worker// } 56*bed243d3SAndroid Build Coastguard Worker// 57*bed243d3SAndroid Build Coastguard Worker// // Present when compiling for host and for device. 58*bed243d3SAndroid Build Coastguard Worker// template <typename T> 59*bed243d3SAndroid Build Coastguard Worker// void __host__ __device__ complex<T> sin(const complex<T>& x) { 60*bed243d3SAndroid Build Coastguard Worker// return complex<T>(sin(x.real()) * cosh(x.imag()), 61*bed243d3SAndroid Build Coastguard Worker// cos(x.real()), sinh(x.imag())); 62*bed243d3SAndroid Build Coastguard Worker// } 63*bed243d3SAndroid Build Coastguard Worker// 64*bed243d3SAndroid Build Coastguard Worker// This is safe because when compiling for device, all function calls in 65*bed243d3SAndroid Build Coastguard Worker// __host__ code to sin() will still resolve to *something*, even if they don't 66*bed243d3SAndroid Build Coastguard Worker// resolve to the same function as they resolve to when compiling for host. We 67*bed243d3SAndroid Build Coastguard Worker// don't care that they don't resolve to the right function because we won't 68*bed243d3SAndroid Build Coastguard Worker// codegen this host code when compiling for device. 69*bed243d3SAndroid Build Coastguard Worker 70*bed243d3SAndroid Build Coastguard Worker#pragma push_macro("_GLIBCXX_USE_C99_COMPLEX") 71*bed243d3SAndroid Build Coastguard Worker#pragma push_macro("_GLIBCXX_USE_C99_COMPLEX_TR1") 72*bed243d3SAndroid Build Coastguard Worker#define _GLIBCXX_USE_C99_COMPLEX 0 73*bed243d3SAndroid Build Coastguard Worker#define _GLIBCXX_USE_C99_COMPLEX_TR1 0 74*bed243d3SAndroid Build Coastguard Worker 75*bed243d3SAndroid Build Coastguard Worker// Work around a compatibility issue with libstdc++ 11.1.0 76*bed243d3SAndroid Build Coastguard Worker// https://bugs.llvm.org/show_bug.cgi?id=50383 77*bed243d3SAndroid Build Coastguard Worker#pragma push_macro("__failed_assertion") 78*bed243d3SAndroid Build Coastguard Worker#if _GLIBCXX_RELEASE == 11 79*bed243d3SAndroid Build Coastguard Worker#define __failed_assertion __cuda_failed_assertion 80*bed243d3SAndroid Build Coastguard Worker#endif 81*bed243d3SAndroid Build Coastguard Worker 82*bed243d3SAndroid Build Coastguard Worker#include_next <complex> 83*bed243d3SAndroid Build Coastguard Worker 84*bed243d3SAndroid Build Coastguard Worker#pragma pop_macro("__failed_assertion") 85*bed243d3SAndroid Build Coastguard Worker#pragma pop_macro("_GLIBCXX_USE_C99_COMPLEX_TR1") 86*bed243d3SAndroid Build Coastguard Worker#pragma pop_macro("_GLIBCXX_USE_C99_COMPLEX") 87*bed243d3SAndroid Build Coastguard Worker 88*bed243d3SAndroid Build Coastguard Worker#pragma clang force_cuda_host_device end 89*bed243d3SAndroid Build Coastguard Worker 90*bed243d3SAndroid Build Coastguard Worker#endif // include guard 91