ViennaCL - The Vienna Computing Library  1.7.0
Free open-source GPU-accelerated linear algebra and solver library.
result_of.hpp
Go to the documentation of this file.
1 #ifndef VIENNACL_META_RESULT_OF_HPP_
2 #define VIENNACL_META_RESULT_OF_HPP_
3 
4 /* =========================================================================
5  Copyright (c) 2010-2015, Institute for Microelectronics,
6  Institute for Analysis and Scientific Computing,
7  TU Wien.
8  Portions of this software are copyright by UChicago Argonne, LLC.
9 
10  -----------------
11  ViennaCL - The Vienna Computing Library
12  -----------------
13 
14  Project Head: Karl Rupp rupp@iue.tuwien.ac.at
15 
16  (A list of authors and contributors can be found in the manual)
17 
18  License: MIT (X11), see file LICENSE in the base directory
19 ============================================================================= */
20 
25 #include <string>
26 #include <fstream>
27 #include <sstream>
28 #include "viennacl/forwards.h"
29 
30 
31 #ifdef VIENNACL_WITH_UBLAS
32 #include <boost/numeric/ublas/matrix_sparse.hpp>
33 #include <boost/numeric/ublas/matrix.hpp>
34 #endif
35 
36 #ifdef VIENNACL_WITH_ARMADILLO
37 #include <armadillo>
38 #endif
39 
40 #ifdef VIENNACL_WITH_EIGEN
41 #include <Eigen/Core>
42 #include <Eigen/Sparse>
43 #endif
44 
45 #ifdef VIENNACL_WITH_MTL4
46 #include <boost/numeric/mtl/mtl.hpp>
47 #endif
48 
49 #ifdef VIENNACL_WITH_OPENCL
50 #ifdef __APPLE__
51 #include <OpenCL/cl.h>
52 #else
53 #include "CL/cl.h"
54 #endif
55 #endif
56 
57 #include <vector>
58 #include <map>
59 
60 namespace viennacl
61 {
62 namespace result_of
63 {
64 //
65 // Retrieve alignment from vector
66 //
68 template<typename T>
69 struct alignment
70 {
71  typedef typename T::ERROR_ARGUMENT_PROVIDED_IS_NOT_A_VECTOR_OR_A_MATRIX error_type;
72  enum { value = 1 };
73 };
74 
76 template<typename T>
77 struct alignment<const T>
78 {
79  enum { value = alignment<T>::value };
80 };
81 
82 template<typename NumericT, unsigned int AlignmentV>
83 struct alignment< vector<NumericT, AlignmentV> >
84 {
85  enum { value = AlignmentV };
86 };
87 
88 template<typename T>
89 struct alignment< vector_range<T> >
90 {
91  enum { value = alignment<T>::value };
92 };
93 
94 template<typename T>
95 struct alignment< vector_slice<T> >
96 {
97  enum { value = alignment<T>::value };
98 };
99 
100 // support for a*x with scalar a and vector x
101 template<typename LHS, typename RHS, typename OP>
102 struct alignment< vector_expression<LHS, RHS, OP> >
103 {
104  enum { value = alignment<LHS>::value };
105 };
106 
107 
108 // Matrices
109 template<typename NumericT, typename F, unsigned int AlignmentV>
110 struct alignment< matrix<NumericT, F, AlignmentV> >
111 {
112  enum { value = AlignmentV };
113 };
114 
115 template<typename T>
116 struct alignment< matrix_range<T> >
117 {
118  enum { value = alignment<T>::value };
119 };
120 
121 template<typename T>
122 struct alignment< matrix_slice<T> >
123 {
124  enum { value = alignment<T>::value };
125 };
126 
127 template<typename LHS, typename RHS>
128 struct alignment< matrix_expression<LHS, RHS, op_trans> >
129 {
130  enum { value = alignment<LHS>::value };
131 };
134 //
135 // Retrieve size_type
136 //
138 template<typename T>
139 struct size_type
140 {
141  typedef typename T::size_type type;
142 };
143 
145 template<typename T, typename SizeType>
146 struct size_type< vector_base<T, SizeType> >
147 {
148  typedef SizeType type;
149 };
150 
151 //
152 // Retrieve difference_type
153 //
155 template<typename T>
156 struct difference_type
157 {
158  typedef typename T::difference_type type;
159 };
160 
161 #ifdef VIENNACL_WITH_ARMADILLO
162 template<typename NumericT>
163 struct size_type<arma::Col<NumericT> > { typedef vcl_size_t type; };
164 
165 template<typename NumericT>
166 struct size_type<arma::Mat<NumericT> > { typedef vcl_size_t type; };
167 
168 template<typename NumericT>
169 struct size_type<arma::SpMat<NumericT> > { typedef vcl_size_t type; };
170 
171 #endif
172 
173 #ifdef VIENNACL_WITH_EIGEN
174 template<class T, int a, int b, int c, int d, int e>
175 struct size_type< Eigen::Matrix<T, a, b, c, d, e> >
176 {
177  typedef vcl_size_t type;
178 };
179 
180 template<class T, int a, int b, int c, int d, int e>
181 struct size_type< Eigen::Map<Eigen::Matrix<T, a, b, c, d, e> > >
182 {
183  typedef vcl_size_t type;
184 };
185 
186 template<>
187 struct size_type<Eigen::VectorXf>
188 {
189  typedef vcl_size_t type;
190 };
191 
192 template<>
193 struct size_type<Eigen::VectorXd>
194 {
195  typedef vcl_size_t type;
196 };
197 
198 template<typename T, int options>
199 struct size_type<Eigen::SparseMatrix<T, options> >
200 {
201  typedef vcl_size_t type;
202 };
203 #endif
204 
206 //
207 // Retrieve value_type:
208 //
210 template<typename T>
212 {
213  typedef typename T::value_type type;
214 };
215 
217 #ifdef VIENNACL_WITH_ARMADILLO
218 template<typename NumericT>
219 struct value_type<arma::Col<NumericT> > { typedef NumericT type; };
220 
221 template<typename NumericT>
222 struct value_type<arma::Mat<NumericT> > { typedef NumericT type; };
223 
224 template<typename NumericT>
225 struct value_type<arma::SpMat<NumericT> > { typedef NumericT type; };
226 
227 #endif
228 
229 #ifdef VIENNACL_WITH_EIGEN
230 template<>
231 struct value_type<Eigen::MatrixXf>
232 {
233  typedef Eigen::MatrixXf::RealScalar type;
234 };
235 
236 template<>
237 struct value_type<Eigen::MatrixXd>
238 {
239  typedef Eigen::MatrixXd::RealScalar type;
240 };
241 
242 template<typename ScalarType, int option>
243 struct value_type<Eigen::SparseMatrix<ScalarType, option> >
244 {
245  typedef ScalarType type;
246 };
247 
248 template<>
249 struct value_type<Eigen::VectorXf>
250 {
251  typedef Eigen::VectorXf::RealScalar type;
252 };
253 
254 template<>
255 struct value_type<Eigen::VectorXd>
256 {
257  typedef Eigen::VectorXd::RealScalar type;
258 };
259 
260 #endif
261 
264 //
265 // Retrieve cpu value_type:
266 //
268 template<typename T>
270 {
271  typedef typename T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type;
272 };
273 
275 template<typename T>
276 struct cpu_value_type<const T>
277 {
278  typedef typename cpu_value_type<T>::type type;
279 };
280 
281 template<>
282 struct cpu_value_type<char>
283 {
284  typedef char type;
285 };
286 
287 template<>
288 struct cpu_value_type<unsigned char>
289 {
290  typedef unsigned char type;
291 };
292 
293 template<>
294 struct cpu_value_type<short>
295 {
296  typedef short type;
297 };
298 
299 template<>
300 struct cpu_value_type<unsigned short>
301 {
302  typedef unsigned short type;
303 };
304 
305 template<>
306 struct cpu_value_type<int>
307 {
308  typedef int type;
309 };
310 
311 template<>
312 struct cpu_value_type<unsigned int>
313 {
314  typedef unsigned int type;
315 };
316 
317 template<>
318 struct cpu_value_type<long>
319 {
320  typedef int type;
321 };
322 
323 template<>
324 struct cpu_value_type<unsigned long>
325 {
326  typedef unsigned long type;
327 };
328 
329 
330 template<>
331 struct cpu_value_type<float>
332 {
333  typedef float type;
334 };
335 
336 template<>
337 struct cpu_value_type<double>
338 {
339  typedef double type;
340 };
341 
342 template<typename T>
343 struct cpu_value_type<viennacl::scalar<T> >
344 {
345  typedef T type;
346 };
347 
348 template<typename T>
349 struct cpu_value_type<viennacl::vector_base<T> >
350 {
351  typedef T type;
352 };
353 
354 template<typename T>
355 struct cpu_value_type<viennacl::implicit_vector_base<T> >
356 {
357  typedef T type;
358 };
359 
360 
361 template<typename T, unsigned int AlignmentV>
362 struct cpu_value_type<viennacl::vector<T, AlignmentV> >
363 {
364  typedef T type;
365 };
366 
367 template<typename T>
368 struct cpu_value_type<viennacl::vector_range<T> >
369 {
370  typedef typename cpu_value_type<T>::type type;
371 };
372 
373 template<typename T>
374 struct cpu_value_type<viennacl::vector_slice<T> >
375 {
376  typedef typename cpu_value_type<T>::type type;
377 };
378 
379 template<typename T1, typename T2, typename OP>
380 struct cpu_value_type<viennacl::vector_expression<const T1, const T2, OP> >
381 {
382  typedef typename cpu_value_type<T1>::type type;
383 };
384 
385 template<typename T1, typename T2, typename OP>
386 struct cpu_value_type<const viennacl::vector_expression<const T1, const T2, OP> >
387 {
388  typedef typename cpu_value_type<T1>::type type;
389 };
390 
391 
392 template<typename T>
393 struct cpu_value_type<viennacl::matrix_base<T> >
394 {
395  typedef T type;
396 };
397 
398 template<typename T>
399 struct cpu_value_type<viennacl::implicit_matrix_base<T> >
400 {
401  typedef T type;
402 };
403 
404 
405 template<typename T, typename F, unsigned int AlignmentV>
406 struct cpu_value_type<viennacl::matrix<T, F, AlignmentV> >
407 {
408  typedef T type;
409 };
410 
411 template<typename T>
412 struct cpu_value_type<viennacl::matrix_range<T> >
413 {
414  typedef typename cpu_value_type<T>::type type;
415 };
416 
417 template<typename T>
418 struct cpu_value_type<viennacl::matrix_slice<T> >
419 {
420  typedef typename cpu_value_type<T>::type type;
421 };
422 
423 template<typename T, unsigned int AlignmentV>
424 struct cpu_value_type<viennacl::compressed_matrix<T, AlignmentV> >
425 {
426  typedef typename cpu_value_type<T>::type type;
427 };
428 
429 template<typename T>
430 struct cpu_value_type<viennacl::compressed_compressed_matrix<T> >
431 {
432  typedef typename cpu_value_type<T>::type type;
433 };
434 
435 template<typename T, unsigned int AlignmentV>
436 struct cpu_value_type<viennacl::coordinate_matrix<T, AlignmentV> >
437 {
438  typedef typename cpu_value_type<T>::type type;
439 };
440 
441 template<typename T, unsigned int AlignmentV>
442 struct cpu_value_type<viennacl::ell_matrix<T, AlignmentV> >
443 {
444  typedef typename cpu_value_type<T>::type type;
445 };
446 
447 template<typename T, typename IndexT>
448 struct cpu_value_type<viennacl::sliced_ell_matrix<T, IndexT> >
449 {
450  typedef typename cpu_value_type<T>::type type;
451 };
452 
453 template<typename T, unsigned int AlignmentV>
454 struct cpu_value_type<viennacl::hyb_matrix<T, AlignmentV> >
455 {
456  typedef typename cpu_value_type<T>::type type;
457 };
458 
459 template<typename T, unsigned int AlignmentV>
460 struct cpu_value_type<viennacl::circulant_matrix<T, AlignmentV> >
461 {
462  typedef typename cpu_value_type<T>::type type;
463 };
464 
465 template<typename T, unsigned int AlignmentV>
466 struct cpu_value_type<viennacl::hankel_matrix<T, AlignmentV> >
467 {
468  typedef typename cpu_value_type<T>::type type;
469 };
470 
471 template<typename T, unsigned int AlignmentV>
472 struct cpu_value_type<viennacl::toeplitz_matrix<T, AlignmentV> >
473 {
474  typedef typename cpu_value_type<T>::type type;
475 };
476 
477 template<typename T, unsigned int AlignmentV>
478 struct cpu_value_type<viennacl::vandermonde_matrix<T, AlignmentV> >
479 {
480  typedef typename cpu_value_type<T>::type type;
481 };
482 
483 template<typename T1, typename T2, typename OP>
484 struct cpu_value_type<viennacl::matrix_expression<T1, T2, OP> >
485 {
486  typedef typename cpu_value_type<T1>::type type;
487 };
488 
489 
490 //
491 // Deduce compatible vector type for a matrix type
492 //
493 
494 template<typename T>
495 struct vector_for_matrix
496 {
497  typedef typename T::ERROR_CANNOT_DEDUCE_VECTOR_FOR_MATRIX_TYPE type;
498 };
499 
500 //ViennaCL
501 template<typename T, typename F, unsigned int A>
502 struct vector_for_matrix< viennacl::matrix<T, F, A> >
503 {
504  typedef viennacl::vector<T,A> type;
505 };
506 
507 template<typename T, unsigned int A>
508 struct vector_for_matrix< viennacl::compressed_matrix<T, A> >
509 {
510  typedef viennacl::vector<T,A> type;
511 };
512 
513 template<typename T, unsigned int A>
514 struct vector_for_matrix< viennacl::coordinate_matrix<T, A> >
515 {
516  typedef viennacl::vector<T,A> type;
517 };
518 
519 #ifdef VIENNACL_WITH_UBLAS
520 //Boost:
521 template<typename T, typename F, typename A>
522 struct vector_for_matrix< boost::numeric::ublas::matrix<T, F, A> >
523 {
524  typedef boost::numeric::ublas::vector<T> type;
525 };
526 
527 template<typename T, typename U, vcl_size_t A, typename B, typename C>
528 struct vector_for_matrix< boost::numeric::ublas::compressed_matrix<T, U, A, B, C> >
529 {
530  typedef boost::numeric::ublas::vector<T> type;
531 };
532 
533 template<typename T, typename U, vcl_size_t A, typename B, typename C>
534 struct vector_for_matrix< boost::numeric::ublas::coordinate_matrix<T, U, A, B, C> >
535 {
536  typedef boost::numeric::ublas::vector<T> type;
537 };
538 #endif
539 
540 template<typename T>
541 struct reference_if_nonscalar
542 {
543  typedef T & type;
544 };
545 
546 #define VIENNACL_REFERENCE_IF_NONSCALAR_INT(TNAME) \
547 template<> struct reference_if_nonscalar<TNAME> { typedef TNAME type; }; \
548 template<> struct reference_if_nonscalar<const TNAME> { typedef const TNAME type; }; \
549 template<> struct reference_if_nonscalar<unsigned TNAME> { typedef unsigned TNAME type; }; \
550 template<> struct reference_if_nonscalar<const unsigned TNAME> { typedef const unsigned TNAME type; };
551 
552  VIENNACL_REFERENCE_IF_NONSCALAR_INT(char)
553  VIENNACL_REFERENCE_IF_NONSCALAR_INT(short)
554  VIENNACL_REFERENCE_IF_NONSCALAR_INT(int)
555  VIENNACL_REFERENCE_IF_NONSCALAR_INT(long)
556 
557 #undef VIENNACL_REFERENCE_IF_NONSCALAR_INT
558 
559 template<>
560 struct reference_if_nonscalar<float>
561 {
562  typedef float type;
563 };
564 
565 template<>
566 struct reference_if_nonscalar<const float>
567 {
568  typedef const float type;
569 };
570 
571 template<>
572 struct reference_if_nonscalar<double>
573 {
574  typedef double type;
575 };
576 
577 template<>
578 struct reference_if_nonscalar<const double>
579 {
580  typedef const double type;
581 };
582 
585 //OpenCL equivalent type
587 template<typename T>
588 struct cl_type
589 {
590  typedef T type;
591 };
592 
594 #ifdef VIENNACL_WITH_OPENCL
595 template<>
596 struct cl_type<float>{ typedef cl_float type; };
597 
598 template<>
599 struct cl_type<double>{ typedef cl_double type; };
600 
601 template<>
602 struct cl_type<int>{ typedef cl_int type; };
603 
604 template<>
605 struct cl_type<unsigned int>{ typedef cl_uint type; };
606 
607 template<>
608 struct cl_type<long>{ typedef cl_long type; };
609 
610 template<>
611 struct cl_type<unsigned long>{ typedef cl_ulong type; };
612 
613 template<>
614 struct cl_type<short>{ typedef cl_short type; };
615 
616 template<>
617 struct cl_type<unsigned short>{ typedef cl_ushort type; };
618 
619 template<>
620 struct cl_type<char>{ typedef cl_char type; };
621 
622 template<>
623 struct cl_type<unsigned char>{ typedef cl_uchar type; };
624 #endif
625 
627 } //namespace result_of
628 } //namespace viennacl
629 
630 
631 #endif
Metafunction for deducing the OpenCL type for a numeric type, e.g. float -> cl_float.
Definition: result_of.hpp:588
This file provides the forward declarations for the main types used within ViennaCL.
Retrieves the alignment from a vector. Deprecated - will be replaced by a pure runtime facility in th...
Definition: result_of.hpp:69
float NumericT
Definition: bisect.cpp:40
Main namespace in ViennaCL. Holds all the basic types such as vector, matrix, etc. and defines operations upon them.
Definition: cpu_ram.hpp:34
Generic helper function for retrieving the value_type associated with type T.
Definition: result_of.hpp:211
Common base class for dense vectors, vector ranges, and vector slices.
Definition: vector_def.hpp:104
std::size_t vcl_size_t
Definition: forwards.h:75
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Definition: result_of.hpp:271
Helper meta function for retrieving the main RAM-based value type. Particularly important to obtain T...
Definition: result_of.hpp:269
float ScalarType
Definition: fft_1d.cpp:42
Generic meta-function for retrieving the size_type associated with type T.
Definition: result_of.hpp:139
T::ERROR_ARGUMENT_PROVIDED_IS_NOT_A_VECTOR_OR_A_MATRIX error_type
Definition: result_of.hpp:71