Tpetra parallel linear algebra Version of the Day
Loading...
Searching...
No Matches
Tpetra_Details_PackTriples.cpp
1// @HEADER
2// ***********************************************************************
3//
4// Tpetra: Templated Linear Algebra Services Package
5// Copyright (2008) Sandia Corporation
6//
7// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8// the U.S. Government retains certain rights in this software.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ************************************************************************
40// @HEADER
41
42#include "Tpetra_Details_PackTriples.hpp"
43
44#ifdef HAVE_TPETRACORE_MPI
45
46namespace { // (anonymous)
47 std::string
48 mpiErrorCodeToString (const int errCode)
49 {
50 if (errCode == MPI_SUCCESS) {
51 return "MPI_SUCCESS";
52 }
53 else {
54 char rawErrString[MPI_MAX_ERROR_STRING];
55 int len = 0;
56 int err = MPI_Error_string (errCode, rawErrString, &len);
57 if (err != MPI_SUCCESS) {
58 // Assume that the string wasn't written. This means it might
59 // not be null terminated, so make it a valid empty string by
60 // writing the null termination character to it.
61 if (MPI_MAX_ERROR_STRING > 0) {
62 rawErrString[0] = '\0';
63 }
64 }
65 return std::string (rawErrString);
66 }
67 }
68} // namespace (anonymous)
69
70#endif // HAVE_TPETRACORE_MPI
71
72namespace Tpetra {
73namespace Details {
74
75#ifdef HAVE_TPETRACORE_MPI
76
77int
78countPackTriplesCountMpi (MPI_Comm comm,
79 int& size,
80 std::ostream* errStrm)
81{
82 using std::endl;
83
84 int curSize = 0;
85 const int errCode = MPI_Pack_size (1, MPI_INT, comm, &curSize);
86 if (errCode != MPI_SUCCESS) {
87 if (errStrm != NULL) {
88 *errStrm << "countPackTripleMpi: MPI_Pack_size failed on "
89 << "MPI_INT call. MPI reports: "
90 << mpiErrorCodeToString (errCode) << endl;
91 }
92 return errCode;
93 }
94 size = curSize; // "commit" the result
95
96 return errCode;
97}
98
99int
100packTriplesCountMpi (const int numEnt,
101 char outBuf[],
102 const int outBufSize,
103 int& outBufCurPos,
104 MPI_Comm comm,
105 std::ostream* errStrm)
106{
107 using std::endl;
108
109 // mfh 19 Jan 2017: Some (generally older) MPI implementations want
110 // the first argument of MPI_Pack to be a pointer to nonconst, even
111 // though it's an input argument that MPI_Pack does not modify.
112 int theNumEnt = numEnt;
113 const int errCode = MPI_Pack (&theNumEnt, 1, MPI_INT, outBuf,
114 outBufSize, &outBufCurPos, comm);
115 if (errCode != MPI_SUCCESS) {
116 if (errStrm != NULL) {
117 *errStrm << "packTriplesCountMpi: MPI_Pack failed with outBufSize="
118 << outBufSize << " and outBufCurPos=" << outBufCurPos
119 << ". MPI reports: " << mpiErrorCodeToString (errCode)
120 << endl;
121 }
122 return errCode;
123 }
124 return errCode;
125}
126
127int
128unpackTriplesCountMpi (const char inBuf[],
129 const int inBufSize,
130 int& inBufCurPos,
131 int& numEnt,
132 MPI_Comm comm,
133 std::ostream* errStrm)
134{
135 using std::endl;
136 int errCode = MPI_SUCCESS;
137
138 // mfh 19 Jan 2017: Some (generally older) MPI implementations want
139 // the first argument to be a nonconst pointer, even though
140 // MPI_Unpack does not modify that argument.
141 int theNumEnt = 0;
142 errCode = MPI_Unpack (const_cast<char*> (inBuf), inBufSize, &inBufCurPos,
143 &theNumEnt, 1, MPI_INT, comm);
144 if (errCode != MPI_SUCCESS) {
145 if (errStrm != NULL) {
146 *errStrm << "unpackTriplesCountMpi: MPI_Unpack failed on gblRowInd: "
147 << "inBufSize=" << inBufSize
148 << ", inBufCurPos=" << inBufCurPos
149 << ". MPI reports: " << mpiErrorCodeToString (errCode)
150 << endl;
151 }
152 return errCode;
153 }
154 if (theNumEnt < 0) {
155 if (errStrm != NULL) {
156 *errStrm << "unpackTriplesCountMpi: The unpacked number of entries "
157 << theNumEnt << " is negative." << endl;
158 }
159 return -1;
160 }
161 numEnt = theNumEnt; // "commit" the change to the output argument
162 return errCode;
163}
164
165#endif // HAVE_TPETRACORE_MPI
166
167int
168#ifdef HAVE_TPETRACORE_MPI
169countPackTriplesCount (const ::Teuchos::Comm<int>& comm,
170 int& size,
171 std::ostream* errStrm)
172#else // NOT HAVE_TPETRACORE_MPI
173countPackTriplesCount (const ::Teuchos::Comm<int>& /* comm */,
174 int& size,
175 std::ostream* errStrm)
176#endif // HAVE_TPETRACORE_MPI
177{
178#ifdef HAVE_TPETRACORE_MPI
179 using ::Tpetra::Details::extractMpiCommFromTeuchos;
182#else // NOT HAVE_TPETRACORE_MPI
183 using std::endl;
184 if (errStrm != NULL) {
185 *errStrm << "countPackTriplesCount: Not implemented (no need; there's no "
186 "need to pack or unpack anything if there's only one process)." << endl;
187 }
188 return -1;
189#endif // HAVE_TPETRACORE_MPI
190}
191
192int
193#ifdef HAVE_TPETRACORE_MPI
194packTriplesCount (const int numEnt,
195 char outBuf[],
196 const int outBufSize,
197 int& outBufCurPos,
198 const ::Teuchos::Comm<int>& comm,
199 std::ostream* errStrm)
200#else // NOT HAVE_TPETRACORE_MPI
201packTriplesCount (const int /* numEnt */,
202 char /* outBuf */[],
203 const int /* outBufSize */,
204 int& /* outBufCurPos */,
205 const ::Teuchos::Comm<int>& /* comm */,
206 std::ostream* errStrm)
207#endif // HAVE_TPETRACORE_MPI
208{
209#ifdef HAVE_TPETRACORE_MPI
210 using ::Tpetra::Details::extractMpiCommFromTeuchos;
214#else // NOT HAVE_TPETRACORE_MPI
215 if (errStrm != NULL) {
216 *errStrm << "packTriplesCount: Not implemented (no need; there's no need "
217 "to pack or unpack anything if there's only one process)." << std::endl;
218 }
219 return -1;
220#endif // HAVE_TPETRACORE_MPI
221}
222
223int
224#ifdef HAVE_TPETRACORE_MPI
225unpackTriplesCount (const char inBuf[],
226 const int inBufSize,
227 int& inBufCurPos,
228 int& numEnt, // output argument!
229 const ::Teuchos::Comm<int>& comm,
230 std::ostream* errStrm)
231#else // NOT HAVE_TPETRACORE_MPI
232unpackTriplesCount (const char /* inBuf */[],
233 const int /* inBufSize */,
234 int& /* inBufCurPos */,
235 int& /* numEnt */,
236 const ::Teuchos::Comm<int>& /* comm */,
237 std::ostream* errStrm)
238#endif // HAVE_TPETRACORE_MPI
239{
240#ifdef HAVE_TPETRACORE_MPI
241 using ::Tpetra::Details::extractMpiCommFromTeuchos;
242
244 const int errCode =
247 return errCode;
248
249#else // NOT HAVE_TPETRACORE_MPI
250 if (errStrm != NULL) {
251 *errStrm << "unpackTriplesCount: Not implemented (no need; there's no need "
252 "to pack or unpack anything if there's only one process)." << std::endl;
253 }
254 return -1;
255#endif // HAVE_TPETRACORE_MPI
256}
257
258} // namespace Details
259} // namespace Tpetra
260
Struct that holds views of the contents of a CrsMatrix.
Implementation details of Tpetra.
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.