I'm using Armadillo C++ library for matrices.
I would like to copy some of the rows to an external array (I need to copy them to the gpu). Is there a fast way to do this?
If I use .rows
, it gives me a subview with no access to data pointers, so I must iterate on the values and copy them one by one. This is very slow.
Is there another option?
Thanks.
Armadillo stores data column-by-column (for compatibility with LAPACK), so extracting columns via .colptr() is the preferred approach. You can refactor your code so that your data is stored column-by-column instead of row-by-row. One brute-force approach to accomplish this is to transpose the matrix.
A possible way to copy some of the rows to an external array is to use the .rows function and assign the result subview as a matrix. Then you can easily access the raw data of this matrix. You can also transpose this matrix if you want row-major data.
The quickest way to get to the matrix data in array format is to use the memptr()
method. It returns a pointer to a C-style array that contains the matrix data. So if you have a Mat<double>
of size n by n, that method gives you a pointer to an array of double
of length n*n.
int n=10;
Mat<double> M(n,n,fill::rand);
double* arr = M.memptr();
if you then loop through arr
you will get the elements in column-major ordering, as mtall pointed out.
Conversely you can very efficiently use an already existing array of data to initialize a matrix, or even just use the matrix object as an interface to perform some linear algebra transformation onto your array (like e.g. a Matrix-vector product). For that have a look into the advanced mat constructor.
This is especially useful for iterative methods such as Lanczos/Arnoldi or Conjugate Gradient related methods and you have an implementation of those working with C-style arrays. You can then just bind these arrays to arma objects without copying to perform transformations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With