Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits > Class Template Reference

The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access. More...

#include <RandomSetter.h>

Classes

struct  ScalarWrapper
 

Public Member Functions

 RandomSetter (SparseMatrixType &target)
 
 ~RandomSetter ()
 
Scalaroperator() (Index row, Index col)
 
Index nonZeros () const
 

Protected Attributes

HashMapTypem_hashmaps
 
SparseMatrixType * mp_target
 
Index m_outerPackets
 
unsigned char m_keyBitsOffset
 

Private Types

enum  { SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted , TargetRowMajor = (SparseMatrixType::Flags & RowMajorBit) ? 1 : 0 , SetterRowMajor = SwapStorage ? 1 - TargetRowMajor : TargetRowMajor }
 
typedef SparseMatrixType::Scalar Scalar
 
typedef SparseMatrixType::StorageIndex StorageIndex
 
typedef MapTraits< ScalarWrapper >::KeyType KeyType
 
typedef MapTraits< ScalarWrapper >::Type HashMapType
 

Static Private Attributes

static constexpr int OuterPacketMask = (1 << OuterPacketBits) - 1
 

Detailed Description

template<typename SparseMatrixType, template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
class Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >

The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access.

Template Parameters
SparseMatrixTypethe type of the sparse matrix we are updating
MapTraitsa traits class representing the map implementation used for the temporary sparse storage. Its default value depends on the system.
OuterPacketBitsdefines the number of rows (or columns) manage by a single map object as a power of two exponent.

This class temporarily represents a sparse matrix object using a generic map implementation allowing for efficient random access. The conversion from the compressed representation to a hash_map object is performed in the RandomSetter constructor, while the sparse matrix is updated back at destruction time. This strategy suggest the use of nested blocks as in this example:

SparseMatrix<double> m(rows,cols);
{
RandomSetter<SparseMatrix<double> > w(m);
// don't use m but w instead with read/write random access to the coefficients:
for(;;)
w(rand(),rand()) = rand;
}
// when w is deleted, the data are copied back to m
// and m is ready to use.
RowVector3d w
Definition: Matrix_resize_int.cpp:3
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
int * m
Definition: level2_cplx_impl.h:294

Since hash_map objects are not fully sorted, representing a full matrix as a single hash_map would involve a big and costly sort to update the compressed matrix back. To overcome this issue, a RandomSetter use multiple hash_map, each representing 2^OuterPacketBits columns or rows according to the storage order. To reach optimal performance, this value should be adjusted according to the average number of nonzeros per rows/columns.

The possible values for the template parameter MapTraits are:

  • StdMapTraits: corresponds to std::map. (does not perform very well)
  • StdUnorderedMapTraits: corresponds to std::unordered_map
  • GoogleDenseHashMapTraits: corresponds to google::dense_hash_map (best efficiency, reasonable memory consumption)
  • GoogleSparseHashMapTraits: corresponds to google::sparse_hash_map (best memory consumption, relatively good performance)

The default map implementation depends on the availability, and the preferred order is: GoogleSparseHashMapTraits, StdUnorderedMapTraits, and finally StdMapTraits.

For performance and memory consumption reasons it is highly recommended to use one of Google's hash_map implementations. To enable the support for them, you must define EIGEN_GOOGLEHASH_SUPPORT. This will include both <google/dense_hash_map> and <google/sparse_hash_map> for you.

See also
https://github.com/sparsehash/sparsehash

Member Typedef Documentation

◆ HashMapType

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
typedef MapTraits<ScalarWrapper>::Type Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::HashMapType
private

◆ KeyType

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
typedef MapTraits<ScalarWrapper>::KeyType Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::KeyType
private

◆ Scalar

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
typedef SparseMatrixType::Scalar Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::Scalar
private

◆ StorageIndex

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
typedef SparseMatrixType::StorageIndex Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::StorageIndex
private

Member Enumeration Documentation

◆ anonymous enum

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
anonymous enum
private
Enumerator
SwapStorage 
TargetRowMajor 
SetterRowMajor 
167  {
168  SwapStorage = 1 - MapTraits<ScalarWrapper>::IsSorted,
169  TargetRowMajor = (SparseMatrixType::Flags & RowMajorBit) ? 1 : 0,
171  };
@ SwapStorage
Definition: RandomSetter.h:168
@ SetterRowMajor
Definition: RandomSetter.h:170
@ TargetRowMajor
Definition: RandomSetter.h:169
const unsigned int RowMajorBit
Definition: Constants.h:70

