ViennaCL - The Vienna Computing Library  1.5.0
viennacl/linalg/cuda/common.hpp
Go to the documentation of this file.
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