mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: support gather of indirect list via globalIndex
This commit is contained in:
@ -28,14 +28,16 @@ Application
|
|||||||
globalIndexTest
|
globalIndexTest
|
||||||
|
|
||||||
Description
|
Description
|
||||||
Simple demonstration and test application for the globalIndex class.
|
Simple tests for the globalIndex class.
|
||||||
|
|
||||||
\*---------------------------------------------------------------------------*/
|
\*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#include "globalIndex.H"
|
#include "globalIndex.H"
|
||||||
|
#include "globalMeshData.H"
|
||||||
#include "argList.H"
|
#include "argList.H"
|
||||||
#include "Time.H"
|
#include "Time.H"
|
||||||
#include "polyMesh.H"
|
#include "polyMesh.H"
|
||||||
|
#include "IndirectList.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
#include "Random.H"
|
#include "Random.H"
|
||||||
|
|
||||||
@ -218,6 +220,34 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Info<< "Gather indirect list of boundary points (patch = 0)\n";
|
||||||
|
{
|
||||||
|
const polyPatch& pp = mesh.boundaryMesh()[0];
|
||||||
|
|
||||||
|
// Map mesh point index to local (compact) point index
|
||||||
|
labelList pointToGlobal;
|
||||||
|
labelList uniqueMeshPointLabels;
|
||||||
|
|
||||||
|
autoPtr<globalIndex> globalPointsPtr =
|
||||||
|
mesh.globalData().mergePoints
|
||||||
|
(
|
||||||
|
pp.meshPoints(),
|
||||||
|
pp.meshPointMap(),
|
||||||
|
pointToGlobal,
|
||||||
|
uniqueMeshPointLabels
|
||||||
|
);
|
||||||
|
|
||||||
|
Info<< "local-sizes: " << globalPointsPtr().sizes() << nl;
|
||||||
|
|
||||||
|
UIndirectList<point> procPoints(mesh.points(), uniqueMeshPointLabels);
|
||||||
|
pointField patchPoints;
|
||||||
|
|
||||||
|
globalPointsPtr().gather(procPoints, patchPoints);
|
||||||
|
|
||||||
|
Info<< "gathered point field = " << patchPoints.size() << " points\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
Info<< "\nEnd\n" << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -237,7 +237,7 @@ public:
|
|||||||
// Other
|
// Other
|
||||||
|
|
||||||
//- Collect data in processor order on master (== procIDs[0]).
|
//- Collect data in processor order on master (== procIDs[0]).
|
||||||
// Needs offsets only on master.
|
// Offsets needed on master only.
|
||||||
template<class Container, class Type>
|
template<class Container, class Type>
|
||||||
static void gather
|
static void gather
|
||||||
(
|
(
|
||||||
@ -247,12 +247,25 @@ public:
|
|||||||
const UList<Type>& fld,
|
const UList<Type>& fld,
|
||||||
List<Type>& allFld,
|
List<Type>& allFld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
);
|
||||||
|
|
||||||
|
//- Collect indirect data in processor order on master
|
||||||
|
// Offsets needed on master only.
|
||||||
|
template<class Type, class Addr>
|
||||||
|
static void gather
|
||||||
|
(
|
||||||
|
const labelUList& offsets,
|
||||||
|
const label comm,
|
||||||
|
const UList<int>& procIDs,
|
||||||
|
const IndirectListBase<Type, Addr>& fld,
|
||||||
|
List<Type>& allFld,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const Pstream::commsTypes = Pstream::commsTypes::scheduled
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Collect data in processor order on master (== procIDs[0]).
|
//- Collect data in processor order on master (== procIDs[0]).
|
||||||
// Needs offsets only on master.
|
// Offsets needed on master only.
|
||||||
template<class Container, class Type>
|
template<class Container, class Type>
|
||||||
void gather
|
void gather
|
||||||
(
|
(
|
||||||
@ -276,8 +289,18 @@ public:
|
|||||||
const UList<Type>& fld,
|
const UList<Type>& fld,
|
||||||
List<Type>& allFld,
|
List<Type>& allFld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
) const;
|
||||||
|
|
||||||
|
//- Collect data indirectly in processor order on master.
|
||||||
|
// Does communication with default communicator and message tag.
|
||||||
|
template<class Type, class Addr>
|
||||||
|
void gather
|
||||||
|
(
|
||||||
|
const IndirectListBase<Type, Addr>& fld,
|
||||||
|
List<Type>& allFld,
|
||||||
|
const int tag = UPstream::msgType(),
|
||||||
|
const Pstream::commsTypes = Pstream::commsTypes::scheduled
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Collect data in processor order on master.
|
//- Collect data in processor order on master.
|
||||||
@ -288,8 +311,7 @@ public:
|
|||||||
const UList<Type>& fld,
|
const UList<Type>& fld,
|
||||||
List<Type>& allFld,
|
List<Type>& allFld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -303,8 +325,7 @@ public:
|
|||||||
const Container& procIDs,
|
const Container& procIDs,
|
||||||
List<Type>& fld,
|
List<Type>& fld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Inplace collect in processor order on master (== procIDs[0]).
|
//- Inplace collect in processor order on master (== procIDs[0]).
|
||||||
@ -331,8 +352,7 @@ public:
|
|||||||
(
|
(
|
||||||
List<Type>& fld,
|
List<Type>& fld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Inplace collect data in processor order on master
|
//- Inplace collect data in processor order on master
|
||||||
@ -343,8 +363,7 @@ public:
|
|||||||
(
|
(
|
||||||
List<Type>& fld,
|
List<Type>& fld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
@ -358,8 +377,7 @@ public:
|
|||||||
const UList<Type>& allFld,
|
const UList<Type>& allFld,
|
||||||
UList<Type>& fld,
|
UList<Type>& fld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
|
||||||
);
|
);
|
||||||
|
|
||||||
//- Distribute data in processor order. Requires fld to be sized!
|
//- Distribute data in processor order. Requires fld to be sized!
|
||||||
@ -386,8 +404,7 @@ public:
|
|||||||
const UList<Type>& allFld,
|
const UList<Type>& allFld,
|
||||||
UList<Type>& fld,
|
UList<Type>& fld,
|
||||||
const int tag = UPstream::msgType(),
|
const int tag = UPstream::msgType(),
|
||||||
const Pstream::commsTypes commsType =
|
const Pstream::commsTypes = Pstream::commsTypes::nonBlocking
|
||||||
Pstream::commsTypes::nonBlocking
|
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
//- Get (potentially remote) data. Elements required given as
|
//- Get (potentially remote) data. Elements required given as
|
||||||
|
|||||||
@ -42,9 +42,21 @@ void Foam::globalIndex::gather
|
|||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes commsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!is_contiguous<Type>::value
|
||||||
|
&& commsType == Pstream::commsTypes::nonBlocking
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot use nonBlocking with non-contiguous data"
|
||||||
|
<< exit(FatalError);
|
||||||
|
// Could also warn and change to scheduled etc...
|
||||||
|
}
|
||||||
|
|
||||||
if (Pstream::myProcNo(comm) == procIDs[0])
|
if (Pstream::myProcNo(comm) == procIDs[0])
|
||||||
{
|
{
|
||||||
allFld.setSize(off.last());
|
allFld.resize(off.last());
|
||||||
|
|
||||||
// Assign my local data
|
// Assign my local data
|
||||||
SubList<Type>(allFld, fld.size(), 0) = fld;
|
SubList<Type>(allFld, fld.size(), 0) = fld;
|
||||||
@ -73,7 +85,7 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
IPstream fromSlave
|
IPstream fromProc
|
||||||
(
|
(
|
||||||
commsType,
|
commsType,
|
||||||
procIDs[i],
|
procIDs[i],
|
||||||
@ -81,22 +93,15 @@ void Foam::globalIndex::gather
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
fromSlave >> procSlot;
|
fromProc >> procSlot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// nonBlocking
|
// nonBlocking && is_contiguous == true (already checked)
|
||||||
|
|
||||||
if (!is_contiguous<Type>::value)
|
const label startOfRequests = Pstream::nRequests();
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "nonBlocking not supported for non-contiguous data"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
label startOfRequests = Pstream::nRequests();
|
|
||||||
|
|
||||||
// Set up reads
|
// Set up reads
|
||||||
for (label i = 1; i < procIDs.size(); ++i)
|
for (label i = 1; i < procIDs.size(); ++i)
|
||||||
@ -108,7 +113,7 @@ void Foam::globalIndex::gather
|
|||||||
commsType,
|
commsType,
|
||||||
procIDs[i],
|
procIDs[i],
|
||||||
reinterpret_cast<char*>(procSlot.data()),
|
reinterpret_cast<char*>(procSlot.data()),
|
||||||
procSlot.byteSize(),
|
procSlot.size_bytes(),
|
||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
@ -153,16 +158,9 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// nonBlocking
|
// nonBlocking && is_contiguous == true (already checked)
|
||||||
|
|
||||||
if (!is_contiguous<Type>::value)
|
const label startOfRequests = Pstream::nRequests();
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "nonBlocking not supported for non-contiguous data"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
label startOfRequests = Pstream::nRequests();
|
|
||||||
|
|
||||||
// Set up write
|
// Set up write
|
||||||
OPstream::write
|
OPstream::write
|
||||||
@ -182,6 +180,64 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Addr>
|
||||||
|
void Foam::globalIndex::gather
|
||||||
|
(
|
||||||
|
const labelUList& off,
|
||||||
|
const label comm,
|
||||||
|
const UList<int>& procIDs,
|
||||||
|
const IndirectListBase<Type, Addr>& fld,
|
||||||
|
List<Type>& allFld,
|
||||||
|
const int tag,
|
||||||
|
const Pstream::commsTypes commsType
|
||||||
|
)
|
||||||
|
{
|
||||||
|
if (commsType == Pstream::commsTypes::nonBlocking)
|
||||||
|
{
|
||||||
|
WarningInFunction
|
||||||
|
<< "Cannot use nonBlocking with indirect list of data"
|
||||||
|
<< exit(FatalError);
|
||||||
|
// Could also warn and change to scheduled etc...
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Pstream::myProcNo(comm) == procIDs[0])
|
||||||
|
{
|
||||||
|
allFld.resize(off.last());
|
||||||
|
|
||||||
|
// Assign my local data
|
||||||
|
SubList<Type>(allFld, fld.size(), 0) = fld;
|
||||||
|
|
||||||
|
// Already verified commsType != nonBlocking
|
||||||
|
for (label i = 1; i < procIDs.size(); ++i)
|
||||||
|
{
|
||||||
|
SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
|
||||||
|
|
||||||
|
IPstream fromProc
|
||||||
|
(
|
||||||
|
commsType,
|
||||||
|
procIDs[i],
|
||||||
|
0,
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
fromProc >> procSlot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OPstream toMaster
|
||||||
|
(
|
||||||
|
commsType,
|
||||||
|
procIDs[0],
|
||||||
|
0,
|
||||||
|
tag,
|
||||||
|
comm
|
||||||
|
);
|
||||||
|
toMaster << fld;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::globalIndex::gather
|
void Foam::globalIndex::gather
|
||||||
(
|
(
|
||||||
@ -203,6 +259,28 @@ void Foam::globalIndex::gather
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template<class Type, class Addr>
|
||||||
|
void Foam::globalIndex::gather
|
||||||
|
(
|
||||||
|
const IndirectListBase<Type, Addr>& fld,
|
||||||
|
List<Type>& allFld,
|
||||||
|
const int tag,
|
||||||
|
const Pstream::commsTypes commsType
|
||||||
|
) const
|
||||||
|
{
|
||||||
|
gather
|
||||||
|
(
|
||||||
|
offsets_,
|
||||||
|
UPstream::worldComm,
|
||||||
|
UPstream::procID(UPstream::worldComm),
|
||||||
|
fld,
|
||||||
|
allFld,
|
||||||
|
tag,
|
||||||
|
commsType
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<class Type>
|
template<class Type>
|
||||||
void Foam::globalIndex::gatherOp
|
void Foam::globalIndex::gatherOp
|
||||||
(
|
(
|
||||||
@ -293,6 +371,18 @@ void Foam::globalIndex::scatter
|
|||||||
const Pstream::commsTypes commsType
|
const Pstream::commsTypes commsType
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!is_contiguous<Type>::value
|
||||||
|
&& commsType == Pstream::commsTypes::nonBlocking
|
||||||
|
)
|
||||||
|
{
|
||||||
|
FatalErrorInFunction
|
||||||
|
<< "Cannot use nonBlocking with non-contiguous data"
|
||||||
|
<< exit(FatalError);
|
||||||
|
// Could also warn and change to scheduled etc...
|
||||||
|
}
|
||||||
|
|
||||||
if (Pstream::myProcNo(comm) == procIDs[0])
|
if (Pstream::myProcNo(comm) == procIDs[0])
|
||||||
{
|
{
|
||||||
fld.deepCopy(SubList<Type>(allFld, off[1]-off[0]));
|
fld.deepCopy(SubList<Type>(allFld, off[1]-off[0]));
|
||||||
@ -305,12 +395,7 @@ void Foam::globalIndex::scatter
|
|||||||
{
|
{
|
||||||
for (label i = 1; i < procIDs.size(); ++i)
|
for (label i = 1; i < procIDs.size(); ++i)
|
||||||
{
|
{
|
||||||
const SubList<Type> procSlot
|
const SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
|
||||||
(
|
|
||||||
allFld,
|
|
||||||
off[i+1]-off[i],
|
|
||||||
off[i]
|
|
||||||
);
|
|
||||||
|
|
||||||
if (is_contiguous<Type>::value)
|
if (is_contiguous<Type>::value)
|
||||||
{
|
{
|
||||||
@ -326,7 +411,7 @@ void Foam::globalIndex::scatter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OPstream toSlave
|
OPstream toProc
|
||||||
(
|
(
|
||||||
commsType,
|
commsType,
|
||||||
procIDs[i],
|
procIDs[i],
|
||||||
@ -334,32 +419,20 @@ void Foam::globalIndex::scatter
|
|||||||
tag,
|
tag,
|
||||||
comm
|
comm
|
||||||
);
|
);
|
||||||
toSlave << procSlot;
|
toProc << procSlot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// nonBlocking
|
// nonBlocking && is_contiguous == true (already checked)
|
||||||
|
|
||||||
if (!is_contiguous<Type>::value)
|
const label startOfRequests = Pstream::nRequests();
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "nonBlocking not supported for non-contiguous data"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
label startOfRequests = Pstream::nRequests();
|
|
||||||
|
|
||||||
// Set up writes
|
// Set up writes
|
||||||
for (label i = 1; i < procIDs.size(); ++i)
|
for (label i = 1; i < procIDs.size(); ++i)
|
||||||
{
|
{
|
||||||
const SubList<Type> procSlot
|
const SubList<Type> procSlot(allFld, off[i+1]-off[i], off[i]);
|
||||||
(
|
|
||||||
allFld,
|
|
||||||
off[i+1]-off[i],
|
|
||||||
off[i]
|
|
||||||
);
|
|
||||||
|
|
||||||
OPstream::write
|
OPstream::write
|
||||||
(
|
(
|
||||||
@ -411,16 +484,9 @@ void Foam::globalIndex::scatter
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// nonBlocking
|
// nonBlocking && is_contiguous == true (already checked)
|
||||||
|
|
||||||
if (!is_contiguous<Type>::value)
|
const label startOfRequests = Pstream::nRequests();
|
||||||
{
|
|
||||||
FatalErrorInFunction
|
|
||||||
<< "nonBlocking not supported for non-contiguous data"
|
|
||||||
<< exit(FatalError);
|
|
||||||
}
|
|
||||||
|
|
||||||
label startOfRequests = Pstream::nRequests();
|
|
||||||
|
|
||||||
// Set up read
|
// Set up read
|
||||||
IPstream::read
|
IPstream::read
|
||||||
@ -472,7 +538,7 @@ void Foam::globalIndex::get
|
|||||||
const int tag
|
const int tag
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
allFld.setSize(globalIds.size());
|
allFld.resize(globalIds.size());
|
||||||
if (globalIds.size())
|
if (globalIds.size())
|
||||||
{
|
{
|
||||||
// Sort according to processor
|
// Sort according to processor
|
||||||
|
|||||||
Reference in New Issue
Block a user