Home | History | Annotate | Download | only in CUDA
      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 (at) 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 
     13 namespace Eigen {
     14 
     15 namespace 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 
     22 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     23 float4 plgamma<float4>(const float4& a)
     24 {
     25   return make_float4(lgammaf(a.x), lgammaf(a.y), lgammaf(a.z), lgammaf(a.w));
     26 }
     27 
     28 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     29 double2 plgamma<double2>(const double2& a)
     30 {
     31   using numext::lgamma;
     32   return make_double2(lgamma(a.x), lgamma(a.y));
     33 }
     34 
     35 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     36 float4 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 
     42 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     43 double2 pdigamma<double2>(const double2& a)
     44 {
     45   using numext::digamma;
     46   return make_double2(digamma(a.x), digamma(a.y));
     47 }
     48 
     49 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     50 float4 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 
     56 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     57 double2 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 
     63 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     64 float4 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 
     70 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     71 double2 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 
     77 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     78 float4 perf<float4>(const float4& a)
     79 {
     80   return make_float4(erff(a.x), erff(a.y), erff(a.z), erff(a.w));
     81 }
     82 
     83 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     84 double2 perf<double2>(const double2& a)
     85 {
     86   using numext::erf;
     87   return make_double2(erf(a.x), erf(a.y));
     88 }
     89 
     90 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     91 float4 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 
     97 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
     98 double2 perfc<double2>(const double2& a)
     99 {
    100   using numext::erfc;
    101   return make_double2(erfc(a.x), erfc(a.y));
    102 }
    103 
    104 
    105 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    106 float4 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 
    116 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    117 double2 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 
    123 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    124 float4 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 
    134 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    135 double2 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 
    141 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    142 float4 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 
    152 template<> EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
    153 double2 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