ViennaCL - The Vienna Computing Library
1.5.1
|
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