Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_PackTriples.cpp
1// @HEADER
2// *****************************************************************************
3// Tpetra: Templated Linear Algebra Services Package
4//
5// Copyright 2008 NTESS and the Tpetra contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Tpetra_Details_PackTriples.hpp"
11
12#ifdef HAVE_TPETRACORE_MPI
13
14namespace { // (anonymous)
15 std::string
16 mpiErrorCodeToString (const int errCode)
17 {
18 if (errCode == MPI_SUCCESS) {
19 return "MPI_SUCCESS";
20 }
21 else {
22 char rawErrString[MPI_MAX_ERROR_STRING];
23 int len = 0;
24 int err = MPI_Error_string (errCode, rawErrString, &len);
25 if (err != MPI_SUCCESS) {
26 // Assume that the string wasn't written. This means it might
27 // not be null terminated, so make it a valid empty string by
28 // writing the null termination character to it.
29 if (MPI_MAX_ERROR_STRING > 0) {
30 rawErrString[0] = '\0';
31 }
32 }
33 return std::string (rawErrString);
34 }
35 }
36} // namespace (anonymous)
37
38#endif // HAVE_TPETRACORE_MPI
39
40namespace Tpetra {
41namespace Details {
42
43#ifdef HAVE_TPETRACORE_MPI
44
45int
46countPackTriplesCountMpi (MPI_Comm comm,
47 int& size,
48 std::ostream* errStrm)
49{
50 using std::endl;
51
52 int curSize = 0;
53 const int errCode = MPI_Pack_size (1, MPI_INT, comm, &curSize);
54 if (errCode != MPI_SUCCESS) {
55 if (errStrm != NULL) {
56 *errStrm << "countPackTripleMpi: MPI_Pack_size failed on "
57 << "MPI_INT call. MPI reports: "
58 << mpiErrorCodeToString (errCode) << endl;
59 }
60 return errCode;
61 }
62 size = curSize; // "commit" the result
63
64 return errCode;
65}
66
67int
68packTriplesCountMpi (const int numEnt,
69 char outBuf[],
70 const int outBufSize,
71 int& outBufCurPos,
72 MPI_Comm comm,
73 std::ostream* errStrm)
74{
75 using std::endl;
76
77 // mfh 19 Jan 2017: Some (generally older) MPI implementations want
78 // the first argument of MPI_Pack to be a pointer to nonconst, even
79 // though it's an input argument that MPI_Pack does not modify.
80 int theNumEnt = numEnt;
81 const int errCode = MPI_Pack (&theNumEnt, 1, MPI_INT, outBuf,
82 outBufSize, &outBufCurPos, comm);
83 if (errCode != MPI_SUCCESS) {
84 if (errStrm != NULL) {
85 *errStrm << "packTriplesCountMpi: MPI_Pack failed with outBufSize="
86 << outBufSize << " and outBufCurPos=" << outBufCurPos
87 << ". MPI reports: " << mpiErrorCodeToString (errCode)
88 << endl;
89 }
90 return errCode;
91 }
92 return errCode;
93}
94
95int
96unpackTriplesCountMpi (const char inBuf[],
97 const int inBufSize,
98 int& inBufCurPos,
99 int& numEnt,
100 MPI_Comm comm,
101 std::ostream* errStrm)
102{
103 using std::endl;
104 int errCode = MPI_SUCCESS;
105
106 // mfh 19 Jan 2017: Some (generally older) MPI implementations want
107 // the first argument to be a nonconst pointer, even though
108 // MPI_Unpack does not modify that argument.
109 int theNumEnt = 0;
110 errCode = MPI_Unpack (const_cast<char*> (inBuf), inBufSize, &inBufCurPos,
111 &theNumEnt, 1, MPI_INT, comm);
112 if (errCode != MPI_SUCCESS) {
113 if (errStrm != NULL) {
114 *errStrm << "unpackTriplesCountMpi: MPI_Unpack failed on gblRowInd: "
115 << "inBufSize=" << inBufSize
116 << ", inBufCurPos=" << inBufCurPos
117 << ". MPI reports: " << mpiErrorCodeToString (errCode)
118 << endl;
119 }
120 return errCode;
121 }
122 if (theNumEnt < 0) {
123 if (errStrm != NULL) {
124 *errStrm << "unpackTriplesCountMpi: The unpacked number of entries "
125 << theNumEnt << " is negative." << endl;
126 }
127 return -1;
128 }
129 numEnt = theNumEnt; // "commit" the change to the output argument
130 return errCode;
131}
132
133#endif // HAVE_TPETRACORE_MPI
134
135int
136#ifdef HAVE_TPETRACORE_MPI
137countPackTriplesCount (const ::Teuchos::Comm<int>& comm,
138 int& size,
139 std::ostream* errStrm)
140#else // NOT HAVE_TPETRACORE_MPI
141countPackTriplesCount (const ::Teuchos::Comm<int>& /* comm */,
142 int& size,
143 std::ostream* errStrm)
144#endif // HAVE_TPETRACORE_MPI
145{
146#ifdef HAVE_TPETRACORE_MPI
147 using ::Tpetra::Details::extractMpiCommFromTeuchos;
148 MPI_Comm mpiComm = extractMpiCommFromTeuchos (comm);
149 return countPackTriplesCountMpi (mpiComm, size, errStrm);
150#else // NOT HAVE_TPETRACORE_MPI
151 using std::endl;
152 if (errStrm != NULL) {
153 *errStrm << "countPackTriplesCount: Not implemented (no need; there's no "
154 "need to pack or unpack anything if there's only one process)." << endl;
155 }
156 return -1;
157#endif // HAVE_TPETRACORE_MPI
158}
159
160int
161#ifdef HAVE_TPETRACORE_MPI
162packTriplesCount (const int numEnt,
163 char outBuf[],
164 const int outBufSize,
165 int& outBufCurPos,
166 const ::Teuchos::Comm<int>& comm,
167 std::ostream* errStrm)
168#else // NOT HAVE_TPETRACORE_MPI
169packTriplesCount (const int /* numEnt */,
170 char /* outBuf */[],
171 const int /* outBufSize */,
172 int& /* outBufCurPos */,
173 const ::Teuchos::Comm<int>& /* comm */,
174 std::ostream* errStrm)
175#endif // HAVE_TPETRACORE_MPI
176{
177#ifdef HAVE_TPETRACORE_MPI
178 using ::Tpetra::Details::extractMpiCommFromTeuchos;
179 MPI_Comm mpiComm = extractMpiCommFromTeuchos (comm);
180 return packTriplesCountMpi (numEnt, outBuf, outBufSize,
181 outBufCurPos, mpiComm, errStrm);
182#else // NOT HAVE_TPETRACORE_MPI
183 if (errStrm != NULL) {
184 *errStrm << "packTriplesCount: Not implemented (no need; there's no need "
185 "to pack or unpack anything if there's only one process)." << std::endl;
186 }
187 return -1;
188#endif // HAVE_TPETRACORE_MPI
189}
190
191int
192#ifdef HAVE_TPETRACORE_MPI
193unpackTriplesCount (const char inBuf[],
194 const int inBufSize,
195 int& inBufCurPos,
196 int& numEnt, // output argument!
197 const ::Teuchos::Comm<int>& comm,
198 std::ostream* errStrm)
199#else // NOT HAVE_TPETRACORE_MPI
200unpackTriplesCount (const char /* inBuf */[],
201 const int /* inBufSize */,
202 int& /* inBufCurPos */,
203 int& /* numEnt */,
204 const ::Teuchos::Comm<int>& /* comm */,
205 std::ostream* errStrm)
206#endif // HAVE_TPETRACORE_MPI
207{
208#ifdef HAVE_TPETRACORE_MPI
209 using ::Tpetra::Details::extractMpiCommFromTeuchos;
210
211 MPI_Comm mpiComm = extractMpiCommFromTeuchos (comm);
212 const int errCode =
213 unpackTriplesCountMpi (inBuf, inBufSize, inBufCurPos,
214 numEnt, mpiComm, errStrm);
215 return errCode;
216
217#else // NOT HAVE_TPETRACORE_MPI
218 if (errStrm != NULL) {
219 *errStrm << "unpackTriplesCount: Not implemented (no need; there's no need "
220 "to pack or unpack anything if there's only one process)." << std::endl;
221 }
222 return -1;
223#endif // HAVE_TPETRACORE_MPI
224}
225
226} // namespace Details
227} // namespace Tpetra
228
Nonmember function that computes a residual Computes R = B - A * X.
int packTriplesCount(const int, char[], const int, int &, const ::Teuchos::Comm< int > &, std::ostream *errStrm)
Pack the count (number) of matrix triples.
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 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.
Namespace Tpetra contains the class and methods constituting the Tpetra library.