Constructor & Destructor Documentation

◆ RandomSetter()

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::RandomSetter ( SparseMatrixType &  target)
inline

Constructs a random setter object from the sparse matrix target

Note that the initial value of target are imported. If you want to re-set a sparse matrix from scratch, then you must set it to zero first using the setZero() function.

180  : mp_target(&target) {
181  const Index outerSize = SwapStorage ? target.innerSize() : target.outerSize();
182  const Index innerSize = SwapStorage ? target.outerSize() : target.innerSize();
183  m_outerPackets = outerSize >> OuterPacketBits;
184  if (outerSize & OuterPacketMask) m_outerPackets += 1;
186  // compute number of bits needed to store inner indices
187  Index aux = innerSize - 1;
188  m_keyBitsOffset = 0;
189  while (aux) {
190  ++m_keyBitsOffset;
191  aux = aux >> 1;
192  }
193  KeyType ik = (1 << (OuterPacketBits + m_keyBitsOffset));
194  for (Index k = 0; k < m_outerPackets; ++k) MapTraits<ScalarWrapper>::setInvalidKey(m_hashmaps[k], ik);
195 
196  // insert current coeffs
197  for (Index j = 0; j < mp_target->outerSize(); ++j)
198  for (typename SparseMatrixType::InnerIterator it(*mp_target, j); it; ++it)
199  (*this)(TargetRowMajor ? j : it.index(), TargetRowMajor ? it.index() : j) = it.value();
200  }
Index m_outerPackets
Definition: RandomSetter.h:297
MapTraits< ScalarWrapper >::KeyType KeyType
Definition: RandomSetter.h:164
unsigned char m_keyBitsOffset
Definition: RandomSetter.h:298
MapTraits< ScalarWrapper >::Type HashMapType
Definition: RandomSetter.h:165
HashMapType * m_hashmaps
Definition: RandomSetter.h:295
static constexpr int OuterPacketMask
Definition: RandomSetter.h:166
SparseMatrixType * mp_target
Definition: RandomSetter.h:296
char char char int int * k
Definition: level2_impl.h:374
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:83
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References j, k, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_hashmaps, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_keyBitsOffset, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_outerPackets, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::mp_target, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::OuterPacketMask, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::SwapStorage, and Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::TargetRowMajor.

◆ ~RandomSetter()

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::~RandomSetter ( )
inline

Destructor updating back the sparse matrix target

