1 #ifndef VIENNACL_COMPRESSED_MATRIX_HPP_
2 #define VIENNACL_COMPRESSED_MATRIX_HPP_
36 #ifdef VIENNACL_WITH_UBLAS
37 #include <boost/numeric/ublas/matrix_sparse.hpp>
49 template<
typename CPUMatrixT,
typename NumericT,
unsigned int AlignmentV>
59 std::vector<NumericT> elements(nonzeros);
64 for (
typename CPUMatrixT::const_iterator1 row_it = cpu_matrix.begin1();
65 row_it != cpu_matrix.end1();
68 row_buffer.set(row_index, data_index);
71 for (
typename CPUMatrixT::const_iterator2 col_it = row_it.begin();
72 col_it != row_it.end();
75 col_buffer.set(data_index, col_it.index2());
76 elements[data_index] = *col_it;
79 data_index = viennacl::tools::align_to_multiple<vcl_size_t>(data_index, AlignmentV);
81 row_buffer.set(row_index, data_index);
83 gpu_matrix.
set(row_buffer.get(),
111 template<
typename CPUMatrixT,
typename NumericT,
unsigned int AlignmentV>
112 void copy(
const CPUMatrixT & cpu_matrix,
115 if ( cpu_matrix.size1() > 0 && cpu_matrix.size2() > 0 )
119 for (
typename CPUMatrixT::const_iterator1 row_it = cpu_matrix.begin1();
120 row_it != cpu_matrix.end1();
124 for (
typename CPUMatrixT::const_iterator2 col_it = row_it.begin();
125 col_it != row_it.end();
130 num_entries += viennacl::tools::align_to_multiple<vcl_size_t>(entries_per_row, AlignmentV);
133 if (num_entries == 0)
148 template<
typename SizeT,
typename NumericT,
unsigned int AlignmentV>
149 void copy(
const std::vector< std::map<SizeT, NumericT> > & cpu_matrix,
154 for (
vcl_size_t i=0; i<cpu_matrix.size(); ++i)
156 if (cpu_matrix[i].
size() > 0)
157 nonzeros += ((cpu_matrix[i].
size() - 1) / AlignmentV + 1) * AlignmentV;
158 if (cpu_matrix[i].
size() > 0)
159 max_col = std::max<vcl_size_t>(max_col, (cpu_matrix[i].rbegin())->first);
167 #ifdef VIENNACL_WITH_UBLAS
172 template<
typename ScalarType,
typename F, vcl_
size_t IB,
typename IA,
typename TA>
173 void copy(
const boost::numeric::ublas::compressed_matrix<ScalarType, F, IB, IA, TA> & ublas_matrix,
181 for (
vcl_size_t i=0; i<=ublas_matrix.size1(); ++i)
182 row_buffer.
set(i, ublas_matrix.index1_data()[i]);
185 for (
vcl_size_t i=0; i<ublas_matrix.nnz(); ++i)
186 col_buffer.
set(i, ublas_matrix.index2_data()[i]);
188 gpu_matrix.
set(row_buffer.get(),
190 &(ublas_matrix.value_data()[0]),
191 ublas_matrix.size1(),
192 ublas_matrix.size2(),
198 #ifdef VIENNACL_WITH_EIGEN
203 template<
typename NumericT,
int flags,
unsigned int AlignmentV>
204 void copy(
const Eigen::SparseMatrix<NumericT, flags> & eigen_matrix,
205 compressed_matrix<NumericT, AlignmentV> & gpu_matrix)
207 assert( (gpu_matrix.size1() == 0 ||
static_cast<vcl_size_t>(eigen_matrix.rows()) == gpu_matrix.size1()) &&
bool(
"Size mismatch") );
208 assert( (gpu_matrix.size2() == 0 ||
static_cast<vcl_size_t>(eigen_matrix.cols()) == gpu_matrix.size2()) &&
bool(
"Size mismatch") );
210 std::vector< std::map<unsigned int, NumericT> > stl_matrix(eigen_matrix.rows());
212 for (
int k=0; k < eigen_matrix.outerSize(); ++k)
213 for (
typename Eigen::SparseMatrix<NumericT, flags>::InnerIterator it(eigen_matrix, k); it; ++it)
214 stl_matrix[it.row()][it.col()] = it.value();
216 copy(tools::const_sparse_matrix_adapter<NumericT>(stl_matrix, eigen_matrix.rows(), eigen_matrix.cols()), gpu_matrix);
221 #ifdef VIENNACL_WITH_MTL4
226 template<
typename NumericT,
unsigned int AlignmentV>
227 void copy(
const mtl::compressed2D<NumericT> & cpu_matrix,
228 compressed_matrix<NumericT, AlignmentV> & gpu_matrix)
230 assert( (gpu_matrix.size1() == 0 ||
static_cast<vcl_size_t>(cpu_matrix.num_rows()) == gpu_matrix.size1()) &&
bool(
"Size mismatch") );
231 assert( (gpu_matrix.size2() == 0 ||
static_cast<vcl_size_t>(cpu_matrix.num_cols()) == gpu_matrix.size2()) &&
bool(
"Size mismatch") );
233 typedef mtl::compressed2D<NumericT> MatrixType;
235 std::vector< std::map<unsigned int, NumericT> > stl_matrix(cpu_matrix.num_rows());
237 using mtl::traits::range_generator;
241 typedef typename min<range_generator<mtl::tag::row, MatrixType>,
242 range_generator<mtl::tag::col, MatrixType> >::type range_type;
246 typedef typename range_type::type c_type;
248 typedef typename mtl::traits::range_generator<mtl::tag::nz, c_type>::type ic_type;
251 typename mtl::traits::row<MatrixType>::type
row(cpu_matrix);
252 typename mtl::traits::col<MatrixType>::type col(cpu_matrix);
253 typename mtl::traits::const_value<MatrixType>::type value(cpu_matrix);
256 for (c_type cursor(my_range.begin(cpu_matrix)), cend(my_range.end(cpu_matrix)); cursor != cend; ++cursor)
257 for (ic_type icursor(mtl::begin<mtl::tag::nz>(cursor)), icend(mtl::end<mtl::tag::nz>(cursor)); icursor != icend; ++icursor)
258 stl_matrix[
row(*icursor)][col(*icursor)] = value(*icursor);
260 copy(tools::const_sparse_matrix_adapter<NumericT>(stl_matrix, cpu_matrix.num_rows(), cpu_matrix.num_cols()), gpu_matrix);
282 template<
typename CPUMatrixT,
typename NumericT,
unsigned int AlignmentV>
284 CPUMatrixT & cpu_matrix )
289 if ( gpu_matrix.
size1() > 0 && gpu_matrix.
size2() > 0 )
294 std::vector<NumericT> elements(gpu_matrix.
nnz());
306 while (data_index < row_buffer[
row])
308 if (col_buffer[data_index] >= gpu_matrix.
size2())
310 std::cerr <<
"ViennaCL encountered invalid data at colbuffer[" << data_index <<
"]: " << col_buffer[data_index] << std::endl;
314 if (std::fabs(elements[data_index]) >
static_cast<NumericT
>(0))
315 cpu_matrix(row-1, static_cast<vcl_size_t>(col_buffer[data_index])) = elements[data_index];
328 template<
typename NumericT,
unsigned int AlignmentV>
330 std::vector< std::map<unsigned int, NumericT> > & cpu_matrix)
333 copy(gpu_matrix, temp);
336 #ifdef VIENNACL_WITH_UBLAS
341 template<
typename ScalarType,
unsigned int AlignmentV,
typename F, vcl_
size_t IB,
typename IA,
typename TA>
343 boost::numeric::ublas::compressed_matrix<ScalarType> & ublas_matrix)
354 ublas_matrix.clear();
355 ublas_matrix.reserve(gpu_matrix.
nnz());
357 ublas_matrix.set_filled(gpu_matrix.
size1() + 1, gpu_matrix.
nnz());
359 for (
vcl_size_t i=0; i<ublas_matrix.size1() + 1; ++i)
360 ublas_matrix.index1_data()[i] = row_buffer[i];
362 for (
vcl_size_t i=0; i<ublas_matrix.nnz(); ++i)
363 ublas_matrix.index2_data()[i] = col_buffer[i];
370 #ifdef VIENNACL_WITH_EIGEN
372 template<
typename NumericT,
int flags,
unsigned int AlignmentV>
373 void copy(compressed_matrix<NumericT, AlignmentV> & gpu_matrix,
374 Eigen::SparseMatrix<NumericT, flags> & eigen_matrix)
376 assert( (static_cast<vcl_size_t>(eigen_matrix.rows()) == gpu_matrix.size1()) &&
bool(
"Size mismatch") );
377 assert( (static_cast<vcl_size_t>(eigen_matrix.cols()) == gpu_matrix.size2()) &&
bool(
"Size mismatch") );
379 if ( gpu_matrix.size1() > 0 && gpu_matrix.size2() > 0 )
384 std::vector<NumericT> elements(gpu_matrix.nnz());
390 eigen_matrix.setZero();
394 while (data_index < row_buffer[
row])
396 assert(col_buffer[data_index] < gpu_matrix.size2() && bool(
"ViennaCL encountered invalid data at col_buffer"));
397 if (elements[data_index] != static_cast<NumericT>(0.0))
398 eigen_matrix.insert(row-1, col_buffer[data_index]) = elements[data_index];
408 #ifdef VIENNACL_WITH_MTL4
410 template<
typename NumericT,
unsigned int AlignmentV>
411 void copy(compressed_matrix<NumericT, AlignmentV> & gpu_matrix,
412 mtl::compressed2D<NumericT> & mtl4_matrix)
414 assert( (static_cast<vcl_size_t>(mtl4_matrix.num_rows()) == gpu_matrix.size1()) &&
bool(
"Size mismatch") );
415 assert( (static_cast<vcl_size_t>(mtl4_matrix.num_cols()) == gpu_matrix.size2()) &&
bool(
"Size mismatch") );
417 if ( gpu_matrix.size1() > 0 && gpu_matrix.size2() > 0 )
423 std::vector<NumericT> elements(gpu_matrix.nnz());
432 mtl::matrix::inserter< mtl::compressed2D<NumericT> > ins(mtl4_matrix);
436 while (data_index < row_buffer[row])
438 assert(col_buffer[data_index] < gpu_matrix.size2() && bool(
"ViennaCL encountered invalid data at col_buffer"));
439 if (elements[data_index] != static_cast<NumericT>(0.0))
440 ins(row-1, col_buffer[data_index]) <<
typename mtl::Collection< mtl::compressed2D<NumericT> >::value_type(elements[data_index]);
458 template<
class NumericT,
unsigned int AlignmentV >
477 : rows_(rows), cols_(cols), nonzeros_(nonzeros), row_block_num_(0)
484 #ifdef VIENNACL_WITH_OPENCL
487 row_buffer_.opencl_handle().context(ctx.opencl_context());
488 col_buffer_.opencl_handle().context(ctx.opencl_context());
489 elements_.opencl_handle().context(ctx.opencl_context());
490 row_blocks_.opencl_handle().context(ctx.opencl_context());
511 : rows_(rows), cols_(cols), nonzeros_(0), row_block_num_(0)
518 #ifdef VIENNACL_WITH_OPENCL
521 row_buffer_.opencl_handle().context(ctx.opencl_context());
522 col_buffer_.opencl_handle().context(ctx.opencl_context());
523 elements_.opencl_handle().context(ctx.opencl_context());
524 row_blocks_.opencl_handle().context(ctx.opencl_context());
544 #ifdef VIENNACL_WITH_OPENCL
547 row_buffer_.opencl_handle().context(ctx.opencl_context());
548 col_buffer_.opencl_handle().context(ctx.opencl_context());
549 elements_.opencl_handle().context(ctx.opencl_context());
550 row_blocks_.opencl_handle().context(ctx.opencl_context());
556 #ifdef VIENNACL_WITH_OPENCL
566 explicit compressed_matrix(cl_mem mem_row_buffer, cl_mem mem_col_buffer, cl_mem mem_elements,
568 rows_(rows), cols_(cols), nonzeros_(nonzeros), row_block_num_(0)
571 row_buffer_.opencl_handle() = mem_row_buffer;
572 row_buffer_.opencl_handle().inc();
573 row_buffer_.
raw_size(
sizeof(cl_uint) * (rows + 1));
576 col_buffer_.opencl_handle() = mem_col_buffer;
577 col_buffer_.opencl_handle().inc();
578 col_buffer_.
raw_size(
sizeof(cl_uint) * nonzeros);
581 elements_.opencl_handle() = mem_elements;
582 elements_.opencl_handle().inc();
583 elements_.
raw_size(
sizeof(NumericT) * nonzeros);
586 generate_row_block_information();
594 assert( (rows_ == 0 || rows_ == other.
size1()) &&
bool(
"Size mismatch") );
595 assert( (cols_ == 0 || cols_ == other.
size2()) &&
bool(
"Size mismatch") );
597 rows_ = other.
size1();
598 cols_ = other.
size2();
599 nonzeros_ = other.
nnz();
600 row_block_num_ = other.row_block_num_;
602 viennacl::backend::typesafe_memory_copy<unsigned int>(other.row_buffer_, row_buffer_);
603 viennacl::backend::typesafe_memory_copy<unsigned int>(other.col_buffer_, col_buffer_);
604 viennacl::backend::typesafe_memory_copy<unsigned int>(other.row_blocks_, row_blocks_);
605 viennacl::backend::typesafe_memory_copy<NumericT>(other.elements_, elements_);
624 void set(
const void * row_jumper,
625 const void * col_buffer,
626 const NumericT * elements,
631 assert( (rows > 0) &&
bool(
"Error in compressed_matrix::set(): Number of rows must be larger than zero!"));
632 assert( (cols > 0) &&
bool(
"Error in compressed_matrix::set(): Number of columns must be larger than zero!"));
633 assert( (nonzeros > 0) &&
bool(
"Error in compressed_matrix::set(): Number of nonzeros must be larger than zero!"));
645 nonzeros_ = nonzeros;
650 generate_row_block_information();
656 if (new_nonzeros > nonzeros_)
670 nonzeros_ = new_nonzeros;
682 assert(new_size1 > 0 && new_size2 > 0 &&
bool(
"Cannot resize to zero size!"));
684 if (new_size1 != rows_ || new_size2 != cols_)
686 std::vector<std::map<unsigned int, NumericT> > stl_sparse_matrix;
691 stl_sparse_matrix.resize(rows_);
694 stl_sparse_matrix[0][0] = 0;
696 stl_sparse_matrix.resize(new_size1);
697 stl_sparse_matrix[0][0] = 0;
700 stl_sparse_matrix.resize(new_size1);
703 if (new_size2 < cols_ && rows_ > 0)
705 for (
vcl_size_t i=0; i<stl_sparse_matrix.size(); ++i)
707 std::list<unsigned int> to_delete;
708 for (
typename std::map<unsigned int, NumericT>::iterator it = stl_sparse_matrix[i].begin();
709 it != stl_sparse_matrix[i].end();
712 if (it->first >= new_size2)
713 to_delete.push_back(it->first);
716 for (std::list<unsigned int>::iterator it = to_delete.begin(); it != to_delete.end(); ++it)
717 stl_sparse_matrix[i].erase(*it);
733 std::vector<NumericT> host_elements(1);
745 assert( (i < rows_) && (j < cols_) &&
bool(
"compressed_matrix access out of bounds!"));
750 if (index < nonzeros_)
754 std::vector< std::map<unsigned int, NumericT> > cpu_backup(rows_);
757 cpu_backup[i][
static_cast<unsigned int>(j)] = 0.0;
760 index = element_index(i, j);
762 assert(index < nonzeros_);
800 viennacl::backend::switch_memory_context<unsigned int>(row_buffer_, new_ctx);
801 viennacl::backend::switch_memory_context<unsigned int>(col_buffer_, new_ctx);
802 viennacl::backend::switch_memory_context<unsigned int>(row_blocks_, new_ctx);
803 viennacl::backend::switch_memory_context<NumericT>(elements_, new_ctx);
823 viennacl::backend::memory_read(col_buffer_, col_indices.element_size()*row_indices[0], row_indices.element_size()*col_indices.size(), col_indices.get());
825 for (
vcl_size_t k=0; k<col_indices.size(); ++k)
827 if (col_indices[k] == j)
828 return row_indices[0] + k;
835 void generate_row_block_information()
847 row_blocks.set(0, 0);
851 num_entries_in_current_batch += entries_in_row;
853 if (num_entries_in_current_batch > shared_mem_size)
855 vcl_size_t rows_in_batch = i - row_blocks[row_block_num_];
856 if (rows_in_batch > 0)
857 row_blocks.set(++row_block_num_, i--);
859 row_blocks.set(++row_block_num_, i+1);
860 num_entries_in_current_batch = 0;
863 if (num_entries_in_current_batch > 0)
864 row_blocks.set(++row_block_num_, rows_);
866 if (row_block_num_ > 0)
868 row_blocks.element_size() * (row_block_num_ + 1),
900 template<
typename T,
unsigned int A>
901 struct op_executor<vector_base<T>,
op_assign, vector_expression<const compressed_matrix<T, A>, const vector_base<T>, op_prod> >
903 static void apply(vector_base<T> & lhs, vector_expression<
const compressed_matrix<T, A>,
const vector_base<T>, op_prod>
const & rhs)
917 template<
typename T,
unsigned int A>
918 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const compressed_matrix<T, A>, const vector_base<T>, op_prod> >
920 static void apply(vector_base<T> & lhs, vector_expression<
const compressed_matrix<T, A>,
const vector_base<T>, op_prod>
const & rhs)
928 template<
typename T,
unsigned int A>
929 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const compressed_matrix<T, A>, const vector_base<T>, op_prod> >
931 static void apply(vector_base<T> & lhs, vector_expression<
const compressed_matrix<T, A>,
const vector_base<T>, op_prod>
const & rhs)
941 template<
typename T,
unsigned int A,
typename LHS,
typename RHS,
typename OP>
942 struct op_executor<vector_base<T>,
op_assign, vector_expression<const compressed_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> >
944 static void apply(vector_base<T> & lhs, vector_expression<
const compressed_matrix<T, A>,
const vector_expression<const LHS, const RHS, OP>, op_prod>
const & rhs)
952 template<
typename T,
unsigned int A,
typename LHS,
typename RHS,
typename OP>
953 struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const compressed_matrix<T, A>, vector_expression<const LHS, const RHS, OP>, op_prod> >
955 static void apply(vector_base<T> & lhs, vector_expression<
const compressed_matrix<T, A>, vector_expression<const LHS, const RHS, OP>, op_prod>
const & rhs)
965 template<
typename T,
unsigned int A,
typename LHS,
typename RHS,
typename OP>
966 struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const compressed_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> >
968 static void apply(vector_base<T> & lhs, vector_expression<
const compressed_matrix<T, A>,
const vector_expression<const LHS, const RHS, OP>, op_prod>
const & rhs)
const vcl_size_t & size2() const
Returns the number of columns.
Helper class implementing an array on the host. Default case: No conversion necessary.
vcl_size_t element_size() const
This class represents a single scalar value on the GPU and behaves mostly like a built-in scalar type...
const vcl_size_t & size1() const
Returns the number of rows.
void switch_memory_context(viennacl::context new_ctx)
Switches the memory context of the matrix.
vcl_size_t size1(MatrixType const &mat)
Generic routine for obtaining the number of rows of a matrix (ViennaCL, uBLAS, etc.)
A proxy class for entries in a vector.
This file provides the forward declarations for the main types used within ViennaCL.
void memory_read(mem_handle const &src_buffer, vcl_size_t src_offset, vcl_size_t bytes_to_read, void *ptr, bool async=false)
Reads data from a buffer back to main RAM.
result_of::size_type< MatrixType >::type size2(MatrixType const &mat)
Generic routine for obtaining the number of columns of a matrix (ViennaCL, uBLAS, etc...
const handle_type & handle() const
Returns the OpenCL handle to the matrix entry array.
const handle_type & handle1() const
Returns the OpenCL handle to the row index array.
const vcl_size_t & nnz() const
Returns the number of nonzero entries.
vcl_size_t element_size(memory_types)
Represents a generic 'context' similar to an OpenCL context, but is backend-agnostic and thus also su...
vcl_size_t size(VectorType const &vec)
Generic routine for obtaining the size of a vector (ViennaCL, uBLAS, etc.)
entry_proxy< NumericT > operator()(vcl_size_t i, vcl_size_t j)
Returns a reference to the (i,j)-th entry of the sparse matrix. If (i,j) does not exist (zero)...
handle_type & handle3()
Returns the OpenCL handle to the row block array.
handle_type & handle()
Returns the OpenCL handle to the matrix entry array.
Implementations of operations using sparse matrices.
const handle_type & handle2() const
Returns the OpenCL handle to the column index array.
void clear()
Resets all entries in the matrix back to zero without changing the matrix size. Resets the sparsity p...
void reserve(vcl_size_t new_nonzeros)
Allocate memory for the supplied number of nonzeros in the matrix. Old values are preserved...
scalar< typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT< NumericT >::ResultType > value_type
compressed_matrix(vcl_size_t rows, vcl_size_t cols, viennacl::context ctx)
Construction of a compressed matrix with the supplied number of rows and columns. If the number of no...
vector_expression< const matrix_base< NumericT, F >, const unsigned int, op_row > row(const matrix_base< NumericT, F > &A, unsigned int i)
viennacl::memory_types memory_type() const
void copy_impl(const CPUMatrixT &cpu_matrix, compressed_compressed_matrix< NumericT > &gpu_matrix, vcl_size_t nonzero_rows, vcl_size_t nonzeros)
viennacl::memory_types memory_context() const
Returns the current memory context to determine whether the matrix is set up for OpenMP, OpenCL, or CUDA.
const handle_type & handle3() const
Returns the OpenCL handle to the row block array.
handle_type & handle1()
Returns the OpenCL handle to the row index array.
compressed_matrix(vcl_size_t rows, vcl_size_t cols, vcl_size_t nonzeros=0, viennacl::context ctx=viennacl::context())
Construction of a compressed matrix with the supplied number of rows and columns. If the number of no...
void switch_active_handle_id(memory_types new_id)
Switches the currently active handle. If no support for that backend is provided, an exception is thr...
void memory_copy(mem_handle const &src_buffer, mem_handle &dst_buffer, vcl_size_t src_offset, vcl_size_t dst_offset, vcl_size_t bytes_to_copy)
Copies 'bytes_to_copy' bytes from address 'src_buffer + src_offset' to memory starting at address 'ds...
compressed_matrix(viennacl::context ctx)
Creates an empty compressed_matrix, but sets the respective context information.
viennacl::context context(T const &t)
Returns an ID for the currently active memory domain of an object.
The vector type with operator-overloads and proxy classes is defined here. Linear algebra operations ...
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) ...
void set(const void *row_jumper, const void *col_buffer, const NumericT *elements, vcl_size_t rows, vcl_size_t cols, vcl_size_t nonzeros)
Sets the row, column and value arrays of the compressed matrix.
void set(vcl_size_t index, U value)
viennacl::backend::mem_handle handle_type
Main abstraction class for multiple memory domains. Represents a buffer in either main RAM...
vcl_size_t raw_size() const
Returns the number of bytes of the currently active buffer.
A sparse square matrix in compressed sparse rows format.
void memory_create(mem_handle &handle, vcl_size_t size_in_bytes, viennacl::context const &ctx, const void *host_ptr=NULL)
Creates an array of the specified size. If the second argument is provided, the buffer is initialized...
T min(const T &lhs, const T &rhs)
Minimum.
void prod_impl(const matrix_base< NumericT > &mat, const vector_base< NumericT > &vec, vector_base< NumericT > &result)
Carries out matrix-vector multiplication.
viennacl::backend::mem_handle & handle(T &obj)
Returns the generic memory handle of an object. Non-const version.
const vcl_size_t & blocks1() const
Returns the internal number of row blocks for an adaptive SpMV.
A proxy class for a single element of a vector or matrix. This proxy should not be noticed by end-use...
compressed_matrix()
Default construction of a compressed matrix. No memory is allocated.
void resize(vcl_size_t new_size1, vcl_size_t new_size2, bool preserve=true)
Resize the matrix.
void memory_shallow_copy(mem_handle const &src_buffer, mem_handle &dst_buffer)
A 'shallow' copy operation from an initialized buffer to an uninitialized buffer. The uninitialized b...
compressed_matrix & operator=(compressed_matrix const &other)
Assignment a compressed matrix from possibly another memory domain.
handle_type & handle2()
Returns the OpenCL handle to the column index array.
memory_types get_active_handle_id() const
Returns an ID for the currently active memory buffer. Other memory buffers might contain old or no da...