From aa002122c2192085879365148c2468eca5943fe7 Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Thu, 6 Apr 2023 14:35:00 +0200 Subject: [PATCH] ENH: simplify handling of pushed/freed requests - previously had an additional stack for freedRequests_, which were used to 'remember' locations into the list of outstandingRequests_ that were handled by 'waitRequest()'. This was principally done for sanity checks on shutdown, but we now just test for any outstanding requests that are *not* MPI_REQUEST_NULL instead (much simpler). The framework with freedRequests_ also had a provision to 'recycle' them by popping from that stack, but this is rather fragile since it would only triggered by some collectives (MPI_Iallreduce, MPI_Ialltoall, MPI_Igather, MPI_Iscatter) with no guarantee that these will all be properly removed again. There was also no pruning of extraneous indices. ENH: consolidate internal reset/push of requests - replace duplicate code with inline functions reset_request(), push_request() ENH: null out trailing requests - extra safety (paranoia) for the UPstream::Request versions of finishedRequests(), waitAnyRequest() CONFIG: document nPollProcInterfaces in etc/controlDict - still experimental, but at least make the keyword known --- etc/controlDict | 6 +- src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H | 89 +++++++----- src/Pstream/mpi/PstreamGlobals.C | 1 - src/Pstream/mpi/PstreamGlobals.H | 60 +++++--- src/Pstream/mpi/UIPstreamRead.C | 16 +- src/Pstream/mpi/UOPstreamWrite.C | 18 +-- src/Pstream/mpi/UPstream.C | 1 - src/Pstream/mpi/UPstreamRequest.C | 30 ++-- src/Pstream/mpi/UPstreamWrappingTemplates.C | 137 +++--------------- 9 files changed, 149 insertions(+), 209 deletions(-) diff --git a/etc/controlDict b/etc/controlDict index ea88edf7d7..d605346302 100644 --- a/etc/controlDict +++ b/etc/controlDict @@ -1,7 +1,7 @@ /*--------------------------------*- C++ -*----------------------------------*\ | ========= | | | \\ / F ield | OpenFOAM: The Open Source CFD Toolbox | -| \\ / O peration | Version: v2212 | +| \\ / O peration | Version: v2306 | | \\ / A nd | Website: www.openfoam.com | | \\/ M anipulation | | \*---------------------------------------------------------------------------*/ @@ -146,6 +146,10 @@ OptimisationSwitches // global reduction, even if multi-pass is not needed) maxCommsSize 0; + // Optional (quite experimental) feature in lduMatrixUpdate + // to poll (processor) interfaces for individual readiness + // instead of waiting for all to complete first. + nPollProcInterfaces 0; // Trap floating point exception. // Can override with FOAM_SIGFPE env variable (true|false) diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H index eb4a485340..820ef017d7 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/UPstream.H @@ -499,56 +499,69 @@ public: ); - // Non-blocking comms + // Requests (non-blocking comms) - //- Number of outstanding requests - static label nRequests() noexcept; + //- Number of outstanding requests (on the internal list of requests) + static label nRequests() noexcept; - //- Truncate outstanding requests to given length, which is - //- expected to be in the range 0 to nRequests. - // A no-op for out-of-range values. - static void resetRequests(const label n); + //- Truncate outstanding requests to given length, which is + //- expected to be in the range [0 to nRequests()]. + // A no-op for out-of-range values. + static void resetRequests(const label n); - //- Wait until all requests (from position onwards) have finished. - // A no-op if parRun() == false, if there are no pending requests - // or if the start is out-of-range (0 to nRequests) - static void waitRequests(const label pos); + //- Wait until all requests (from position onwards) have finished. + //- Corresponds to MPI_Waitall() + // A no-op if parRun() == false, + // if the position is out-of-range [0 to nRequests()], + // or the internal list of requests is empty. + // + // \param pos starting position within the internal list of requests + static void waitRequests(const label pos); - //- Wait until all requests have finished. - // A no-op if parRun() == false or the list is empty - static void waitRequests(UList& requests); + //- Wait until all requests have finished. + //- Corresponds to MPI_Waitall() + // A no-op if parRun() == false, or the list is empty. + static void waitRequests(UList& requests); - //- Wait until any request has finished and return its index. - // Returns -1 if parRun() == false, or the list is empty, - // or if all the requests have already been handled - static label waitAnyRequest(UList& requests); + //- Wait until any request has finished and return its index. + //- Corresponds to MPI_Waitany() + // Returns -1 if parRun() == false, or the list is empty, + // or if all the requests have already been handled + static label waitAnyRequest(UList& requests); - //- Wait until request i has finished. - // A no-op if parRun() == false, - // there are no pending requests, - // or if the index is out-of-range (0 to nRequests) - static void waitRequest(const label i); + //- Wait until request i has finished. + //- Corresponds to MPI_Wait() + // A no-op if parRun() == false, + // there are no pending requests, + // or if the index is out-of-range (0 to nRequests) + static void waitRequest(const label i); - //- Wait until specified request has finished. - // A no-op if parRun() == false or for a null-request - static void waitRequest(UPstream::Request& req); + //- Wait until specified request has finished. + //- Corresponds to MPI_Wait() + // A no-op if parRun() == false or for a null-request + static void waitRequest(UPstream::Request& req); - //- Non-blocking comms: has request i finished? - // A no-op and returns true if parRun() == false, - // there are no pending requests, - // or if the index is out-of-range (0 to nRequests) - static bool finishedRequest(const label i); + //- Non-blocking comms: has request i finished? + //- Corresponds to MPI_Test() + // A no-op and returns true if parRun() == false, + // there are no pending requests, + // or if the index is out-of-range (0 to nRequests) + static bool finishedRequest(const label i); - //- Non-blocking comms: has request finished? - // A no-op and returns true if parRun() == false - // or for a null-request - static bool finishedRequest(UPstream::Request& req); + //- Non-blocking comms: has request finished? + //- Corresponds to MPI_Test() + // A no-op and returns true if parRun() == false + // or for a null-request + static bool finishedRequest(UPstream::Request& req); - //- Non-blocking comms: have all requests finished? - // A no-op and returns true if parRun() == false or list is empty - static bool finishedRequests(UList& requests); + //- Non-blocking comms: have all requests finished? + //- Corresponds to MPI_Testall() + // A no-op and returns true if parRun() == false or list is empty + static bool finishedRequests(UList& requests); + // General + //- Set as parallel run on/off. // \return the previous value static bool parRun(const bool on) noexcept diff --git a/src/Pstream/mpi/PstreamGlobals.C b/src/Pstream/mpi/PstreamGlobals.C index 601d371331..5fd81abae9 100644 --- a/src/Pstream/mpi/PstreamGlobals.C +++ b/src/Pstream/mpi/PstreamGlobals.C @@ -36,7 +36,6 @@ Foam::DynamicList Foam::PstreamGlobals::MPICommunicators_; Foam::DynamicList Foam::PstreamGlobals::MPIGroups_; Foam::DynamicList Foam::PstreamGlobals::outstandingRequests_; -Foam::DynamicList Foam::PstreamGlobals::freedRequests_; // * * * * * * * * * * * * * * * Global Functions * * * * * * * * * * * * * // diff --git a/src/Pstream/mpi/PstreamGlobals.H b/src/Pstream/mpi/PstreamGlobals.H index 1edb623a1a..276f189328 100644 --- a/src/Pstream/mpi/PstreamGlobals.H +++ b/src/Pstream/mpi/PstreamGlobals.H @@ -29,7 +29,7 @@ Namespace Description Global functions and variables for working with parallel streams, - but principally for mpi + but principally for MPI. SourceFiles PstreamGlobals.C @@ -40,6 +40,7 @@ SourceFiles #define Foam_PstreamGlobals_H #include "DynamicList.H" +#include "UPstream.H" // for UPstream::Request #include // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // @@ -71,7 +72,6 @@ extern DynamicList MPIGroups_; //- Outstanding non-blocking operations. extern DynamicList outstandingRequests_; -extern DynamicList