18 #define VIENNACL_WITH_UBLAS
43 #include "boost/numeric/ublas/vector.hpp"
44 #include "boost/numeric/ublas/matrix.hpp"
45 #include "boost/numeric/ublas/matrix_proxy.hpp"
46 #include "boost/numeric/ublas/vector_proxy.hpp"
47 #include "boost/numeric/ublas/io.hpp"
49 template<
typename MatrixType,
typename VCLMatrixType>
52 typedef typename MatrixType::value_type value_type;
54 boost::numeric::ublas::matrix<value_type> vcl_A_cpu(vcl_A.size1(), vcl_A.size2());
58 for (std::size_t i=0; i<ublas_A.size1(); ++i)
60 for (std::size_t j=0; j<ublas_A.size2(); ++j)
62 if (ublas_A(i,j) != vcl_A_cpu(i,j))
64 std::cout <<
"Error at index (" << i <<
", " << j <<
"): " << ublas_A(i,j) <<
" vs " << vcl_A_cpu(i,j) << std::endl;
65 std::cout << std::endl <<
"TEST failed!" << std::endl;
71 std::cout <<
"PASSED!" << std::endl;
78 template<
typename UBLASMatrixType,
79 typename ViennaCLMatrixType1,
typename ViennaCLMatrixType2,
typename ViennaCLMatrixType3>
80 int run_test(UBLASMatrixType & ublas_A, UBLASMatrixType & ublas_B, UBLASMatrixType & ublas_C,
81 ViennaCLMatrixType1 & vcl_A, ViennaCLMatrixType2 & vcl_B, ViennaCLMatrixType3 vcl_C)
86 cpu_value_type alpha = 3;
89 cpu_value_type beta = 2;
96 std::cout <<
"Checking for zero_matrix initializer..." << std::endl;
97 ublas_A = boost::numeric::ublas::zero_matrix<cpu_value_type>(ublas_A.size1(), ublas_A.size2());
102 std::cout <<
"Checking for scalar_matrix initializer..." << std::endl;
103 ublas_A = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_A.size1(), ublas_A.size2(), alpha);
108 ublas_A = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_A.size1(), ublas_A.size2(), gpu_beta);
121 std::cout << std::endl;
129 std::cout <<
"Testing matrix assignment... ";
145 std::cout <<
"Testing upper left copy to GPU... ";
152 std::cout <<
"Testing lower right copy to GPU... ";
162 std::cout <<
"Testing upper left copy to A... ";
166 std::cout <<
"Testing lower right copy to C... ";
177 std::cout <<
"Inplace add: ";
184 std::cout <<
"Scaled inplace add: ";
185 ublas_C += beta * ublas_A;
186 vcl_C += gpu_beta * vcl_A;
191 std::cout <<
"Add: ";
192 ublas_C = ublas_A + ublas_B;
193 vcl_C = vcl_A + vcl_B;
198 std::cout <<
"Add with flipsign: ";
199 ublas_C = - ublas_A + ublas_B;
200 vcl_C = - vcl_A + vcl_B;
206 std::cout <<
"Scaled add (left): ";
207 ublas_C = alpha * ublas_A + ublas_B;
208 vcl_C = alpha * vcl_A + vcl_B;
213 std::cout <<
"Scaled add (left): ";
214 vcl_C = gpu_alpha * vcl_A + vcl_B;
219 std::cout <<
"Scaled add (right): ";
220 ublas_C = ublas_A + beta * ublas_B;
221 vcl_C = vcl_A + beta * vcl_B;
226 std::cout <<
"Scaled add (right): ";
227 vcl_C = vcl_A + gpu_beta * vcl_B;
233 std::cout <<
"Scaled add (both): ";
234 ublas_C = alpha * ublas_A + beta * ublas_B;
235 vcl_C = alpha * vcl_A + beta * vcl_B;
240 std::cout <<
"Scaled add (both): ";
241 vcl_C = gpu_alpha * vcl_A + gpu_beta * vcl_B;
250 std::cout <<
"Inplace sub: ";
257 std::cout <<
"Scaled Inplace sub: ";
258 ublas_C -= alpha * ublas_B;
259 vcl_C -= alpha * vcl_B;
267 std::cout <<
"Sub: ";
268 ublas_C = ublas_A - ublas_B;
269 vcl_C = vcl_A - vcl_B;
274 std::cout <<
"Scaled sub (left): ";
275 ublas_B = alpha * ublas_A - ublas_C;
276 vcl_B = alpha * vcl_A - vcl_C;
281 std::cout <<
"Scaled sub (left): ";
282 vcl_B = gpu_alpha * vcl_A - vcl_C;
287 std::cout <<
"Scaled sub (right): ";
288 ublas_B = ublas_A - beta * ublas_C;
289 vcl_B = vcl_A - vcl_C * beta;
294 std::cout <<
"Scaled sub (right): ";
295 vcl_B = vcl_A - vcl_C * gpu_beta;
300 std::cout <<
"Scaled sub (both): ";
301 ublas_B = alpha * ublas_A - beta * ublas_C;
302 vcl_B = alpha * vcl_A - vcl_C * beta;
307 std::cout <<
"Scaled sub (both): ";
308 vcl_B = gpu_alpha * vcl_A - vcl_C * gpu_beta;
313 std::cout <<
"Unary operator-: ";
327 std::cout <<
"Multiplication with CPU scalar: ";
334 std::cout <<
"Multiplication with GPU scalar: ";
342 std::cout <<
"Division with CPU scalar: ";
349 std::cout <<
"Division with GPU scalar: ";
358 std::cout <<
"Testing elementwise multiplication..." << std::endl;
359 ublas_B = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_B.size1(), ublas_B.size2(), 2);
360 ublas_A = 3 * ublas_B;
440 ublas_B = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_B.size1(), ublas_B.size2(), 2);
441 ublas_A = 3 * ublas_B;
521 std::cout <<
"Testing unary elementwise operations..." << std::endl;
523 #define GENERATE_UNARY_OP_TEST(FUNCNAME) \
524 ublas_B = boost::numeric::ublas::scalar_matrix<cpu_value_type>(ublas_B.size1(), ublas_B.size2(), 1); \
525 ublas_A = 3 * ublas_B; \
526 ublas_C = 2 * ublas_A; \
527 viennacl::copy(ublas_A, vcl_A); \
528 viennacl::copy(ublas_B, vcl_B); \
529 viennacl::copy(ublas_C, vcl_C); \
530 viennacl::copy(ublas_B, vcl_B); \
532 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
533 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
534 ublas_C(i,j) = std::FUNCNAME(ublas_A(i,j)); \
535 vcl_C = viennacl::linalg::element_##FUNCNAME(vcl_A); \
537 if (!check_for_equality(ublas_C, vcl_C)) \
539 std::cout << "Failure at C = " << #FUNCNAME << "(A)" << std::endl; \
540 return EXIT_FAILURE; \
543 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
544 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
545 ublas_C(i,j) = std::FUNCNAME(ublas_A(i,j) + ublas_B(i,j)); \
546 vcl_C = viennacl::linalg::element_##FUNCNAME(vcl_A + vcl_B); \
548 if (!check_for_equality(ublas_C, vcl_C)) \
550 std::cout << "Failure at C = " << #FUNCNAME << "(A + B)" << std::endl; \
551 return EXIT_FAILURE; \
554 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
555 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
556 ublas_C(i,j) += std::FUNCNAME(ublas_A(i,j)); \
557 vcl_C += viennacl::linalg::element_##FUNCNAME(vcl_A); \
559 if (!check_for_equality(ublas_C, vcl_C)) \
561 std::cout << "Failure at C += " << #FUNCNAME << "(A)" << std::endl; \
562 return EXIT_FAILURE; \
565 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
566 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
567 ublas_C(i,j) += std::FUNCNAME(ublas_A(i,j) + ublas_B(i,j)); \
568 vcl_C += viennacl::linalg::element_##FUNCNAME(vcl_A + vcl_B); \
570 if (!check_for_equality(ublas_C, vcl_C)) \
572 std::cout << "Failure at C += " << #FUNCNAME << "(A + B)" << std::endl; \
573 return EXIT_FAILURE; \
576 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
577 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
578 ublas_C(i,j) -= std::FUNCNAME(ublas_A(i,j)); \
579 vcl_C -= viennacl::linalg::element_##FUNCNAME(vcl_A); \
581 if (!check_for_equality(ublas_C, vcl_C)) \
583 std::cout << "Failure at C -= " << #FUNCNAME << "(A)" << std::endl; \
584 return EXIT_FAILURE; \
587 for (std::size_t i=0; i<ublas_C.size1(); ++i) \
588 for (std::size_t j=0; j<ublas_C.size2(); ++j) \
589 ublas_C(i,j) -= std::FUNCNAME(ublas_A(i,j) + ublas_B(i,j)); \
590 vcl_C -= viennacl::linalg::element_##FUNCNAME(vcl_A + vcl_B); \
592 if (!check_for_equality(ublas_C, vcl_C)) \
594 std::cout << "Failure at C -= " << #FUNCNAME << "(A + B)" << std::endl; \
595 return EXIT_FAILURE; \
601 std::cout <<
"Complicated expressions: ";
605 ublas_B += alpha * (- ublas_A - beta * ublas_C + ublas_A);
606 vcl_B += gpu_alpha * (- vcl_A - vcl_C * beta + vcl_A);
611 ublas_B += (- ublas_A - beta * ublas_C + ublas_A * beta) / gpu_alpha;
612 vcl_B += (- vcl_A - vcl_C * beta + gpu_beta * vcl_A) / gpu_alpha;
618 ublas_B -= alpha * (- ublas_A - beta * ublas_C - ublas_A);
619 vcl_B -= gpu_alpha * (- vcl_A - vcl_C * beta - vcl_A);
624 ublas_B -= (- ublas_A - beta * ublas_C - ublas_A * beta) / alpha;
625 vcl_B -= (- vcl_A - vcl_C * beta - gpu_beta * vcl_A) / gpu_alpha;
630 std::cout << std::endl;
631 std::cout <<
"----------------------------------------------" << std::endl;
632 std::cout << std::endl;
641 template<
typename T,
typename ScalarType>
645 typedef boost::numeric::ublas::matrix<ScalarType> MatrixType;
649 std::size_t dim_rows = 131;
650 std::size_t dim_cols = 33;
655 MatrixType ublas_A(dim_rows, dim_cols);
656 MatrixType ublas_B(dim_rows, dim_cols);
657 MatrixType ublas_C(dim_rows, dim_cols);
659 for (std::size_t i=0; i<ublas_A.size1(); ++i)
660 for (std::size_t j=0; j<ublas_A.size2(); ++j)
662 ublas_A(i,j) =
ScalarType((i+2) + (j+1)*(i+2));
663 ublas_B(i,j) =
ScalarType((j+2) + (j+1)*(j+2));
664 ublas_C(i,j) =
ScalarType((i+1) + (i+1)*(i+2));
667 MatrixType ublas_A_large(4 * dim_rows, 4 * dim_cols);
668 for (std::size_t i=0; i<ublas_A_large.size1(); ++i)
669 for (std::size_t j=0; j<ublas_A_large.size2(); ++j)
670 ublas_A_large(i,j) =
ScalarType(i * ublas_A_large.size2() + j);
673 VCLMatrixType vcl_A_full(4 * dim_rows, 4 * dim_cols);
674 VCLMatrixType vcl_B_full(4 * dim_rows, 4 * dim_cols);
675 VCLMatrixType vcl_C_full(4 * dim_rows, 4 * dim_cols);
684 VCLMatrixType vcl_A(dim_rows, dim_cols);
698 VCLMatrixType vcl_B(dim_rows, dim_cols);
712 VCLMatrixType vcl_C(dim_rows, dim_cols);
735 std::cout << std::endl;
736 std::cout <<
"//" << std::endl;
737 std::cout <<
"////////// Test: Copy CTOR //////////" << std::endl;
738 std::cout <<
"//" << std::endl;
741 std::cout <<
"Testing matrix created from range... ";
742 VCLMatrixType vcl_temp = vcl_range_A;
744 std::cout <<
"PASSED!" << std::endl;
747 std::cout <<
"ublas_A: " << ublas_A << std::endl;
748 std::cout <<
"vcl_temp: " << vcl_temp << std::endl;
749 std::cout <<
"vcl_range_A: " << vcl_range_A << std::endl;
750 std::cout <<
"vcl_A: " << vcl_A << std::endl;
751 std::cout << std::endl <<
"TEST failed!" << std::endl;
755 std::cout <<
"Testing matrix created from slice... ";
756 VCLMatrixType vcl_temp2 = vcl_range_B;
758 std::cout <<
"PASSED!" << std::endl;
761 std::cout << std::endl <<
"TEST failed!" << std::endl;
766 std::cout <<
"//" << std::endl;
767 std::cout <<
"////////// Test: Initializer for matrix type //////////" << std::endl;
768 std::cout <<
"//" << std::endl;
771 boost::numeric::ublas::matrix<ScalarType> ublas_dummy1 = boost::numeric::ublas::identity_matrix<ScalarType>(ublas_A.size1());
772 boost::numeric::ublas::matrix<ScalarType> ublas_dummy2 = boost::numeric::ublas::scalar_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1(), 3);
773 boost::numeric::ublas::matrix<ScalarType> ublas_dummy3 = boost::numeric::ublas::zero_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1());
779 std::cout <<
"Testing initializer CTOR... ";
784 std::cout <<
"PASSED!" << std::endl;
787 std::cout << std::endl <<
"TEST failed!" << std::endl;
791 ublas_dummy1 = boost::numeric::ublas::zero_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1());
792 ublas_dummy2 = boost::numeric::ublas::identity_matrix<ScalarType>(ublas_A.size1());
793 ublas_dummy3 = boost::numeric::ublas::scalar_matrix<ScalarType>(ublas_A.size1(), ublas_A.size1(), 3);
799 std::cout <<
"Testing initializer assignment... ";
804 std::cout <<
"PASSED!" << std::endl;
807 std::cout << std::endl <<
"TEST failed!" << std::endl;
818 std::cout <<
"Testing A=matrix, B=matrix, C=matrix ..." << std::endl;
822 if (
run_test(ublas_A, ublas_B, ublas_C,
823 vcl_A, vcl_B, vcl_C) != EXIT_SUCCESS)
828 std::cout <<
"Testing A=matrix, B=matrix, C=range ..." << std::endl;
832 if (
run_test(ublas_A, ublas_B, ublas_C,
833 vcl_A, vcl_B, vcl_range_C) != EXIT_SUCCESS)
838 std::cout <<
"Testing A=matrix, B=matrix, C=slice ..." << std::endl;
842 if (
run_test(ublas_A, ublas_B, ublas_C,
843 vcl_A, vcl_B, vcl_slice_C) != EXIT_SUCCESS)
848 std::cout <<
"Testing A=matrix, B=range, C=matrix ..." << std::endl;
852 if (
run_test(ublas_A, ublas_B, ublas_C,
853 vcl_A, vcl_range_B, vcl_C) != EXIT_SUCCESS)
858 std::cout <<
"Testing A=matrix, B=range, C=range ..." << std::endl;
862 if (
run_test(ublas_A, ublas_B, ublas_C,
863 vcl_A, vcl_range_B, vcl_range_C) != EXIT_SUCCESS)
868 std::cout <<
"Testing A=matrix, B=range, C=slice ..." << std::endl;
872 if (
run_test(ublas_A, ublas_B, ublas_C,
873 vcl_A, vcl_range_B, vcl_slice_C) != EXIT_SUCCESS)
879 std::cout <<
"Testing A=matrix, B=slice, C=matrix ..." << std::endl;
883 if (
run_test(ublas_A, ublas_B, ublas_C,
884 vcl_A, vcl_slice_B, vcl_C) != EXIT_SUCCESS)
889 std::cout <<
"Testing A=matrix, B=slice, C=range ..." << std::endl;
893 if (
run_test(ublas_A, ublas_B, ublas_C,
894 vcl_A, vcl_slice_B, vcl_range_C) != EXIT_SUCCESS)
899 std::cout <<
"Testing A=matrix, B=slice, C=slice ..." << std::endl;
903 if (
run_test(ublas_A, ublas_B, ublas_C,
904 vcl_A, vcl_slice_B, vcl_slice_C) != EXIT_SUCCESS)
912 std::cout <<
"Testing A=range, B=matrix, C=matrix ..." << std::endl;
916 if (
run_test(ublas_A, ublas_B, ublas_C,
917 vcl_range_A, vcl_B, vcl_C) != EXIT_SUCCESS)
922 std::cout <<
"Testing A=range, B=matrix, C=range ..." << std::endl;
926 if (
run_test(ublas_A, ublas_B, ublas_C,
927 vcl_range_A, vcl_B, vcl_range_C) != EXIT_SUCCESS)
932 std::cout <<
"Testing A=range, B=matrix, C=slice ..." << std::endl;
936 if (
run_test(ublas_A, ublas_B, ublas_C,
937 vcl_range_A, vcl_B, vcl_slice_C) != EXIT_SUCCESS)
944 std::cout <<
"Testing A=range, B=range, C=matrix ..." << std::endl;
948 if (
run_test(ublas_A, ublas_B, ublas_C,
949 vcl_range_A, vcl_range_B, vcl_C) != EXIT_SUCCESS)
954 std::cout <<
"Testing A=range, B=range, C=range ..." << std::endl;
958 if (
run_test(ublas_A, ublas_B, ublas_C,
959 vcl_range_A, vcl_range_B, vcl_range_C) != EXIT_SUCCESS)
964 std::cout <<
"Testing A=range, B=range, C=slice ..." << std::endl;
968 if (
run_test(ublas_A, ublas_B, ublas_C,
969 vcl_range_A, vcl_range_B, vcl_slice_C) != EXIT_SUCCESS)
976 std::cout <<
"Testing A=range, B=slice, C=matrix ..." << std::endl;
980 if (
run_test(ublas_A, ublas_B, ublas_C,
981 vcl_range_A, vcl_slice_B, vcl_C) != EXIT_SUCCESS)
986 std::cout <<
"Testing A=range, B=slice, C=range ..." << std::endl;
990 if (
run_test(ublas_A, ublas_B, ublas_C,
991 vcl_range_A, vcl_slice_B, vcl_range_C) != EXIT_SUCCESS)
996 std::cout <<
"Testing A=range, B=slice, C=slice ..." << std::endl;
1000 if (
run_test(ublas_A, ublas_B, ublas_C,
1001 vcl_range_A, vcl_slice_B, vcl_slice_C) != EXIT_SUCCESS)
1003 return EXIT_FAILURE;
1008 std::cout <<
"Testing A=slice, B=matrix, C=matrix ..." << std::endl;
1012 if (
run_test(ublas_A, ublas_B, ublas_C,
1013 vcl_slice_A, vcl_B, vcl_C) != EXIT_SUCCESS)
1015 return EXIT_FAILURE;
1018 std::cout <<
"Testing A=slice, B=matrix, C=range ..." << std::endl;
1022 if (
run_test(ublas_A, ublas_B, ublas_C,
1023 vcl_slice_A, vcl_B, vcl_range_C) != EXIT_SUCCESS)
1025 return EXIT_FAILURE;
1028 std::cout <<
"Testing A=slice, B=matrix, C=slice ..." << std::endl;
1032 if (
run_test(ublas_A, ublas_B, ublas_C,
1033 vcl_slice_A, vcl_B, vcl_slice_C) != EXIT_SUCCESS)
1035 return EXIT_FAILURE;
1040 std::cout <<
"Testing A=slice, B=range, C=matrix ..." << std::endl;
1044 if (
run_test(ublas_A, ublas_B, ublas_C,
1045 vcl_slice_A, vcl_range_B, vcl_C) != EXIT_SUCCESS)
1047 return EXIT_FAILURE;
1050 std::cout <<
"Testing A=slice, B=range, C=range ..." << std::endl;
1054 if (
run_test(ublas_A, ublas_B, ublas_C,
1055 vcl_slice_A, vcl_range_B, vcl_range_C) != EXIT_SUCCESS)
1057 return EXIT_FAILURE;
1060 std::cout <<
"Testing A=slice, B=range, C=slice ..." << std::endl;
1064 if (
run_test(ublas_A, ublas_B, ublas_C,
1065 vcl_slice_A, vcl_range_B, vcl_slice_C) != EXIT_SUCCESS)
1067 return EXIT_FAILURE;
1072 std::cout <<
"Testing A=slice, B=slice, C=matrix ..." << std::endl;
1076 if (
run_test(ublas_A, ublas_B, ublas_C,
1077 vcl_slice_A, vcl_slice_B, vcl_C) != EXIT_SUCCESS)
1079 return EXIT_FAILURE;
1082 std::cout <<
"Testing A=slice, B=slice, C=range ..." << std::endl;
1086 if (
run_test(ublas_A, ublas_B, ublas_C,
1087 vcl_slice_A, vcl_slice_B, vcl_range_C) != EXIT_SUCCESS)
1089 return EXIT_FAILURE;
1092 std::cout <<
"Testing A=slice, B=slice, C=slice ..." << std::endl;
1096 if (
run_test(ublas_A, ublas_B, ublas_C,
1097 vcl_slice_A, vcl_slice_B, vcl_slice_C) != EXIT_SUCCESS)
1099 return EXIT_FAILURE;
1103 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.