ViennaCL - The Vienna Computing Library  1.5.1
viennacl/meta/result_of.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_META_RESULT_OF_HPP_
00002 #define VIENNACL_META_RESULT_OF_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2014, 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 <string>
00026 #include <fstream>
00027 #include <sstream>
00028 #include "viennacl/forwards.h"
00029 
00030 
00031 #ifdef VIENNACL_WITH_UBLAS
00032 #include <boost/numeric/ublas/matrix_sparse.hpp>
00033 #include <boost/numeric/ublas/matrix.hpp>
00034 #endif
00035 
00036 #ifdef VIENNACL_WITH_EIGEN
00037 #include <Eigen/Core>
00038 #include <Eigen/Sparse>
00039 #endif
00040 
00041 #ifdef VIENNACL_WITH_MTL4
00042 #include <boost/numeric/mtl/mtl.hpp>
00043 #endif
00044 
00045 #ifdef VIENNACL_WITH_OPENCL
00046 #ifdef __APPLE__
00047 #include <OpenCL/cl.h>
00048 #else
00049 #include "CL/cl.h"
00050 #endif
00051 #endif
00052 
00053 #include <vector>
00054 #include <map>
00055 
00056 namespace viennacl
00057 {
00058     namespace result_of
00059     {
00060       //
00061       // Retrieve alignment from vector
00062       //
00064       template <typename T>
00065       struct alignment
00066       {
00067         typedef typename T::ERROR_ARGUMENT_PROVIDED_IS_NOT_A_VECTOR_OR_A_MATRIX   error_type;
00068         enum { value = 1 };
00069       };
00070 
00072       template <typename T>
00073       struct alignment<const T>
00074       {
00075         enum { value = alignment<T>::value };
00076       };
00077 
00078       template <typename SCALARTYPE, unsigned int ALIGNMENT>
00079       struct alignment< vector<SCALARTYPE, ALIGNMENT> >
00080       {
00081         enum { value = ALIGNMENT };
00082       };
00083 
00084       template <typename T>
00085       struct alignment< vector_range<T> >
00086       {
00087         enum { value = alignment<T>::value };
00088       };
00089 
00090       template <typename T>
00091       struct alignment< vector_slice<T> >
00092       {
00093         enum { value = alignment<T>::value };
00094       };
00095 
00096       // support for a*x with scalar a and vector x
00097       template <typename LHS, typename RHS, typename OP>
00098       struct alignment< vector_expression<LHS, RHS, OP> >
00099       {
00100         enum { value = alignment<LHS>::value };
00101       };
00102 
00103 
00104       // Matrices
00105       template <typename SCALARTYPE, typename F, unsigned int ALIGNMENT>
00106       struct alignment< matrix<SCALARTYPE, F, ALIGNMENT> >
00107       {
00108         enum { value = ALIGNMENT };
00109       };
00110 
00111       template <typename T>
00112       struct alignment< matrix_range<T> >
00113       {
00114         enum { value = alignment<T>::value };
00115       };
00116 
00117       template <typename T>
00118       struct alignment< matrix_slice<T> >
00119       {
00120         enum { value = alignment<T>::value };
00121       };
00122 
00123       template <typename LHS, typename RHS>
00124       struct alignment< matrix_expression<LHS, RHS, op_trans> >
00125       {
00126         enum { value = alignment<LHS>::value };
00127       };
00130       //
00131       // Majority specifier for matrices (row_major, column_major)
00132       //
00134       template <typename T>
00135       struct orientation_functor
00136       {
00137         typedef typename T::ERROR_ARGUMENT_PROVIDED_IS_NOT_A_MATRIX     type;
00138       };
00139 
00141       template <typename T>
00142       struct orientation_functor<const T>
00143       {
00144         typedef typename orientation_functor<T>::type  type;
00145       };
00146 
00147       template <typename SCALARTYPE, typename F, unsigned int ALIGNMENT>
00148       struct orientation_functor< matrix<SCALARTYPE, F, ALIGNMENT> >
00149       {
00150         typedef F     type;
00151       };
00152 
00153       template <typename T>
00154       struct orientation_functor< matrix_range<T> >
00155       {
00156         typedef typename orientation_functor<T>::type  type;
00157       };
00158 
00159       template <typename T>
00160       struct orientation_functor< matrix_slice<T> >
00161       {
00162         typedef typename orientation_functor<T>::type  type;
00163       };
00164 
00165       template <typename SCALARTYPE, typename F>
00166       struct orientation_functor< matrix_base<SCALARTYPE, F> >
00167       {
00168         typedef F     type;
00169       };
00170 
00171       template <typename LHS, typename RHS>
00172       struct orientation_functor< matrix_expression<LHS, RHS, op_trans> >
00173       {
00174         typedef typename orientation_functor<LHS>::type  type;
00175       };
00179       //
00180       // Retrieve size_type
00181       //
00183       template <typename T>
00184       struct size_type
00185       {
00186         typedef typename T::size_type   type;
00187       };
00188 
00190       template <typename T, typename SizeType>
00191       struct size_type< vector_base<T, SizeType> >
00192       {
00193         typedef SizeType   type;
00194       };
00195 
00196       #ifdef VIENNACL_WITH_EIGEN
00197       template <class T, int a, int b, int c, int d, int e>
00198       struct size_type< Eigen::Matrix<T, a, b, c, d, e> >
00199       {
00200         typedef vcl_size_t   type;
00201       };
00202 
00203       template <>
00204       struct size_type<Eigen::VectorXf>
00205       {
00206         typedef vcl_size_t   type;
00207       };
00208 
00209       template <>
00210       struct size_type<Eigen::VectorXd>
00211       {
00212         typedef vcl_size_t   type;
00213       };
00214 
00215       template <typename T, int options>
00216       struct size_type<Eigen::SparseMatrix<T, options> >
00217       {
00218         typedef vcl_size_t   type;
00219       };
00220       #endif
00221 
00223       //
00224       // Retrieve value_type:
00225       //
00227       template <typename T>
00228       struct value_type
00229       {
00230         typedef typename T::value_type    type;
00231       };
00232 
00234 #ifdef VIENNACL_WITH_EIGEN
00235       template <>
00236       struct value_type<Eigen::MatrixXf>
00237       {
00238         typedef Eigen::MatrixXf::RealScalar    type;
00239       };
00240 
00241       template <>
00242       struct value_type<Eigen::MatrixXd>
00243       {
00244         typedef Eigen::MatrixXd::RealScalar    type;
00245       };
00246 
00247       template <typename ScalarType, int option>
00248       struct value_type<Eigen::SparseMatrix<ScalarType, option> >
00249       {
00250         typedef ScalarType    type;
00251       };
00252 
00253       template <>
00254       struct value_type<Eigen::VectorXf>
00255       {
00256         typedef Eigen::VectorXf::RealScalar    type;
00257       };
00258 
00259       template <>
00260       struct value_type<Eigen::VectorXd>
00261       {
00262         typedef Eigen::VectorXd::RealScalar    type;
00263       };
00264 
00265 #endif
00266 
00269       //
00270       // Retrieve cpu value_type:
00271       //
00273       template <typename T>
00274       struct cpu_value_type
00275       {
00276         typedef typename T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T    type;
00277       };
00278 
00280       template <typename T>
00281       struct cpu_value_type<const T>
00282       {
00283         typedef typename cpu_value_type<T>::type    type;
00284       };
00285 
00286       template <>
00287       struct cpu_value_type<char>
00288       {
00289         typedef char    type;
00290       };
00291 
00292       template <>
00293       struct cpu_value_type<unsigned char>
00294       {
00295         typedef unsigned char    type;
00296       };
00297 
00298       template <>
00299       struct cpu_value_type<short>
00300       {
00301         typedef short    type;
00302       };
00303 
00304       template <>
00305       struct cpu_value_type<unsigned short>
00306       {
00307         typedef unsigned short    type;
00308       };
00309 
00310       template <>
00311       struct cpu_value_type<int>
00312       {
00313         typedef int    type;
00314       };
00315 
00316       template <>
00317       struct cpu_value_type<unsigned int>
00318       {
00319         typedef unsigned int    type;
00320       };
00321 
00322       template <>
00323       struct cpu_value_type<long>
00324       {
00325         typedef int    type;
00326       };
00327 
00328       template <>
00329       struct cpu_value_type<unsigned long>
00330       {
00331         typedef unsigned long    type;
00332       };
00333 
00334 
00335       template <>
00336       struct cpu_value_type<float>
00337       {
00338         typedef float    type;
00339       };
00340 
00341       template <>
00342       struct cpu_value_type<double>
00343       {
00344         typedef double    type;
00345       };
00346 
00347       template <typename T>
00348       struct cpu_value_type<viennacl::scalar<T> >
00349       {
00350         typedef T    type;
00351       };
00352 
00353       template <typename T>
00354       struct cpu_value_type<viennacl::vector_base<T> >
00355       {
00356         typedef T    type;
00357       };
00358 
00359       template <typename T>
00360       struct cpu_value_type<viennacl::implicit_vector_base<T> >
00361       {
00362         typedef T    type;
00363       };
00364 
00365 
00366       template <typename T, unsigned int ALIGNMENT>
00367       struct cpu_value_type<viennacl::vector<T, ALIGNMENT> >
00368       {
00369         typedef T    type;
00370       };
00371 
00372       template <typename T>
00373       struct cpu_value_type<viennacl::vector_range<T> >
00374       {
00375         typedef typename cpu_value_type<T>::type    type;
00376       };
00377 
00378       template <typename T>
00379       struct cpu_value_type<viennacl::vector_slice<T> >
00380       {
00381         typedef typename cpu_value_type<T>::type    type;
00382       };
00383 
00384       template <typename T1, typename T2, typename OP>
00385       struct cpu_value_type<viennacl::vector_expression<const T1, const T2, OP> >
00386       {
00387         typedef typename cpu_value_type<T1>::type    type;
00388       };
00389 
00390       template <typename T1, typename T2, typename OP>
00391       struct cpu_value_type<const viennacl::vector_expression<const T1, const T2, OP> >
00392       {
00393         typedef typename cpu_value_type<T1>::type    type;
00394       };
00395 
00396 
00397       template <typename T, typename F>
00398       struct cpu_value_type<viennacl::matrix_base<T, F> >
00399       {
00400         typedef T    type;
00401       };
00402 
00403       template <typename T>
00404       struct cpu_value_type<viennacl::implicit_matrix_base<T> >
00405       {
00406         typedef T    type;
00407       };
00408 
00409 
00410       template <typename T, typename F, unsigned int ALIGNMENT>
00411       struct cpu_value_type<viennacl::matrix<T, F, ALIGNMENT> >
00412       {
00413         typedef T    type;
00414       };
00415 
00416       template <typename T>
00417       struct cpu_value_type<viennacl::matrix_range<T> >
00418       {
00419         typedef typename cpu_value_type<T>::type    type;
00420       };
00421 
00422       template <typename T>
00423       struct cpu_value_type<viennacl::matrix_slice<T> >
00424       {
00425         typedef typename cpu_value_type<T>::type    type;
00426       };
00427 
00428       template <typename T, unsigned int ALIGNMENT>
00429       struct cpu_value_type<viennacl::compressed_matrix<T, ALIGNMENT> >
00430       {
00431         typedef typename cpu_value_type<T>::type    type;
00432       };
00433 
00434       template <typename T>
00435       struct cpu_value_type<viennacl::compressed_compressed_matrix<T> >
00436       {
00437         typedef typename cpu_value_type<T>::type    type;
00438       };
00439 
00440       template <typename T, unsigned int ALIGNMENT>
00441       struct cpu_value_type<viennacl::coordinate_matrix<T, ALIGNMENT> >
00442       {
00443         typedef typename cpu_value_type<T>::type    type;
00444       };
00445 
00446       template <typename T, unsigned int ALIGNMENT>
00447       struct cpu_value_type<viennacl::ell_matrix<T, ALIGNMENT> >
00448       {
00449         typedef typename cpu_value_type<T>::type    type;
00450       };
00451 
00452       template <typename T, unsigned int ALIGNMENT>
00453       struct cpu_value_type<viennacl::hyb_matrix<T, ALIGNMENT> >
00454       {
00455         typedef typename cpu_value_type<T>::type    type;
00456       };
00457 
00458       template <typename T, unsigned int ALIGNMENT>
00459       struct cpu_value_type<viennacl::circulant_matrix<T, ALIGNMENT> >
00460       {
00461         typedef typename cpu_value_type<T>::type    type;
00462       };
00463 
00464       template <typename T, unsigned int ALIGNMENT>
00465       struct cpu_value_type<viennacl::hankel_matrix<T, ALIGNMENT> >
00466       {
00467         typedef typename cpu_value_type<T>::type    type;
00468       };
00469 
00470       template <typename T, unsigned int ALIGNMENT>
00471       struct cpu_value_type<viennacl::toeplitz_matrix<T, ALIGNMENT> >
00472       {
00473         typedef typename cpu_value_type<T>::type    type;
00474       };
00475 
00476       template <typename T, unsigned int ALIGNMENT>
00477       struct cpu_value_type<viennacl::vandermonde_matrix<T, ALIGNMENT> >
00478       {
00479         typedef typename cpu_value_type<T>::type    type;
00480       };
00481 
00482       template <typename T1, typename T2, typename OP>
00483       struct cpu_value_type<viennacl::matrix_expression<T1, T2, OP> >
00484       {
00485         typedef typename cpu_value_type<T1>::type    type;
00486       };
00487 
00488 
00489       //
00490       // Deduce compatible vector type for a matrix type
00491       //
00492 
00493       template <typename T>
00494       struct vector_for_matrix
00495       {
00496         typedef typename T::ERROR_CANNOT_DEDUCE_VECTOR_FOR_MATRIX_TYPE   type;
00497       };
00498 
00499       //ViennaCL
00500       template <typename T, typename F, unsigned int A>
00501       struct vector_for_matrix< viennacl::matrix<T, F, A> >
00502       {
00503         typedef viennacl::vector<T,A>   type;
00504       };
00505 
00506       template <typename T, unsigned int A>
00507       struct vector_for_matrix< viennacl::compressed_matrix<T, A> >
00508       {
00509         typedef viennacl::vector<T,A>   type;
00510       };
00511 
00512       template <typename T, unsigned int A>
00513       struct vector_for_matrix< viennacl::coordinate_matrix<T, A> >
00514       {
00515         typedef viennacl::vector<T,A>   type;
00516       };
00517 
00518       #ifdef VIENNACL_WITH_UBLAS
00519       //Boost:
00520       template <typename T, typename F, typename A>
00521       struct vector_for_matrix< boost::numeric::ublas::matrix<T, F, A> >
00522       {
00523         typedef boost::numeric::ublas::vector<T>   type;
00524       };
00525 
00526       template <typename T, typename U, vcl_size_t A, typename B, typename C>
00527       struct vector_for_matrix< boost::numeric::ublas::compressed_matrix<T, U, A, B, C> >
00528       {
00529         typedef boost::numeric::ublas::vector<T>   type;
00530       };
00531 
00532       template <typename T, typename U, vcl_size_t A, typename B, typename C>
00533       struct vector_for_matrix< boost::numeric::ublas::coordinate_matrix<T, U, A, B, C> >
00534       {
00535         typedef boost::numeric::ublas::vector<T>   type;
00536       };
00537       #endif
00538 
00539 
00540       template <typename T>
00541       struct reference_if_nonscalar
00542       {
00543         typedef T &    type;
00544       };
00545 
00546 #define VIENNACL_REFERENCE_IF_NONSCALAR_INT(TNAME) \
00547       template <> struct reference_if_nonscalar<TNAME>                { typedef                TNAME  type; }; \
00548       template <> struct reference_if_nonscalar<const TNAME>          { typedef          const TNAME  type; }; \
00549       template <> struct reference_if_nonscalar<unsigned TNAME>       { typedef       unsigned TNAME  type; }; \
00550       template <> struct reference_if_nonscalar<const unsigned TNAME> { typedef const unsigned TNAME  type; };
00551 
00552       VIENNACL_REFERENCE_IF_NONSCALAR_INT(char)
00553       VIENNACL_REFERENCE_IF_NONSCALAR_INT(short)
00554       VIENNACL_REFERENCE_IF_NONSCALAR_INT(int)
00555       VIENNACL_REFERENCE_IF_NONSCALAR_INT(long)
00556 
00557 #undef VIENNACL_REFERENCE_IF_NONSCALAR_INT
00558 
00559       template <>
00560       struct reference_if_nonscalar<float>
00561       {
00562         typedef float    type;
00563       };
00564 
00565       template <>
00566       struct reference_if_nonscalar<const float>
00567       {
00568         typedef const float    type;
00569       };
00570 
00571       template <>
00572       struct reference_if_nonscalar<double>
00573       {
00574         typedef double    type;
00575       };
00576 
00577       template <>
00578       struct reference_if_nonscalar<const double>
00579       {
00580         typedef const double    type;
00581       };
00582 
00585       //OpenCL equivalent type
00587       template<typename T>
00588       struct cl_type
00589       {
00590           typedef T type;
00591       };
00592 
00594 #ifdef VIENNACL_WITH_OPENCL
00595       template<>
00596       struct cl_type<float>{ typedef cl_float type; };
00597 
00598       template<>
00599       struct cl_type<double>{ typedef cl_double type; };
00600 
00601       template<>
00602       struct cl_type<int>{ typedef cl_int type; };
00603 
00604       template<>
00605       struct cl_type<unsigned int>{  typedef cl_uint type; };
00606 
00607       template<>
00608       struct cl_type<long>{  typedef cl_long type;  };
00609 
00610       template<>
00611       struct cl_type<unsigned long>{ typedef cl_ulong type; };
00612 
00613       template<>
00614       struct cl_type<short>{ typedef cl_short type;  };
00615 
00616       template<>
00617       struct cl_type<unsigned short>{ typedef cl_ushort type; };
00618 
00619       template<>
00620       struct cl_type<char>{ typedef cl_char type; };
00621 
00622       template<>
00623       struct cl_type<unsigned char>{ typedef cl_uchar type; };
00624 #endif
00625 
00627     } //namespace result_of
00628 } //namespace viennacl
00629 
00630 
00631 #endif