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