sparse_setter.cpp File Reference
#include <google/sparse_hash_map>
#include "BenchSparseUtil.h"

Macros

#define SIZE   100000
 
#define NBPERROW   24
 
#define REPEAT   2
 
#define NBTRIES   2
 
#define KK   10
 
#define EIGEN_GOOGLEHASH_SUPPORT
 
#define CHECK_MEM
 
#define BENCH(X)
 

Typedefs

typedef std::vector< Vector2i > Coordinates
 
typedef std::vector< float > Values
 

Functions

EIGEN_DONT_INLINE Scalarsetinnerrand_eigen (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_eigen_dynamic (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_eigen_compact (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_eigen_sumeq (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_eigen_gnu_hash (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_eigen_google_dense (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_eigen_google_sparse (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_scipy (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_ublas_mapped (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_ublas_coord (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_ublas_compressed (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_ublas_genvec (const Coordinates &coords, const Values &vals)
 
EIGEN_DONT_INLINE Scalarsetrand_mtl (const Coordinates &coords, const Values &vals)
 
int main (int argc, char *argv[])
 
template<class T >
void coo_tocsr (const int n_row, const int n_col, const int nnz, const Coordinates Aij, const Values Ax, int Bp[], int Bj[], T Bx[])
 
template<class T1 , class T2 >
bool kv_pair_less (const std::pair< T1, T2 > &x, const std::pair< T1, T2 > &y)
 
template<class I , class T >
void csr_sort_indices (const I n_row, const I Ap[], I Aj[], T Ax[])
 
template<class I , class T >
void csr_sum_duplicates (const I n_row, const I n_col, I Ap[], I Aj[], T Ax[])
 

Macro Definition Documentation

◆ BENCH

#define BENCH (   X)
Value:
timer.reset(); \
for (int _j = 0; _j < NBTRIES; ++_j) { \
timer.start(); \
for (int _k = 0; _k < REPEAT; ++_k) { \
X \
} \
timer.stop(); \
}
#define REPEAT
Definition: sparse_setter.cpp:16
#define NBTRIES
Definition: sparse_setter.cpp:20

◆ CHECK_MEM

#define CHECK_MEM

◆ EIGEN_GOOGLEHASH_SUPPORT

#define EIGEN_GOOGLEHASH_SUPPORT

◆ KK

#define KK   10

◆ NBPERROW

#define NBPERROW   24

◆ NBTRIES

#define NBTRIES   2

◆ REPEAT

#define REPEAT   2

◆ SIZE

#define SIZE   100000

Typedef Documentation

◆ Coordinates

typedef std::vector<Vector2i> Coordinates

◆ Values

typedef std::vector<float> Values

Function Documentation

◆ coo_tocsr()

template<class T >
void coo_tocsr ( const int  n_row,
const int  n_col,
const int  nnz,
const Coordinates  Aij,
const Values  Ax,
int  Bp[],
int  Bj[],
T  Bx[] 
)
279  {
280  // compute number of non-zero entries per row of A coo_tocsr
281  std::fill(Bp, Bp + n_row, 0);
282 
283  for (int n = 0; n < nnz; n++) {
284  Bp[Aij[n].x()]++;
285  }
286 
287  // cumsum the nnz per row to get Bp[]
288  for (int i = 0, cumsum = 0; i < n_row; i++) {
289  int temp = Bp[i];
290  Bp[i] = cumsum;
291  cumsum += temp;
292  }
293  Bp[n_row] = nnz;
294 
295  // write Aj,Ax into Bj,Bx
296  for (int n = 0; n < nnz; n++) {
297  int row = Aij[n].x();
298  int dest = Bp[row];
299 
300  Bj[dest] = Aij[n].y();
301  Bx[dest] = Ax[n];
302 
303  Bp[row]++;
304  }
305 
306  for (int i = 0, last = 0; i <= n_row; i++) {
307  int temp = Bp[i];
308  Bp[i] = last;
309  last = temp;
310  }
311 
312  // now Bp,Bj,Bx form a CSR representation (with possible duplicates)
313 }
int i
Definition: BiCGSTAB_step_by_step.cpp:9
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
m row(1)
static constexpr const last_t last
Definition: IndexedViewHelper.h:48

References i, Eigen::placeholders::last, n, and row().

◆ csr_sort_indices()

template<class I , class T >
void csr_sort_indices ( const I  n_row,
const I  Ap[],
I  Aj[],
T  Ax[] 
)
321  {
322  std::vector<std::pair<I, T> > temp;
323 
324  for (I i = 0; i < n_row; i++) {
325  I row_start = Ap[i];
326  I row_end = Ap[i + 1];
327 
328  temp.clear();
329 
330  for (I jj = row_start; jj < row_end; jj++) {
331  temp.push_back(std::make_pair(Aj[jj], Ax[jj]));
332  }
333 
334  std::sort(temp.begin(), temp.end(), kv_pair_less<I, T>);
335 
336  for (I jj = row_start, n = 0; jj < row_end; jj++, n++) {
337  Aj[jj] = temp[n].first;
338  Ax[jj] = temp[n].second;
339  }
340  }
341 }
#define I
Definition: main.h:127

References i, I, and n.

Referenced by setrand_scipy().

◆ csr_sum_duplicates()

template<class I , class T >
void csr_sum_duplicates ( const I  n_row,
const I  n_col,
I  Ap[],
I  Aj[],
T  Ax[] 
)
344  {
345  I nnz = 0;
346  I row_end = 0;
347  for (I i = 0; i < n_row; i++) {
348  I jj = row_end;
349  row_end = Ap[i + 1];
350  while (jj < row_end) {
351  I j = Aj[jj];
352  T x = Ax[jj];
353  jj++;
354  while (jj < row_end && Aj[jj] == j) {
355  x += Ax[jj];
356  jj++;
357  }
358  Aj[nnz] = j;
359  Ax[nnz] = x;
360  nnz++;
361  }
362  Ap[i + 1] = nnz;
363  }
364 }
list x
Definition: plotDoE.py:28
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2

References i, I, j, and plotDoE::x.

Referenced by setrand_scipy().

◆ kv_pair_less()

template<class T1 , class T2 >
bool kv_pair_less ( const std::pair< T1, T2 > &  x,
const std::pair< T1, T2 > &  y 
)
316  {
317  return x.first < y.first;
318 }
Scalar * y
Definition: level1_cplx_impl.h:128

References plotDoE::x, and y.

◆ main()

int main ( int argc  ,
char argv[] 
)
64  {
65  int rows = SIZE;
66  int cols = SIZE;
67  bool fullyrand = true;
68 
70  Coordinates coords;
71  Values values;
72  if (fullyrand) {
73  Coordinates pool;
74  pool.reserve(cols * NBPERROW);
75  std::cerr << "fill pool"
76  << "\n";
77  for (int i = 0; i < cols * NBPERROW;) {
78  // DynamicSparseMatrix<int> stencil(SIZE,SIZE);
79  Vector2i ij(internal::random<int>(0, rows - 1), internal::random<int>(0, cols - 1));
80  // if(stencil.coeffRef(ij.x(), ij.y())==0)
81  {
82  // stencil.coeffRef(ij.x(), ij.y()) = 1;
83  pool.push_back(ij);
84  }
85  ++i;
86  }
87  std::cerr << "pool ok"
88  << "\n";
89  int n = cols * NBPERROW * KK;
90  coords.reserve(n);
91  values.reserve(n);
92  for (int i = 0; i < n; ++i) {
93  int i = internal::random<int>(0, pool.size());
94  coords.push_back(pool[i]);
95  values.push_back(internal::random<Scalar>());
96  }
97  } else {
98  for (int j = 0; j < cols; ++j)
99  for (int i = 0; i < NBPERROW; ++i) {
100  coords.push_back(Vector2i(internal::random<int>(0, rows - 1), j));
101  values.push_back(internal::random<Scalar>());
102  }
103  }
104  std::cout << "nnz = " << coords.size() << "\n";
105  CHECK_MEM
106 // dense matrices
107 #ifdef DENSEMATRIX
108  {
109  BENCH(setrand_eigen_dense(coords, values);)
110  std::cout << "Eigen Dense\t" << timer.value() << "\n";
111  }
112 #endif
113 
114  // eigen sparse matrices
115  // if (!fullyrand)
116  // {
117  // BENCH(setinnerrand_eigen(coords,values);)
118  // std::cout << "Eigen fillrand\t" << timer.value() << "\n";
119  // }
120  {
121  BENCH(setrand_eigen_dynamic(coords, values);)
122  std::cout << "Eigen dynamic\t" << timer.value() << "\n";
123  }
124  // {
125  // BENCH(setrand_eigen_compact(coords,values);)
126  // std::cout << "Eigen compact\t" << timer.value() << "\n";
127  // }
128  {
129  BENCH(setrand_eigen_sumeq(coords, values);)
130  std::cout << "Eigen sumeq\t" << timer.value() << "\n";
131  }
132  {
133  // BENCH(setrand_eigen_gnu_hash(coords,values);)
134  // std::cout << "Eigen std::map\t" << timer.value() << "\n";
135  }
136  {
137  BENCH(setrand_scipy(coords, values);)
138  std::cout << "scipy\t" << timer.value() << "\n";
139  }
140 #ifndef NOGOOGLE
141  {
142  BENCH(setrand_eigen_google_dense(coords, values);)
143  std::cout << "Eigen google dense\t" << timer.value() << "\n";
144  }
145  {
146  BENCH(setrand_eigen_google_sparse(coords, values);)
147  std::cout << "Eigen google sparse\t" << timer.value() << "\n";
148  }
149 #endif
150 
151 #ifndef NOUBLAS
152  {
153  // BENCH(setrand_ublas_mapped(coords,values);)
154  // std::cout << "ublas mapped\t" << timer.value() << "\n";
155  } {
156  BENCH(setrand_ublas_genvec(coords, values);)
157  std::cout << "ublas vecofvec\t" << timer.value() << "\n";
158  }
159 /*{
160  timer.reset();
161  timer.start();
162  for (int k=0; k<REPEAT; ++k)
163  setrand_ublas_compressed(coords,values);
164  timer.stop();
165  std::cout << "ublas comp\t" << timer.value() << "\n";
166 }
167 {
168  timer.reset();
169  timer.start();
170  for (int k=0; k<REPEAT; ++k)
171  setrand_ublas_coord(coords,values);
172  timer.stop();
173  std::cout << "ublas coord\t" << timer.value() << "\n";
174 }*/
175 #endif
176 
177 // MTL4
178 #ifndef NOMTL
179  {
180  BENCH(setrand_mtl(coords, values));
181  std::cout << "MTL\t" << timer.value() << "\n";
182  }
183 #endif
184 
185  return 0;
186 }
int rows
Definition: Tutorial_commainit_02.cpp:1
int cols
Definition: Tutorial_commainit_02.cpp:1
Template argument; use a member class of CGCoordinates to instantiate.
Definition: BenchTimer.h:55
double timer
Definition: oomph_metis_from_parmetis_3.1.1/struct.h:210
#define NBPERROW
Definition: sparse_setter.cpp:12
EIGEN_DONT_INLINE Scalar * setrand_mtl(const Coordinates &coords, const Values &vals)
EIGEN_DONT_INLINE Scalar * setrand_eigen_sumeq(const Coordinates &coords, const Values &vals)
Definition: sparse_setter.cpp:212
EIGEN_DONT_INLINE Scalar * setrand_eigen_google_dense(const Coordinates &coords, const Values &vals)
Definition: sparse_setter.cpp:254
#define BENCH(X)
Definition: sparse_setter.cpp:37
#define SIZE
Definition: sparse_setter.cpp:8
std::vector< float > Values
Definition: sparse_setter.cpp:48
EIGEN_DONT_INLINE Scalar * setrand_ublas_genvec(const Coordinates &coords, const Values &vals)
Definition: sparse_setter.cpp:422
EIGEN_DONT_INLINE Scalar * setrand_eigen_google_sparse(const Coordinates &coords, const Values &vals)
Definition: sparse_setter.cpp:265
EIGEN_DONT_INLINE Scalar * setrand_eigen_dynamic(const Coordinates &coords, const Values &vals)
Definition: sparse_setter.cpp:200
#define CHECK_MEM
Definition: sparse_setter.cpp:34
EIGEN_DONT_INLINE Scalar * setrand_scipy(const Coordinates &coords, const Values &vals)
Definition: sparse_setter.cpp:366
#define KK
Definition: sparse_setter.cpp:24

References BENCH, CHECK_MEM, cols, i, j, KK, n, NBPERROW, rows, setrand_eigen_dynamic(), setrand_eigen_google_dense(), setrand_eigen_google_sparse(), setrand_eigen_sumeq(), setrand_mtl(), setrand_scipy(), setrand_ublas_genvec(), and SIZE.

◆ setinnerrand_eigen()

EIGEN_DONT_INLINE Scalar * setinnerrand_eigen ( const Coordinates coords,
const Values vals 
)
188  {
189  using namespace Eigen;
191  // mat.startFill(2000000/*coords.size()*/);
192  for (int i = 0; i < coords.size(); ++i) {
193  mat.insert(coords[i].x(), coords[i].y()) = vals[i];
194  }
195  mat.finalize();
196  CHECK_MEM;
197  return 0;
198 }
Eigen::SparseMatrix< double > mat
Definition: EigenUnitTest.cpp:10
void finalize()
Definition: SparseMatrix.h:461
Scalar & insert(Index row, Index col)
Definition: SparseMatrix.h:1586
Namespace containing all symbols from the Eigen library.
Definition: bench_norm.cpp:70

References CHECK_MEM, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::finalize(), i, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::insert(), SIZE, plotDoE::x, and y.

◆ setrand_eigen_compact()

EIGEN_DONT_INLINE Scalar * setrand_eigen_compact ( const Coordinates coords,
const Values vals 
)
228  {
229  using namespace Eigen;
230  DynamicSparseMatrix<Scalar> setter(SIZE, SIZE);
231  setter.reserve(coords.size() / 10);
232  for (int i = 0; i < coords.size(); ++i) {
233  setter.coeffRef(coords[i].x(), coords[i].y()) += vals[i];
234  }
235  SparseMatrix<Scalar> mat = setter;
236  CHECK_MEM;
237  return &mat.coeffRef(coords[0].x(), coords[0].y());
238 }
Scalar & coeffRef(Index row, Index col)
Definition: SparseMatrix.h:275

References CHECK_MEM, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), i, SIZE, plotDoE::x, and y.

◆ setrand_eigen_dynamic()

EIGEN_DONT_INLINE Scalar * setrand_eigen_dynamic ( const Coordinates coords,
const Values vals 
)
200  {
201  using namespace Eigen;
202  DynamicSparseMatrix<Scalar> mat(SIZE, SIZE);
203  mat.reserve(coords.size() / 10);
204  for (int i = 0; i < coords.size(); ++i) {
205  mat.coeffRef(coords[i].x(), coords[i].y()) += vals[i];
206  }
207  mat.finalize();
208  CHECK_MEM;
209  return &mat.coeffRef(coords[0].x(), coords[0].y());
210 }
void reserve(Index reserveSize)
Definition: SparseMatrix.h:315

References CHECK_MEM, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::finalize(), i, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::reserve(), SIZE, plotDoE::x, and y.

Referenced by main().

◆ setrand_eigen_gnu_hash()

EIGEN_DONT_INLINE Scalar * setrand_eigen_gnu_hash ( const Coordinates coords,
const Values vals 
)
240  {
241  using namespace Eigen;
243  {
245  for (int i = 0; i < coords.size(); ++i) {
246  setter(coords[i].x(), coords[i].y()) += vals[i];
247  }
248  CHECK_MEM;
249  }
250  return &mat.coeffRef(coords[0].x(), coords[0].y());
251 }
The RandomSetter is a wrapper object allowing to set/update a sparse matrix with random access.
Definition: RandomSetter.h:156
Definition: RandomSetter.h:29

References CHECK_MEM, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), i, SIZE, plotDoE::x, and y.

◆ setrand_eigen_google_dense()

EIGEN_DONT_INLINE Scalar * setrand_eigen_google_dense ( const Coordinates coords,
const Values vals 
)
254  {
255  using namespace Eigen;
257  {
258  RandomSetter<SparseMatrix<Scalar>, GoogleDenseHashMapTraits> setter(mat);
259  for (int i = 0; i < coords.size(); ++i) setter(coords[i].x(), coords[i].y()) += vals[i];
260  CHECK_MEM;
261  }
262  return &mat.coeffRef(coords[0].x(), coords[0].y());
263 }

References CHECK_MEM, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), i, SIZE, plotDoE::x, and y.

Referenced by main().

◆ setrand_eigen_google_sparse()

EIGEN_DONT_INLINE Scalar * setrand_eigen_google_sparse ( const Coordinates coords,
const Values vals 
)
265  {
266  using namespace Eigen;
268  {
269  RandomSetter<SparseMatrix<Scalar>, GoogleSparseHashMapTraits> setter(mat);
270  for (int i = 0; i < coords.size(); ++i) setter(coords[i].x(), coords[i].y()) += vals[i];
271  CHECK_MEM;
272  }
273  return &mat.coeffRef(coords[0].x(), coords[0].y());
274 }

References CHECK_MEM, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), i, SIZE, plotDoE::x, and y.

Referenced by main().

◆ setrand_eigen_sumeq()

EIGEN_DONT_INLINE Scalar * setrand_eigen_sumeq ( const Coordinates coords,
const Values vals 
)
212  {
213  using namespace Eigen;
214  int n = coords.size() / KK;
215  DynamicSparseMatrix<Scalar> mat(SIZE, SIZE);
216  for (int j = 0; j < KK; ++j) {
217  DynamicSparseMatrix<Scalar> aux(SIZE, SIZE);
218  mat.reserve(n);
219  for (int i = j * n; i < (j + 1) * n; ++i) {
220  aux.insert(coords[i].x(), coords[i].y()) += vals[i];
221  }
222  aux.finalize();
223  mat += aux;
224  }
225  return &mat.coeffRef(coords[0].x(), coords[0].y());
226 }

References Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), i, j, KK, n, Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::reserve(), SIZE, and plotDoE::x.

Referenced by main().

◆ setrand_mtl()

EIGEN_DONT_INLINE Scalar* setrand_mtl ( const Coordinates coords,
const Values vals 
)

Referenced by main().

◆ setrand_scipy()

EIGEN_DONT_INLINE Scalar * setrand_scipy ( const Coordinates coords,
const Values vals 
)
366  {
367  using namespace Eigen;
369  mat.resizeNonZeros(coords.size());
370  // std::cerr << "setrand_scipy...\n";
371  coo_tocsr<Scalar>(SIZE, SIZE, coords.size(), coords, vals, mat._outerIndexPtr(), mat._innerIndexPtr(),
372  mat._valuePtr());
373  // std::cerr << "coo_tocsr ok\n";
374 
375  csr_sort_indices(SIZE, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());
376 
377  csr_sum_duplicates(SIZE, SIZE, mat._outerIndexPtr(), mat._innerIndexPtr(), mat._valuePtr());
378 
379  mat.resizeNonZeros(mat._outerIndexPtr()[SIZE]);
380 
381  return &mat.coeffRef(coords[0].x(), coords[0].y());
382 }
void resizeNonZeros(Index size)
Definition: SparseMatrix.h:754
void csr_sum_duplicates(const I n_row, const I n_col, I Ap[], I Aj[], T Ax[])
Definition: sparse_setter.cpp:344
void csr_sort_indices(const I n_row, const I Ap[], I Aj[], T Ax[])
Definition: sparse_setter.cpp:321

References Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::coeffRef(), csr_sort_indices(), csr_sum_duplicates(), Eigen::SparseMatrix< Scalar_, Options_, StorageIndex_ >::resizeNonZeros(), SIZE, plotDoE::x, and y.

Referenced by main().

◆ setrand_ublas_compressed()

EIGEN_DONT_INLINE Scalar* setrand_ublas_compressed ( const Coordinates coords,
const Values vals 
)

◆ setrand_ublas_coord()

EIGEN_DONT_INLINE Scalar* setrand_ublas_coord ( const Coordinates coords,
const Values vals 
)

◆ setrand_ublas_genvec()

EIGEN_DONT_INLINE Scalar * setrand_ublas_genvec ( const Coordinates coords,
const Values vals 
)
422  {
423  using namespace boost;
424  using namespace boost::numeric;
425  using namespace boost::numeric::ublas;
426 
427  // ublas::vector<coordinate_vector<Scalar> > foo;
428  generalized_vector_of_vector<Scalar, row_major, ublas::vector<coordinate_vector<Scalar> > > aux(SIZE, SIZE);
429  for (int i = 0; i < coords.size(); ++i) {
430  aux(coords[i].x(), coords[i].y()) += vals[i];
431  }
432  CHECK_MEM;
433  compressed_matrix<Scalar, row_major> mat(aux);
434  return 0; //&mat(coords[0].x(), coords[0].y());
435 }
Definition: boostmultiprec.cpp:107

References CHECK_MEM, i, SIZE, plotDoE::x, and y.

Referenced by main().

◆ setrand_ublas_mapped()

EIGEN_DONT_INLINE Scalar * setrand_ublas_mapped ( const Coordinates coords,
const Values vals 
)
385  {
386  using namespace boost;
387  using namespace boost::numeric;
388  using namespace boost::numeric::ublas;
389  mapped_matrix<Scalar> aux(SIZE, SIZE);
390  for (int i = 0; i < coords.size(); ++i) {
391  aux(coords[i].x(), coords[i].y()) += vals[i];
392  }
393  CHECK_MEM;
394  compressed_matrix<Scalar> mat(aux);
395  return 0; // &mat(coords[0].x(), coords[0].y());
396 }

References CHECK_MEM, i, SIZE, plotDoE::x, and y.