ViennaCL - The Vienna Computing Library
1.5.0
|
00001 #ifndef VIENNACL_LINALG_CUDA_COMMON_HPP_ 00002 #define VIENNACL_LINALG_CUDA_COMMON_HPP_ 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2013, Institute for Microelectronics, 00006 Institute for Analysis and Scientific Computing, 00007 TU Wien. 00008 Portions of this software are copyright by UChicago Argonne, LLC. 00009 00010 ----------------- 00011 ViennaCL - The Vienna Computing Library 00012 ----------------- 00013 00014 Project Head: Karl Rupp rupp@iue.tuwien.ac.at 00015 00016 (A list of authors and contributors can be found in the PDF manual) 00017 00018 License: MIT (X11), see file LICENSE in the base directory 00019 ============================================================================= */ 00020 00025 #include "viennacl/traits/handle.hpp" 00026 00027 #define VIENNACL_CUDA_LAST_ERROR_CHECK(message) detail::cuda_last_error_check (message, __FILE__, __LINE__) 00028 00029 namespace viennacl 00030 { 00031 namespace linalg 00032 { 00033 namespace cuda 00034 { 00035 namespace detail 00036 { 00037 inline unsigned int make_options(vcl_size_t length, bool reciprocal, bool flip_sign) 00038 { 00039 return static_cast<unsigned int>( ((length > 1) ? (static_cast<unsigned int>(length) << 2) : 0) + (reciprocal ? 2 : 0) + (flip_sign ? 1 : 0) ); 00040 } 00041 00042 inline void cuda_last_error_check(const char * message, const char * file, const int line ) 00043 { 00044 cudaError_t error_code = cudaGetLastError(); 00045 00046 if(cudaSuccess != error_code) 00047 { 00048 std::cerr << file << "(" << line << "): " << ": getLastCudaError() CUDA error " << error_code << ": " << cudaGetErrorString( error_code ) << " @ " << message << std::endl; 00049 throw "CUDA error"; 00050 } 00051 } 00052 00053 template <typename T, typename U> 00054 T * cuda_arg(vector_base<U> & obj) 00055 { 00056 return reinterpret_cast<T *>(viennacl::traits::handle(obj).cuda_handle().get()); 00057 } 00058 00059 template <typename T, typename U> 00060 const T * cuda_arg(vector_base<U> const & obj) 00061 { 00062 return reinterpret_cast<const T *>(viennacl::traits::handle(obj).cuda_handle().get()); 00063 } 00064 00065 template <typename NumericT, typename F> 00066 NumericT * cuda_arg(matrix_base<NumericT, F> & obj) 00067 { 00068 return reinterpret_cast<NumericT *>(viennacl::traits::handle(obj).cuda_handle().get()); 00069 } 00070 00071 template <typename NumericT, typename F> 00072 const NumericT * cuda_arg(matrix_base<NumericT, F> const & obj) 00073 { 00074 return reinterpret_cast<const NumericT *>(viennacl::traits::handle(obj).cuda_handle().get()); 00075 } 00076 00077 00078 template <typename ScalarType, typename T> 00079 typename viennacl::enable_if< viennacl::is_scalar<T>::value, 00080 ScalarType *>::type 00081 cuda_arg(T & obj) 00082 { 00083 return reinterpret_cast<ScalarType *>(viennacl::traits::handle(obj).cuda_handle().get()); 00084 } 00085 00086 template <typename ScalarType, typename T> 00087 typename viennacl::enable_if< viennacl::is_scalar<T>::value, 00088 const ScalarType *>::type 00089 cuda_arg(T const & obj) 00090 { 00091 return reinterpret_cast<const ScalarType *>(viennacl::traits::handle(obj).cuda_handle().get()); 00092 } 00093 00094 template <typename ScalarType> 00095 ScalarType * cuda_arg(viennacl::backend::mem_handle::cuda_handle_type & h) 00096 { 00097 return reinterpret_cast<ScalarType *>(h.get()); 00098 } 00099 00100 template <typename ScalarType> 00101 ScalarType const * cuda_arg(viennacl::backend::mem_handle::cuda_handle_type const & h) 00102 { 00103 return reinterpret_cast<const ScalarType *>(h.get()); 00104 } 00105 00106 //template <typename ScalarType> 00107 //ScalarType cuda_arg(ScalarType const & val) { return val; } 00108 00109 inline unsigned int cuda_arg(unsigned int val) { return val; } 00110 00111 template <typename T> char cuda_arg(char val) { return val; } 00112 template <typename T> unsigned char cuda_arg(unsigned char val) { return val; } 00113 00114 template <typename T> short cuda_arg(short val) { return val; } 00115 template <typename T> unsigned short cuda_arg(unsigned short val) { return val; } 00116 00117 template <typename T> int cuda_arg(int val) { return val; } 00118 template <typename T> unsigned int cuda_arg(unsigned int val) { return val; } 00119 00120 template <typename T> long cuda_arg(long val) { return val; } 00121 template <typename T> unsigned long cuda_arg(unsigned long val) { return val; } 00122 00123 template <typename T> float cuda_arg(float val) { return val; } 00124 template <typename T> double cuda_arg(double val) { return val; } 00125 00126 template <typename T, typename U> 00127 typename viennacl::backend::mem_handle::cuda_handle_type & arg_reference(viennacl::scalar<T> & s, U) { return s.handle().cuda_handle(); } 00128 00129 template <typename T, typename U> 00130 typename viennacl::backend::mem_handle::cuda_handle_type const & arg_reference(viennacl::scalar<T> const & s, U) { return s.handle().cuda_handle(); } 00131 00132 // all other cases where T is not a ViennaCL scalar 00133 template <typename T> 00134 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00135 char const &>::type 00136 arg_reference(T, char const & val) { return val; } 00137 00138 template <typename T> 00139 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00140 unsigned char const &>::type 00141 arg_reference(T, unsigned char const & val) { return val; } 00142 00143 template <typename T> 00144 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00145 short const &>::type 00146 arg_reference(T, short const & val) { return val; } 00147 00148 template <typename T> 00149 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00150 unsigned short const &>::type 00151 arg_reference(T, unsigned short const & val) { return val; } 00152 00153 template <typename T> 00154 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00155 int const &>::type 00156 arg_reference(T, int const & val) { return val; } 00157 00158 template <typename T> 00159 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00160 unsigned int const &>::type 00161 arg_reference(T, unsigned int const & val) { return val; } 00162 00163 template <typename T> 00164 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00165 long const &>::type 00166 arg_reference(T, long const & val) { return val; } 00167 00168 template <typename T> 00169 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00170 unsigned long const &>::type 00171 arg_reference(T, unsigned long const & val) { return val; } 00172 00173 template <typename T> 00174 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00175 float const &>::type 00176 arg_reference(T, float const & val) { return val; } 00177 00178 template <typename T> 00179 typename viennacl::enable_if< viennacl::is_cpu_scalar<T>::value, 00180 double const &>::type 00181 arg_reference(T, double const & val) { return val; } 00182 } //namespace detail 00183 00184 } //namespace cuda 00185 } //namespace linalg 00186 } //namespace viennacl 00187 00188 00189 #endif