42 #ifndef TPETRA_DETAILS_PACKTRIPLES_HPP
43 #define TPETRA_DETAILS_PACKTRIPLES_HPP
45 #include "TpetraCore_config.h"
46 #include "Teuchos_Comm.hpp"
47 #ifdef HAVE_TPETRACORE_MPI
50 #endif // HAVE_TPETRACORE_MPI
62 #ifdef HAVE_TPETRACORE_MPI
69 countPackTriplesCountMpi (MPI_Comm comm,
71 std::ostream* errStrm = NULL);
74 packTriplesCountMpi (
const int numEnt,
79 std::ostream* errStrm = NULL);
81 template<
class ScalarType,
class OrdinalType>
83 countPackTriplesMpi (MPI_Datatype ordinalDt,
84 MPI_Datatype scalarDt,
88 std::ostream* errStrm = NULL)
91 int errCode = MPI_SUCCESS;
99 errCode = MPI_Pack_size (2, ordinalDt, comm, &curSize);
100 if (errCode != MPI_SUCCESS) {
101 if (errStrm != NULL) {
102 *errStrm <<
"countPackTripleMpi: MPI_Pack_size failed on "
103 "ordinalDt call" << endl;
107 totalSize += curSize;
112 errCode = MPI_Pack_size (1, scalarDt, comm, &curSize);
113 if (errCode != MPI_SUCCESS) {
114 if (errStrm != NULL) {
115 *errStrm <<
"countPackTripleMpi: MPI_Pack_size failed on "
116 "scalarDt call" << endl;
120 totalSize += curSize;
128 template<
class ScalarType,
class OrdinalType>
130 packTripleMpi (
const OrdinalType gblRowInd,
131 const OrdinalType gblColInd,
132 MPI_Datatype ordinalDt,
133 const ScalarType& val,
134 MPI_Datatype scalarDt,
136 const int outBufSize,
139 std::ostream* errStrm = NULL)
142 int errCode = MPI_SUCCESS;
145 OrdinalType inds[2] = {gblRowInd, gblColInd};
146 errCode = MPI_Pack (inds, 2, ordinalDt,
147 outBuf, outBufSize, &outBufCurPos, comm);
148 if (errCode != MPI_SUCCESS) {
149 if (errStrm != NULL) {
150 *errStrm <<
"packTripleMpi: MPI_Pack failed for indices i=" << gblRowInd
151 <<
", j=" << gblColInd <<
", where outBufSize=" << outBufSize
152 <<
" and outBufCurPos=" << outBufCurPos <<
"." << endl;
159 errCode = MPI_Pack (const_cast<ScalarType*> (&val), 1, scalarDt,
160 outBuf, outBufSize, &outBufCurPos, comm);
161 if (errCode != MPI_SUCCESS) {
162 if (errStrm != NULL) {
163 *errStrm <<
"packTripleMpi: MPI_Pack failed on val = " << val
171 template<
class ScalarType,
class OrdinalType>
173 packTriplesMpi (
const OrdinalType gblRowInds[],
174 const OrdinalType gblColInds[],
175 MPI_Datatype ordinalDt,
176 const ScalarType vals[],
177 MPI_Datatype scalarDt,
180 const int outBufSize,
183 std::ostream* errStrm = NULL)
186 int errCode = MPI_SUCCESS;
188 for (
int k = 0; k < numEnt; ++k) {
189 errCode = packTripleMpi (gblRowInds[k], gblColInds[k], ordinalDt,
190 vals[k], scalarDt, outBuf, outBufSize,
191 outBufCurPos, comm, errStrm);
192 if (errCode != MPI_SUCCESS) {
193 if (errStrm != NULL) {
194 *errStrm <<
"packTriplesMpi: packTripleMpi failed at entry k=" << k
203 template<
class ScalarType,
class OrdinalType>
205 unpackTripleMpi (
const char inBuf[],
208 OrdinalType& gblRowInd,
209 OrdinalType& gblColInd,
210 MPI_Datatype ordinalDt,
212 MPI_Datatype scalarDt,
214 std::ostream* errStrm = NULL)
217 int errCode = MPI_SUCCESS;
224 OrdinalType inds[2] = {
static_cast<OrdinalType
> (0),
225 static_cast<OrdinalType> (0)};
226 errCode = MPI_Unpack (const_cast<char*> (inBuf), inBufSize, &inBufCurPos,
227 inds, 2, ordinalDt, comm);
228 if (errCode != MPI_SUCCESS) {
229 if (errStrm != NULL) {
230 *errStrm <<
"unpackTripleMpi: MPI_Unpack failed when unpacking indices: "
231 "inBufSize=" << inBufSize <<
", inBufCurPos=" << inBufCurPos << endl;
241 errCode = MPI_Unpack (const_cast<char*> (inBuf), inBufSize, &inBufCurPos,
242 &val, 1, scalarDt, comm);
243 if (errCode != MPI_SUCCESS) {
244 if (errStrm != NULL) {
245 *errStrm <<
"unpackTripleMpi: MPI_Unpack failed when unpacking value: "
246 "inBufSize=" << inBufSize <<
", inBufCurPos=" << inBufCurPos << endl;
254 unpackTriplesCountMpi (
const char inBuf[],
259 std::ostream* errStrm = NULL);
261 template<
class ScalarType,
class OrdinalType>
263 unpackTriplesMpi (
const char inBuf[],
266 OrdinalType gblRowInds[],
267 OrdinalType gblColInds[],
268 MPI_Datatype ordinalDt,
270 MPI_Datatype scalarDt,
273 std::ostream* errStrm = NULL)
276 int errCode = MPI_SUCCESS;
278 for (
int k = 0; k < numEnt; ++k) {
279 errCode = unpackTripleMpi (inBuf, inBufSize, inBufCurPos,
280 gblRowInds[k], gblColInds[k], ordinalDt,
281 vals[k], scalarDt, comm, errStrm);
282 if (errCode != MPI_SUCCESS) {
283 if (errStrm != NULL) {
284 *errStrm <<
"unpackTriplesMpi: packTripleMpi failed at entry k=" << k
285 <<
": inBufSize=" << inBufSize
286 <<
", inBufCurPos=" << inBufCurPos
295 #endif // HAVE_TPETRACORE_MPI
324 std::ostream* errStrm = NULL);
351 template<
class ScalarType,
class OrdinalType>
354 const ::Teuchos::Comm<int>& comm,
356 std::ostream* errStrm = NULL)
358 #ifdef HAVE_TPETRACORE_MPI
359 using ::Tpetra::Details::extractMpiCommFromTeuchos;
360 using ::Tpetra::Details::MpiTypeTraits;
362 static_assert (MpiTypeTraits<ScalarType>::isSpecialized,
"countPackTriples: "
363 "ScalarType lacks an MpiTypeTraits specialization.");
364 static_assert (MpiTypeTraits<OrdinalType>::isSpecialized,
"countPackTriples: "
365 "OrdinalType lacks an MpiTypeTraits specialization.");
367 MPI_Comm mpiComm = extractMpiCommFromTeuchos (comm);
368 MPI_Datatype ordinalDt = MpiTypeTraits<OrdinalType>::getType ();
369 MPI_Datatype scalarDt = MpiTypeTraits<ScalarType>::getType ();
372 countPackTriplesMpi<ScalarType, OrdinalType> (ordinalDt, scalarDt,
375 if (MpiTypeTraits<ScalarType>::needsFree) {
376 (void) MPI_Type_free (&scalarDt);
378 if (MpiTypeTraits<OrdinalType>::needsFree) {
379 (void) MPI_Type_free (&ordinalDt);
383 #else // NOT HAVE_TPETRACORE_MPI
384 if (errStrm != NULL) {
385 *errStrm <<
"countPackTriples: Not implemented (no need; there's no need "
386 "to pack or unpack anything if there's only one process)." << std::endl;
389 #endif // HAVE_TPETRACORE_MPI
420 const int outBufSize,
422 const ::Teuchos::Comm<int>& comm,
423 std::ostream* errStrm = NULL);
450 template<
class ScalarType,
class OrdinalType>
452 #ifdef HAVE_TPETRACORE_MPI
454 const OrdinalType gblColInds[],
455 const ScalarType vals[],
458 const int outBufSize,
460 const ::Teuchos::Comm<int>& comm,
461 std::ostream* errStrm = NULL)
462 #else // NOT HAVE_TPETRACORE_MPI
464 const OrdinalType [],
470 const ::Teuchos::Comm<int>& ,
471 std::ostream* errStrm = NULL)
472 #endif // HAVE_TPETRACORE_MPI
474 #ifdef HAVE_TPETRACORE_MPI
475 using ::Tpetra::Details::extractMpiCommFromTeuchos;
476 using ::Tpetra::Details::MpiTypeTraits;
478 static_assert (MpiTypeTraits<ScalarType>::isSpecialized,
"packTriples: "
479 "ScalarType lacks an MpiTypeTraits specialization.");
480 static_assert (MpiTypeTraits<OrdinalType>::isSpecialized,
"packTriples: "
481 "OrdinalType lacks an MpiTypeTraits specialization.");
483 MPI_Comm mpiComm = extractMpiCommFromTeuchos (comm);
484 MPI_Datatype ordinalDt = MpiTypeTraits<OrdinalType>::getType ();
485 MPI_Datatype scalarDt = MpiTypeTraits<ScalarType>::getType ();
488 packTriplesMpi (gblRowInds, gblColInds, ordinalDt, vals, scalarDt,
489 numEnt, outBuf, outBufSize, outBufCurPos, mpiComm, errStrm);
490 if (MpiTypeTraits<ScalarType>::needsFree) {
491 (void) MPI_Type_free (&scalarDt);
493 if (MpiTypeTraits<OrdinalType>::needsFree) {
494 (void) MPI_Type_free (&ordinalDt);
498 #else // NOT HAVE_TPETRACORE_MPI
499 if (errStrm != NULL) {
500 *errStrm <<
"packTriples: Not implemented (no need; there's no need to "
501 "pack or unpack anything if there's only one process)." << std::endl;
504 #endif // HAVE_TPETRACORE_MPI
535 const ::Teuchos::Comm<int>& comm,
536 std::ostream* errStrm = NULL);
566 template<
class ScalarType,
class OrdinalType>
568 #ifdef HAVE_TPETRACORE_MPI
572 OrdinalType gblRowInds[],
573 OrdinalType gblColInds[],
576 const ::Teuchos::Comm<int>& comm,
577 std::ostream* errStrm = NULL)
578 #else // NOT HAVE_TPETRACORE_MPI
586 const ::Teuchos::Comm<int>& ,
587 std::ostream* errStrm = NULL)
588 #endif // HAVE_TPETRACORE_MPI
590 #ifdef HAVE_TPETRACORE_MPI
591 using ::Tpetra::Details::extractMpiCommFromTeuchos;
592 using ::Tpetra::Details::MpiTypeTraits;
594 static_assert (MpiTypeTraits<ScalarType>::isSpecialized,
"unpackTriples: "
595 "ScalarType lacks an MpiTypeTraits specialization.");
596 static_assert (MpiTypeTraits<OrdinalType>::isSpecialized,
"unpackTriples: "
597 "OrdinalType lacks an MpiTypeTraits specialization.");
599 MPI_Comm mpiComm = extractMpiCommFromTeuchos (comm);
600 MPI_Datatype ordinalDt = MpiTypeTraits<OrdinalType>::getType ();
601 MPI_Datatype scalarDt = MpiTypeTraits<ScalarType>::getType ();
604 unpackTriplesMpi (inBuf, inBufSize, inBufCurPos,
605 gblRowInds, gblColInds, ordinalDt,
606 vals, scalarDt, numEnt, mpiComm, errStrm);
607 if (MpiTypeTraits<ScalarType>::needsFree) {
608 (void) MPI_Type_free (&scalarDt);
610 if (MpiTypeTraits<OrdinalType>::needsFree) {
611 (void) MPI_Type_free (&ordinalDt);
615 #else // NOT HAVE_TPETRACORE_MPI
616 if (errStrm != NULL) {
617 *errStrm <<
"unpackTriples: Not implemented (no need; there's no need to "
618 "pack or unpack anything if there's only one process)." << std::endl;
621 #endif // HAVE_TPETRACORE_MPI
627 #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.