CompressedSparseMatrix.hpp
Go to the documentation of this file.
1 /*
2  * STRUMPACK -- STRUctured Matrices PACKage, Copyright (c) 2014, The
3  * Regents of the University of California, through Lawrence Berkeley
4  * National Laboratory (subject to receipt of any required approvals
5  * from the U.S. Dept. of Energy). All rights reserved.
6  *
7  * If you have questions about your rights to use or distribute this
8  * software, please contact Berkeley Lab's Technology Transfer
9  * Department at TTD@lbl.gov.
10  *
11  * NOTICE. This software is owned by the U.S. Department of Energy. As
12  * such, the U.S. Government has been granted for itself and others
13  * acting on its behalf a paid-up, nonexclusive, irrevocable,
14  * worldwide license in the Software to reproduce, prepare derivative
15  * works, and perform publicly and display publicly. Beginning five
16  * (5) years after the date permission to assert copyright is obtained
17  * from the U.S. Department of Energy, and subject to any subsequent
18  * five (5) year renewals, the U.S. Government is granted for itself
19  * and others acting on its behalf a paid-up, nonexclusive,
20  * irrevocable, worldwide license in the Software to reproduce,
21  * prepare derivative works, distribute copies to the public, perform
22  * publicly and display publicly, and to permit others to do so.
23  *
24  * Developers: Pieter Ghysels, Francois-Henry Rouet, Xiaoye S. Li.
25  * (Lawrence Berkeley National Lab, Computational Research
26  * Division).
27  *
28  */
34 #ifndef COMPRESSED_SPARSE_MATRIX_HPP
35 #define COMPRESSED_SPARSE_MATRIX_HPP
36 
37 #include <vector>
38 #include <string>
39 #include <tuple>
40 
41 #include "misc/Tools.hpp"
42 #include "misc/Triplet.hpp"
43 #include "dense/DenseMatrix.hpp"
44 #include "StrumpackOptions.hpp"
45 
46 namespace strumpack {
47 
48  // forward declarations
49  template<typename integer_t> class CSRGraph;
50  template<typename scalar_t> class DenseMatrix;
51  template<typename scalar_t> class DistributedMatrix;
52 
53 
54  template<typename scalar_t, typename integer_t,
55  typename real_t = typename RealType<scalar_t>::value_type>
56  class MatchingData {
57  public:
58  MatchingData() {}
59  MatchingData(MatchingJob j, std::size_t n) : job(j) {
60  if (job != MatchingJob::NONE)
61  Q.resize(n);
63  R.resize(n);
64  C.resize(n);
65  }
66  }
67 
69  std::vector<integer_t> Q;
70  std::vector<real_t> R, C;
71 
72  integer_t mc64_work_int(std::size_t n, std::size_t nnz) const {
73  switch (job) {
74  case MatchingJob::MAX_SMALLEST_DIAGONAL: return 4*n;
75  case MatchingJob::MAX_SMALLEST_DIAGONAL_2: return 10*n + nnz;
79  default: return 5*n;
80  }
81  }
82 
83  integer_t mc64_work_double(std::size_t n, std::size_t nnz) const {
84  switch (job) {
85  case MatchingJob::MAX_CARDINALITY: return 0;
87  case MatchingJob::MAX_SMALLEST_DIAGONAL_2: return nnz;
88  case MatchingJob::MAX_DIAGONAL_SUM: return 2*n + nnz;
90  default: return 3*n + nnz;
91  }
92  }
93  };
94 
95  template<typename scalar_t,
96  typename real_t = typename RealType<scalar_t>::value_type>
97  class Equilibration {
98  public:
99  Equilibration() {}
100  Equilibration(std::size_t N) : R(N), C(N) {}
101  // use this one for block-row distributed sparse matrix, with rows
102  // local rows, and cols global columns
103  Equilibration(std::size_t rows, std::size_t cols) : R(rows), C(cols) {}
104 
105  int info = 0;
106  EquilibrationType type = EquilibrationType::NONE;
107  real_t rcond = 1, ccond = 1, Amax = 0;
108  std::vector<real_t> R, C;
109 
110  void set_type() {
111  const real_t thres = 0.1;
112  const real_t small = blas::lamch<real_t>('S') / blas::lamch<real_t>('P');
113  const real_t large = 1. / small;
114  if (rcond >= thres && Amax >= small && Amax <= large) {
115  R.clear();
116  if (ccond >= thres) {
117  type = EquilibrationType::NONE;
118  C.clear();
119  } else type = EquilibrationType::COLUMN;
120  } else {
121  if (ccond >= thres) {
122  type = EquilibrationType::ROW;
123  C.clear();
124  } else type = EquilibrationType::BOTH;
125  }
126  }
127  };
128 
149  template<typename scalar_t,typename integer_t>
152  using real_t = typename RealType<scalar_t>::value_type;
153 #if defined(STRUMPACK_USE_MPI)
155 #endif
158 
159  public:
164 
170  integer_t size() const { return n_; }
171 
177  integer_t nnz() const { return nnz_; }
178 
188  const integer_t* ptr() const { return ptr_.data(); }
189 
197  const integer_t* ind() const { return ind_.data(); }
198 
206  const scalar_t* val() const { return val_.data(); }
207 
216  integer_t* ptr() { return ptr_.data(); }
217 
225  integer_t* ind() { return ind_.data(); }
226 
233  scalar_t* val() { return val_.data(); }
234 
240  const integer_t& ptr(integer_t i) const { assert(i >= 0 && i <= size()); return ptr_[i]; }
241 
248  const integer_t& ind(integer_t i) const { assert(i >= 0 && i < nnz()); return ind_[i]; }
249 
255  const scalar_t& val(integer_t i) const { assert(i >= 0 && i < nnz()); return val_[i]; }
256 
262  integer_t& ptr(integer_t i) { assert(i <= size()); return ptr_[i]; }
263 
270  integer_t& ind(integer_t i) { assert(i < nnz()); return ind_[i]; }
271 
277  scalar_t& val(integer_t i) { assert(i < nnz()); return val_[i]; }
278 
279  virtual real_t norm1() const = 0; //{ assert(false); return -1.; };
280 
285  bool symm_sparse() const { return symm_sparse_; }
286 
294  void set_symm_sparse(bool symm_sparse=true) { symm_sparse_ = symm_sparse; }
295 
296 
310  virtual void spmv(const DenseM_t& x, DenseM_t& y) const = 0;
311 
325  virtual void spmv(const scalar_t* x, scalar_t* y) const = 0;
326 
331  virtual void permute(const integer_t* iorder, const integer_t* order);
332 
333  virtual void permute(const std::vector<integer_t>& iorder,
334  const std::vector<integer_t>& order) {
335  permute(iorder.data(), order.data());
336  }
337 
338  virtual void permute_columns(const std::vector<integer_t>& perm) = 0;
339 
340  virtual Equil_t equilibration() const { return Equil_t(this->size()); }
341 
342  virtual void equilibrate(const Equil_t&) {}
343 
344  virtual Match_t matching(MatchingJob, bool apply=true);
345 
346  virtual void apply_matching(const Match_t&);
347 
348  virtual void symmetrize_sparsity();
349 
350  virtual void print() const;
351  virtual void print_dense(const std::string& name) const {
352  std::cerr << "print_dense not implemented for this matrix type"
353  << std::endl;
354  }
355  virtual void print_matrix_market(const std::string& filename) const {
356  std::cerr << "print_matrix_market not implemented for this matrix type"
357  << std::endl;
358  }
359 
360  virtual int read_matrix_market(const std::string& filename) = 0;
361 
362  virtual real_t max_scaled_residual(const scalar_t* x,
363  const scalar_t* b) const = 0;
364  virtual real_t max_scaled_residual(const DenseM_t& x,
365  const DenseM_t& b) const = 0;
366 
367 
368 #ifndef DOXYGEN_SHOULD_SKIP_THIS
369  virtual CSRGraph<integer_t>
370  extract_graph(int ordering_level, integer_t lo, integer_t hi) const = 0;
371  virtual CSRGraph<integer_t>
372  extract_graph_sep_CB(int ordering_level, integer_t lo, integer_t hi,
373  const std::vector<integer_t>& upd) const = 0;
374  virtual CSRGraph<integer_t>
375  extract_graph_CB_sep(int ordering_level, integer_t lo, integer_t hi,
376  const std::vector<integer_t>& upd) const = 0;
377  virtual CSRGraph<integer_t>
378  extract_graph_CB(int ordering_level,
379  const std::vector<integer_t>& upd) const = 0;
380 
381  virtual void
382  extract_separator(integer_t sep_end, const std::vector<std::size_t>& I,
383  const std::vector<std::size_t>& J, DenseM_t& B,
384  int depth) const = 0;
385  virtual void
386  extract_front(DenseM_t& F11, DenseM_t& F12, DenseM_t& F21,
387  integer_t slo, integer_t shi,
388  const std::vector<integer_t>& upd,
389  int depth) const = 0;
390  virtual void
391  push_front_elements(integer_t, integer_t, const std::vector<integer_t>&,
392  std::vector<Triplet<scalar_t>>&,
393  std::vector<Triplet<scalar_t>>&,
394  std::vector<Triplet<scalar_t>>&) const = 0;
395  virtual void
396  set_front_elements(integer_t, integer_t, const std::vector<integer_t>&,
397  Triplet<scalar_t>*, Triplet<scalar_t>*,
398  Triplet<scalar_t>*) const = 0;
399  virtual void
400  count_front_elements(integer_t, integer_t, const std::vector<integer_t>&,
401  std::size_t&, std::size_t&, std::size_t&) const = 0;
402 
403  virtual void
404  front_multiply(integer_t slo, integer_t shi,
405  const std::vector<integer_t>& upd,
406  const DenseM_t& R, DenseM_t& Sr, DenseM_t& Sc,
407  int depth) const = 0;
408 
409  virtual void
410  front_multiply_F11(Trans op, integer_t slo, integer_t shi,
411  const DenseM_t& R, DenseM_t& S, int depth) const = 0;
412  virtual void
413  front_multiply_F12(Trans op, integer_t slo, integer_t shi,
414  const std::vector<integer_t>& upd,
415  const DenseM_t& R, DenseM_t& S, int depth) const = 0;
416  virtual void
417  front_multiply_F21(Trans op, integer_t slo, integer_t shi,
418  const std::vector<integer_t>& upd,
419  const DenseM_t& R, DenseM_t& S, int depth) const = 0;
420 
421 #if defined(STRUMPACK_USE_MPI)
422  virtual void
423  extract_F11_block(scalar_t* F, integer_t ldF,
424  integer_t row, integer_t nr_rows,
425  integer_t col, integer_t nr_cols) const = 0;
426  virtual void
427  extract_F12_block(scalar_t* F, integer_t ldF,
428  integer_t row, integer_t nr_rows,
429  integer_t col, integer_t nr_cols,
430  const integer_t* upd) const = 0;
431  virtual void
432  extract_F21_block(scalar_t* F, integer_t ldF,
433  integer_t row, integer_t nr_rows,
434  integer_t col, integer_t nr_cols,
435  const integer_t* upd) const = 0;
436  virtual void
437  extract_separator_2d(integer_t sep_end,
438  const std::vector<std::size_t>& I,
439  const std::vector<std::size_t>& J,
440  DistM_t& B) const = 0;
441  virtual void
442  front_multiply_2d(integer_t sep_begin, integer_t sep_end,
443  const std::vector<integer_t>& upd,
444  const DistM_t& R, DistM_t& Srow, DistM_t& Scol,
445  int depth) const = 0;
446  virtual void
447  front_multiply_2d(Trans op, integer_t sep_begin, integer_t sep_end,
448  const std::vector<integer_t>& upd, const DistM_t& R,
449  DistM_t& S, int depth) const = 0;
450 #endif //STRUMPACK_USE_MPI
451 #endif //DOXYGEN_SHOULD_SKIP_THIS
452 
453  protected:
454  integer_t n_, nnz_;
455  std::vector<integer_t> ptr_, ind_;
456  std::vector<scalar_t> val_;
457  bool symm_sparse_;
458 
459  enum MMsym {GENERAL, SYMMETRIC, SKEWSYMMETRIC, HERMITIAN};
460 
461  CompressedSparseMatrix();
462  CompressedSparseMatrix(integer_t n, integer_t nnz,
463  bool symm_sparse=false);
464  CompressedSparseMatrix(integer_t n,
465  const integer_t* row_ptr,
466  const integer_t* col_ind,
467  const scalar_t* values, bool symm_sparsity);
468 
469  std::vector<std::tuple<integer_t,integer_t,scalar_t>>
470  read_matrix_market_entries(const std::string& filename);
471 
472  virtual int strumpack_mc64(MatchingJob, Match_t&) { return 0; }
473 
474  virtual void scale(const std::vector<scalar_t>&,
475  const std::vector<scalar_t>&) = 0;
476  virtual void scale_real(const std::vector<real_t>&,
477  const std::vector<real_t>&) = 0;
478 
479  long long spmv_flops() const;
480  long long spmv_bytes() const;
481  };
482 
483 } //end namespace strumpack
484 
485 #endif // COMPRESSED_SPARSE_MATRIX_HPP
Contains the DenseMatrix and DenseMatrixWrapper classes, simple wrappers around BLAS/LAPACK style den...
Holds options for the sparse solver.
Definition: CompressedSparseMatrix.hpp:49
Abstract base class for compressed sparse matrix storage.
Definition: CompressedSparseMatrix.hpp:150
const integer_t & ind(integer_t i) const
Definition: CompressedSparseMatrix.hpp:248
const scalar_t * val() const
Definition: CompressedSparseMatrix.hpp:206
bool symm_sparse() const
Definition: CompressedSparseMatrix.hpp:285
const integer_t & ptr(integer_t i) const
Definition: CompressedSparseMatrix.hpp:240
integer_t * ptr()
Definition: CompressedSparseMatrix.hpp:216
integer_t nnz() const
Definition: CompressedSparseMatrix.hpp:177
virtual void spmv(const scalar_t *x, scalar_t *y) const =0
integer_t size() const
Definition: CompressedSparseMatrix.hpp:170
scalar_t & val(integer_t i)
Definition: CompressedSparseMatrix.hpp:277
integer_t & ind(integer_t i)
Definition: CompressedSparseMatrix.hpp:270
integer_t & ptr(integer_t i)
Definition: CompressedSparseMatrix.hpp:262
scalar_t * val()
Definition: CompressedSparseMatrix.hpp:233
virtual ~CompressedSparseMatrix()
Definition: CompressedSparseMatrix.hpp:163
virtual void permute(const integer_t *iorder, const integer_t *order)
virtual void spmv(const DenseM_t &x, DenseM_t &y) const =0
integer_t * ind()
Definition: CompressedSparseMatrix.hpp:225
const integer_t * ptr() const
Definition: CompressedSparseMatrix.hpp:188
const scalar_t & val(integer_t i) const
Definition: CompressedSparseMatrix.hpp:255
void set_symm_sparse(bool symm_sparse=true)
Definition: CompressedSparseMatrix.hpp:294
const integer_t * ind() const
Definition: CompressedSparseMatrix.hpp:197
This class represents a matrix, stored in column major format, to allow direct use of BLAS/LAPACK rou...
Definition: DenseMatrix.hpp:138
Definition: DistributedMatrix.hpp:52
Definition: CompressedSparseMatrix.hpp:97
Definition: CompressedSparseMatrix.hpp:56
Definition: StrumpackOptions.hpp:42
MatchingJob
Definition: StrumpackOptions.hpp:113
Trans
Definition: DenseMatrix.hpp:51