18 #define VIENNACL_WITH_UBLAS
42 #include "boost/numeric/ublas/vector.hpp"
43 #include "boost/numeric/ublas/matrix.hpp"
44 #include "boost/numeric/ublas/matrix_proxy.hpp"
45 #include "boost/numeric/ublas/vector_proxy.hpp"
46 #include "boost/numeric/ublas/io.hpp"
48 template<
typename MatrixType,
typename VCLMatrixType>
51 typedef typename MatrixType::value_type value_type;
53 boost::numeric::ublas::matrix<value_type> vcl_A_cpu(vcl_A.size1(), vcl_A.size2());
57 for (std::size_t i=0; i<ublas_A.size1(); ++i)
59 for (std::size_t j=0; j<ublas_A.size2(); ++j)
61 if (ublas_A(i,j) != vcl_A_cpu(i,j))
63 std::cout <<
"Error at index (" << i <<
", " << j <<
"): " << ublas_A(i,j) <<
" vs " << vcl_A_cpu(i,j) << std::endl;
64 std::cout << std::endl <<
"TEST failed!" << std::endl;
70 std::cout <<
"PASSED!" << std::endl;
77 template<
typename UBLASMatrixType,
78 typename ViennaCLMatrixType1,
typename ViennaCLMatrixType2,
typename ViennaCLMatrixType3>
79 int run_test(UBLASMatrixType & ublas_A, UBLASMatrixType & ublas_B, UBLASMatrixType & ublas_C,
80 ViennaCLMatrixType1 & vcl_A, ViennaCLMatrixType2 & vcl_B, ViennaCLMatrixType3 vcl_C)
85 cpu_value_type alpha = 3;
88 cpu_value_type beta = 2;
95 std::cout <<
"Checking for zero_matrix initializer..." << std::endl;
96 ublas_A = boost::numeric::ublas::zero_matrix<cpu_value_type>(ublas_A.size1(), ublas_A.size2());
101 std::cout <<
"Checking for scalar_matrix initializer..." << std::endl;
102 ublas_A = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_A.size1(), ublas_A.size2(), alpha);
107 ublas_A = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_A.size1(), ublas_A.size2(), gpu_beta);
120 std::cout << std::endl;
128 std::cout <<
"Testing matrix assignment... ";
144 std::cout <<
"Testing upper left copy to GPU... ";
151 std::cout <<
"Testing lower right copy to GPU... ";
161 std::cout <<
"Testing upper left copy to A... ";
165 std::cout <<
"Testing lower right copy to C... ";
176 std::cout <<
"Inplace add: ";
183 std::cout <<
"Scaled inplace add: ";
184 ublas_C += beta * ublas_A;
185 vcl_C += gpu_beta * vcl_A;
190 std::cout <<
"Add: ";
191 ublas_C = ublas_A + ublas_B;
192 vcl_C = vcl_A + vcl_B;
197 std::cout <<
"Add with flipsign: ";
198 ublas_C = - ublas_A + ublas_B;
199 vcl_C = - vcl_A + vcl_B;
205 std::cout <<
"Scaled add (left): ";
206 ublas_C = alpha * ublas_A + ublas_B;
207 vcl_C = alpha * vcl_A + vcl_B;
212 std::cout <<
"Scaled add (left): ";
213 vcl_C = gpu_alpha * vcl_A + vcl_B;
218 std::cout <<
"Scaled add (right): ";
219 ublas_C = ublas_A + beta * ublas_B;
220 vcl_C = vcl_A + beta * vcl_B;
225 std::cout <<
"Scaled add (right): ";
226 vcl_C = vcl_A + gpu_beta * vcl_B;
232 std::cout <<
"Scaled add (both): ";
233 ublas_C = alpha * ublas_A + beta * ublas_B;
234 vcl_C = alpha * vcl_A + beta * vcl_B;
239 std::cout <<
"Scaled add (both): ";
240 vcl_C = gpu_alpha * vcl_A + gpu_beta * vcl_B;
249 std::cout <<
"Inplace sub: ";
256 std::cout <<
"Scaled Inplace sub: ";
257 ublas_C -= alpha * ublas_B;
258 vcl_C -= alpha * vcl_B;
266 std::cout <<
"Sub: ";
267 ublas_C = ublas_A - ublas_B;
268 vcl_C = vcl_A - vcl_B;
273 std::cout <<
"Scaled sub (left): ";
274 ublas_B = alpha * ublas_A - ublas_C;
275 vcl_B = alpha * vcl_A - vcl_C;
280 std::cout <<
"Scaled sub (left): ";
281 vcl_B = gpu_alpha * vcl_A - vcl_C;
286 std::cout <<
"Scaled sub (right): ";
287 ublas_B = ublas_A - beta * ublas_C;
288 vcl_B = vcl_A - vcl_C * beta;
293 std::cout <<
"Scaled sub (right): ";
294 vcl_B = vcl_A - vcl_C * gpu_beta;
299 std::cout <<
"Scaled sub (both): ";
300 ublas_B = alpha * ublas_A - beta * ublas_C;
301 vcl_B = alpha * vcl_A - vcl_C * beta;
306 std::cout <<
"Scaled sub (both): ";
307 vcl_B = gpu_alpha * vcl_A - vcl_C * gpu_beta;
312 std::cout <<
"Unary operator-: ";
326 std::cout <<
"Multiplication with CPU scalar: ";
333 std::cout <<
"Multiplication with GPU scalar: ";
341 std::cout <<
"Division with CPU scalar: ";
348 std::cout <<
"Division with GPU scalar: ";
357 std::cout <<
"Testing elementwise multiplication..." << std::endl;
358 ublas_B = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_B.size1(), ublas_B.size2(), 2);
359 ublas_A = 3 * ublas_B;
439 ublas_B = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_B.size1(), ublas_B.size2(), 2);
440 ublas_A = 3 * ublas_B;
520 std::cout <<
"Testing unary elementwise operations..." << std::endl;
522 #define GENERATE_UNARY_OP_TEST(FUNCNAME) \
523 ublas_B = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_B.size1(), ublas_B.size2(), 1); \
524 ublas_A = 3 * ublas_B; \
525 ublas_C = 2 * ublas_A; \
526 viennacl::copy(ublas_A, vcl_A); \
527 viennacl::copy(ublas_B, vcl_B); \
528 viennacl::copy(ublas_C, vcl_C); \
529 viennacl::copy(ublas_B, vcl_B); \
531 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
532 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
533 ublas_C(i,j) = std::FUNCNAME(ublas_A(i,j)); \
534 vcl_C = viennacl::linalg::element_##FUNCNAME(vcl_A); \
536 if (!check_for_equality(ublas_C, vcl_C)) \
538 std::cout << "Failure at C = " << #FUNCNAME << "(A)" << std::endl; \
539 return EXIT_FAILURE; \
542 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
543 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
544 ublas_C(i,j) = std::FUNCNAME(ublas_A(i,j) + ublas_B(i,j)); \
545 vcl_C = viennacl::linalg::element_##FUNCNAME(vcl_A + vcl_B); \
547 if (!check_for_equality(ublas_C, vcl_C)) \
549 std::cout << "Failure at C = " << #FUNCNAME << "(A + B)" << std::endl; \
550 return EXIT_FAILURE; \
553 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
554 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
555 ublas_C(i,j) += std::FUNCNAME(ublas_A(i,j)); \
556 vcl_C += viennacl::linalg::element_##FUNCNAME(vcl_A); \
558 if (!check_for_equality(ublas_C, vcl_C)) \
560 std::cout << "Failure at C += " << #FUNCNAME << "(A)" << std::endl; \
561 return EXIT_FAILURE; \
564 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
565 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
566 ublas_C(i,j) += std::FUNCNAME(ublas_A(i,j) + ublas_B(i,j)); \
567 vcl_C += viennacl::linalg::element_##FUNCNAME(vcl_A + vcl_B); \
569 if (!check_for_equality(ublas_C, vcl_C)) \
571 std::cout << "Failure at C += " << #FUNCNAME << "(A + B)" << std::endl; \
572 return EXIT_FAILURE; \
575 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
576 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
577 ublas_C(i,j) -= std::FUNCNAME(ublas_A(i,j)); \
578 vcl_C -= viennacl::linalg::element_##FUNCNAME(vcl_A); \
580 if (!check_for_equality(ublas_C, vcl_C)) \
582 std::cout << "Failure at C -= " << #FUNCNAME << "(A)" << std::endl; \
583 return EXIT_FAILURE; \
586 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
587 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
588 ublas_C(i,j) -= std::FUNCNAME(ublas_A(i,j) + ublas_B(i,j)); \
589 vcl_C -= viennacl::linalg::element_##FUNCNAME(vcl_A + vcl_B); \
591 if (!check_for_equality(ublas_C, vcl_C)) \
593 std::cout << "Failure at C -= " << #FUNCNAME << "(A + B)" << std::endl; \
594 return EXIT_FAILURE; \
600 std::cout <<
"Complicated expressions: ";
604 ublas_B += alpha * (- ublas_A - beta * ublas_C + ublas_A);
605 vcl_B += gpu_alpha * (- vcl_A - vcl_C * beta + vcl_A);
610 ublas_B += (- ublas_A - beta * ublas_C + ublas_A * beta) / gpu_alpha;
611 vcl_B += (- vcl_A - vcl_C * beta + gpu_beta * vcl_A) / gpu_alpha;
617 ublas_B -= alpha * (- ublas_A - beta * ublas_C - ublas_A);
618 vcl_B -= gpu_alpha * (- vcl_A - vcl_C * beta - vcl_A);
623 ublas_B -= (- ublas_A - beta * ublas_C - ublas_A * beta) / alpha;
624 vcl_B -= (- vcl_A - vcl_C * beta - gpu_beta * vcl_A) / gpu_alpha;
629 std::cout << std::endl;
630 std::cout <<
"----------------------------------------------" << std::endl;
631 std::cout << std::endl;
640 template<
typename T,
typename ScalarType>
644 typedef boost::numeric::ublas::matrix<ScalarType> MatrixType;
648 std::size_t dim_rows = 131;
649 std::size_t dim_cols = 33;
654 MatrixType ublas_A(dim_rows, dim_cols);
655 MatrixType ublas_B(dim_rows, dim_cols);
656 MatrixType ublas_C(dim_rows, dim_cols);
658 for (std::size_t i=0; i<ublas_A.size1(); ++i)
659 for (std::size_t j=0; j<ublas_A.size2(); ++j)
661 ublas_A(i,j) =
ScalarType((i+2) + (j+1)*(i+2));
662 ublas_B(i,j) =
ScalarType((j+2) + (j+1)*(j+2));
663 ublas_C(i,j) =
ScalarType((i+1) + (i+1)*(i+2));
666 MatrixType ublas_A_large(4 * dim_rows, 4 * dim_cols);
667 for (std::size_t i=0; i<ublas_A_large.size1(); ++i)
668 for (std::size_t j=0; j<ublas_A_large.size2(); ++j)
669 ublas_A_large(i,j) =
ScalarType(i * ublas_A_large.size2() + j);
672 VCLMatrixType vcl_A_full(4 * dim_rows, 4 * dim_cols);
673 VCLMatrixType vcl_B_full(4 * dim_rows, 4 * dim_cols);
674 VCLMatrixType vcl_C_full(4 * dim_rows, 4 * dim_cols);
683 VCLMatrixType vcl_A(dim_rows, dim_cols);
697 VCLMatrixType vcl_B(dim_rows, dim_cols);
711 VCLMatrixType vcl_C(dim_rows, dim_cols);
734 std::cout << std::endl;
735 std::cout <<
"//" << std::endl;
736 std::cout <<
"////////// Test: Copy CTOR //////////" << std::endl;
737 std::cout <<
"//" << std::endl;
740 std::cout <<
"Testing matrix created from range... ";
741 VCLMatrixType vcl_temp = vcl_range_A;
743 std::cout <<
"PASSED!" << std::endl;
746 std::cout <<
"ublas_A: " << ublas_A << std::endl;
747 std::cout <<
"vcl_temp: " << vcl_temp << std::endl;
748 std::cout <<
"vcl_range_A: " << vcl_range_A << std::endl;
749 std::cout <<
"vcl_A: " << vcl_A << std::endl;
750 std::cout << std::endl <<
"TEST failed!" << std::endl;
754 std::cout <<
"Testing matrix created from slice... ";
755 VCLMatrixType vcl_temp2 = vcl_range_B;
757 std::cout <<
"PASSED!" << std::endl;
760 std::cout << std::endl <<
"TEST failed!" << std::endl;
765 std::cout <<
"//" << std::endl;
766 std::cout <<
"////////// Test: Initializer for matrix type //////////" << std::endl;
767 std::cout <<
"//" << std::endl;
770 boost::numeric::ublas::matrix<ScalarType> ublas_dummy1 = boost::numeric::ublas::identity_matrix<ScalarType>(ublas_A.size1());
771 boost::numeric::ublas::matrix<ScalarType> ublas_dummy2 = boost::numeric::ublas::scalar_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1(), 3);
772 boost::numeric::ublas::matrix<ScalarType> ublas_dummy3 = boost::numeric::ublas::zero_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1());
778 std::cout <<
"Testing initializer CTOR... ";
783 std::cout <<
"PASSED!" << std::endl;
786 std::cout << std::endl <<
"TEST failed!" << std::endl;
790 ublas_dummy1 = boost::numeric::ublas::zero_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1());
791 ublas_dummy2 = boost::numeric::ublas::identity_matrix<ScalarType>(ublas_A.size1());
792 ublas_dummy3 = boost::numeric::ublas::scalar_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1(), 3);
798 std::cout <<
"Testing initializer assignment... ";
803 std::cout <<
"PASSED!" << std::endl;
806 std::cout << std::endl <<
"TEST failed!" << std::endl;
817 std::cout <<
"Testing A=matrix, B=matrix, C=matrix ..." << std::endl;
821 if (
run_test(ublas_A, ublas_B, ublas_C,
822 vcl_A, vcl_B, vcl_C) != EXIT_SUCCESS)
827 std::cout <<
"Testing A=matrix, B=matrix, C=range ..." << std::endl;
831 if (
run_test(ublas_A, ublas_B, ublas_C,
832 vcl_A, vcl_B, vcl_range_C) != EXIT_SUCCESS)
837 std::cout <<
"Testing A=matrix, B=matrix, C=slice ..." << std::endl;
841 if (
run_test(ublas_A, ublas_B, ublas_C,
842 vcl_A, vcl_B, vcl_slice_C) != EXIT_SUCCESS)
847 std::cout <<
"Testing A=matrix, B=range, C=matrix ..." << std::endl;
851 if (
run_test(ublas_A, ublas_B, ublas_C,
852 vcl_A, vcl_range_B, vcl_C) != EXIT_SUCCESS)
857 std::cout <<
"Testing A=matrix, B=range, C=range ..." << std::endl;
861 if (
run_test(ublas_A, ublas_B, ublas_C,
862 vcl_A, vcl_range_B, vcl_range_C) != EXIT_SUCCESS)
867 std::cout <<
"Testing A=matrix, B=range, C=slice ..." << std::endl;
871 if (
run_test(ublas_A, ublas_B, ublas_C,
872 vcl_A, vcl_range_B, vcl_slice_C) != EXIT_SUCCESS)
878 std::cout <<
"Testing A=matrix, B=slice, C=matrix ..." << std::endl;
882 if (
run_test(ublas_A, ublas_B, ublas_C,
883 vcl_A, vcl_slice_B, vcl_C) != EXIT_SUCCESS)
888 std::cout <<
"Testing A=matrix, B=slice, C=range ..." << std::endl;
892 if (
run_test(ublas_A, ublas_B, ublas_C,
893 vcl_A, vcl_slice_B, vcl_range_C) != EXIT_SUCCESS)
898 std::cout <<
"Testing A=matrix, B=slice, C=slice ..." << std::endl;
902 if (
run_test(ublas_A, ublas_B, ublas_C,
903 vcl_A, vcl_slice_B, vcl_slice_C) != EXIT_SUCCESS)
911 std::cout <<
"Testing A=range, B=matrix, C=matrix ..." << std::endl;
915 if (
run_test(ublas_A, ublas_B, ublas_C,
916 vcl_range_A, vcl_B, vcl_C) != EXIT_SUCCESS)
921 std::cout <<
"Testing A=range, B=matrix, C=range ..." << std::endl;
925 if (
run_test(ublas_A, ublas_B, ublas_C,
926 vcl_range_A, vcl_B, vcl_range_C) != EXIT_SUCCESS)
931 std::cout <<
"Testing A=range, B=matrix, C=slice ..." << std::endl;
935 if (
run_test(ublas_A, ublas_B, ublas_C,
936 vcl_range_A, vcl_B, vcl_slice_C) != EXIT_SUCCESS)
943 std::cout <<
"Testing A=range, B=range, C=matrix ..." << std::endl;
947 if (
run_test(ublas_A, ublas_B, ublas_C,
948 vcl_range_A, vcl_range_B, vcl_C) != EXIT_SUCCESS)
953 std::cout <<
"Testing A=range, B=range, C=range ..." << std::endl;
957 if (
run_test(ublas_A, ublas_B, ublas_C,
958 vcl_range_A, vcl_range_B, vcl_range_C) != EXIT_SUCCESS)
963 std::cout <<
"Testing A=range, B=range, C=slice ..." << std::endl;
967 if (
run_test(ublas_A, ublas_B, ublas_C,
968 vcl_range_A, vcl_range_B, vcl_slice_C) != EXIT_SUCCESS)
975 std::cout <<
"Testing A=range, B=slice, C=matrix ..." << std::endl;
979 if (
run_test(ublas_A, ublas_B, ublas_C,
980 vcl_range_A, vcl_slice_B, vcl_C) != EXIT_SUCCESS)
985 std::cout <<
"Testing A=range, B=slice, C=range ..." << std::endl;
989 if (
run_test(ublas_A, ublas_B, ublas_C,
990 vcl_range_A, vcl_slice_B, vcl_range_C) != EXIT_SUCCESS)
995 std::cout <<
"Testing A=range, B=slice, C=slice ..." << std::endl;
999 if (
run_test(ublas_A, ublas_B, ublas_C,
1000 vcl_range_A, vcl_slice_B, vcl_slice_C) != EXIT_SUCCESS)
1002 return EXIT_FAILURE;
1007 std::cout <<
"Testing A=slice, B=matrix, C=matrix ..." << std::endl;
1011 if (
run_test(ublas_A, ublas_B, ublas_C,
1012 vcl_slice_A, vcl_B, vcl_C) != EXIT_SUCCESS)
1014 return EXIT_FAILURE;
1017 std::cout <<
"Testing A=slice, B=matrix, C=range ..." << std::endl;
1021 if (
run_test(ublas_A, ublas_B, ublas_C,
1022 vcl_slice_A, vcl_B, vcl_range_C) != EXIT_SUCCESS)
1024 return EXIT_FAILURE;
1027 std::cout <<
"Testing A=slice, B=matrix, C=slice ..." << std::endl;
1031 if (
run_test(ublas_A, ublas_B, ublas_C,
1032 vcl_slice_A, vcl_B, vcl_slice_C) != EXIT_SUCCESS)
1034 return EXIT_FAILURE;
1039 std::cout <<
"Testing A=slice, B=range, C=matrix ..." << std::endl;
1043 if (
run_test(ublas_A, ublas_B, ublas_C,
1044 vcl_slice_A, vcl_range_B, vcl_C) != EXIT_SUCCESS)
1046 return EXIT_FAILURE;
1049 std::cout <<
"Testing A=slice, B=range, C=range ..." << std::endl;
1053 if (
run_test(ublas_A, ublas_B, ublas_C,
1054 vcl_slice_A, vcl_range_B, vcl_range_C) != EXIT_SUCCESS)
1056 return EXIT_FAILURE;
1059 std::cout <<
"Testing A=slice, B=range, C=slice ..." << std::endl;
1063 if (
run_test(ublas_A, ublas_B, ublas_C,
1064 vcl_slice_A, vcl_range_B, vcl_slice_C) != EXIT_SUCCESS)
1066 return EXIT_FAILURE;
1071 std::cout <<
"Testing A=slice, B=slice, C=matrix ..." << std::endl;
1075 if (
run_test(ublas_A, ublas_B, ublas_C,
1076 vcl_slice_A, vcl_slice_B, vcl_C) != EXIT_SUCCESS)
1078 return EXIT_FAILURE;
1081 std::cout <<
"Testing A=slice, B=slice, C=range ..." << std::endl;
1085 if (
run_test(ublas_A, ublas_B, ublas_C,
1086 vcl_slice_A, vcl_slice_B, vcl_range_C) != EXIT_SUCCESS)
1088 return EXIT_FAILURE;
1091 std::cout <<
"Testing A=slice, B=slice, C=slice ..." << std::endl;
1095 if (
run_test(ublas_A, ublas_B, ublas_C,
1096 vcl_slice_A, vcl_slice_B, vcl_slice_C) != EXIT_SUCCESS)
1098 return EXIT_FAILURE;
1102 return EXIT_SUCCESS;
viennacl::vector_expression< const vector_base< T >, const vector_base< T >, op_element_binary< op_div > > element_div(vector_base< T > const &v1, vector_base< T > const &v2)
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
Class for representing strided submatrices of a bigger matrix A.
Generic interface for matrix-vector and matrix-matrix products. See viennacl/linalg/vector_operations...
Implementation of the dense matrix class.
void finish()
Synchronizes the execution. finish() will only return after all compute kernels (CUDA, OpenCL) have completed.
Represents a vector consisting of 1 at a given index and zeros otherwise. To be used as an initialize...
Represents a vector consisting of scalars 's' only, i.e. v[i] = s for all i. To be used as an initial...
bool check_for_equality(MatrixType const &ublas_A, VCLMatrixType const &vcl_A)
#define GENERATE_UNARY_OP_TEST(FUNCNAME)
Represents a vector consisting of zeros only. To be used as an initializer for viennacl::vector, vector_range, or vector_slize only.
T::ERROR_CANNOT_DEDUCE_CPU_SCALAR_TYPE_FOR_T type
Proxy classes for vectors.
Proxy classes for matrices.
int run_test(UBLASMatrixType &ublas_A, UBLASMatrixType &ublas_B, UBLASMatrixType &ublas_C, ViennaCLMatrixType1 &vcl_A, ViennaCLMatrixType2 &vcl_B, ViennaCLMatrixType3 vcl_C)
void copy(std::vector< NumericT > &cpu_vec, circulant_matrix< NumericT, AlignmentV > &gpu_mat)
Copies a circulant matrix from the std::vector to the OpenCL device (either GPU or multi-core CPU) ...
A range class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
viennacl::vector_expression< const vector_base< T >, const vector_base< T >, op_element_binary< op_prod > > element_prod(vector_base< T > const &v1, vector_base< T > const &v2)
Class for representing non-strided submatrices of a bigger matrix A.
A slice class that refers to an interval [start, stop), where 'start' is included, and 'stop' is excluded.
Implementation of the ViennaCL scalar class.