ViennaCL - The Vienna Computing Library  1.4.2
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-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 <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 #include <vector>
00046 #include <map>
00047 
00048 namespace viennacl
00049 {
00050     namespace result_of
00051     {
00052       //
00053       // Retrieve alignment from vector
00054       //
00056       template <typename T>
00057       struct alignment
00058       {
00059         typedef typename T::ERROR_ARGUMENT_PROVIDED_IS_NOT_A_VECTOR_OR_A_MATRIX   error_type;
00060         enum { value = 1 };
00061       };
00062       
00064       template <typename T>
00065       struct alignment<const T>
00066       {
00067         enum { value = alignment<T>::value };
00068       };
00069       
00070       template <typename SCALARTYPE, unsigned int ALIGNMENT>
00071       struct alignment< vector<SCALARTYPE, ALIGNMENT> >
00072       {
00073         enum { value = ALIGNMENT };
00074       };
00075 
00076       template <typename T>
00077       struct alignment< vector_range<T> >
00078       {
00079         enum { value = alignment<T>::value };
00080       };
00081 
00082       template <typename T>
00083       struct alignment< vector_slice<T> >
00084       {
00085         enum { value = alignment<T>::value };
00086       };
00087 
00088       // support for a*x with scalar a and vector x
00089       template <typename LHS, typename RHS, typename OP>
00090       struct alignment< vector_expression<LHS, RHS, OP> >
00091       {
00092         enum { value = alignment<LHS>::value };
00093       };
00094 
00095 
00096       // Matrices
00097       template <typename SCALARTYPE, typename F, unsigned int ALIGNMENT>
00098       struct alignment< matrix<SCALARTYPE, F, ALIGNMENT> >
00099       {
00100         enum { value = ALIGNMENT };
00101       };
00102 
00103       template <typename T>
00104       struct alignment< matrix_range<T> >
00105       {
00106         enum { value = alignment<T>::value };
00107       };
00108 
00109       template <typename T>
00110       struct alignment< matrix_slice<T> >
00111       {
00112         enum { value = alignment<T>::value };
00113       };
00114       
00115       template <typename LHS, typename RHS>
00116       struct alignment< matrix_expression<LHS, RHS, op_trans> >
00117       {
00118         enum { value = alignment<LHS>::value };
00119       };
00122       //
00123       // Majority specifier for matrices (row_major, column_major)
00124       //
00126       template <typename T>
00127       struct orientation_functor
00128       {
00129         typedef typename T::ERROR_ARGUMENT_PROVIDED_IS_NOT_A_MATRIX     type;
00130       };
00131 
00133       template <typename T>
00134       struct orientation_functor<const T>
00135       {
00136         typedef typename orientation_functor<T>::type  type;
00137       };
00138       
00139       template <typename SCALARTYPE, typename F, unsigned int ALIGNMENT>
00140       struct orientation_functor< matrix<SCALARTYPE, F, ALIGNMENT> >
00141       {
00142         typedef F     type;
00143       };
00144 
00145       template <typename T>
00146       struct orientation_functor< matrix_range<T> >
00147       {
00148         typedef typename orientation_functor<T>::type  type;
00149       };
00150 
00151       template <typename T>
00152       struct orientation_functor< matrix_slice<T> >
00153       {
00154         typedef typename orientation_functor<T>::type  type;
00155       };
00156 
00157       template <typename LHS, typename RHS>
00158       struct orientation_functor< matrix_expression<LHS, RHS, op_trans> >
00159       {
00160         typedef typename orientation_functor<LHS>::type  type;
00161       };
00165       //
00166       // Retrieve size_type 
00167       //
00169       template <typename T>
00170       struct size_type
00171       {
00172         typedef typename T::size_type   type;
00173       };
00174 
00176       #ifdef VIENNACL_WITH_EIGEN
00177       template <class T, int a, int b, int c, int d, int e>
00178       struct size_type< Eigen::Matrix<T, a, b, c, d, e> >
00179       {
00180         typedef std::size_t   type;
00181       };
00182       
00183       template <>
00184       struct size_type<Eigen::VectorXf>
00185       {
00186         typedef std::size_t   type;
00187       };
00188       
00189       template <>
00190       struct size_type<Eigen::VectorXd>
00191       {
00192         typedef std::size_t   type;
00193       };
00194 
00195       template <typename T, int options>
00196       struct size_type<Eigen::SparseMatrix<T, options> >
00197       {
00198         typedef std::size_t   type;
00199       };
00200       #endif
00201 
00203       //
00204       // Retrieve value_type:
00205       //
00207       template <typename T>
00208       struct value_type
00209       {
00210         typedef typename T::value_type    type; 
00211       };
00212       
00214 #ifdef VIENNACL_WITH_EIGEN  
00215       template <>
00216       struct value_type<Eigen::MatrixXf>
00217       {
00218         typedef Eigen::MatrixXf::RealScalar    type; 
00219       };
00220       
00221       template <>
00222       struct value_type<Eigen::MatrixXd>
00223       {
00224         typedef Eigen::MatrixXd::RealScalar    type; 
00225       };
00226 
00227       template <typename ScalarType, int option>
00228       struct value_type<Eigen::SparseMatrix<ScalarType, option> >
00229       {
00230         typedef ScalarType    type; 
00231       };
00232 
00233       template <>
00234       struct value_type<Eigen::VectorXf>
00235       {
00236         typedef Eigen::VectorXf::RealScalar    type; 
00237       };
00238 
00239       template <>
00240       struct value_type<Eigen::VectorXd>
00241       {
00242         typedef Eigen::VectorXd::RealScalar    type; 
00243       };
00244       
00245 #endif
00246 
00249       //
00250       // Retrieve cpu value_type:
00251       //
00253       template <typename T>
00254       struct cpu_value_type
00255       {
00256         typedef typename T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T    type; 
00257       };
00258 
00260       template <typename T>
00261       struct cpu_value_type<const T>
00262       {
00263         typedef typename cpu_value_type<T>::type    type;
00264       };
00265       
00266       template <>
00267       struct cpu_value_type<float>
00268       {
00269         typedef float    type; 
00270       };
00271       
00272       template <>
00273       struct cpu_value_type<double>
00274       {
00275         typedef double    type; 
00276       };
00277       
00278       template <typename T>
00279       struct cpu_value_type<viennacl::scalar<T> >
00280       {
00281         typedef T    type; 
00282       };
00283 
00284       template <typename T>
00285       struct cpu_value_type<viennacl::vector_base<T> >
00286       {
00287         typedef T    type; 
00288       };
00289       
00290       template <typename T, unsigned int ALIGNMENT>
00291       struct cpu_value_type<viennacl::vector<T, ALIGNMENT> >
00292       {
00293         typedef T    type; 
00294       };
00295       
00296       template <typename T>
00297       struct cpu_value_type<viennacl::vector_range<T> >
00298       {
00299         typedef typename cpu_value_type<T>::type    type; 
00300       };
00301 
00302       template <typename T>
00303       struct cpu_value_type<viennacl::vector_slice<T> >
00304       {
00305         typedef typename cpu_value_type<T>::type    type; 
00306       };
00307       
00308       template <typename T1, typename T2, typename OP>
00309       struct cpu_value_type<viennacl::vector_expression<const T1, const T2, OP> >
00310       {
00311         typedef typename cpu_value_type<T1>::type    type; 
00312       };
00313       
00314       template <typename T1, typename T2, typename OP>
00315       struct cpu_value_type<const viennacl::vector_expression<const T1, const T2, OP> >
00316       {
00317         typedef typename cpu_value_type<T1>::type    type; 
00318       };
00319       
00320       
00321       template <typename T, typename F>
00322       struct cpu_value_type<viennacl::matrix_base<T, F> >
00323       {
00324         typedef T    type; 
00325       };
00326       
00327       template <typename T, typename F, unsigned int ALIGNMENT>
00328       struct cpu_value_type<viennacl::matrix<T, F, ALIGNMENT> >
00329       {
00330         typedef T    type; 
00331       };
00332       
00333       template <typename T>
00334       struct cpu_value_type<viennacl::matrix_range<T> >
00335       {
00336         typedef typename cpu_value_type<T>::type    type; 
00337       };
00338 
00339       template <typename T>
00340       struct cpu_value_type<viennacl::matrix_slice<T> >
00341       {
00342         typedef typename cpu_value_type<T>::type    type; 
00343       };
00344       
00345       template <typename T1, typename T2, typename OP>
00346       struct cpu_value_type<viennacl::matrix_expression<T1, T2, OP> >
00347       {
00348         typedef typename cpu_value_type<T1>::type    type; 
00349       };
00350       
00351       
00352       
00353       template <typename T>
00354       struct matrix_expression_internal_storage
00355       {
00356         typedef T &     type;
00357       };
00358      
00359       template <>
00360       struct matrix_expression_internal_storage<const float>
00361       {
00362         typedef float type;
00363       };
00364       
00365       template <>
00366       struct matrix_expression_internal_storage<const double>
00367       {
00368         typedef double type;
00369       };
00370       
00371       
00372       
00373       
00374       //
00375       // Deduce compatible vector type for a matrix type
00376       //
00377 
00378       template <typename T>
00379       struct vector_for_matrix
00380       {
00381         typedef typename T::ERROR_CANNOT_DEDUCE_VECTOR_FOR_MATRIX_TYPE   type;
00382       };
00383 
00384       //ViennaCL
00385       template <typename T, typename F, unsigned int A>
00386       struct vector_for_matrix< viennacl::matrix<T, F, A> >
00387       {
00388         typedef viennacl::vector<T,A>   type;
00389       };
00390 
00391       template <typename T, unsigned int A>
00392       struct vector_for_matrix< viennacl::compressed_matrix<T, A> >
00393       {
00394         typedef viennacl::vector<T,A>   type;
00395       };
00396 
00397       template <typename T, unsigned int A>
00398       struct vector_for_matrix< viennacl::coordinate_matrix<T, A> >
00399       {
00400         typedef viennacl::vector<T,A>   type;
00401       };
00402 
00403       #ifdef VIENNACL_WITH_UBLAS
00404       //Boost:
00405       template <typename T, typename F, typename A>
00406       struct vector_for_matrix< boost::numeric::ublas::matrix<T, F, A> >
00407       {
00408         typedef boost::numeric::ublas::vector<T>   type;
00409       };
00410 
00411       template <typename T, typename U, std::size_t A, typename B, typename C>
00412       struct vector_for_matrix< boost::numeric::ublas::compressed_matrix<T, U, A, B, C> >
00413       {
00414         typedef boost::numeric::ublas::vector<T>   type;
00415       };
00416 
00417       template <typename T, typename U, std::size_t A, typename B, typename C>
00418       struct vector_for_matrix< boost::numeric::ublas::coordinate_matrix<T, U, A, B, C> >
00419       {
00420         typedef boost::numeric::ublas::vector<T>   type;
00421       };
00422       #endif
00423 
00424       
00425       template <typename T>
00426       struct reference_if_nonscalar
00427       {
00428         typedef T &    type;
00429       };
00430     
00431       template <>
00432       struct reference_if_nonscalar<float>
00433       {
00434         typedef float    type;
00435       };
00436 
00437       template <>
00438       struct reference_if_nonscalar<const float>
00439       {
00440         typedef const float    type;
00441       };
00442       
00443       template <>
00444       struct reference_if_nonscalar<double>
00445       {
00446         typedef double    type;
00447       };
00448       
00449       template <>
00450       struct reference_if_nonscalar<const double>
00451       {
00452         typedef const double    type;
00453       };
00456     } //namespace result_of
00457 } //namespace viennacl
00458     
00459 
00460 #endif