diff --git a/applications/test/Tuple2/Make/files b/applications/test/Tuple2/Make/files index be0026f0cd..f58d59d0f2 100644 --- a/applications/test/Tuple2/Make/files +++ b/applications/test/Tuple2/Make/files @@ -1,3 +1,3 @@ -Test-Tuple2.C +Test-Tuple2.cxx EXE = $(FOAM_USER_APPBIN)/Test-Tuple2 diff --git a/applications/test/Tuple2/Test-Tuple2.C b/applications/test/Tuple2/Test-Tuple2.cxx similarity index 97% rename from applications/test/Tuple2/Test-Tuple2.C rename to applications/test/Tuple2/Test-Tuple2.cxx index 9163f14e54..a2ebf44592 100644 --- a/applications/test/Tuple2/Test-Tuple2.C +++ b/applications/test/Tuple2/Test-Tuple2.cxx @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011 OpenFOAM Foundation - Copyright (C) 2019-2020 OpenCFD Ltd. + Copyright (C) 2019-2025 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -32,6 +32,7 @@ Description \*---------------------------------------------------------------------------*/ +#include "argList.H" #include "labelPair.H" #include "Tuple2.H" #include "label.H" @@ -102,8 +103,12 @@ void printTuple2(const Pair& t) // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // // Main program: -int main() +int main(int argc, char *argv[]) { + argList::noCheckProcessorDirectories(); + + #include "setRootCase.H" + typedef Tuple2 indexedScalar; Info<< "Default constructed Tuple: " << indexedScalar() << nl; diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H b/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H index 9181ff8d32..1dfe3b0433 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/Pstream.H @@ -34,7 +34,6 @@ SourceFiles Pstream.C PstreamBroadcast.C PstreamGather.C - PstreamCombineGather.C PstreamGatherList.C PstreamExchangeConsensus.C PstreamExchange.C @@ -125,14 +124,18 @@ public: ); - // Gather + // Gather/scatter : single value //- Gather (reduce) data, applying \c bop to combine \c value //- from different processors. The basis for Foam::reduce(). - // Uses linear/tree communication (with parallel guard). - template + // A no-op for non-parallel. + // + // \tparam InplaceMode indicates that the binary operator + // modifies values in-place, not using assignment + template static void gather ( + //! [in,out] the result is only reliable on rank=0 T& value, const BinaryOp& bop, const int tag = UPstream::msgType(), @@ -168,17 +171,13 @@ public: ); - // Gather/combine data - // Inplace combine values from processors. - // (Uses construct from Istream instead of \c << operator) + // Inplace combine (gather) : single value - //- Gather data, applying \c cop to inplace combine \c value - //- from different processors. - // Uses linear/tree communication (with parallel guard). + //- Forwards to Pstream::gather with an \em in-place \c cop template static void combineGather ( - //! [in,out] + //! [in,out] the result is only reliable on rank=0 T& value, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -188,13 +187,10 @@ public: //- Reduce inplace (cf. MPI Allreduce) //- applying \c cop to inplace combine \c value //- from different processors. - //- After completion all processors have the same data. - // Uses linear/tree communication. - // Wraps combineGather/broadcast (may change in the future). template static void combineReduce ( - //! [in,out] + //! [in,out] the result is consistent on all ranks T& value, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -205,37 +201,65 @@ public: template static void combineAllGather ( + //! [in,out] the result is consistent on all ranks T& value, const CombineOp& cop, const int tag = UPstream::msgType(), const label comm = UPstream::worldComm ) { - Pstream::combineReduce(value, cop, tag, comm); + Pstream::listCombineReduce(value, cop, tag, comm); } - // Combine variants working on whole List at a time. + // Gather/combine variants working on entire List - //- Combines List elements. - // Uses linear/tree communication (with parallel guard). + //- Gather (reduce) list elements, + //- applying \c bop to each list element + // + // \tparam InplaceMode indicates that the binary operator + // modifies values in-place, not using assignment + template + static void listGather + ( + //! [in,out] the result is only reliable on rank=0 + UList& values, + const BinaryOp& bop, + const int tag = UPstream::msgType(), + const label comm = UPstream::worldComm + ); + + //- Forwards to Pstream::listGather with an \em in-place \c cop template static void listCombineGather ( - //! [in,out] + //! [in,out] the result is only reliable on rank=0 UList& values, const CombineOp& cop, const int tag = UPstream::msgType(), const label comm = UPstream::worldComm ); - //- Combines List elements. - //- After completion all processors have the same data. - // Uses linear/tree communication (with parallel guard). + //- Gather (reduce) list elements, + //- applying \c bop to combine each list element. + // + // \tparam InplaceMode indicates that the binary operator + // modifies values in-place, not using assignment + template + static void listGatherReduce + ( + //! [in,out] the result is consistent on all ranks + List& values, + const BinaryOp& bop, + const int tag = UPstream::msgType(), + const label comm = UPstream::worldComm + ); + + //- Forwards to Pstream::listGatherReduce with an \em in-place \c cop template static void listCombineReduce ( - //! [in,out] - List (not UList) due to broadcast() + //! [in,out] the result is consistent on all ranks List& values, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -246,7 +270,7 @@ public: template static void listCombineAllGather ( - //! [in,out] - List (not UList) due to broadcast() + //! [in,out] the result is consistent on all ranks List& values, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -257,14 +281,28 @@ public: } - // Combine variants working on whole map at a time. - // Container needs iterators, find() and insert methods defined. + // Gather/combine variants working on Map/HashTable containers - //- Combine Map elements. - // Uses linear/tree communication (with parallel guard). + //- Gather (reduce) Map/HashTable containers, + //- applying \c bop to combine entries from different processors. + // + // \tparam InplaceMode indicates that the binary operator + // modifies values in-place, not using assignment + template + static void mapGather + ( + //! [in,out] the result is only reliable on rank=0 + Container& values, + const BinaryOp& bop, + const int tag = UPstream::msgType(), + const label comm = UPstream::worldComm + ); + + //- Forwards to Pstream::mapGather with an \em in-place \c cop template static void mapCombineGather ( + //! [in,out] the result is only reliable on rank=0 Container& values, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -272,15 +310,26 @@ public: ); //- Reduce inplace (cf. MPI Allreduce) - //- applying \c cop to inplace combine map \c values + //- applying \c bop to combine map \c values //- from different processors. //- After completion all processors have the same data. - // Uses the specified communication schedule. + // // Wraps mapCombineGather/broadcast (may change in the future). - //- After completion all processors have the same data. + template + static void mapGatherReduce + ( + //! [in,out] the result is consistent on all ranks + Container& values, + const BinaryOp& bop, + const int tag = UPstream::msgType(), + const label comm = UPstream::worldComm + ); + + //- Forwards to Pstream::mapGatherReduce with an \em in-place \c cop template static void mapCombineReduce ( + //! [in,out] the result is consistent on all ranks Container& values, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -291,6 +340,7 @@ public: template static void mapCombineAllGather ( + //! [in,out] the result is consistent on all ranks Container& values, const CombineOp& cop, const int tag = UPstream::msgType(), @@ -343,7 +393,7 @@ public: ); //- Gather data, but keep individual values separate. - //- Uses MPI_Allgather or manual linear/tree communication. + //- Uses MPI_Allgather or manual communication. // After completion all processors have the same data. // Wraps gatherList/scatterList (may change in the future). template @@ -612,7 +662,6 @@ public: #ifdef NoRepository #include "PstreamBroadcast.C" #include "PstreamGather.C" - #include "PstreamCombineGather.C" #include "PstreamGatherList.C" #include "PstreamExchange.C" #endif diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamCombineGather.C b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamCombineGather.C deleted file mode 100644 index f91a9ffae5..0000000000 --- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamCombineGather.C +++ /dev/null @@ -1,365 +0,0 @@ -/*---------------------------------------------------------------------------*\ - ========= | - \\ / F ield | OpenFOAM: The Open Source CFD Toolbox - \\ / O peration | - \\ / A nd | www.openfoam.com - \\/ M anipulation | -------------------------------------------------------------------------------- - Copyright (C) 2011-2017 OpenFOAM Foundation - Copyright (C) 2019-2025 OpenCFD Ltd. -------------------------------------------------------------------------------- -License - This file is part of OpenFOAM. - - OpenFOAM is free software: you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - OpenFOAM is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - for more details. - - You should have received a copy of the GNU General Public License - along with OpenFOAM. If not, see . - -Description - Variant of gather. - Normal gather uses: - - default construct and read (>>) from Istream - - binary operator and assignment operator to combine values - - combineGather uses: - - construct from Istream - - modify operator which modifies its lhs - -\*---------------------------------------------------------------------------*/ - -#include "IPstream.H" -#include "OPstream.H" -#include "IOstreams.H" -#include "contiguous.H" - -// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // - -template -void Foam::Pstream::combineGather -( - T& value, - const CombineOp& cop, - const int tag, - const label comm -) -{ - if (UPstream::is_parallel(comm)) - { - // Communication order - const auto& comms = UPstream::whichCommunication(comm); - // if (comms.empty()) return; // extra safety? - const auto& myComm = comms[UPstream::myProcNo(comm)]; - - // Receive from my downstairs neighbours - for (const auto belowID : myComm.below()) - { - if constexpr (is_contiguous_v) - { - T received; - - UIPstream::read - ( - UPstream::commsTypes::scheduled, - belowID, - reinterpret_cast(&received), - sizeof(T), - tag, - comm - ); - - if (debug & 2) - { - Perr<< " received from " - << belowID << " data:" << received << endl; - } - - cop(value, received); - } - else - { - IPstream fromBelow - ( - UPstream::commsTypes::scheduled, - belowID, - 0, // bufsize - tag, - comm - ); - T received(fromBelow); - - if (debug & 2) - { - Perr<< " received from " - << belowID << " data:" << received << endl; - } - - cop(value, received); - } - } - - // Send up value - if (myComm.above() >= 0) - { - if (debug & 2) - { - Perr<< " sending to " << myComm.above() - << " data:" << value << endl; - } - - if constexpr (is_contiguous_v) - { - UOPstream::write - ( - UPstream::commsTypes::scheduled, - myComm.above(), - reinterpret_cast(&value), - sizeof(T), - tag, - comm - ); - } - else - { - OPstream::send(value, myComm.above(), tag, comm); - } - } - } -} - - -template -void Foam::Pstream::combineReduce -( - T& value, - const CombineOp& cop, - const int tag, - const label comm -) -{ - if (UPstream::is_parallel(comm)) - { - Pstream::combineGather(value, cop, tag, comm); - Pstream::broadcast(value, comm); - } -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template -void Foam::Pstream::listCombineGather -( - UList& values, - const CombineOp& cop, - const int tag, - const label comm -) -{ - if (UPstream::is_parallel(comm)) - { - // Communication order - const auto& comms = UPstream::whichCommunication(comm); - // if (comms.empty()) return; // extra safety? - const auto& myComm = comms[UPstream::myProcNo(comm)]; - - // Receive from my downstairs neighbours - for (const auto belowID : myComm.below()) - { - if constexpr (is_contiguous_v) - { - List received(values.size()); - - UIPstream::read - ( - UPstream::commsTypes::scheduled, - belowID, - received, - tag, - comm - ); - - if (debug & 2) - { - Perr<< " received from " - << belowID << " data:" << received << endl; - } - - forAll(values, i) - { - cop(values[i], received[i]); - } - } - else - { - IPstream fromBelow - ( - UPstream::commsTypes::scheduled, - belowID, - 0, // bufsize - tag, - comm - ); - List received(fromBelow); - - if (debug & 2) - { - Perr<< " received from " - << belowID << " data:" << received << endl; - } - - forAll(values, i) - { - cop(values[i], received[i]); - } - } - } - - // Send up values - if (myComm.above() >= 0) - { - if (debug & 2) - { - Perr<< " sending to " << myComm.above() - << " data:" << values << endl; - } - - if constexpr (is_contiguous_v) - { - UOPstream::write - ( - UPstream::commsTypes::scheduled, - myComm.above(), - values, - tag, - comm - ); - } - else - { - OPstream::send(values, myComm.above(), tag, comm); - } - } - } -} - - -template -void Foam::Pstream::listCombineReduce -( - List& values, - const CombineOp& cop, - const int tag, - const label comm -) -{ - if (UPstream::is_parallel(comm)) - { - Pstream::listCombineGather(values, cop, tag, comm); - Pstream::broadcast(values, comm); - } -} - - -// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // - -template -void Foam::Pstream::mapCombineGather -( - Container& values, - const CombineOp& cop, - const int tag, - const label comm -) -{ - if (UPstream::is_parallel(comm)) - { - // Communication order - const auto& comms = UPstream::whichCommunication(comm); - // if (comms.empty()) return; // extra safety? - const auto& myComm = comms[UPstream::myProcNo(comm)]; - - // Receive from my downstairs neighbours - for (const auto belowID : myComm.below()) - { - // Map/HashTable: non-contiguous - - IPstream fromBelow - ( - UPstream::commsTypes::scheduled, - belowID, - 0, // bufsize - tag, - comm - ); - Container received(fromBelow); - - if (debug & 2) - { - Perr<< " received from " - << belowID << " data:" << received << endl; - } - - for - ( - auto recvIter = received.cbegin(); - recvIter != received.cend(); - ++recvIter - ) - { - auto masterIter = values.find(recvIter.key()); - - if (masterIter.good()) - { - // Combine with existing - cop(masterIter.val(), recvIter.val()); - } - else - { - // Insert new key/value - values.insert(recvIter.key(), recvIter.val()); - } - } - } - - // Send up values - if (myComm.above() >= 0) - { - if (debug & 2) - { - Perr<< " sending to " << myComm.above() - << " data:" << values << endl; - } - - OPstream::send(values, myComm.above(), tag, comm); - } - } -} - - -template -void Foam::Pstream::mapCombineReduce -( - Container& values, - const CombineOp& cop, - const int tag, - const label comm -) -{ - if (UPstream::is_parallel(comm)) - { - Pstream::mapCombineGather(values, cop, tag, comm); - Pstream::broadcast(values, comm); - } -} - - -// ************************************************************************* // diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.C b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.C index e28bc0bb4c..154aee8fb9 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.C +++ b/src/OpenFOAM/db/IOstreams/Pstreams/PstreamGather.C @@ -30,15 +30,25 @@ Description The gathered data will be a single value constructed from the values on individual processors using a user-specified operator. +Note + Normal gather uses: + - binary operator that returns a value. + So assignment that return value to yield the new value + + Combine gather uses: + - binary operator modifies its first parameter in-place + \*---------------------------------------------------------------------------*/ +#include "contiguous.H" #include "IPstream.H" #include "OPstream.H" -#include "contiguous.H" // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -template +// Single value variants + +template void Foam::Pstream::gather ( T& value, @@ -47,15 +57,21 @@ void Foam::Pstream::gather const label communicator ) { - if (UPstream::is_parallel(communicator)) + if (!UPstream::is_parallel(communicator)) + { + // Nothing to do + return; + } + else { // Communication order const auto& comms = UPstream::whichCommunication(communicator); // if (comms.empty()) return; // extra safety? const auto& myComm = comms[UPstream::myProcNo(communicator)]; + const auto& below = myComm.below(); // Receive from my downstairs neighbours - for (const auto belowID : myComm.below()) + for (const auto proci : below) { T received; @@ -64,7 +80,7 @@ void Foam::Pstream::gather UIPstream::read ( UPstream::commsTypes::scheduled, - belowID, + proci, reinterpret_cast(&received), sizeof(T), tag, @@ -73,15 +89,42 @@ void Foam::Pstream::gather } else { - IPstream::recv(received, belowID, tag, communicator); + IPstream::recv(received, proci, tag, communicator); } - value = bop(value, received); + if constexpr (InplaceMode) + { + if (debug & 2) + { + Perr<< " received from " + << proci << " data:" << received << endl; + } + } + + if constexpr (InplaceMode) + { + // In-place binary operation + bop(value, received); + } + else + { + // Assign result of binary operation + value = bop(value, received); + } } // Send up value if (myComm.above() >= 0) { + if constexpr (InplaceMode) + { + if (debug & 2) + { + Perr<< " sending to " << myComm.above() + << " data:" << value << endl; + } + } + if constexpr (is_contiguous_v) { UOPstream::write @@ -103,54 +146,391 @@ void Foam::Pstream::gather } +template +void Foam::Pstream::combineGather +( + T& value, + const CombineOp& cop, + const int tag, + const label comm +) +{ + // In-place binary operation + Pstream::gather(value, cop, tag, comm); +} + + +template +void Foam::Pstream::combineReduce +( + T& value, + const CombineOp& cop, + const int tag, + const label comm +) +{ + if (UPstream::is_parallel(comm)) + { + // In-place binary operation + Pstream::gather(value, cop, tag, comm); + Pstream::broadcast(value, comm); + } +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// List variants + +template +void Foam::Pstream::listGather +( + UList& values, + const BinaryOp& bop, + const int tag, + const label communicator +) +{ + if (!UPstream::is_parallel(communicator) || values.empty()) + { + // Nothing to do + return; + } + else + { + // Communication order + const auto& comms = UPstream::whichCommunication(communicator); + // if (comms.empty()) return; // extra safety? + const auto& myComm = comms[UPstream::myProcNo(communicator)]; + const auto& below = myComm.below(); + + // Same length on all ranks + const label listLen = values.size(); + + List received; + + if (!below.empty()) + { + // Pre-size for contiguous reading + if constexpr (is_contiguous_v) + { + received.resize_nocopy(listLen); + } + } + + // Receive from my downstairs neighbours + for (const auto proci : below) + { + if constexpr (is_contiguous_v) + { + UIPstream::read + ( + UPstream::commsTypes::scheduled, + proci, + received, + tag, + communicator + ); + } + else + { + received.clear(); // extra safety? + IPstream::recv(received, proci, tag, communicator); + } + + if constexpr (InplaceMode) + { + if (debug & 2) + { + Perr<< " received from " + << proci << " data:" << received << endl; + } + } + + for (label i = 0; i < listLen; ++i) + { + if constexpr (InplaceMode) + { + // In-place binary operation + bop(values[i], received[i]); + } + else + { + // Assign result of binary operation + values[i] = bop(values[i], received[i]); + } + } + } + + // Send up values + if (myComm.above() >= 0) + { + if constexpr (InplaceMode) + { + if (debug & 2) + { + Perr<< " sending to " << myComm.above() + << " data:" << values << endl; + } + } + + if constexpr (is_contiguous_v) + { + UOPstream::write + ( + UPstream::commsTypes::scheduled, + myComm.above(), + values, + tag, + communicator + ); + } + else + { + OPstream::send(values, myComm.above(), tag, communicator); + } + } + } +} + + +template +void Foam::Pstream::listGatherReduce +( + List& values, + const BinaryOp& bop, + const int tag, + const label comm +) +{ + Pstream::listGather(values, bop, tag, comm); + if (!values.empty()) + { + Pstream::broadcast(values, comm); + } +} + + +template +void Foam::Pstream::listCombineGather +( + UList& values, + const CombineOp& cop, + const int tag, + const label comm +) +{ + // In-place binary operation + Pstream::listGather(values, cop, tag, comm); +} + + +template +void Foam::Pstream::listCombineReduce +( + List& values, + const CombineOp& cop, + const int tag, + const label comm +) +{ + // In-place binary operation + Pstream::listGatherReduce(values, cop, tag, comm); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Map variants + +template +void Foam::Pstream::mapGather +( + Container& values, + const BinaryOp& bop, + const int tag, + const label communicator +) +{ + if (!UPstream::is_parallel(communicator)) + { + // Nothing to do + return; + } + else + { + // Communication order + const auto& comms = UPstream::whichCommunication(communicator); + // if (comms.empty()) return; // extra safety? + const auto& myComm = comms[UPstream::myProcNo(communicator)]; + const auto& below = myComm.below(); + + // Receive from my downstairs neighbours + for (const auto proci : below) + { + // Map/HashTable: non-contiguous + Container received; + IPstream::recv(received, proci, tag, communicator); + + if constexpr (InplaceMode) + { + if (debug & 2) + { + Perr<< " received from " + << proci << " data:" << received << endl; + } + } + + const auto last = received.end(); + + for (auto iter = received.begin(); iter != last; ++iter) + { + auto slot = values.find(iter.key()); + + if (slot.good()) + { + // Combine with existing entry + + if constexpr (InplaceMode) + { + // In-place binary operation + bop(slot.val(), iter.val()); + } + else + { + // Assign result of binary operation + slot.val() = bop(slot.val(), iter.val()); + } + } + else + { + // Create a new entry + values.emplace(iter.key(), std::move(iter.val())); + } + + } + } + + // Send up values + if (myComm.above() >= 0) + { + if constexpr (InplaceMode) + { + if (debug & 2) + { + Perr<< " sending to " << myComm.above() + << " data:" << values << endl; + } + } + + OPstream::send(values, myComm.above(), tag, communicator); + } + } +} + + +template +void Foam::Pstream::mapGatherReduce +( + Container& values, + const BinaryOp& bop, + const int tag, + const label comm +) +{ + Pstream::mapGather + ( + values, bop, tag, comm + ); + Pstream::broadcast(values, comm); +} + + +template +void Foam::Pstream::mapCombineGather +( + Container& values, + const CombineOp& cop, + const int tag, + const label comm +) +{ + // In-place binary operation + Pstream::mapGather + ( + values, cop, tag, comm + ); +} + + +template +void Foam::Pstream::mapCombineReduce +( + Container& values, + const CombineOp& cop, + const int tag, + const label comm +) +{ + // In-place binary operation + Pstream::mapGatherReduce + ( + values, cop, tag, comm + ); +} + + +// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // + +// Single values to/from a list + template Foam::List Foam::Pstream::listGatherValues ( const T& localValue, - const label comm, + const label communicator, [[maybe_unused]] const int tag ) { - if constexpr (is_contiguous_v) + if (!UPstream::is_parallel(communicator)) + { + // non-parallel: return own value + // TBD: only when UPstream::is_rank(communicator) as well? + List allValues(1); + allValues[0] = localValue; + return allValues; + } + else if constexpr (is_contiguous_v) { // UPstream version is contiguous only - return UPstream::listGatherValues(localValue, comm); + return UPstream::listGatherValues(localValue, communicator); } else { + // Standard gather (all to one) + + // The data are non-contiguous! + // + // Non-trivial to manage non-blocking gather without a + // PEX/NBX approach (eg, PstreamBuffers). + // Leave with simple exchange for now + List allValues; - - if (UPstream::is_parallel(comm)) + if (UPstream::master(communicator)) { - const label numProc = UPstream::nProcs(comm); + allValues.resize(UPstream::nProcs(communicator)); - if (UPstream::master(comm)) + for (const int proci : UPstream::subProcs(communicator)) { - allValues.resize(numProc); - - // Non-trivial to manage non-blocking gather without a - // PEX/NBX approach (eg, PstreamBuffers). - // Leave with simple exchange for now - - allValues[0] = localValue; - - for (int proci = 1; proci < numProc; ++proci) - { - IPstream::recv(allValues[proci], proci, tag, comm); - } + IPstream::recv(allValues[proci], proci, tag, communicator); } - else if (UPstream::is_rank(comm)) - { - OPstream::send(localValue, UPstream::masterNo(), tag, comm); - } - } - else - { - // non-parallel: return own value - // TBD: only when UPstream::is_rank(comm) as well? - allValues.resize(1); + allValues[0] = localValue; } + else if (UPstream::is_rank(communicator)) + { + OPstream::send(localValue, UPstream::masterNo(), tag, communicator); + } return allValues; } @@ -161,73 +541,74 @@ template T Foam::Pstream::listScatterValues ( const UList& allValues, - const label comm, + const label communicator, [[maybe_unused]] const int tag ) { - if constexpr (is_contiguous_v) + if (!UPstream::is_parallel(communicator)) + { + // non-parallel: return first value + // TBD: only when UPstream::is_rank(communicator) as well? + + if (!allValues.empty()) + { + return allValues[0]; + } + + return T{}; // Fallback value + } + else if constexpr (is_contiguous_v) { // UPstream version is contiguous only - return UPstream::listScatterValues(allValues, comm); + return UPstream::listScatterValues(allValues, communicator); } else { - T localValue{}; + // Standard scatter (one to all) - if (UPstream::is_parallel(comm)) - { - const label numProc = UPstream::nProcs(comm); + T localValue{}; - if (UPstream::master(comm) && allValues.size() < numProc) - { - FatalErrorInFunction - << "Attempting to send " << allValues.size() - << " values to " << numProc << " processors" << endl - << Foam::abort(FatalError); - } + if (UPstream::master(communicator)) + { + const label numProc = UPstream::nProcs(communicator); - if (UPstream::master(comm)) - { - const label startOfRequests = UPstream::nRequests(); + if (allValues.size() < numProc) + { + FatalErrorInFunction + << "Attempting to send " << allValues.size() + << " values to " << numProc << " processors" << endl + << Foam::abort(FatalError); + } - List> sendBuffers(numProc); + const label startOfRequests = UPstream::nRequests(); - for (int proci = 1; proci < numProc; ++proci) - { - UOPstream toProc - ( - UPstream::commsTypes::nonBlocking, - proci, - sendBuffers[proci], - tag, - comm - ); - toProc << allValues[proci]; - } + List> sendBuffers(numProc); - // Wait for outstanding requests - UPstream::waitRequests(startOfRequests); + for (const int proci : UPstream::subProcs(communicator)) + { + UOPstream toProc + ( + UPstream::commsTypes::nonBlocking, + proci, + sendBuffers[proci], + tag, + communicator + ); + toProc << allValues[proci]; + } - return allValues[0]; - } - else if (UPstream::is_rank(comm)) - { - IPstream::recv(localValue, UPstream::masterNo(), tag, comm); - } - } - else - { - // non-parallel: return first value - // TBD: only when UPstream::is_rank(comm) as well? + // Wait for outstanding requests + UPstream::waitRequests(startOfRequests); - if (!allValues.empty()) - { - return allValues[0]; - } - } + return allValues[0]; + } + else if (UPstream::is_rank(communicator)) + { + IPstream::recv(localValue, UPstream::masterNo(), tag, communicator); + } - return localValue; - } + return localValue; + } } diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/compat/PstreamCombineGather.C b/src/OpenFOAM/db/IOstreams/Pstreams/compat/PstreamCombineGather.C new file mode 100644 index 0000000000..7cec1b4541 --- /dev/null +++ b/src/OpenFOAM/db/IOstreams/Pstreams/compat/PstreamCombineGather.C @@ -0,0 +1 @@ +#warning File removed - left for old dependency check only diff --git a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamCombineReduceOps.H b/src/OpenFOAM/db/IOstreams/Pstreams/compat/PstreamCombineReduceOps.H similarity index 95% rename from src/OpenFOAM/db/IOstreams/Pstreams/PstreamCombineReduceOps.H rename to src/OpenFOAM/db/IOstreams/Pstreams/compat/PstreamCombineReduceOps.H index 5c8f52d6ac..905cd788c3 100644 --- a/src/OpenFOAM/db/IOstreams/Pstreams/PstreamCombineReduceOps.H +++ b/src/OpenFOAM/db/IOstreams/Pstreams/compat/PstreamCombineReduceOps.H @@ -20,6 +20,8 @@ Description #ifndef FoamCompat_PstreamCombineReduceOps_H #define FoamCompat_PstreamCombineReduceOps_H +#warning Deprecated header + #include "Pstream.H" #include "ops.H" @@ -32,6 +34,7 @@ namespace Foam //- Compatibility wrapper for Pstream::combineReduce template +FOAM_DEPRECATED_FOR(2022-08, "Pstream::combineReduce()") void combineReduce ( T& value, diff --git a/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C b/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C index 8795e1cfe0..f8b250f690 100644 --- a/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C +++ b/src/dynamicMesh/motionSolvers/displacement/pointSmoothing/hexMeshSmootherMotionSolver.C @@ -455,7 +455,7 @@ Foam::labelList Foam::hexMeshSmootherMotionSolver::countZeroOrPos const labelList& elems ) const { - labelList n(size, 0); + labelList n(size, Zero); for (const label elem : elems) { if (elem >= 0) @@ -463,8 +463,8 @@ Foam::labelList Foam::hexMeshSmootherMotionSolver::countZeroOrPos n[elem]++; } } - Pstream::listCombineGather(n, plusEqOp