44 #ifdef HAVE_TPETRACORE_MPI 45 # include "Teuchos_DefaultMpiComm.hpp" 46 #endif // HAVE_TPETRACORE_MPI 47 #include "Teuchos_DefaultSerialComm.hpp" 49 #ifdef HAVE_TPETRACORE_MPI 51 std::string getMpiErrorString (
const int errCode) {
54 char errString [MPI_MAX_ERROR_STRING+1];
55 int errStringLen = MPI_MAX_ERROR_STRING;
56 (void) MPI_Error_string (errCode, errString, &errStringLen);
61 if (errString[errStringLen-1] !=
'\0') {
62 errString[errStringLen] =
'\0';
64 return std::string (errString);
67 #endif // HAVE_TPETRACORE_MPI 73 #ifdef HAVE_TPETRACORE_MPI 76 req_ (MPI_REQUEST_NULL)
80 MpiCommRequest (
const MPI_Request req) :
86 waitWithStatus (MPI_Status& status)
88 if (req_ != MPI_REQUEST_NULL) {
89 MPI_Request req = req_;
90 const int err = MPI_Wait (&req, &status);
91 TEUCHOS_TEST_FOR_EXCEPTION
92 (err != MPI_SUCCESS, std::runtime_error,
93 "MpiCommRequest::waitWithStatus: MPI_Wait failed with error \"" 94 << getMpiErrorString (err));
97 req_ = MPI_REQUEST_NULL;
105 if (req_ != MPI_REQUEST_NULL) {
106 MPI_Request req = req_;
107 const int err = MPI_Wait (&req, MPI_STATUS_IGNORE);
108 TEUCHOS_TEST_FOR_EXCEPTION
109 (err != MPI_SUCCESS, std::runtime_error,
110 "MpiCommRequest::wait: MPI_Wait failed with error \"" 111 << getMpiErrorString (err));
114 req_ = MPI_REQUEST_NULL;
122 if (req_ != MPI_REQUEST_NULL) {
123 const int err = MPI_Cancel (&req_);
124 TEUCHOS_TEST_FOR_EXCEPTION
125 (err != MPI_SUCCESS, std::runtime_error,
126 "MpiCommRequest::cancel: MPI_Cancel failed with the following error: " 127 << getMpiErrorString (err));
142 if (req_ != MPI_REQUEST_NULL) {
145 const int err = MPI_Cancel (&req_);
146 if (err == MPI_SUCCESS) {
163 (void) MPI_Wait (&req_, MPI_STATUS_IGNORE);
168 #endif // HAVE_TPETRACORE_MPI 170 std::shared_ptr<CommRequest>
173 return std::shared_ptr<CommRequest> (
new DeferredActionCommRequest ());
176 DeferredActionCommRequest::
177 DeferredActionCommRequest () :
192 if (! actionTaken_) {
205 #ifdef HAVE_TPETRACORE_MPI 207 std::shared_ptr<CommRequest>
208 iallreduceRawVoid (
const void* sendbuf,
211 MPI_Datatype mpiDatatype,
212 const bool mpiDatatypeNeedsFree,
213 const Teuchos::EReductionType op,
216 MPI_Op rawOp = ::Teuchos::Details::getMpiOpForEReductionType (op);
219 const bool useMpi3 =
true;
221 const bool useMpi3 =
false;
222 #endif // MPI_VERSION >= 3 228 MPI_Request rawRequest = MPI_REQUEST_NULL;
229 int err = MPI_SUCCESS;
230 if (sendbuf == recvbuf) {
234 err = MPI_Iallreduce (MPI_IN_PLACE, recvbuf, count, mpiDatatype,
235 rawOp, comm, &rawRequest);
238 err = MPI_Iallreduce (sendbuf, recvbuf, count, mpiDatatype,
239 rawOp, comm, &rawRequest);
241 TEUCHOS_TEST_FOR_EXCEPTION
242 (err != MPI_SUCCESS, std::runtime_error,
243 "MPI_Iallreduce failed with the following error: " 244 << getMpiErrorString (err));
245 if (mpiDatatypeNeedsFree) {
249 (void) MPI_Type_free (&mpiDatatype);
251 return std::shared_ptr<CommRequest> (
new MpiCommRequest (rawRequest));
253 TEUCHOS_TEST_FOR_EXCEPTION
254 (
true, std::logic_error,
"Should never get here. " 255 "Please report this bug to the Tpetra developers.");
256 #endif // MPI_VERSION >= 3 274 int mpiInitialized = 0;
275 (void) MPI_Initialized (&mpiInitialized);
276 int mpiFinalized = 0;
277 (void) MPI_Finalized (&mpiFinalized);
278 if (mpiFinalized == 0 && mpiInitialized != 0) {
289 if (mpiDatatypeNeedsFree) {
292 MPI_Datatype dupDatatype;
293 (void) MPI_Type_dup (mpiDatatype, &dupDatatype);
295 if (sendbuf == recvbuf) {
296 (void) MPI_Allreduce (MPI_IN_PLACE, recvbuf, count, dupDatatype,
300 (void) MPI_Allreduce (sendbuf, recvbuf, count, dupDatatype,
303 #else // MPI_VERSION < 3 304 if (sendbuf == recvbuf) {
305 (void) MPI_Allreduce (MPI_IN_PLACE, recvbuf,
306 count, dupDatatype, rawOp, comm);
310 (void) MPI_Allreduce (const_cast<void*> (sendbuf), recvbuf,
311 count, dupDatatype, rawOp, comm);
313 #endif // MPI_VERSION >= 3 314 (void) MPI_Type_free (&dupDatatype);
318 if (sendbuf == recvbuf) {
319 (void) MPI_Allreduce (MPI_IN_PLACE, recvbuf, count, mpiDatatype,
323 (void) MPI_Allreduce (sendbuf, recvbuf, count, mpiDatatype,
326 #else // MPI_VERSION < 3 327 if (sendbuf == recvbuf) {
328 (void) MPI_Allreduce (MPI_IN_PLACE, recvbuf,
329 count, mpiDatatype, rawOp, comm);
333 (void) MPI_Allreduce (const_cast<void*> (sendbuf), recvbuf,
334 count, mpiDatatype, rawOp, comm);
336 #endif // MPI_VERSION >= 3 343 #endif // HAVE_TPETRACORE_MPI Namespace Tpetra contains the class and methods constituting the Tpetra library.
void wait()
Wait on this communication request to complete.
DeferredActionCommRequest()
Default constructor (take no action on wait).
void cancel()
Cancel the pending communication request, without taking the specified action.
Implementation details of Tpetra.
Declaration of Tpetra::Details::iallreduce.