![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2014 Benoit Steiner <benoit.steiner.goog@gmail.com> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00009 00010 #ifndef EIGEN_COMPLEX_CUDA_H 00011 #define EIGEN_COMPLEX_CUDA_H 00012 00013 // clang-format off 00014 00015 namespace Eigen { 00016 00017 namespace internal { 00018 00019 #if defined(__CUDACC__) && defined(EIGEN_USE_GPU) 00020 00021 // Many std::complex methods such as operator+, operator-, operator* and 00022 // operator/ are not constexpr. Due to this, clang does not treat them as device 00023 // functions and thus Eigen functors making use of these operators fail to 00024 // compile. Here, we manually specialize these functors for complex types when 00025 // building for CUDA to avoid non-constexpr methods. 00026 00027 // Sum 00028 template<typename T> struct scalar_sum_op<const std::complex<T>, const std::complex<T> > : binary_op_base<const std::complex<T>, const std::complex<T> > { 00029 typedef typename std::complex<T> result_type; 00030 00031 EIGEN_EMPTY_STRUCT_CTOR(scalar_sum_op) 00032 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator() (const std::complex<T>& a, const std::complex<T>& b) const { 00033 return std::complex<T>(numext::real(a) + numext::real(b), 00034 numext::imag(a) + numext::imag(b)); 00035 } 00036 }; 00037 00038 template<typename T> struct scalar_sum_op<std::complex<T>, std::complex<T> > : scalar_sum_op<const std::complex<T>, const std::complex<T> > {}; 00039 00040 00041 // Difference 00042 template<typename T> struct scalar_difference_op<const std::complex<T>, const std::complex<T> > : binary_op_base<const std::complex<T>, const std::complex<T> > { 00043 typedef typename std::complex<T> result_type; 00044 00045 EIGEN_EMPTY_STRUCT_CTOR(scalar_difference_op) 00046 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator() (const std::complex<T>& a, const std::complex<T>& b) const { 00047 return std::complex<T>(numext::real(a) - numext::real(b), 00048 numext::imag(a) - numext::imag(b)); 00049 } 00050 }; 00051 00052 template<typename T> struct scalar_difference_op<std::complex<T>, std::complex<T> > : scalar_difference_op<const std::complex<T>, const std::complex<T> > {}; 00053 00054 00055 // Product 00056 template<typename T> struct scalar_product_op<const std::complex<T>, const std::complex<T> > : binary_op_base<const std::complex<T>, const std::complex<T> > { 00057 enum { 00058 Vectorizable = packet_traits<std::complex<T>>::HasMul 00059 }; 00060 typedef typename std::complex<T> result_type; 00061 00062 EIGEN_EMPTY_STRUCT_CTOR(scalar_product_op) 00063 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator() (const std::complex<T>& a, const std::complex<T>& b) const { 00064 const T a_real = numext::real(a); 00065 const T a_imag = numext::imag(a); 00066 const T b_real = numext::real(b); 00067 const T b_imag = numext::imag(b); 00068 return std::complex<T>(a_real * b_real - a_imag * b_imag, 00069 a_real * b_imag + a_imag * b_real); 00070 } 00071 }; 00072 00073 template<typename T> struct scalar_product_op<std::complex<T>, std::complex<T> > : scalar_product_op<const std::complex<T>, const std::complex<T> > {}; 00074 00075 00076 // Quotient 00077 template<typename T> struct scalar_quotient_op<const std::complex<T>, const std::complex<T> > : binary_op_base<const std::complex<T>, const std::complex<T> > { 00078 enum { 00079 Vectorizable = packet_traits<std::complex<T>>::HasDiv 00080 }; 00081 typedef typename std::complex<T> result_type; 00082 00083 EIGEN_EMPTY_STRUCT_CTOR(scalar_quotient_op) 00084 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE std::complex<T> operator() (const std::complex<T>& a, const std::complex<T>& b) const { 00085 const T a_real = numext::real(a); 00086 const T a_imag = numext::imag(a); 00087 const T b_real = numext::real(b); 00088 const T b_imag = numext::imag(b); 00089 const T norm = T(1) / (b_real * b_real + b_imag * b_imag); 00090 return std::complex<T>((a_real * b_real + a_imag * b_imag) * norm, 00091 (a_imag * b_real - a_real * b_imag) * norm); 00092 } 00093 }; 00094 00095 template<typename T> struct scalar_quotient_op<std::complex<T>, std::complex<T> > : scalar_quotient_op<const std::complex<T>, const std::complex<T> > {}; 00096 00097 #endif 00098 00099 } // end namespace internal 00100 00101 } // end namespace Eigen 00102 00103 #endif // EIGEN_COMPLEX_CUDA_H