10 #ifndef TPETRA_DETAILS_PACKTRIPLES_HPP
11 #define TPETRA_DETAILS_PACKTRIPLES_HPP
13 #include "TpetraCore_config.h"
14 #include "Teuchos_Comm.hpp"
15 #ifdef HAVE_TPETRACORE_MPI
18 #endif // HAVE_TPETRACORE_MPI
30 #ifdef HAVE_TPETRACORE_MPI
36 int countPackTriplesCountMpi(MPI_Comm comm,
38 std::ostream* errStrm = NULL);
40 int packTriplesCountMpi(
const int numEnt,
45 std::ostream* errStrm = NULL);
47 template <
class ScalarType,
class OrdinalType>
48 int countPackTriplesMpi(MPI_Datatype ordinalDt,
49 MPI_Datatype scalarDt,
53 std::ostream* errStrm = NULL) {
55 int errCode = MPI_SUCCESS;
63 errCode = MPI_Pack_size(2, ordinalDt, comm, &curSize);
64 if (errCode != MPI_SUCCESS) {
65 if (errStrm != NULL) {
66 *errStrm <<
"countPackTripleMpi: MPI_Pack_size failed on "
77 errCode = MPI_Pack_size(1, scalarDt, comm, &curSize);
78 if (errCode != MPI_SUCCESS) {
79 if (errStrm != NULL) {
80 *errStrm <<
"countPackTripleMpi: MPI_Pack_size failed on "
94 template <
class ScalarType,
class OrdinalType>
95 int packTripleMpi(
const OrdinalType gblRowInd,
96 const OrdinalType gblColInd,
97 MPI_Datatype ordinalDt,
98 const ScalarType& val,
99 MPI_Datatype scalarDt,
101 const int outBufSize,
104 std::ostream* errStrm = NULL) {
106 int errCode = MPI_SUCCESS;
109 OrdinalType inds[2] = {gblRowInd, gblColInd};
110 errCode = MPI_Pack(inds, 2, ordinalDt,
111 outBuf, outBufSize, &outBufCurPos, comm);
112 if (errCode != MPI_SUCCESS) {
113 if (errStrm != NULL) {
114 *errStrm <<
"packTripleMpi: MPI_Pack failed for indices i=" << gblRowInd
115 <<
", j=" << gblColInd <<
", where outBufSize=" << outBufSize
116 <<
" and outBufCurPos=" << outBufCurPos <<
"." << endl;
123 errCode = MPI_Pack(const_cast<ScalarType*>(&val), 1, scalarDt,
124 outBuf, outBufSize, &outBufCurPos, comm);
125 if (errCode != MPI_SUCCESS) {
126 if (errStrm != NULL) {
127 *errStrm <<
"packTripleMpi: MPI_Pack failed on val = " << val
135 template <
class ScalarType,
class OrdinalType>
136 int packTriplesMpi(
const OrdinalType gblRowInds[],
137 const OrdinalType gblColInds[],
138 MPI_Datatype ordinalDt,
139 const ScalarType vals[],
140 MPI_Datatype scalarDt,
143 const int outBufSize,
146 std::ostream* errStrm = NULL) {
148 int errCode = MPI_SUCCESS;
150 for (
int k = 0; k < numEnt; ++k) {
151 errCode = packTripleMpi(gblRowInds[k], gblColInds[k], ordinalDt,
152 vals[k], scalarDt, outBuf, outBufSize,
153 outBufCurPos, comm, errStrm);
154 if (errCode != MPI_SUCCESS) {
155 if (errStrm != NULL) {
156 *errStrm <<
"packTriplesMpi: packTripleMpi failed at entry k=" << k
165 template <
class ScalarType,
class OrdinalType>
166 int unpackTripleMpi(
const char inBuf[],
169 OrdinalType& gblRowInd,
170 OrdinalType& gblColInd,
171 MPI_Datatype ordinalDt,
173 MPI_Datatype scalarDt,
175 std::ostream* errStrm = NULL) {
177 int errCode = MPI_SUCCESS;
184 OrdinalType inds[2] = {
static_cast<OrdinalType
>(0),
185 static_cast<OrdinalType>(0)};
186 errCode = MPI_Unpack(const_cast<char*>(inBuf), inBufSize, &inBufCurPos,
187 inds, 2, ordinalDt, comm);
188 if (errCode != MPI_SUCCESS) {
189 if (errStrm != NULL) {
190 *errStrm <<
"unpackTripleMpi: MPI_Unpack failed when unpacking indices: "
192 << inBufSize <<
", inBufCurPos=" << inBufCurPos << endl;
202 errCode = MPI_Unpack(const_cast<char*>(inBuf), inBufSize, &inBufCurPos,
203 &val, 1, scalarDt, comm);
204 if (errCode != MPI_SUCCESS) {
205 if (errStrm != NULL) {
206 *errStrm <<
"unpackTripleMpi: MPI_Unpack failed when unpacking value: "
208 << inBufSize <<
", inBufCurPos=" << inBufCurPos << endl;
215 int unpackTriplesCountMpi(
const char inBuf[],
220 std::ostream* errStrm = NULL);
222 template <
class ScalarType,
class OrdinalType>
223 int unpackTriplesMpi(
const char inBuf[],
226 OrdinalType gblRowInds[],
227 OrdinalType gblColInds[],
228 MPI_Datatype ordinalDt,
230 MPI_Datatype scalarDt,
233 std::ostream* errStrm = NULL) {
235 int errCode = MPI_SUCCESS;
237 for (
int k = 0; k < numEnt; ++k) {
238 errCode = unpackTripleMpi(inBuf, inBufSize, inBufCurPos,
239 gblRowInds[k], gblColInds[k], ordinalDt,
240 vals[k], scalarDt, comm, errStrm);
241 if (errCode != MPI_SUCCESS) {
242 if (errStrm != NULL) {
243 *errStrm <<
"unpackTriplesMpi: packTripleMpi failed at entry k=" << k
244 <<
": inBufSize=" << inBufSize
245 <<
", inBufCurPos=" << inBufCurPos
254 #endif // HAVE_TPETRACORE_MPI
282 std::ostream* errStrm = NULL);
309 template <
class ScalarType,
class OrdinalType>
311 const ::Teuchos::Comm<int>& comm,
313 std::ostream* errStrm = NULL) {
314 #ifdef HAVE_TPETRACORE_MPI
315 using ::Tpetra::Details::extractMpiCommFromTeuchos;
316 using ::Tpetra::Details::MpiTypeTraits;
318 static_assert(MpiTypeTraits<ScalarType>::isSpecialized,
320 "ScalarType lacks an MpiTypeTraits specialization.");
321 static_assert(MpiTypeTraits<OrdinalType>::isSpecialized,
323 "OrdinalType lacks an MpiTypeTraits specialization.");
325 MPI_Comm mpiComm = extractMpiCommFromTeuchos(comm);
326 MPI_Datatype ordinalDt = MpiTypeTraits<OrdinalType>::getType();
327 MPI_Datatype scalarDt = MpiTypeTraits<ScalarType>::getType();
330 countPackTriplesMpi<ScalarType, OrdinalType>(ordinalDt, scalarDt,
333 if (MpiTypeTraits<ScalarType>::needsFree) {
334 (void)MPI_Type_free(&scalarDt);
336 if (MpiTypeTraits<OrdinalType>::needsFree) {
337 (void)MPI_Type_free(&ordinalDt);
341 #else // NOT HAVE_TPETRACORE_MPI
342 if (errStrm != NULL) {
343 *errStrm <<
"countPackTriples: Not implemented (no need; there's no need "
344 "to pack or unpack anything if there's only one process)."
348 #endif // HAVE_TPETRACORE_MPI
378 const int outBufSize,
380 const ::Teuchos::Comm<int>& comm,
381 std::ostream* errStrm = NULL);
408 template <
class ScalarType,
class OrdinalType>
410 #ifdef HAVE_TPETRACORE_MPI
412 const OrdinalType gblColInds[],
413 const ScalarType vals[],
416 const int outBufSize,
418 const ::Teuchos::Comm<int>& comm,
419 std::ostream* errStrm = NULL)
420 #else // NOT HAVE_TPETRACORE_MPI
422 const OrdinalType [],
428 const ::Teuchos::Comm<int>& ,
429 std::ostream* errStrm = NULL)
430 #endif // HAVE_TPETRACORE_MPI
432 #ifdef HAVE_TPETRACORE_MPI
433 using ::Tpetra::Details::extractMpiCommFromTeuchos;
434 using ::Tpetra::Details::MpiTypeTraits;
436 static_assert(MpiTypeTraits<ScalarType>::isSpecialized,
438 "ScalarType lacks an MpiTypeTraits specialization.");
439 static_assert(MpiTypeTraits<OrdinalType>::isSpecialized,
441 "OrdinalType lacks an MpiTypeTraits specialization.");
443 MPI_Comm mpiComm = extractMpiCommFromTeuchos(comm);
444 MPI_Datatype ordinalDt = MpiTypeTraits<OrdinalType>::getType();
445 MPI_Datatype scalarDt = MpiTypeTraits<ScalarType>::getType();
448 packTriplesMpi(gblRowInds, gblColInds, ordinalDt, vals, scalarDt,
449 numEnt, outBuf, outBufSize, outBufCurPos, mpiComm, errStrm);
450 if (MpiTypeTraits<ScalarType>::needsFree) {
451 (void)MPI_Type_free(&scalarDt);
453 if (MpiTypeTraits<OrdinalType>::needsFree) {
454 (void)MPI_Type_free(&ordinalDt);
458 #else // NOT HAVE_TPETRACORE_MPI
459 if (errStrm != NULL) {
460 *errStrm <<
"packTriples: Not implemented (no need; there's no need to "
461 "pack or unpack anything if there's only one process)."
465 #endif // HAVE_TPETRACORE_MPI
495 const ::Teuchos::Comm<int>& comm,
496 std::ostream* errStrm = NULL);
526 template <
class ScalarType,
class OrdinalType>
528 #ifdef HAVE_TPETRACORE_MPI
532 OrdinalType gblRowInds[],
533 OrdinalType gblColInds[],
536 const ::Teuchos::Comm<int>& comm,
537 std::ostream* errStrm = NULL)
538 #else // NOT HAVE_TPETRACORE_MPI
546 const ::Teuchos::Comm<int>& ,
547 std::ostream* errStrm = NULL)
548 #endif // HAVE_TPETRACORE_MPI
550 #ifdef HAVE_TPETRACORE_MPI
551 using ::Tpetra::Details::extractMpiCommFromTeuchos;
552 using ::Tpetra::Details::MpiTypeTraits;
554 static_assert(MpiTypeTraits<ScalarType>::isSpecialized,
556 "ScalarType lacks an MpiTypeTraits specialization.");
557 static_assert(MpiTypeTraits<OrdinalType>::isSpecialized,
559 "OrdinalType lacks an MpiTypeTraits specialization.");
561 MPI_Comm mpiComm = extractMpiCommFromTeuchos(comm);
562 MPI_Datatype ordinalDt = MpiTypeTraits<OrdinalType>::getType();
563 MPI_Datatype scalarDt = MpiTypeTraits<ScalarType>::getType();
566 unpackTriplesMpi(inBuf, inBufSize, inBufCurPos,
567 gblRowInds, gblColInds, ordinalDt,
568 vals, scalarDt, numEnt, mpiComm, errStrm);
569 if (MpiTypeTraits<ScalarType>::needsFree) {
570 (void)MPI_Type_free(&scalarDt);
572 if (MpiTypeTraits<OrdinalType>::needsFree) {
573 (void)MPI_Type_free(&ordinalDt);
577 #else // NOT HAVE_TPETRACORE_MPI
578 if (errStrm != NULL) {
579 *errStrm <<
"unpackTriples: Not implemented (no need; there's no need to "
580 "pack or unpack anything if there's only one process)."
584 #endif // HAVE_TPETRACORE_MPI
590 #endif // TPETRA_DETAILS_PACKTRIPLES_HPP
int packTriplesCount(const int, char[], const int, int &, const ::Teuchos::Comm< int > &, std::ostream *errStrm)
Pack the count (number) of matrix triples.
Add specializations of Teuchos::Details::MpiTypeTraits for Kokkos::complex<float> and Kokkos::complex...
int unpackTriplesCount(const char[], const int, int &, int &, const ::Teuchos::Comm< int > &, std::ostream *errStrm)
Unpack just the count of triples from the given input buffer.
int countPackTriplesCount(const ::Teuchos::Comm< int > &, int &size, std::ostream *errStrm)
Compute the buffer size required by packTriples for packing the number of matrix entries ("triples")...
int countPackTriples(const int numEnt, const ::Teuchos::Comm< int > &comm, int &size, std::ostream *errStrm=NULL)
Compute the buffer size required by packTriples for packing numEnt number of (i,j,A(i,j)) matrix entries ("triples").
int unpackTriples(const char[], const int, int &, OrdinalType[], OrdinalType[], ScalarType[], const int, const ::Teuchos::Comm< int > &, std::ostream *errStrm=NULL)
Unpack matrix entries ("triples" (i, j, A(i,j))) from the given input buffer.
int packTriples(const OrdinalType[], const OrdinalType[], const ScalarType[], const int, char[], const int, int &, const ::Teuchos::Comm< int > &, std::ostream *errStrm=NULL)
Pack matrix entries ("triples" (i, j, A(i,j))) into the given output buffer.