1// This file is part of Eigen, a lightweight C++ template library 2// for linear algebra. 3// 4// Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 5// 6// This Source Code Form is subject to the terms of the Mozilla 7// Public License v. 2.0. If a copy of the MPL was not distributed 8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9 10#ifndef EIGEN_CUDA_SPECIALFUNCTIONS_H 11#define EIGEN_CUDA_SPECIALFUNCTIONS_H 12 13namespace Eigen { 14 15namespace internal { 16 17// Make sure this is only available when targeting a GPU: we don't want to 18// introduce conflicts between these packet_traits definitions and the ones 19// we'll use on the host side (SSE, AVX, ...) 20#if defined(__CUDACC__) && defined(EIGEN_USE_GPU) 21 22template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 23float4 plgamma<float4>(const float4& a) 24{ 25 return make_float4(lgammaf(a.x), lgammaf(a.y), lgammaf(a.z), lgammaf(a.w)); 26} 27 28template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 29double2 plgamma<double2>(const double2& a) 30{ 31 using numext::lgamma; 32 return make_double2(lgamma(a.x), lgamma(a.y)); 33} 34 35template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 36float4 pdigamma<float4>(const float4& a) 37{ 38 using numext::digamma; 39 return make_float4(digamma(a.x), digamma(a.y), digamma(a.z), digamma(a.w)); 40} 41 42template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 43double2 pdigamma<double2>(const double2& a) 44{ 45 using numext::digamma; 46 return make_double2(digamma(a.x), digamma(a.y)); 47} 48 49template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 50float4 pzeta<float4>(const float4& x, const float4& q) 51{ 52 using numext::zeta; 53 return make_float4(zeta(x.x, q.x), zeta(x.y, q.y), zeta(x.z, q.z), zeta(x.w, q.w)); 54} 55 56template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 57double2 pzeta<double2>(const double2& x, const double2& q) 58{ 59 using numext::zeta; 60 return make_double2(zeta(x.x, q.x), zeta(x.y, q.y)); 61} 62 63template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 64float4 ppolygamma<float4>(const float4& n, const float4& x) 65{ 66 using numext::polygamma; 67 return make_float4(polygamma(n.x, x.x), polygamma(n.y, x.y), polygamma(n.z, x.z), polygamma(n.w, x.w)); 68} 69 70template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 71double2 ppolygamma<double2>(const double2& n, const double2& x) 72{ 73 using numext::polygamma; 74 return make_double2(polygamma(n.x, x.x), polygamma(n.y, x.y)); 75} 76 77template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 78float4 perf<float4>(const float4& a) 79{ 80 return make_float4(erff(a.x), erff(a.y), erff(a.z), erff(a.w)); 81} 82 83template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 84double2 perf<double2>(const double2& a) 85{ 86 using numext::erf; 87 return make_double2(erf(a.x), erf(a.y)); 88} 89 90template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 91float4 perfc<float4>(const float4& a) 92{ 93 using numext::erfc; 94 return make_float4(erfc(a.x), erfc(a.y), erfc(a.z), erfc(a.w)); 95} 96 97template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 98double2 perfc<double2>(const double2& a) 99{ 100 using numext::erfc; 101 return make_double2(erfc(a.x), erfc(a.y)); 102} 103 104 105template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 106float4 pigamma<float4>(const float4& a, const float4& x) 107{ 108 using numext::igamma; 109 return make_float4( 110 igamma(a.x, x.x), 111 igamma(a.y, x.y), 112 igamma(a.z, x.z), 113 igamma(a.w, x.w)); 114} 115 116template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 117double2 pigamma<double2>(const double2& a, const double2& x) 118{ 119 using numext::igamma; 120 return make_double2(igamma(a.x, x.x), igamma(a.y, x.y)); 121} 122 123template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 124float4 pigammac<float4>(const float4& a, const float4& x) 125{ 126 using numext::igammac; 127 return make_float4( 128 igammac(a.x, x.x), 129 igammac(a.y, x.y), 130 igammac(a.z, x.z), 131 igammac(a.w, x.w)); 132} 133 134template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 135double2 pigammac<double2>(const double2& a, const double2& x) 136{ 137 using numext::igammac; 138 return make_double2(igammac(a.x, x.x), igammac(a.y, x.y)); 139} 140 141template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 142float4 pbetainc<float4>(const float4& a, const float4& b, const float4& x) 143{ 144 using numext::betainc; 145 return make_float4( 146 betainc(a.x, b.x, x.x), 147 betainc(a.y, b.y, x.y), 148 betainc(a.z, b.z, x.z), 149 betainc(a.w, b.w, x.w)); 150} 151 152template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE 153double2 pbetainc<double2>(const double2& a, const double2& b, const double2& x) 154{ 155 using numext::betainc; 156 return make_double2(betainc(a.x, b.x, x.x), betainc(a.y, b.y, x.y)); 157} 158 159#endif 160 161} // end namespace internal 162 163} // end namespace Eigen 164 165#endif // EIGEN_CUDA_SPECIALFUNCTIONS_H 166