Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_SpMatUtil.H
Go to the documentation of this file.
1#ifndef AMREX_SPMAT_UTIL_H_
2#define AMREX_SPMAT_UTIL_H_
3#include <AMReX_Config.H>
4
5#include <AMReX_SpMatrix.H>
6#include <AMReX_Random.H>
7
8namespace amrex {
9
23template <typename T, template <typename> class V>
24CSR<T,V> transpose (CSR<T,V> const& csr, Long ncols)
25{
26 Long nnz = csr.nnz;
27
28 CSR<T,V> csrt;
29 csrt.mat.resize(nnz);
30 csrt.col_index.resize(nnz);
31 csrt.row_offset.resize(ncols+1);
32 csrt.nnz = nnz;
33
34 detail::transpose(csrt.view(), csr.const_view());
35
36 return csrt;
37}
38
47template <typename T, template<typename> class Allocator>
49 AlgPartition const& col_partition)
50{
51 const_cast<SpMatrix<T,Allocator>&>(A).startComm_tr(col_partition);
52
54 AT.m_row_begin = col_partition[ParallelDescriptor::MyProc()];
55 AT.m_row_end = col_partition[ParallelDescriptor::MyProc()+1];
56 AT.m_partition = col_partition;
57 AT.m_nnz = A.m_csr.nnz;
58
59 // transpose the diagonal part
60 auto at_csr = transpose(A.m_csr, AT.numLocalRows());
61 AT.m_csr = std::move(at_csr);
62
63 const_cast<SpMatrix<T,Allocator>&>(A).finishComm_tr(AT);
64
65 return AT;
66}
67
69template <typename T, template<typename> class Allocator = DefaultAllocator>
71{
72 SpMatrix<T,Allocator> I(std::move(partition), 1);
73 I.setVal([=] AMREX_GPU_DEVICE (Long row, Long* col, T* val) {
74 *col = row; *val = T(1);
75 }, CsrSorted{true});
76 return I;
77}
78
94template <typename T, template<typename> class Allocator = DefaultAllocator>
96 Real lambda, int nnz_per_row_max)
97{
98 AMREX_ALWAYS_ASSERT(partition.numGlobalRows() == nrows);
99
100 auto nlrows = partition.numLocalRows();
101 Long lnnz = nlrows * nnz_per_row_max;
102 typename SpMatrix<T,Allocator>::template container_type<T> mat(lnnz);
103 typename SpMatrix<T,Allocator>::template container_type<Long> col_index(lnnz);
104 typename SpMatrix<T,Allocator>::template container_type<Long> row_offset(nlrows+1, 0);
105 auto* pmat = mat.data();
106 auto* pcol = col_index.data();
107 auto* prow = row_offset.data();
108
109 auto ncols_max = (unsigned int)
110 std::min(ncols, Long(std::numeric_limits<unsigned int>::max()));
111 // A row cannot have more distinct columns than ncols.
112 auto nnz_row_cap = int(std::min(Long(nnz_per_row_max), ncols));
113
114 ParallelForRNG(nlrows, [=] AMREX_GPU_DEVICE (Long lrow, RandomEngine const& eng)
115 {
116 auto os = lrow * nnz_per_row_max;
117 prow[lrow] = os;
118 if (lrow+1 == nlrows) {
119 prow[lrow+1] = lnnz;
120 }
121
122 auto nnz_row = int(std::min(Long(amrex::RandomPoisson(lambda, eng)),
123 Long(nnz_row_cap)));
124
125 for (int j = 0; j < nnz_row; ++j) {
126 pmat[os+j] = Random(eng);
127 while (true) {
128 auto c = Long(Random_int(ncols_max, eng));
129 bool new_c = true;
130 for (int jj = 0; jj < j; ++jj) {
131 new_c = new_c && (c != pcol[os+jj]);
132 }
133 if (new_c) {
134 pcol[os+j] = c;
135 break;
136 }
137 }
138 }
139
140 for (int j = nnz_row; j < nnz_per_row_max; ++j) {
141 pcol[os+j] = -1;
142 pmat[os+j] = T(0);
143 }
144 });
145
147 r.define(std::move(partition), pmat, pcol, lnnz, prow,
148 CsrSorted{false}, CsrValid{false});
149
150 return r;
151}
152
174template <typename T, template<typename> class Allocator = DefaultAllocator>
176 int ulp = 2)
177{
178 auto const& col_partition_A = A.columnPartition();
179 auto const& col_partition_B = B.columnPartition();
180 if (col_partition_A.empty() && ! col_partition_B.empty()) {
181 const_cast<SpMatrix<T,Allocator>&>(A).setColumnPartition(col_partition_B);
182 } else if (! col_partition_A.empty() && col_partition_B.empty()) {
183 const_cast<SpMatrix<T,Allocator>&>(B).setColumnPartition(col_partition_A);
184 }
185
186 auto const& pca = A.const_parcsr();
187 auto const& pcb = B.const_parcsr();
188
189 if (pca.row_begin != pcb.row_begin ||
190 pca.col_begin != pcb.col_begin ||
191 pca.csr0.nnz != pcb.csr0.nnz ||
192 pca.csr0.nrows != pcb.csr0.nrows ||
193 pca.csr1.nnz != pcb.csr1.nnz ||
194 pca.csr1.nrows != pcb.csr1.nrows)
195 {
196 return false;
197 }
198
199 Long N = std::max({pca.csr0.nnz, pca.csr0.nrows, pca.csr1.nnz, pca.csr1.nrows});
200 auto r = Reduce::Min<int>(N, [=] AMREX_GPU_DEVICE (Long i) {
201 bool t = true;
202 if (i < pca.csr0.nnz) {
203 t = amrex::almostEqual(pca.csr0.mat[i], pcb.csr0.mat[i], ulp) &&
204 pca.csr0.col_index[i] == pcb.csr0.col_index[i];
205 }
206 if (t && i < pca.csr0.nrows) {
207 t = pca.csr0.row_offset[i] == pcb.csr0.row_offset[i];
208 // Which local rows have remote entries.
209 if (t && pca.csr1.nnz > 0) {
210 t = pca.row_map[i] == pcb.row_map[i];
211 }
212 }
213 if (t && i < pca.csr1.nnz) {
214 // Remote column indices are local; compare the global ones.
215 t = amrex::almostEqual(pca.csr1.mat[i], pcb.csr1.mat[i], ulp) &&
216 pca.col_map[pca.csr1.col_index[i]] == pcb.col_map[pcb.csr1.col_index[i]];
217 }
218 if (t && i < pca.csr1.nrows) {
219 t = pca.csr1.row_offset[i] == pcb.csr1.row_offset[i];
220 }
221 return int(t);
222 }, 1);
223
224 return r;
225}
226
227}
228
229#endif
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
Definition AMReX_AlgPartition.H:21
Long numGlobalRows() const
Total number of rows covered by the partition.
Definition AMReX_AlgPartition.H:50
Long numLocalRows() const
Number of local rows.
Definition AMReX_AlgPartition.H:45
Distributed CSR matrix that manages storage and GPU-friendly partitions.
Definition AMReX_SpMatrix.H:63
T * data()
Don't use this beyond initial setup.
Definition AMReX_SpMatrix.H:203
AlgPartition const & columnPartition() const
Return the column partition used for matrix-vector and matrix-matrix multiplications.
Definition AMReX_SpMatrix.H:188
ParCsr< T const > const_parcsr() const
Const-qualified alias of parcsr() for convenience.
Definition AMReX_SpMatrix.H:1089
Long numLocalRows() const
Number of rows owned by this rank.
Definition AMReX_SpMatrix.H:191
void setVal(F const &f, CsrSorted is_sorted)
Initialize matrix entries using a row-wise functor.
Definition AMReX_SpMatrix.H:993
void define(AlgPartition partition, int nnz_per_row)
Allocate storage for a default-constructed matrix with a fixed number of nonzeros per row.
Definition AMReX_SpMatrix.H:775
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
amrex_long Long
Definition AMReX_INT.H:30
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
unsigned int Random_int(unsigned int n)
Generates one pseudorandom unsigned integer which is uniformly distributed on [0,n-1]-interval for ea...
Definition AMReX_Random.cpp:186
Real Random()
Generate a psuedo-random real from uniform distribution.
Definition AMReX_Random.cpp:155
unsigned int RandomPoisson(Real lambda)
Generate a psuedo-random integer from a Poisson distribution.
Definition AMReX_Random.cpp:172
__host__ __device__ bool almostEqual(T x, T y, int ulp=2)
Definition AMReX_Algorithm.H:139
Definition AMReX_Amr.cpp:50
SpMatrix< T, Allocator > RandomMatrix(AlgPartition partition, Long nrows, Long ncols, Real lambda, int nnz_per_row_max)
Return a random sparse matrix.
Definition AMReX_SpMatUtil.H:95
amrex::ArenaAllocator< T > DefaultAllocator
Definition AMReX_GpuAllocators.H:205
SpMatrix< T, Allocator > IdentityMatrix(AlgPartition partition)
Return an identity matrix with given partition.
Definition AMReX_SpMatUtil.H:70
CSR< T, V > transpose(CSR< T, V > const &csr, Long ncols)
Build the transpose CSR of csr.
Definition AMReX_SpMatUtil.H:24
AMREX_ATTRIBUTE_FLATTEN_FOR void ParallelForRNG(T n, L const &f) noexcept
Definition AMReX_GpuLaunchFunctsC.H:1157
const int[]
Definition AMReX_BLProfiler.cpp:1665
Owning CSR container backed by AMReX resizable vectors.
Definition AMReX_CSR.H:50
V< Long > row_offset
Definition AMReX_CSR.H:53
Long nnz
Definition AMReX_CSR.H:54
CsrView< T > view()
Mutable view of the underlying buffers.
Definition AMReX_CSR.H:78
CsrView< T const > const_view() const
Convenience alias for view() const.
Definition AMReX_CSR.H:93
V< Long > col_index
Definition AMReX_CSR.H:52
V< T > mat
Definition AMReX_CSR.H:51
Sorted CSR means for each row the column indices are sorted.
Definition AMReX_SpMatrix.H:47
Valid CSR means all entries are valid. It may be sorted ro unsorted.
Definition AMReX_SpMatrix.H:53
Definition AMReX_RandomEngine.H:72