203  {
204  KeyType keyBitsMask = (1 << m_keyBitsOffset) - 1;
205  if (!SwapStorage) // also means the map is sorted
206  {
207  mp_target->setZero();
208  mp_target->makeCompressed();
209  mp_target->reserve(nonZeros());
210  Index prevOuter = -1;
211  for (Index k = 0; k < m_outerPackets; ++k) {
212  const Index outerOffset = (1 << OuterPacketBits) * k;
213  typename HashMapType::iterator end = m_hashmaps[k].end();
214  for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it != end; ++it) {
215  const Index outer = (it->first >> m_keyBitsOffset) + outerOffset;
216  const Index inner = it->first & keyBitsMask;
217  if (prevOuter != outer) {
218  for (Index j = prevOuter + 1; j <= outer; ++j) mp_target->startVec(j);
219  prevOuter = outer;
220  }
221  mp_target->insertBackByOuterInner(outer, inner) = it->second.value;
222  }
223  }
224  mp_target->finalize();
225  } else {
226  VectorXi positions(mp_target->outerSize());
227  positions.setZero();
228  // pass 1
229  for (Index k = 0; k < m_outerPackets; ++k) {
230  typename HashMapType::iterator end = m_hashmaps[k].end();
231  for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it != end; ++it) {
232  const Index outer = it->first & keyBitsMask;
233  ++positions[outer];
234  }
235  }
236  // prefix sum
237  StorageIndex count = 0;
238  for (Index j = 0; j < mp_target->outerSize(); ++j) {
239  StorageIndex tmp = positions[j];
240  mp_target->outerIndexPtr()[j] = count;
241  positions[j] = count;
242  count += tmp;
243  }
244  mp_target->makeCompressed();
245  mp_target->outerIndexPtr()[mp_target->outerSize()] = count;
246  mp_target->resizeNonZeros(count);
247  // pass 2
248  for (Index k = 0; k < m_outerPackets; ++k) {
249  const Index outerOffset = (1 << OuterPacketBits) * k;
250  typename HashMapType::iterator end = m_hashmaps[k].end();
251  for (typename HashMapType::iterator it = m_hashmaps[k].begin(); it != end; ++it) {
252  const Index inner = (it->first >> m_keyBitsOffset) + outerOffset;
253  const Index outer = it->first & keyBitsMask;
254  // sorted insertion
255  // Note that we have to deal with at most 2^OuterPacketBits unsorted coefficients,
256  // moreover those 2^OuterPacketBits coeffs are likely to be sparse, an so only a
257  // small fraction of them have to be sorted, whence the following simple procedure:
258  Index posStart = mp_target->outerIndexPtr()[outer];
259  Index i = (positions[outer]++) - 1;
260  while ((i >= posStart) && (mp_target->innerIndexPtr()[i] > inner)) {
261  mp_target->valuePtr()[i + 1] = mp_target->valuePtr()[i];
262  mp_target->innerIndexPtr()[i + 1] = mp_target->innerIndexPtr()[i];
263  --i;
264  }
265  mp_target->innerIndexPtr()[i + 1] = internal::convert_index<StorageIndex>(inner);
266  mp_target->valuePtr()[i + 1] = it->second.value;
267  }
268  }
269  }
270  delete[] m_hashmaps;
271  }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
SparseMatrixType::StorageIndex StorageIndex
Definition: RandomSetter.h:158
Index nonZeros() const
Definition: RandomSetter.h:288
static constexpr lastp1_t end
Definition: IndexedViewHelper.h:79
Eigen::Matrix< Scalar, Dynamic, Dynamic, ColMajor > tmp
Definition: level3_impl.h:365

References Eigen::placeholders::end, i, j, k, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_hashmaps, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_keyBitsOffset, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_outerPackets, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::mp_target, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::nonZeros(), Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::SwapStorage, and tmp.

Member Function Documentation

◆ nonZeros()

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
Index Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::nonZeros ( ) const
inline
Returns
the number of non zero coefficients
Note
According to the underlying map/hash_map implementation, this function might be quite expensive.
288  {
289  Index nz = 0;
290  for (Index k = 0; k < m_outerPackets; ++k) nz += static_cast<Index>(m_hashmaps[k].size());
291  return nz;
292  }
Scalar Scalar int size
Definition: benchVecAdd.cpp:17
const unsigned nz
Definition: ConstraintElementsUnitTest.cpp:32

References k, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_hashmaps, Mesh_Parameters::nz, and size.

Referenced by Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::~RandomSetter().

◆ operator()()

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
Scalar& Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::operator() ( Index  row,
Index  col 
)
inline
Returns
a reference to the coefficient at given coordinates row, col
274  {
275  const Index outer = SetterRowMajor ? row : col;
276  const Index inner = SetterRowMajor ? col : row;
277  const Index outerMajor = outer >> OuterPacketBits; // index of the packet/map
278  const Index outerMinor = outer & OuterPacketMask; // index of the inner vector in the packet
279  const KeyType key = internal::convert_index<KeyType>((outerMinor << m_keyBitsOffset) | inner);
280  return m_hashmaps[outerMajor][key].value;
281  }
m col(1)
m row(1)

References col(), Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_hashmaps, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_keyBitsOffset, Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::OuterPacketMask, row(), and Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::SetterRowMajor.

Member Data Documentation

◆ m_hashmaps

◆ m_keyBitsOffset

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
unsigned char Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_keyBitsOffset
protected

◆ m_outerPackets

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
Index Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::m_outerPackets
protected

◆ mp_target

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
SparseMatrixType* Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::mp_target
protected

◆ OuterPacketMask

template<typename SparseMatrixType , template< typename T > class MapTraits = StdUnorderedMapTraits, int OuterPacketBits = 6>
constexpr int Eigen::RandomSetter< SparseMatrixType, MapTraits, OuterPacketBits >::OuterPacketMask = (1 << OuterPacketBits) - 1
staticconstexprprivate

The documentation for this class was generated from the following file: