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
347 std::shared_ptr<CommRequest>
348 iallreduce (
const int localValue,
350 const ::Teuchos::EReductionType op,
351 const ::Teuchos::Comm<int>& comm)
353 using input_view_type =
354 Kokkos::View<
const int*, Kokkos::HostSpace,
355 Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
356 using output_view_type =
357 Kokkos::View<
int*, Kokkos::HostSpace,
358 Kokkos::MemoryTraits<Kokkos::Unmanaged>>;
360 input_view_type localView (&localValue, 1);
361 output_view_type globalView (&globalValue, 1);
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.
Declaration of Tpetra::Details::iallreduce.
std::shared_ptr< CommRequest > iallreduce(const InputViewType &sendbuf, const OutputViewType &recvbuf, const ::Teuchos::EReductionType op, const ::Teuchos::Comm< int > &comm)
Nonblocking all-reduce, for either rank-1 or rank-0 Kokkos::View objects.