This tutorial shows how data can be directly transferred from the Armadillo Library to ViennaCL objects using the built-in convenience wrappers.
The first step is to include the necessary headers and activate the Armadillo convenience functions in ViennaCL:
#include <iostream>
#define ARMA_DONT_USE_BLAS
#define ARMA_DONT_USE_LAPACK
#include <armadillo>
#define VIENNACL_WITH_ARMADILLO 1
The following function contains the main code for this tutorial. It consists of the following steps:
- Creates Armadillo matrices and vectors
- Initializes them with data
- Create ViennaCL objects
- Copy them over to the respective ViennaCL objects
- Compute matrix-vector products in both Armadillo and ViennaCL and compare results.
template<typename NumericT>
void run_tutorial()
{
typedef arma::SpMat<NumericT> ArmaSparseMatrix;
typedef arma::Mat<NumericT> ArmaMatrix;
typedef arma::Col<NumericT> ArmaVector;
Create and fill dense matrices from the Armadillo library:
ArmaMatrix arma_densemat(6, 5);
ArmaMatrix arma_densemat2(6, 5);
arma_densemat(0,0) = 2.0; arma_densemat(0,1) = -1.0;
arma_densemat(1,0) = -1.0; arma_densemat(1,1) = 2.0; arma_densemat(1,2) = -1.0;
arma_densemat(2,1) = -1.0; arma_densemat(2,2) = -1.0; arma_densemat(2,3) = -1.0;
arma_densemat(3,2) = -1.0; arma_densemat(3,3) = 2.0; arma_densemat(3,4) = -1.0;
arma_densemat(5,4) = -1.0; arma_densemat(4,4) = -1.0;
Create and fill sparse matrices from the Armadillo library:
ArmaSparseMatrix arma_sparsemat(6, 5);
ArmaSparseMatrix arma_sparsemat2(6, 5);
arma_sparsemat(0,0) = 2.0; arma_sparsemat(0,1) = -1.0;
arma_sparsemat(1,1) = 2.0; arma_sparsemat(1,2) = -1.0;
arma_sparsemat(2,2) = -1.0; arma_sparsemat(2,3) = -1.0;
arma_sparsemat(3,3) = 2.0; arma_sparsemat(3,4) = -1.0;
arma_sparsemat(5,4) = -1.0;
Create and fill a few vectors from the Armadillo library:
ArmaVector arma_rhs(5);
ArmaVector arma_result(6);
ArmaVector arma_temp(6);
arma_rhs(0) = 10.0;
arma_rhs(1) = 11.0;
arma_rhs(2) = 12.0;
arma_rhs(3) = 13.0;
arma_rhs(4) = 14.0;
Create the corresponding ViennaCL objects:
Directly copy the Armadillo objects to ViennaCL objects
viennacl::copy(arma_rhs.memptr(), arma_rhs.memptr() + arma_rhs.n_elem, vcl_rhs.begin());
std::cout << "VCL sparsematrix dimensions: " << vcl_sparsemat.size1() << ", " << vcl_sparsemat.size2() << std::endl;
Run dense matrix-vector products and compare results:
arma_result = arma_densemat * arma_rhs;
std::cout << "Difference for dense matrix-vector product: " << norm(arma_result - arma_temp) << std::endl;
std::cout << "Difference for dense matrix-vector product (Armadillo -> ViennaCL -> Armadillo): "
<< norm(arma_densemat2 * arma_rhs - arma_temp) << std::endl;
Run sparse matrix-vector products and compare results:
arma_result = arma_sparsemat * arma_rhs;
std::cout << "Difference for sparse matrix-vector product: " << norm(arma_result - arma_temp) << std::endl;
std::cout << "Difference for sparse matrix-vector product (Armadillo -> ViennaCL -> Armadillo): "
<< norm(arma_sparsemat2 * arma_rhs - arma_temp) << std::endl;
}
In the main() routine we only call the worker function defined above with both single and double precision arithmetic.
{
std::cout << "----------------------------------------------" << std::endl;
std::cout << "## Single precision" << std::endl;
std::cout << "----------------------------------------------" << std::endl;
run_tutorial<float>();
#ifdef VIENNACL_HAVE_OPENCL
#endif
{
std::cout << "----------------------------------------------" << std::endl;
std::cout << "## Double precision" << std::endl;
std::cout << "----------------------------------------------" << std::endl;
run_tutorial<double>();
}
That's it. Print a success message and exit.
std::cout << std::endl;
std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;
std::cout << std::endl;
}
Full Example Code
#include <iostream>
#define ARMA_DONT_USE_BLAS
#define ARMA_DONT_USE_LAPACK
#include <armadillo>
#define VIENNACL_WITH_ARMADILLO 1
template<typename NumericT>
void run_tutorial()
{
typedef arma::SpMat<NumericT> ArmaSparseMatrix;
typedef arma::Mat<NumericT> ArmaMatrix;
typedef arma::Col<NumericT> ArmaVector;
ArmaMatrix arma_densemat(6, 5);
ArmaMatrix arma_densemat2(6, 5);
arma_densemat(0,0) = 2.0; arma_densemat(0,1) = -1.0;
arma_densemat(1,0) = -1.0; arma_densemat(1,1) = 2.0; arma_densemat(1,2) = -1.0;
arma_densemat(2,1) = -1.0; arma_densemat(2,2) = -1.0; arma_densemat(2,3) = -1.0;
arma_densemat(3,2) = -1.0; arma_densemat(3,3) = 2.0; arma_densemat(3,4) = -1.0;
arma_densemat(5,4) = -1.0; arma_densemat(4,4) = -1.0;
ArmaSparseMatrix arma_sparsemat(6, 5);
ArmaSparseMatrix arma_sparsemat2(6, 5);
arma_sparsemat(0,0) = 2.0; arma_sparsemat(0,1) = -1.0;
arma_sparsemat(1,1) = 2.0; arma_sparsemat(1,2) = -1.0;
arma_sparsemat(2,2) = -1.0; arma_sparsemat(2,3) = -1.0;
arma_sparsemat(3,3) = 2.0; arma_sparsemat(3,4) = -1.0;
arma_sparsemat(5,4) = -1.0;
ArmaVector arma_rhs(5);
ArmaVector arma_result(6);
ArmaVector arma_temp(6);
arma_rhs(0) = 10.0;
arma_rhs(1) = 11.0;
arma_rhs(2) = 12.0;
arma_rhs(3) = 13.0;
arma_rhs(4) = 14.0;
std::cout <<
"VCL sparsematrix dimensions: " << vcl_sparsemat.
size1() <<
", " << vcl_sparsemat.
size2() << std::endl;
arma_result = arma_densemat * arma_rhs;
std::cout << "Difference for dense matrix-vector product: " << norm(arma_result - arma_temp) << std::endl;
std::cout << "Difference for dense matrix-vector product (Armadillo -> ViennaCL -> Armadillo): "
<< norm(arma_densemat2 * arma_rhs - arma_temp) << std::endl;
arma_result = arma_sparsemat * arma_rhs;
std::cout << "Difference for sparse matrix-vector product: " << norm(arma_result - arma_temp) << std::endl;
std::cout << "Difference for sparse matrix-vector product (Armadillo -> ViennaCL -> Armadillo): "
<< norm(arma_sparsemat2 * arma_rhs - arma_temp) << std::endl;
}
{
std::cout << "----------------------------------------------" << std::endl;
std::cout << "## Single precision" << std::endl;
std::cout << "----------------------------------------------" << std::endl;
run_tutorial<float>();
#ifdef VIENNACL_HAVE_OPENCL
#endif
{
std::cout << "----------------------------------------------" << std::endl;
std::cout << "## Double precision" << std::endl;
std::cout << "----------------------------------------------" << std::endl;
run_tutorial<double>();
}
std::cout << std::endl;
std::cout << "!!!! TUTORIAL COMPLETED SUCCESSFULLY !!!!" << std::endl;
std::cout << std::endl;
}