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
271 return std::shared_ptr<CommRequest> (
new DeferredActionCommRequest ([=] () {
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