1#ifndef AMREX_COMPOSITE_SYSTEM_UTIL_H_
2#define AMREX_COMPOSITE_SYSTEM_UTIL_H_
3#include <AMReX_Config.H>
39 std::ostringstream os;
40 os << std::scientific << std::setprecision(6) <<
x;
64 std::sort(trips.begin(), trips.end(), [] (
Triplet const& a,
Triplet const& b) {
65 return (a.row < b.row) || (a.row == b.row && a.col < b.col);
72 Long prev_row = -1, prev_col = -1;
73 for (
auto const& t : trips) {
75 if (t.row == prev_row && t.col == prev_col) {
113 if (nprocs == 1) {
return std::move(trips); }
118 for (
auto const& t : trips) {
119 auto it = std::upper_bound(rank_offset.begin(), rank_offset.end(), t.row);
120 const int p =
static_cast<int>(it - rank_offset.begin()) - 1;
122 if (
p == myproc) { local.push_back(t); }
else { sendbuf[
p].push_back(t); }
126 constexpr Long int_max = std::numeric_limits<int>::max();
127 Vector<int> sendcnt(nprocs), recvcnt(nprocs), sdispl(nprocs), rdispl(nprocs);
128 for (
int p = 0;
p < nprocs; ++
p) {
130 sendcnt[
p] =
static_cast<int>(sendbuf[
p].
size());
132 MPI_Alltoall(sendcnt.data(), 1, MPI_INT, recvcnt.data(), 1, MPI_INT, comm);
133 Long stot = 0, rtot = 0;
134 for (
int p = 0;
p < nprocs; ++
p) {
135 sdispl[
p] =
static_cast<int>(stot); stot += sendcnt[
p];
136 rdispl[
p] =
static_cast<int>(rtot); rtot += recvcnt[
p];
141 for (
auto const& b : sendbuf) { sbuf.insert(sbuf.end(), b.begin(), b.end()); }
144 local.resize(nlocal + rtot);
146 MPI_Type_contiguous(
int(
sizeof(
Triplet)), MPI_BYTE, &ttype);
147 MPI_Type_commit(&ttype);
148 MPI_Alltoallv(sbuf.data(), sendcnt.data(), sdispl.data(), ttype,
149 local.data()+nlocal, recvcnt.data(), rdispl.data(), ttype, comm);
150 MPI_Type_free(&ttype);
154 return std::move(trips);
175 BL_PROFILE(
"composite::triplets_to_spmatrix");
177 const Long row_end = row_begin + nrows;
183 auto const* pr = rows.
data();
184 auto const* pc = cols.
data();
185 auto const* pv = vals.
data();
187 auto* ppos = pos.
data();
193 auto* ps = dsend.
data();
196 if (pr[i] < row_begin || pr[i] >= row_end) {
197 ps[ppos[i]] =
Triplet{.row = pr[i], .col = pc[i], .val = pv[i]};
204 const auto nrecv =
Long(hrecv.
size());
211 auto const* pt = drecv.
data();
212 auto* r = rows.
data();
213 auto* c = cols.
data();
214 auto* v = vals.
data();
226 const auto ntrip =
Long(rows.
size());
227 auto const* pr = rows.
data();
228 auto const* pc = cols.
data();
229 auto const* pv = vals.
data();
232 auto* pcnt = cnt.
data();
233 auto* pstart = start.
data();
236 if (pr[i] >= row_begin && pr[i] < row_end) {
246 if (r < nrows) { pcnt[r] = 0; }
else { pstart[r] = n_owned; }
249 auto* pp = perm.data();
252 if (pr[i] >= row_begin && pr[i] < row_end) {
253 const Long r = pr[i]-row_begin;
260 auto* pnu = nuniq.data();
263 const Long b = pstart[r], e = pstart[r+1];
264 for (
Long k = b+1; k < e; ++k) {
265 const Long t = pp[k];
266 const Long ct = pc[t];
268 while (m > b && (pc[pp[m-1]] > ct || (pc[pp[m-1]] == ct && pp[m-1] > t))) {
275 for (
Long k = b; k < e; ++k) {
276 if (k == b || pc[pp[k]] != pc[pp[k-1]]) { ++u; }
283 csr.row_offset.resize(nrows+1);
284 auto* pro = csr.row_offset.data();
290 csr.col_index.resize(nnz);
292 auto* pci = csr.col_index.data();
293 auto* pm = csr.mat.data();
296 if (r == nrows) { pro[r] = nnz;
return; }
298 for (
Long k = pstart[r]; k < pstart[r+1]; ++k) {
299 const Long t = pp[k];
300 if (k == pstart[r] || pc[t] != pc[pp[k-1]]) {
319 static std::map<std::string,int> counter;
344 if (nprocs == 1) {
return v; }
348 int nloc =
static_cast<int>(v.
size());
350 MPI_Gather(&nloc, 1, MPI_INT, counts.data(), 1, MPI_INT, 0, comm);
354 for (
int p = 0;
p < nprocs; ++
p) { displs[
p] =
int(ntot); ntot += counts[
p]; }
359 MPI_Gatherv(v.data(), nloc, mt, g.data(), counts.data(), displs.data(), mt, 0, comm);
374 (total <= std::min(gather_max,
Long(std::numeric_limits<int>::max())));
380 std::ofstream ofs(name);
381 if (!ofs) {
amrex::Abort(
"Cannot open dump file " + name); }
382 ofs << std::setprecision(std::numeric_limits<Real>::max_digits10);
387inline void check_dump (std::ofstream
const& ofs, std::string
const& name)
389 if (!ofs) {
amrex::Abort(
"Failed to write dump file " + name); }
399inline void write_row_map (std::string
const& file, std::string
const& title,
405 Long nglobal = info.size();
409 for (
Long r = 0; r < info.size(); ++r) {
410 for (
int c = 0; c < 4; ++c) { flat[r*4+c] = info[r][c]; }
412 auto write = [&] (std::string
const& name, std::string
const& note,
Long first_row,
416 ofs <<
"# " << title <<
"\n" << note <<
"# row level i j k scaling\n";
417 for (
Long r = 0; r < sc.size(); ++r) {
418 ofs << first_row+r+1 <<
' ' << fl[r*4] <<
' ' << fl[r*4+1] <<
' '
419 << fl[r*4+2] <<
' ' << fl[r*4+3] <<
' ' << sc[r] <<
'\n';
426 if (myproc == 0) { write(file,
"", 0, gflat, gscl); }
428 write(file +
"." + std::to_string(myproc),
429 "# part " + std::to_string(myproc) +
" of " + std::to_string(nprocs) +
430 ": rows owned by this rank\n", row_begin, flat, scaling);
487 auto write = [&] (std::string
const& name, std::string
const& note,
Vector<Long> const& rr,
491 ofs <<
"%%MatrixMarket matrix coordinate real general\n" << note;
492 ofs << nglobal <<
' ' << nglobal <<
' ' << vv.size() <<
'\n';
493 for (
Long n = 0; n < vv.size(); ++n) {
494 ofs << rr[n]+1 <<
' ' << cc[n]+1 <<
' ' << vv[n] <<
'\n';
502 if (myproc == 0) { write(file,
"", grows, gcols, gvals); }
504 write(file +
"." + std::to_string(myproc),
505 "% part " + std::to_string(myproc) +
" of " + std::to_string(nprocs) +
521 auto write = [&] (std::string
const& name, std::string
const& note,
Vector<Real> const&
x)
524 ofs <<
"%%MatrixMarket matrix array real general\n" << note;
525 ofs <<
x.size() <<
" 1\n";
526 for (
auto const& xi :
x) { ofs << xi <<
'\n'; }
531 if (myproc == 0) { write(file,
"", g); }
533 write(file +
"." + std::to_string(myproc),
534 "% part " + std::to_string(myproc) +
" of " + std::to_string(nprocs) +
535 ": rows " + std::to_string(row_begin+1) +
" to " +
536 std::to_string(row_begin+v.
size()) +
" of " + std::to_string(nglobal) +
"\n", v);
#define BL_PROFILE(a)
Definition AMReX_BLProfiler.H:593
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
#define AMREX_GPU_DEVICE
Definition AMReX_GpuQualifiers.H:18
while parser_exe_t p
Definition AMReX_Parser_Exe_Body.H:33
Algebraic multigrid solver for SpMatrix / AlgVector systems.
Definition AMReX_AlgMG.H:264
void setAggressiveNumLevels(int n)
Number of levels with aggressive coarsening, starting at the finest. Next setup.
Definition AMReX_AlgMG.H:322
void setChebyshevDegree(int d)
Chebyshev polynomial degree. Next solve.
Definition AMReX_AlgMG.H:298
void setMaxCoarseSize(Long n)
Stop coarsening when a level has at most this many rows. Next setup.
Definition AMReX_AlgMG.H:320
void setPreSmooth(int nu)
Number of pre-smoothing sweeps; negative restores the smoother's default.
Definition AMReX_AlgMG.H:305
void setBottomSolver(BottomSolver bs)
Definition AMReX_AlgMG.H:360
void setPMaxElmts(int n)
Definition AMReX_AlgMG.H:337
void setPostSmooth(int nu)
Number of post-smoothing sweeps; negative restores the smoother's default.
Definition AMReX_AlgMG.H:307
void setInterpType(InterpType it)
Takes effect at the next setup.
Definition AMReX_AlgMG.H:334
void setTruncFactor(T f)
Drop interpolation weights below this fraction of the row maximum. Next setup.
Definition AMReX_AlgMG.H:345
void setMaxLevels(int n)
Definition AMReX_AlgMG.H:318
void setStrongThreshold(T theta)
Definition AMReX_AlgMG.H:315
void setSmoother(Smoother sm)
Takes effect at the next solve; the hierarchy is kept.
Definition AMReX_AlgMG.H:294
void setVerbose(int v)
Definition AMReX_AlgMG.H:284
void setKrylovSolver(KrylovSolver a)
Krylov solver with the V-cycle as preconditioner (see KrylovSolver). Default None.
Definition AMReX_AlgMG.H:347
Definition AMReX_AlgPartition.H:26
size_type size() const noexcept
Definition AMReX_PODVector.H:654
iterator begin() noexcept
Definition AMReX_PODVector.H:680
void resize(size_type a_new_size, GrowthStrategy strategy=GrowthStrategy::Poisson)
Definition AMReX_PODVector.H:734
iterator end() noexcept
Definition AMReX_PODVector.H:684
void clear() noexcept
Definition AMReX_PODVector.H:652
T * data() noexcept
Definition AMReX_PODVector.H:672
Parse Parameters From Command Line and Input Files.
Definition AMReX_ParmParse.H:354
int query_enum_case_insensitive(std::string_view name, T &ref, int ival=FIRST) const
. Query enum value using given name.
Definition AMReX_ParmParse.H:1451
int query(std::string_view name, bool &ref, int ival=FIRST) const
Same as querykth() but searches for the last occurrence of name.
Definition AMReX_ParmParse.cpp:2010
Distributed CSR matrix that manages storage and GPU-friendly partitions.
Definition AMReX_SpMatrix.H:65
CSR< T, container_type > csr_type
Definition AMReX_SpMatrix.H:70
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:917
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
amrex_real Real
Floating Point Type for Fields.
Definition AMReX_REAL.H:80
amrex_long Long
Definition AMReX_INT.H:30
PODVector< T, ArenaAllocator< T > > DeviceVector
A PODVector that uses the standard memory Arena. Note that the memory might or might not be managed d...
Definition AMReX_GpuContainers.H:24
int MyProc() noexcept
Definition AMReX_ParallelDescriptor.H:128
void Sum(Gpu::DeviceVector< T > &v, MPI_Comm comm)
Definition AMReX_GpuParallelReduce.H:37
int NProcs() noexcept
Definition AMReX_ParallelDescriptor.H:255
__host__ __device__ constexpr const T & max(const T &a, const T &b) noexcept
Definition AMReX_Algorithm.H:54
__host__ __device__ AMREX_FORCE_INLINE void AddNoRet(T *sum, T value) noexcept
Definition AMReX_GpuAtomic.H:283
__host__ __device__ AMREX_FORCE_INLINE T Add(T *sum, T value) noexcept
Definition AMReX_GpuAtomic.H:200
void copyAsync(HostToDevice, InIter begin, InIter end, OutIter result) noexcept
A host-to-device copy routine. Note this is just a wrapper around memcpy, so it assumes contiguous st...
Definition AMReX_GpuContainers.H:228
static constexpr DeviceToHost deviceToHost
Definition AMReX_GpuContainers.H:106
static constexpr HostToDevice hostToDevice
Definition AMReX_GpuContainers.H:105
void streamSynchronize() noexcept
Definition AMReX_GpuDevice.H:329
static constexpr struct amrex::Scan::Type::Exclusive exclusive
static constexpr RetSum retSum
Definition AMReX_Scan.H:34
T PrefixSum(N n, FIN const &fin, FOUT const &fout, TYPE, RetSum a_ret_sum=retSum)
Definition AMReX_Scan.H:815
Definition AMReX_CompositeSystemUtil.H:31
void write_row_map(std::string const &file, std::string const &title, Vector< std::array< Long, 4 > > const &info, Vector< Real > const &scaling, Long row_begin, MPI_Comm comm, Long gather_max)
Write the row map of a composite system: one line per row with the 1-based row, AMR level,...
Definition AMReX_CompositeSystemUtil.H:399
std::string to_sci(double x)
Scientific notation for messages (std::to_string prints 0.000000 for 1e-7).
Definition AMReX_CompositeSystemUtil.H:37
void write_vector_market(std::string const &file, Vector< Real > const &v, Long nglobal, Long row_begin, MPI_Comm comm, Long gather_max)
Write a distributed vector (this rank's rows start at the global row row_begin) as a Matrix Market de...
Definition AMReX_CompositeSystemUtil.H:516
bool dump_single_file(Long total, Long gather_max, MPI_Comm comm)
Whether a dump of total values goes to one file written by rank 0 (always on one rank)....
Definition AMReX_CompositeSystemUtil.H:371
void check_dump(std::ofstream const &ofs, std::string const &name)
Abort if writing a dump file failed.
Definition AMReX_CompositeSystemUtil.H:387
void algmg_parse_options(AlgMG< Real > &mg, std::string const &prefix, AlgMGKrylovSolver krylov)
Configure an AlgMG solver from <prefix>.algmg.*: verbose, krylov (none|bicgstab|gmres|pcg; default kr...
Definition AMReX_CompositeSystemUtil.H:442
bool dump_pending(std::string const &prefix, int max)
Whether a dump with this prefix is still pending (fewer than max written).
Definition AMReX_CompositeSystemUtil.H:324
void write_matrix_market(std::string const &file, OwnedCSR const &csr, Long nglobal, MPI_Comm comm, Long gather_max)
Write a distributed matrix in Matrix Market coordinate format (1-based indices, "general"),...
Definition AMReX_CompositeSystemUtil.H:475
std::ofstream open_dump(std::string const &name)
Open a dump file for writing, aborting on failure.
Definition AMReX_CompositeSystemUtil.H:378
void triplets_to_spmatrix(Gpu::DeviceVector< Long > &rows, Gpu::DeviceVector< Long > &cols, Gpu::DeviceVector< Real > &vals, Long row_begin, Long nrows, Vector< Long > const &rank_offset, MPI_Comm comm, SpMatrix< Real > &mat)
Build an SpMatrix of this rank's rows [row_begin, row_begin+nrows) from (row, column,...
Definition AMReX_CompositeSystemUtil.H:170
Vector< T > gather_on_root(Vector< T > const &v, MPI_Comm comm)
Gather the chunks of a distributed array on rank 0 (ranks in order); other ranks return an empty vect...
Definition AMReX_CompositeSystemUtil.H:341
int next_dump_index(std::string const &prefix, int max)
Index of the next dump for this prefix, or -1 once max have been written.
Definition AMReX_CompositeSystemUtil.H:330
Vector< Triplet > exchange_triplets(Vector< Triplet > &&trips, Vector< Long > const &rank_offset, MPI_Comm comm)
Send each triplet to the rank owning its row (rank p owns rows [rank_offset[p], rank_offset[p+1])) an...
Definition AMReX_CompositeSystemUtil.H:109
std::map< std::string, int > & dump_counters()
Dumps written so far per dump prefix, over all solver objects of the run.
Definition AMReX_CompositeSystemUtil.H:317
int MPI_Comm
Definition AMReX_ccse-mpi.H:51
int MPI_Datatype
Definition AMReX_ccse-mpi.H:53
__host__ __device__ void ignore_unused(const Ts &...)
No-op helper that marks variables as intentionally unused.
Definition AMReX.H:273
AlgMGInterpType
Definition AMReX_AlgMG.H:220
void ParallelFor(TypeList< CTOs... > ctos, std::array< int, sizeof...(CTOs)> const &runtime_options, T N, F &&f)
Definition AMReX_CTOParallelForImpl.H:202
AlgMGBottomSolver
Definition AMReX_AlgMG.H:210
AlgMGKrylovSolver
Definition AMReX_AlgMG.H:216
@ x
Definition AMReX_Orientation.H:14
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:244
const int[]
Definition AMReX_BLProfiler.cpp:1665
AlgMGSmoother
Definition AMReX_AlgMG.H:229
V< Index > col_index
Definition AMReX_CSR.H:62
V< T > mat
Definition AMReX_CSR.H:61
V< Index > row_offset
Definition AMReX_CSR.H:63
Long nnz
Definition AMReX_CSR.H:64
Sorted CSR means for each row the column indices are sorted.
Definition AMReX_SpMatrix.H:49
static MPI_Datatype type()
Rows owned by this rank in CSR form, columns sorted within each row and duplicates summed.
Definition AMReX_CompositeSystemUtil.H:49
Vector< Long > col_index
global column indices
Definition AMReX_CompositeSystemUtil.H:53
Long nnz() const
Definition AMReX_CompositeSystemUtil.H:56
void define(Long a_row_begin, Long a_nrows, Vector< Triplet > trips)
Definition AMReX_CompositeSystemUtil.H:60
Long nrows
number of rows owned by this rank
Definition AMReX_CompositeSystemUtil.H:51
Vector< Real > values
Definition AMReX_CompositeSystemUtil.H:54
Long row_begin
first global row of this rank
Definition AMReX_CompositeSystemUtil.H:50
Vector< Long > row_offset
size nrows+1
Definition AMReX_CompositeSystemUtil.H:52
void toSpMatrix(SpMatrix< Real > &mat, Vector< Long > const &rank_offset) const
Define an SpMatrix (device memory in GPU builds) with this CSR.
Definition AMReX_CompositeSystemUtil.H:89
(row, column, value) of a matrix entry with global indices
Definition AMReX_CompositeSystemUtil.H:34
Real val
Definition AMReX_CompositeSystemUtil.H:34
Long row
Definition AMReX_CompositeSystemUtil.H:34
Long col
Definition AMReX_CompositeSystemUtil.H:34