GEOSX
CRSMatrix.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020, Lawrence Livermore National Security, LLC and LvArray contributors.
3  * All rights reserved.
4  * See the LICENSE file for details.
5  * SPDX-License-Identifier: (BSD-3-Clause)
6  */
7 
13 #pragma once
14 
15 #include "CRSMatrixView.hpp"
16 #include "arrayManipulation.hpp"
17 
18 namespace LvArray
19 {
20 
21 template< typename COL_TYPE, typename INDEX_TYPE, template< typename > class BUFFER_TYPE >
23 
31 template< typename T,
32  typename COL_TYPE,
33  typename INDEX_TYPE,
34  template< typename > class BUFFER_TYPE >
35 class CRSMatrix : protected CRSMatrixView< T, COL_TYPE, INDEX_TYPE, BUFFER_TYPE >
36 {
37 
40 
41 public:
42 
43  using typename ParentClass::EntryType;
44  using typename ParentClass::ColType;
45  using typename ParentClass::IndexType;
46 
50 
58  CRSMatrix( INDEX_TYPE const nrows=0,
59  INDEX_TYPE const ncols=0,
60  INDEX_TYPE const initialRowCapacity=0 ):
61  ParentClass( true )
62  {
63  resize( nrows, ncols, initialRowCapacity );
64  setName( "" );
65  }
66 
71  inline
72  CRSMatrix( CRSMatrix const & src ):
73  ParentClass( true )
74  { *this = src; }
75 
79  inline
80  CRSMatrix( CRSMatrix && ) = default;
81 
86  { ParentClass::free( this->m_entries ); }
87 
89 
93 
100  inline
101  CRSMatrix & operator=( CRSMatrix const & src )
102  {
103  this->m_numCols = src.m_numCols;
105  src.m_offsets[ src.m_numArrays ],
106  src.m_offsets,
107  src.m_sizes,
108  src.m_values,
109  typename ParentClass::template PairOfBuffers< T >( this->m_entries, src.m_entries ) );
110  return *this;
111  }
112 
118  inline
120  {
121  ParentClass::free( this->m_entries );
122  ParentClass::operator=( std::move( src ) );
123  return *this;
124  }
125 
131  template< typename POLICY >
132  inline
134  {
135  // Destroy the current entries.
136  if( !std::is_trivially_destructible< T >::value )
137  {
139  RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, numRows() ),
140  [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row )
141  {
142  INDEX_TYPE const nnz = view.numNonZeros( row );
143  T * const entries = view.getEntries( row );
144  arrayManipulation::destroy( entries, nnz );
145  } );
146  }
147 
148  // Reallocate to the appropriate length
149  bufferManipulation::reserve( this->m_entries, 0, src.nonZeroCapacity() );
150 
152 
154  RAJA::forall< POLICY >( RAJA::TypedRangeSegment< INDEX_TYPE >( 0, numRows() ),
155  [view] LVARRAY_HOST_DEVICE ( INDEX_TYPE const row )
156  {
157  T * const rowEntries = view.getEntries( row );
158  for( INDEX_TYPE i = 0; i < view.numNonZeros( row ); ++i )
159  {
160  new ( rowEntries + i ) T();
161  }
162  } );
163 
164  setName( "" );
165  }
166 
176  template< typename POLICY >
177  void resizeFromRowCapacities( INDEX_TYPE const nRows, INDEX_TYPE const nCols, INDEX_TYPE const * const rowCapacities )
178  {
179  LVARRAY_ERROR_IF( !arrayManipulation::isPositive( nCols ), "nCols must be positive." );
181  "COL_TYPE must be able to hold the range of columns: [0, " << nCols - 1 << "]." );
182 
183  this->m_numCols = nCols;
184  ParentClass::template resizeFromCapacities< POLICY >( nRows, rowCapacities, this->m_entries );
185  }
186 
188 
192 
200  constexpr inline
202  toView() const &
203  { return ParentClass::toView(); }
204 
212  constexpr inline
214  toView() const && = delete;
215 
222  LVARRAY_HOST_DEVICE constexpr inline
225  { return ParentClass::toViewConstSizes(); }
226 
234  LVARRAY_HOST_DEVICE constexpr inline
236  toViewConstSizes() const && = delete;
237 
244  LVARRAY_HOST_DEVICE constexpr inline
246  toViewConst() const &
247  { return ParentClass::toViewConst(); }
248 
256  LVARRAY_HOST_DEVICE constexpr inline
258  toViewConst() const && = delete;
259 
261 
269  LVARRAY_HOST_DEVICE constexpr inline
271  toSparsityPatternView() const && = delete;
272 
274 
278 
280  using ParentClass::numRows;
284  using ParentClass::empty;
285 
287 
291 
296 
298 
302 
308  inline
309  void reserveNonZeros( INDEX_TYPE const nnz )
310  { ParentClass::reserveValues( nnz, this->m_entries ); }
311 
317  inline
318  void reserveNonZeros( INDEX_TYPE const row, INDEX_TYPE const nnz )
319  {
320  if( nonZeroCapacity( row ) >= nnz ) return;
321  setRowCapacity( row, nnz );
322  }
323 
334  inline
335  void setRowCapacity( INDEX_TYPE const row, INDEX_TYPE newCapacity )
336  {
337  if( newCapacity > numColumns() ) newCapacity = numColumns();
338  ParentClass::setCapacityOfArray( row, newCapacity, this->m_entries );
339  }
340 
351  void resize( INDEX_TYPE const nRows, INDEX_TYPE const nCols, INDEX_TYPE const initialRowCapacity )
352  { ParentClass::resize( nRows, nCols, initialRowCapacity, this->m_entries ); }
353 
359  inline
360  void compress()
361  { ParentClass::compress( this->m_entries ); }
362 
364 
368 
377  inline
378  bool insertNonZero( INDEX_TYPE const row, COL_TYPE const col, T const & entry )
379  { return ParentClass::insertIntoSetImpl( row, col, CallBacks( *this, row, &entry ) ); }
380 
391  inline
392  INDEX_TYPE insertNonZeros( INDEX_TYPE const row,
393  COL_TYPE const * const cols,
394  T const * const entriesToInsert,
395  INDEX_TYPE const ncols )
396  { return ParentClass::insertIntoSetImpl( row, cols, cols + ncols, CallBacks( *this, row, entriesToInsert ) ); }
397 
400 
402 
406 
412  template< typename POLICY >
413  inline
414  void setValues( T const & value ) const
415  { ParentClass::template setValues< POLICY >( value ); }
416 
421  template< typename AtomicPolicy >
422  inline
423  void addToRow( INDEX_TYPE const row,
424  COL_TYPE const * const LVARRAY_RESTRICT cols,
425  T const * const LVARRAY_RESTRICT vals,
426  INDEX_TYPE const nCols ) const
427  { ParentClass::template addToRow< AtomicPolicy >( row, cols, vals, nCols ); }
428 
433  template< typename AtomicPolicy >
434  inline
435  void addToRowBinarySearch( INDEX_TYPE const row,
436  COL_TYPE const * const LVARRAY_RESTRICT cols,
437  T const * const LVARRAY_RESTRICT vals,
438  INDEX_TYPE const nCols ) const
439  { ParentClass::template addToRowBinarySearch< AtomicPolicy >( row, cols, vals, nCols ); }
440 
445  template< typename AtomicPolicy >
446  inline
447  void addToRowLinearSearch( INDEX_TYPE const row,
448  COL_TYPE const * const LVARRAY_RESTRICT cols,
449  T const * const LVARRAY_RESTRICT vals,
450  INDEX_TYPE const nCols ) const
451  { ParentClass::template addToRowLinearSearch< AtomicPolicy >( row, cols, vals, nCols ); }
452 
457  template< typename AtomicPolicy >
458  inline
459  void addToRowBinarySearchUnsorted( INDEX_TYPE const row,
460  COL_TYPE const * const LVARRAY_RESTRICT cols,
461  T const * const LVARRAY_RESTRICT vals,
462  INDEX_TYPE const nCols ) const
463  { ParentClass::template addToRowBinarySearchUnsorted< AtomicPolicy >( row, cols, vals, nCols ); }
464 
466 
470 
478  void move( MemorySpace const space, bool const touch=true ) const
479  { return ParentClass::move( space, touch ); }
480 
482 
487  void setName( std::string const & name )
488  { ParentClass::template setName< decltype( *this ) >( name ); }
489 
490 private:
491 
499  void dynamicallyGrowRow( INDEX_TYPE const row, INDEX_TYPE const newNNZ )
500  { setRowCapacity( row, 2 * newNNZ ); }
501 
506  class CallBacks
507  {
508 public:
509 
516  CallBacks( CRSMatrix & crsM,
517  INDEX_TYPE const row, T const * const entriesToInsert ):
518  m_crsM( crsM ),
519  m_row( row ),
520  m_rowNNZ( crsM.numNonZeros( row ) ),
521  m_rowCapacity( crsM.nonZeroCapacity( row ) ),
522  m_entries( nullptr ),
523  m_entriesToInsert( entriesToInsert )
524  {}
525 
534  inline
535  COL_TYPE * incrementSize( COL_TYPE * const curPtr, INDEX_TYPE const nToAdd )
536  {
537  LVARRAY_UNUSED_VARIABLE( curPtr );
538  if( m_rowNNZ + nToAdd > m_rowCapacity )
539  {
540  m_crsM.dynamicallyGrowRow( m_row, m_rowNNZ + nToAdd );
541  }
542 
543  m_entries = m_crsM.getEntries( m_row );
544  return m_crsM.getSetValues( m_row );
545  }
546 
553  inline
554  void insert( INDEX_TYPE const pos ) const
555  { arrayManipulation::emplace( m_entries, m_rowNNZ, pos, m_entriesToInsert[0] ); }
556 
564  inline
565  void set( INDEX_TYPE const pos, INDEX_TYPE const colPos ) const
566  { new (&m_entries[pos]) T( m_entriesToInsert[colPos] ); }
567 
579  inline
580  void insert( INDEX_TYPE const nLeftToInsert,
581  INDEX_TYPE const colPos,
582  INDEX_TYPE const pos,
583  INDEX_TYPE const prevPos ) const
584  {
585  arrayManipulation::shiftUp( m_entries, prevPos, pos, nLeftToInsert );
586  new (&m_entries[pos + nLeftToInsert - 1]) T( m_entriesToInsert[colPos] );
587  }
588 
589 private:
591  CRSMatrix & m_crsM;
592 
594  INDEX_TYPE const m_row;
595 
597  INDEX_TYPE const m_rowNNZ;
598 
600  INDEX_TYPE const m_rowCapacity;
601 
603  T * m_entries;
604 
606  T const * const m_entriesToInsert;
607  };
608 };
609 
610 } /* namespace LvArray */
#define LVARRAY_UNUSED_VARIABLE(X)
Mark X as an unused variable, used to silence compiler warnings.
Definition: Macros.hpp:51
This class implements a compressed row storage sparsity pattern.
Definition: CRSMatrix.hpp:22
constexpr CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > toViewConstSizes() const
void assimilate(SparsityPattern< COL_TYPE, INDEX_TYPE, BUFFER_TYPE > &&src)
Steal the resources from a SparsityPattern.
Definition: CRSMatrix.hpp:133
This class provides a view into a compressed row storage sparsity pattern.
bool insertNonZero(INDEX_TYPE const row, COL_TYPE const col, T const &entry)
Insert a non-zero entry at the given position.
Definition: CRSMatrix.hpp:378
INDEX_TYPE_NC removeNonZeros(INDEX_TYPE const row, COL_TYPE const *const LVARRAY_RESTRICT cols, INDEX_TYPE const ncols) const
Remove non-zero entries from the given row.
constexpr CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > toViewConst() const &
Definition: CRSMatrix.hpp:246
constexpr INDEX_TYPE_NC numColumns() const
void resize(INDEX_TYPE const nRows, INDEX_TYPE const nCols, INDEX_TYPE const initialRowCapacity)
Set the dimensions of the matrix.
Definition: CRSMatrix.hpp:351
void reserve(BUFFER &buf, std::ptrdiff_t const size, std::ptrdiff_t const newCapacity)
Reserve space in the buffer for at least the given capacity.
bool insertIntoSetImpl(INDEX_TYPE const i, COL_TYPE const &value, CALLBACKS &&cbacks) const
Helper function to insert a value into the given set.
CRSMatrix(INDEX_TYPE const nrows=0, INDEX_TYPE const ncols=0, INDEX_TYPE const initialRowCapacity=0)
Constructor.
Definition: CRSMatrix.hpp:58
#define LVARRAY_ERROR_IF(EXP, MSG)
Abort execution if EXP is true.
Definition: Macros.hpp:101
void setName(std::string const &name)
Set the name associated with this CRSMatrix which is used in the chai callback.
Definition: CRSMatrix.hpp:487
constexpr CRSMatrixView< T const, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > toViewConst() const
constexpr CRSMatrixView< T, COL_TYPE, INDEX_TYPE const, BUFFER_TYPE > toView() const
BUFFER_TYPE< INDEX_TYPE > m_offsets
void move(MemorySpace const space, bool const touch=true) const
Move this SparsityPattern to the given memory space and touch the values, sizes and offsets...
void addToRowBinarySearch(INDEX_TYPE const row, COL_TYPE const *const LVARRAY_RESTRICT cols, T const *const LVARRAY_RESTRICT vals, INDEX_TYPE const nCols) const
Add to the given entries, the entries must already exist in the matrix.
Definition: CRSMatrix.hpp:435
void assimilate(SparsityPatternView &&src)
Steal the resources of src, clearing it in the process.
INDEX_TYPE insertNonZeros(INDEX_TYPE const row, COL_TYPE const *const cols, T const *const entriesToInsert, INDEX_TYPE const ncols)
Insert a non-zero entries into the given row.
Definition: CRSMatrix.hpp:392
void addToRowBinarySearchUnsorted(INDEX_TYPE const row, COL_TYPE const *const LVARRAY_RESTRICT cols, T const *const LVARRAY_RESTRICT vals, INDEX_TYPE const nCols) const
Add to the given entries, the entries must already exist in the matrix.
Definition: CRSMatrix.hpp:459
CRSMatrix & operator=(CRSMatrix &&src)
Default move assignment operator, performs a shallow copy.
Definition: CRSMatrix.hpp:119
void shiftUp(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, std::ptrdiff_t const n)
Shift the values in the array at or above the given position up by the given amount. New uninitialized values take their place.
BUFFER_TYPE< SIZE_TYPE > m_sizes
Holds the size of each array.
constexpr INDEX_TYPE const * getOffsets() const
void compress(BUFFERS &... buffers)
Compress the arrays so that the values of each array are contiguous with no extra capacity in between...
Contains the implementation of LvArray::CRSMatrixView.
constexpr std::enable_if< std::is_signed< INDEX_TYPE >::value, bool >::type isPositive(INDEX_TYPE const i)
void destroy(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size)
Destory the values in the array.
constexpr INDEX_TYPE_NC numRows() const
~CRSMatrix()
Destructor, frees the entries, values (columns), sizes and offsets Buffers.
Definition: CRSMatrix.hpp:85
constexpr INDEX_TYPE_NC nonZeroCapacity() const
void reserveNonZeros(INDEX_TYPE const nnz)
Reserve space to hold at least the given total number of non zero entries.
Definition: CRSMatrix.hpp:309
BUFFER_TYPE< T > m_entries
Holds the entries of the matrix, of length numNonZeros().
void resize(INDEX_TYPE const nrows, INDEX_TYPE const ncols, INDEX_TYPE_NC initialRowCapacity, BUFFERS &... buffers)
Resize the SparsityPattern to the given size.
CRSMatrixView & operator=(CRSMatrixView const &)=default
Default copy assignment operator.
constexpr ArraySlice< COL_TYPE const, 1, 0, INDEX_TYPE_NC > getColumns(INDEX_TYPE const row) const
ArraySlice< T, 1, 0, INDEX_TYPE_NC > getEntries(INDEX_TYPE const row) const
void move(MemorySpace const space, bool const touch=true) const
Move this SparsityPattern to the given memory space and touch the values, sizes and offsets...
Definition: CRSMatrix.hpp:478
INDEX_TYPE IndexType
The integer type used for indexing.
void emplace(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, ARGS &&... args)
Insert into the array constructing the new value in place.
void setValues(T const &value) const
Set all the entries in the matrix to the given value.
Definition: CRSMatrix.hpp:414
void addToRowLinearSearch(INDEX_TYPE const row, COL_TYPE const *const LVARRAY_RESTRICT cols, T const *const LVARRAY_RESTRICT vals, INDEX_TYPE const nCols) const
Add to the given entries, the entries must already exist in the matrix.
Definition: CRSMatrix.hpp:447
Contains functions for manipulating a contiguous array of values.
constexpr CRSMatrixView< T, COL_TYPE, INDEX_TYPE const, BUFFER_TYPE > toView() const &
Definition: CRSMatrix.hpp:202
MemorySpace
An enum containing the available memory spaces.
The top level namespace.
Definition: Array.hpp:24
CRSMatrix & operator=(CRSMatrix const &src)
Copy assignment operator, performs a deep copy.
Definition: CRSMatrix.hpp:101
INDEX_TYPE_NC m_numCols
The number of columns in the matrix.
void compress()
Compress the CRSMatrix so that the non-zeros and values of each row are contiguous with no extra capa...
Definition: CRSMatrix.hpp:360
void setEqualTo(INDEX_TYPE const srcNumArrays, INDEX_TYPE const srcMaxOffset, BUFFER_TYPE< INDEX_TYPE > const &srcOffsets, BUFFER_TYPE< INDEX_TYPE > const &srcSizes, BUFFER_TYPE< COL_TYPE > const &srcValues, PAIRS_OF_BUFFERS &&... pairs)
Set this ArrayOfArraysView equal to the provided arrays.
COL_TYPE ColType
The integer type used to enumerate the columns.
INDEX_TYPE_NC m_numArrays
The number of arrays contained.
void free(BUFFERS &... buffers)
Destroy all the objects held by this array and free all associated memory.
constexpr SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > toSparsityPatternView() const &
bool removeNonZero(INDEX_TYPE const row, COL_TYPE const col) const
Remove a non-zero entry at the given position.
void setCapacityOfArray(INDEX_TYPE const i, INDEX_TYPE const newCapacity, BUFFERS &... buffers)
Set the capacity of the given array.
CRSMatrix(CRSMatrix const &src)
Copy constructor, performs a deep copy.
Definition: CRSMatrix.hpp:72
void resizeFromRowCapacities(INDEX_TYPE const nRows, INDEX_TYPE const nCols, INDEX_TYPE const *const rowCapacities)
Clears the matrix and creates a new matrix with the given number of rows and columns.
Definition: CRSMatrix.hpp:177
std::string string
String type.
Definition: DataTypes.hpp:131
std::pair< BUFFER_TYPE< U > &, BUFFER_TYPE< U > const & > PairOfBuffers
Alias for a std::pair of buffers.
void reserveNonZeros(INDEX_TYPE const row, INDEX_TYPE const nnz)
Reserve space to hold at least the given number of non zero entries in the given row.
Definition: CRSMatrix.hpp:318
void addToRow(INDEX_TYPE const row, COL_TYPE const *const LVARRAY_RESTRICT cols, T const *const LVARRAY_RESTRICT vals, INDEX_TYPE const nCols) const
Add to the given entries, the entries must already exist in the matrix. The columns must be sorted...
Definition: CRSMatrix.hpp:423
constexpr CRSMatrixView< T, COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > toViewConstSizes() const &
Definition: CRSMatrix.hpp:224
constexpr std::enable_if_t< std::is_arithmetic< T >::value, T > max(T const a, T const b)
Definition: math.hpp:46
void setRowCapacity(INDEX_TYPE const row, INDEX_TYPE newCapacity)
Set the non zero capacity of the given row.
Definition: CRSMatrix.hpp:335
void reserveValues(INDEX_TYPE const newValueCapacity, BUFFERS &... buffers)
Reserve space for the given number of values.
void insert(T *const LVARRAY_RESTRICT ptr, std::ptrdiff_t const size, std::ptrdiff_t const index, ITERATOR first, std::ptrdiff_t const n)
Insert the given values into the array at the given position.
constexpr SparsityPatternView< COL_TYPE const, INDEX_TYPE const, BUFFER_TYPE > toSparsityPatternView() const &&=delete
Overload for rvalues that is deleted.
This class implements a compressed row storage matrix.
Definition: CRSMatrix.hpp:35
T EntryType
The type of the entries in the matrix.
#define LVARRAY_HOST_DEVICE
Mark a function for both host and device usage.
Definition: Macros.hpp:389
This class provides a view into a compressed row storage matrix.