mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
Merge branch 'feature-alltoall' into 'develop'
Feature alltoall Added the on-the-fly creation of communication schedule See merge request !40
This commit is contained in:
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
\\/ M anipulation | Copyright (C) 2015-2016 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -95,157 +95,6 @@ void Foam::UPstream::setParRun(const label nProcs)
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::calcLinearComm
|
||||
(
|
||||
const label nProcs
|
||||
)
|
||||
{
|
||||
List<commsStruct> linearCommunication(nProcs);
|
||||
|
||||
// Master
|
||||
labelList belowIDs(nProcs - 1);
|
||||
forAll(belowIDs, i)
|
||||
{
|
||||
belowIDs[i] = i + 1;
|
||||
}
|
||||
|
||||
linearCommunication[0] = commsStruct
|
||||
(
|
||||
nProcs,
|
||||
0,
|
||||
-1,
|
||||
belowIDs,
|
||||
labelList(0)
|
||||
);
|
||||
|
||||
// Slaves. Have no below processors, only communicate up to master
|
||||
for (label procID = 1; procID < nProcs; procID++)
|
||||
{
|
||||
linearCommunication[procID] = commsStruct
|
||||
(
|
||||
nProcs,
|
||||
procID,
|
||||
0,
|
||||
labelList(0),
|
||||
labelList(0)
|
||||
);
|
||||
}
|
||||
return linearCommunication;
|
||||
}
|
||||
|
||||
|
||||
void Foam::UPstream::collectReceives
|
||||
(
|
||||
const label procID,
|
||||
const List<DynamicList<label>>& receives,
|
||||
DynamicList<label>& allReceives
|
||||
)
|
||||
{
|
||||
// Append my children (and my children children etc.) to allReceives.
|
||||
|
||||
const DynamicList<label>& myChildren = receives[procID];
|
||||
|
||||
forAll(myChildren, childI)
|
||||
{
|
||||
allReceives.append(myChildren[childI]);
|
||||
collectReceives(myChildren[childI], receives, allReceives);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::List<Foam::UPstream::commsStruct> Foam::UPstream::calcTreeComm
|
||||
(
|
||||
label nProcs
|
||||
)
|
||||
{
|
||||
// Tree like schedule. For 8 procs:
|
||||
// (level 0)
|
||||
// 0 receives from 1
|
||||
// 2 receives from 3
|
||||
// 4 receives from 5
|
||||
// 6 receives from 7
|
||||
// (level 1)
|
||||
// 0 receives from 2
|
||||
// 4 receives from 6
|
||||
// (level 2)
|
||||
// 0 receives from 4
|
||||
//
|
||||
// The sends/receives for all levels are collected per processor
|
||||
// (one send per processor; multiple receives possible) creating a table:
|
||||
//
|
||||
// So per processor:
|
||||
// proc receives from sends to
|
||||
// ---- ------------- --------
|
||||
// 0 1,2,4 -
|
||||
// 1 - 0
|
||||
// 2 3 0
|
||||
// 3 - 2
|
||||
// 4 5 0
|
||||
// 5 - 4
|
||||
// 6 7 4
|
||||
// 7 - 6
|
||||
|
||||
label nLevels = 1;
|
||||
while ((1 << nLevels) < nProcs)
|
||||
{
|
||||
nLevels++;
|
||||
}
|
||||
|
||||
List<DynamicList<label>> receives(nProcs);
|
||||
labelList sends(nProcs, -1);
|
||||
|
||||
// Info<< "Using " << nLevels << " communication levels" << endl;
|
||||
|
||||
label offset = 2;
|
||||
label childOffset = offset/2;
|
||||
|
||||
for (label level = 0; level < nLevels; level++)
|
||||
{
|
||||
label receiveID = 0;
|
||||
while (receiveID < nProcs)
|
||||
{
|
||||
// Determine processor that sends and we receive from
|
||||
label sendID = receiveID + childOffset;
|
||||
|
||||
if (sendID < nProcs)
|
||||
{
|
||||
receives[receiveID].append(sendID);
|
||||
sends[sendID] = receiveID;
|
||||
}
|
||||
|
||||
receiveID += offset;
|
||||
}
|
||||
|
||||
offset <<= 1;
|
||||
childOffset <<= 1;
|
||||
}
|
||||
|
||||
// For all processors find the processors it receives data from
|
||||
// (and the processors they receive data from etc.)
|
||||
List<DynamicList<label>> allReceives(nProcs);
|
||||
for (label procID = 0; procID < nProcs; procID++)
|
||||
{
|
||||
collectReceives(procID, receives, allReceives[procID]);
|
||||
}
|
||||
|
||||
|
||||
List<commsStruct> treeCommunication(nProcs);
|
||||
|
||||
for (label procID = 0; procID < nProcs; procID++)
|
||||
{
|
||||
treeCommunication[procID] = commsStruct
|
||||
(
|
||||
nProcs,
|
||||
procID,
|
||||
sends[procID],
|
||||
receives[procID].shrink(),
|
||||
allReceives[procID].shrink()
|
||||
);
|
||||
}
|
||||
return treeCommunication;
|
||||
}
|
||||
|
||||
|
||||
Foam::label Foam::UPstream::allocateCommunicator
|
||||
(
|
||||
const label parentIndex,
|
||||
@ -299,9 +148,9 @@ Foam::label Foam::UPstream::allocateCommunicator
|
||||
}
|
||||
parentCommunicator_[index] = parentIndex;
|
||||
|
||||
linearCommunication_[index] = calcLinearComm(procIDs_[index].size());
|
||||
treeCommunication_[index] = calcTreeComm(procIDs_[index].size());
|
||||
|
||||
// Size but do not fill structure - this is done on-the-fly
|
||||
linearCommunication_[index] = List<commsStruct>(procIDs_[index].size());
|
||||
treeCommunication_[index] = List<commsStruct>(procIDs_[index].size());
|
||||
|
||||
if (doPstream && parRun())
|
||||
{
|
||||
@ -397,6 +246,115 @@ Foam::label Foam::UPstream::procNo
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
Foam::UPstream::commsStruct&
|
||||
Foam::UList<Foam::UPstream::commsStruct>::operator[](const label procID)
|
||||
{
|
||||
UPstream::commsStruct& t = v_[procID];
|
||||
|
||||
if (t.allBelow().size() + t.allNotBelow().size() + 1 != size())
|
||||
{
|
||||
// Not yet allocated
|
||||
|
||||
label above(-1);
|
||||
labelList below(0);
|
||||
labelList allBelow(0);
|
||||
|
||||
if (size() < UPstream::nProcsSimpleSum)
|
||||
{
|
||||
// Linear schedule
|
||||
|
||||
if (procID == 0)
|
||||
{
|
||||
below.setSize(size()-1);
|
||||
for (label procI = 1; procI < size(); procI++)
|
||||
{
|
||||
below[procI-1] = procI;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
above = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use tree like schedule. For 8 procs:
|
||||
// (level 0)
|
||||
// 0 receives from 1
|
||||
// 2 receives from 3
|
||||
// 4 receives from 5
|
||||
// 6 receives from 7
|
||||
// (level 1)
|
||||
// 0 receives from 2
|
||||
// 4 receives from 6
|
||||
// (level 2)
|
||||
// 0 receives from 4
|
||||
//
|
||||
// The sends/receives for all levels are collected per processor
|
||||
// (one send per processor; multiple receives possible) creating
|
||||
// a table:
|
||||
//
|
||||
// So per processor:
|
||||
// proc receives from sends to
|
||||
// ---- ------------- --------
|
||||
// 0 1,2,4 -
|
||||
// 1 - 0
|
||||
// 2 3 0
|
||||
// 3 - 2
|
||||
// 4 5 0
|
||||
// 5 - 4
|
||||
// 6 7 4
|
||||
// 7 - 6
|
||||
|
||||
label mod = 0;
|
||||
|
||||
for (label step = 1; step < size(); step = mod)
|
||||
{
|
||||
mod = step * 2;
|
||||
|
||||
if (procID % mod)
|
||||
{
|
||||
above = procID - (procID % mod);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
for
|
||||
(
|
||||
label j = procID + step;
|
||||
j < size() && j < procID + mod;
|
||||
j += step
|
||||
)
|
||||
{
|
||||
below.append(j);
|
||||
}
|
||||
for
|
||||
(
|
||||
label j = procID + step;
|
||||
j < size() && j < procID + mod;
|
||||
j++
|
||||
)
|
||||
{
|
||||
allBelow.append(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
t = UPstream::commsStruct(size(), procID, above, below, allBelow);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
template<>
|
||||
const Foam::UPstream::commsStruct&
|
||||
Foam::UList<Foam::UPstream::commsStruct>::operator[](const label procID) const
|
||||
{
|
||||
return const_cast<UList<UPstream::commsStruct>& >(*this).operator[](procID);
|
||||
}
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
bool Foam::UPstream::parRun_(false);
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation |
|
||||
\\/ M anipulation | Copyright 2015-2016 OpenCFD Ltd.
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -504,6 +504,14 @@ public:
|
||||
|
||||
Ostream& operator<<(Ostream&, const UPstream::commsStruct&);
|
||||
|
||||
// Template specialisation for access of commsStruct
|
||||
template<>
|
||||
UPstream::commsStruct&
|
||||
UList<UPstream::commsStruct>::operator[](const label);
|
||||
template<>
|
||||
const UPstream::commsStruct&
|
||||
UList<UPstream::commsStruct>::operator[](const label) const;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
|
||||
\\ / O peration |
|
||||
\\ / A nd | Copyright (C) 2011-2016 OpenFOAM Foundation
|
||||
\\/ M anipulation | Copyright (C) 2015 OpenCFD Ltd.
|
||||
\\/ M anipulation |
|
||||
-------------------------------------------------------------------------------
|
||||
License
|
||||
This file is part of OpenFOAM.
|
||||
@ -61,8 +61,6 @@ void Foam::Pstream::exchange
|
||||
|
||||
recvBufs.setSize(sendBufs.size());
|
||||
|
||||
recvBufs.setSize(sendBufs.size());
|
||||
|
||||
if (UPstream::parRun() && UPstream::nProcs(comm) > 1)
|
||||
{
|
||||
label startOfRequests = Pstream::nRequests();
|
||||
|
||||
Reference in New Issue
Block a user