21 #ifndef AMESOS2_EPETRACRSMATRIX_MATRIXADAPTER_DECL_HPP
22 #define AMESOS2_EPETRACRSMATRIX_MATRIXADAPTER_DECL_HPP
24 #include "Amesos2_config.h"
26 #include <Epetra_CrsMatrix.h>
27 #ifdef HAVE_AMESOS2_EPETRAEXT
28 #include <EpetraExt_Reindex_CrsMatrix.h>
30 #include <Epetra_Comm.h>
31 #include <Epetra_SerialComm.h>
33 # include <Epetra_MpiComm.h>
37 #include "Amesos2_MatrixAdapter_decl.hpp"
56 class ConcreteMatrixAdapter< Epetra_CrsMatrix >
63 typedef Epetra_CrsMatrix matrix_t;
69 typedef super_t::scalar_t scalar_t;
70 typedef super_t::local_ordinal_t local_ordinal_t;
71 typedef super_t::global_ordinal_t global_ordinal_t;
72 typedef super_t::node_t node_t;
73 typedef super_t::global_size_t global_size_t;
75 typedef Tpetra::Map<local_ordinal_t,global_ordinal_t,node_t> map_t;
76 typedef ConcreteMatrixAdapter<matrix_t> type;
78 ConcreteMatrixAdapter(RCP<matrix_t> m);
81 RCP<const MatrixAdapter<matrix_t> > get_impl(
const Teuchos::Ptr<const map_t> map,
EDistribution distribution = ROOTED)
const;
82 RCP<const MatrixAdapter<matrix_t> > reindex_impl(Teuchos::RCP<const map_t> &contigRowMap,
83 Teuchos::RCP<const map_t> &contigColMap,
84 const EPhase current_phase)
const;
87 template<
typename KV_S,
typename KV_GO,
typename KV_GS,
typename host_ordinal_type_array,
typename host_scalar_type_array>
88 local_ordinal_t gather_impl(KV_S& nzvals, KV_GO& indices, KV_GS& pointers,
89 host_ordinal_type_array &recvCounts, host_ordinal_type_array &recvDispls,
90 host_ordinal_type_array &transpose_map, host_scalar_type_array &nzvals_t,
91 bool column_major,
EPhase current_phase)
const
93 local_ordinal_t ret = -1;
95 auto rowMap = this->getRowMap();
96 auto colMap = this->getColMap();
98 auto comm = rowMap->getComm();
99 auto nRanks = comm->getSize();
100 auto myRank = comm->getRank();
102 RCP<Teuchos::Comm<int>> comm = Teuchos::createSerialComm<int>();
107 int *lclRowptr =
nullptr;
108 int *lclColind =
nullptr;
109 double *lclNzvals =
nullptr;
110 this->mat_->ExtractCrsDataPointers(lclRowptr, lclColind, lclNzvals);
112 int nRows = this->mat_->NumGlobalRows();
113 int myNRows = this->mat_->NumMyRows();
114 int myNnz = this->mat_->NumMyNonzeros();
115 if(current_phase == PREORDERING || current_phase == SYMBFACT) {
117 Kokkos::resize(recvCounts, nRanks);
118 Kokkos::resize(recvDispls, nRanks+1);
121 global_ordinal_t rowIndexBase = rowMap->getIndexBase();
122 global_ordinal_t colIndexBase = colMap->getIndexBase();
124 host_ordinal_type_array perm_g2l;
125 host_ordinal_type_array perm_l2g;
129 bool need_to_perm =
false;
131 #ifdef HAVE_AMESOS2_TIMERS
132 Teuchos::RCP< Teuchos::Time > gatherTime = Teuchos::TimeMonitor::getNewCounter (
"Amesos2::gather(rowptr)");
133 Teuchos::TimeMonitor GatherTimer(*gatherTime);
135 Teuchos::gather<int, int> (&myNRows, 1, recvCounts.data(), 1, 0, *comm);
137 Kokkos::resize(recvDispls, nRanks+1);
139 for (
int p = 1; p <= nRanks; p++) {
140 recvDispls(p) = recvDispls(p-1) + recvCounts(p-1);
142 if (recvDispls(nRanks) != nRows) {
143 TEUCHOS_TEST_FOR_EXCEPTION(
true, std::runtime_error,
"Amesos2_TpetraCrsMatrix_MatrixAdapter::gather_impl : mismatch between gathered(local nrows) and global nrows.");
146 for (
int p = 0; p < nRanks; p++) {
150 recvDispls(nRanks) = 0;
154 host_ordinal_type_array lclMap;
155 Kokkos::resize(lclMap, myNRows);
157 Kokkos::resize(perm_g2l, nRows);
158 Kokkos::resize(perm_l2g, nRows);
160 Kokkos::resize(perm_g2l, 1);
162 for (
int i=0; i < myNRows; i++) {
163 lclMap(i) = rowMap->getGlobalElement(i);
165 Teuchos::gatherv<int, local_ordinal_t> (lclMap.data(), myNRows, perm_g2l.data(),
166 recvCounts.data(), recvDispls.data(),
169 for (
int i=0; i < nRows; i++) {
170 perm_g2l(i) -= rowIndexBase;
171 perm_l2g(perm_g2l(i)) = i;
172 if (i != perm_g2l(i)) need_to_perm =
true;
176 if (myRank == 0 && (column_major || need_to_perm)) {
177 Kokkos::resize(pointers_t, nRows+1);
178 }
else if (myRank != 0) {
179 Kokkos::resize(pointers_t, 2);
181 local_ordinal_t sendIdx = (myNRows > 0 ? 1 : 0);
182 local_ordinal_t *pointers_ = ((myRank != 0 || (column_major || need_to_perm)) ? pointers_t.data() : pointers.data());
183 Teuchos::gatherv<int, local_ordinal_t> (&lclRowptr[sendIdx], myNRows, &pointers_[1],
184 recvCounts.data(), recvDispls.data(),
189 recvCounts(0) = pointers_[recvDispls(1)];
190 local_ordinal_t displs = recvCounts(0);
191 for (
int p = 1; p < nRanks; p++) {
194 if (recvDispls(p+1) > recvDispls(p)) {
196 recvCounts(p) = pointers_[recvDispls(p+1)];
198 for (
int i = 1+recvDispls(p); i <= recvDispls(p+1); i++) {
199 pointers_[i] += displs;
201 displs += recvCounts(p);
204 ret = pointers_[nRows];
208 #ifdef HAVE_AMESOS2_TIMERS
209 Teuchos::RCP< Teuchos::Time > gatherTime = Teuchos::TimeMonitor::getNewCounter (
"Amesos2::gather(colind)");
210 Teuchos::TimeMonitor GatherTimer(*gatherTime);
215 for (
int p = 0; p < nRanks; p++) {
216 recvDispls(p+1) = recvDispls(p) + recvCounts(p);
220 KV_GO lclColind_ (
"localColind_", myNnz);
221 for (
int i = 0; i < int(myNnz); i++) lclColind_(i) = (colMap->getGlobalElement((lclColind[i])) - colIndexBase);
222 if (column_major || need_to_perm) {
223 Kokkos::resize(indices_t, indices.extent(0));
224 Teuchos::gatherv<int, local_ordinal_t> (lclColind_.data(), myNnz, indices_t.data(),
225 recvCounts.data(), recvDispls.data(),
228 Teuchos::gatherv<int, local_ordinal_t> (lclColind_.data(), myNnz, indices.data(),
229 recvCounts.data(), recvDispls.data(),
234 #ifdef HAVE_AMESOS2_TIMERS
235 Teuchos::RCP< Teuchos::Time > gatherTime = Teuchos::TimeMonitor::getNewCounter (
"Amesos2::gather(transpose index)");
236 Teuchos::TimeMonitor GatherTimer(*gatherTime);
240 Kokkos::resize(transpose_map, ret);
242 for (
int i=0; i<=nRows; i++) {
245 for (
int k=0; k<ret; k++) {
246 int col = indices_t(k);
251 for (
int i=1; i < nRows; i++) {
252 pointers(i+1) += pointers(i);
255 for (
int row=0; row<nRows; row++) {
256 int i = perm_g2l(row);
257 for (
int k=pointers_t(i); k<pointers_t(i+1); k++) {
258 int col = indices_t(k);
259 transpose_map(k) = pointers(1+col);
260 indices(pointers(1+col)) = row;
264 }
else if (need_to_perm) {
266 Kokkos::resize(transpose_map, ret);
267 for (
int i=0; i<nRows; i++) {
268 int row = perm_g2l(i);
269 pointers(row+2) = pointers_t(i+1)-pointers_t(i);
271 for (
int i=1; i < nRows; i++) {
272 pointers(i+1) += pointers(i);
274 for (
int i=0; i<nRows; i++) {
275 int row = perm_g2l(i);
276 for (
int k=pointers_t(i); k<pointers_t(i+1); k++) {
277 int col = indices_t(k);
278 transpose_map(k) = pointers(1+row);
279 indices(pointers(1+row)) = col;
284 Kokkos::resize(transpose_map, 0);
291 #ifdef HAVE_AMESOS2_TIMERS
292 Teuchos::RCP< Teuchos::Time > gatherTime = Teuchos::TimeMonitor::getNewCounter (
"Amesos2::gather(nzvals)");
293 Teuchos::TimeMonitor GatherTimer(*gatherTime);
296 if (transpose_map.extent(0) > 0) {
297 Kokkos::resize(nzvals_t, nzvals.extent(0));
298 Teuchos::gatherv<int, scalar_t> (lclNzvals, myNnz, nzvals_t.data(),
299 recvCounts.data(), recvDispls.data(),
302 Teuchos::gatherv<int, scalar_t> (lclNzvals, myNnz, nzvals.data(),
303 recvCounts.data(), recvDispls.data(),
309 ret = pointers(nRows);
310 if (transpose_map.extent(0) > 0) {
311 for (
int k=0; k<ret; k++) {
312 nzvals(transpose_map(k)) = nzvals_t(k);
318 Teuchos::broadcast<int, local_ordinal_t>(*comm, 0, 1, &ret);
325 describe (Teuchos::FancyOStream& os,
326 const Teuchos::EVerbosityLevel verbLevel =
327 Teuchos::Describable::verbLevel_default)
const;
328 #ifdef HAVE_AMESOS2_EPETRAEXT
330 mutable RCP<EpetraExt::CrsMatrix_Reindex> StdIndex_;
331 mutable RCP<Epetra_CrsMatrix> ContigMat_;
337 #endif // AMESOS2_EPETRACRSMATRIX_MATRIXADAPTER_DECL_HPP
EPhase
Used to indicate a phase in the direct solution.
Definition: Amesos2_TypeDecl.hpp:31
A Matrix adapter interface for Amesos2.
Definition: Amesos2_MatrixAdapter_decl.hpp:42
Provides the Epetra_RowMatrix abstraction for the concrete Epetra row matric adapters.
Definition: Amesos2_AbstractConcreteMatrixAdapter.hpp:55
EDistribution
Definition: Amesos2_TypeDecl.hpp:89