37 UPstream::Request(MPI_REQUEST_NULL)
51 *
this = UPstream::Request(MPI_REQUEST_NULL);
102 if (MPI_REQUEST_NULL != request)
109 req = UPstream::Request(MPI_REQUEST_NULL);
127 if (MPI_REQUEST_NULL != request)
129 MPI_Cancel(&request);
130 MPI_Request_free(&request);
146 if (MPI_REQUEST_NULL != request)
148 MPI_Cancel(&request);
149 MPI_Request_free(&request);
151 req = UPstream::Request(MPI_REQUEST_NULL);
164 for (
auto& req : requests)
167 if (MPI_REQUEST_NULL != request)
169 MPI_Cancel(&request);
170 MPI_Request_free(&request);
175 requests = UPstream::Request(MPI_REQUEST_NULL);
196 if (len >= 0 && len < count)
205 for (
const label i :
range)
208 if (MPI_REQUEST_NULL != request)
210 MPI_Cancel(&request);
211 MPI_Request_free(&request);
230 if (MPI_REQUEST_NULL != request)
236 MPI_Request_free(&request);
238 req = UPstream::Request(MPI_REQUEST_NULL);
251 for (
auto& req : requests)
254 if (MPI_REQUEST_NULL != request)
260 MPI_Request_free(&request);
265 requests = UPstream::Request(MPI_REQUEST_NULL);
287 if (len >= 0 && len < count)
299 Perr<<
"UPstream::waitRequests : starting wait for "
308 if (MPI_Wait(mpiRequests, MPI_STATUS_IGNORE))
311 <<
"MPI_Wait returned with error"
318 if (MPI_Waitall(count, mpiRequests, MPI_STATUSES_IGNORE))
321 <<
"MPI_Waitall returned with error"
336 Perr<<
"UPstream::waitRequests : finished wait." <<
endl;
353 auto* mpiRequests =
reinterpret_cast<MPI_Request*
>(requests.data());
356 for (
auto& req : requests)
360 if (MPI_REQUEST_NULL != request)
362 mpiRequests[
count] = request;
376 if (MPI_Waitall(count, mpiRequests, MPI_STATUSES_IGNORE))
379 <<
"MPI_Waitall returned with error"
386 requests = UPstream::Request(MPI_REQUEST_NULL);
407 if (len >= 0 && len < count)
418 Perr<<
"UPstream::waitAnyRequest : starting wait for any of "
425 int index = MPI_UNDEFINED;
426 if (MPI_Waitany(count, mpiRequests, &index, MPI_STATUS_IGNORE))
429 <<
"MPI_Waitany returned with error"
435 if (index == MPI_UNDEFINED)
449 DynamicList<int>* indices
460 if (indices) indices->clear();
468 if (len >= 0 && len < count)
479 Perr<<
"UPstream:waitSomeRequest : starting wait for some of "
485 List<int> tmpIndices;
488 indices->resize_nocopy(count);
492 tmpIndices.resize(count);
506 (indices ? indices->data() : tmpIndices.data()),
512 <<
"MPI_Waitsome returned with error"
518 if (outcount == MPI_UNDEFINED || outcount < 1)
521 if (indices) indices->clear();
527 indices->resize(outcount);
536 UList<UPstream::Request>& requests,
537 DynamicList<int>* indices
543 if (indices) indices->clear();
550 const int count =
static_cast<int>(requests.size());
551 auto* mpiRequests =
reinterpret_cast<MPI_Request*
>(requests.data());
554 for (
int i = 0; i <
count; ++i)
560 List<int> tmpIndices;
563 indices->resize_nocopy(count);
567 tmpIndices.resize(count);
572 Perr<<
"UPstream:waitSomeRequest : starting wait for some of "
573 << requests.size() <<
" requests" <<
endl;
587 (indices ? indices->data() : tmpIndices.data()),
593 <<
"MPI_Waitsome returned with error"
599 if (outcount == MPI_UNDEFINED || outcount < 1)
602 if (indices) indices->clear();
605 requests = UPstream::Request(MPI_REQUEST_NULL);
611 indices->resize(outcount);
617 for (label i = requests.size()-1; i >= 0; --i)
619 requests[i] = UPstream::Request(mpiRequests[i]);
638 const int count =
static_cast<int>(requests.size());
639 auto* mpiRequests =
reinterpret_cast<MPI_Request*
>(requests.data());
644 for (
int i = 0; i <
count; ++i)
652 int index = MPI_UNDEFINED;
653 if (MPI_Waitany(count, mpiRequests, &index, MPI_STATUS_IGNORE))
656 <<
"MPI_Waitany returned with error"
662 if (index == MPI_UNDEFINED)
670 for (label i = requests.size()-1; i >= 0; --i)
672 requests[i] = UPstream::Request(mpiRequests[i]);
761 if (MPI_REQUEST_NULL == request)
768 Perr<<
"UPstream::waitRequest : starting wait for request:"
775 if (MPI_Wait(&request, MPI_STATUS_IGNORE))
778 <<
"MPI_Wait returned with error"
786 Perr<<
"UPstream::waitRequest : finished wait for request:"
803 if (MPI_REQUEST_NULL == request)
810 if (MPI_Wait(&request, MPI_STATUS_IGNORE))
813 <<
"MPI_Wait returned with error"
819 req = UPstream::Request(MPI_REQUEST_NULL);
850 Perr<<
"UPstream::finishedRequest : check request:"
863 MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
868 MPI_Request request = MPI_REQUEST_NULL;
869 MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
890 MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
893 req = UPstream::Request(request);
922 if (len >= 0 && len < count)
931 Perr<<
"UPstream::finishedRequests : check " <<
count
932 <<
" requests starting at " <<
pos <<
endl;
944 MPI_Request request = MPI_REQUEST_NULL;
945 MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
952 MPI_Test(mpiRequests, &flag, MPI_STATUS_IGNORE);
958 MPI_Testall(count, mpiRequests, &flag, MPI_STATUSES_IGNORE);
976 const int count =
static_cast<int>(requests.size());
977 auto* mpiRequests =
reinterpret_cast<MPI_Request*
>(requests.data());
980 for (
int i = 0; i <
count; ++i)
995 MPI_Request request = MPI_REQUEST_NULL;
996 MPI_Test(&request, &flag, MPI_STATUS_IGNORE);
1003 MPI_Test(mpiRequests, &flag, MPI_STATUS_IGNORE);
1009 MPI_Testall(count, mpiRequests, &flag, MPI_STATUSES_IGNORE);
1016 for (label i = requests.size()-1; i >= 0; --i)
1018 requests[i] = UPstream::Request(mpiRequests[i]);
1036 bool anyActive =
false;
1037 MPI_Request mpiRequests[2];
1047 mpiRequests[0] = MPI_REQUEST_NULL;
1056 mpiRequests[1] = MPI_REQUEST_NULL;
1059 if (MPI_REQUEST_NULL != mpiRequests[0])
1068 if (MPI_REQUEST_NULL != mpiRequests[1])
1101 <<
"MPI_Testsome returned with error"
1107 if (outcount == MPI_UNDEFINED)
1129 for (
int i = 0; i < outcount; ++i)
1131 const int idx = indices[i];
1151 return (outcount > 0);
1166 MPI_Request mpiRequests[2];
1176 if (MPI_REQUEST_NULL != mpiRequests[count])
1187 if (MPI_REQUEST_NULL != mpiRequests[count])
1206 if (MPI_Waitall(count, mpiRequests, MPI_STATUSES_IGNORE))
1209 <<
"MPI_Waitall returned with error"
Functions to wrap MPI_Bcast, MPI_Allreduce, MPI_Iallreduce etc.
void reset() noexcept
Reset to default constructed value (MPI_REQUEST_NULL).
bool good() const noexcept
True if not equal to MPI_REQUEST_NULL.
Request() noexcept
Default construct as MPI_REQUEST_NULL.
static void freeRequest(UPstream::Request &req)
Non-blocking comms: free outstanding request. Corresponds to MPI_Request_free().
static bool waitSomeRequests(label pos, label len=-1, DynamicList< int > *indices=nullptr)
Wait until some requests (from position onwards) have finished. Corresponds to MPI_Waitsome().
static bool finishedRequests(label pos, label len=-1)
Non-blocking comms: have all requests (from position onwards) finished? Corresponds to MPI_Testall().
static void addRequest(UPstream::Request &req)
Transfer the (wrapped) MPI request to the internal global list and invalidate the parameter (ignores ...
static label nRequests() noexcept
Number of outstanding requests (on the internal list of requests).
static void cancelRequest(const label i)
Non-blocking comms: cancel and free outstanding request. Corresponds to MPI_Cancel() + MPI_Request_fr...
static void resetRequests(const label n)
Truncate outstanding requests to given length, which is expected to be in the range [0 to nRequests()...
static void freeRequests(UList< UPstream::Request > &requests)
Non-blocking comms: free outstanding requests. Corresponds to MPI_Request_free().
static bool finishedRequestPair(label &req0, label &req1)
Non-blocking comms: have both requests finished? Corresponds to pair of MPI_Test().
static void cancelRequests(UList< UPstream::Request > &requests)
Non-blocking comms: cancel and free outstanding requests. Corresponds to MPI_Cancel() + MPI_Request_f...
static bool waitAnyRequest(label pos, label len=-1)
Wait until any request (from position onwards) has finished. Corresponds to MPI_Waitany().
static void removeRequests(label pos, label len=-1)
Non-blocking comms: cancel/free outstanding requests (from position onwards) and remove from internal...
static void waitRequestPair(label &req0, label &req1)
Non-blocking comms: wait for both requests to finish. Corresponds to pair of MPI_Wait().
static void waitRequests()
Wait for all requests to finish.
static bool activeRequest(const label i)
Is request i active (!= MPI_REQUEST_NULL)?
static bool finishedRequest(const label i)
Non-blocking comms: has request i finished? Corresponds to MPI_Test().
static void waitRequest(const label i)
Wait until request i has finished. Corresponds to MPI_Wait().
static bool & parRun() noexcept
Test if this a parallel run.
static void beginTiming()
Update timer prior to measurement.
static void addWaitTime()
Add time increment to wait time.
#define FatalErrorInFunction
Report an error message using Foam::FatalError.
unsigned int count(const UList< bool > &bools, const bool val=true)
Count number of 'true' entries.
DynamicList< MPI_Request > outstandingRequests_
Outstanding non-blocking operations.
string trim(const std::string &s)
Return string trimmed of leading and trailing whitespace.
dimensionedScalar pos(const dimensionedScalar &ds)
prefixOSstream Perr
OSstream wrapped stderr (std::cerr) with parallel prefix.
Ostream & endl(Ostream &os)
Add newline and flush stream.
errorManip< error > abort(error &err)
error FatalError
Error stream (stdout output on all processes), with additional 'FOAM FATAL ERROR' header text and sta...
static Type to_mpi(UPstream::Communicator arg) noexcept
Cast UPstream::Communicator to MPI_Comm.