Clean up distribution

This commit is contained in:
Alejandro Gallo 2021-11-08 15:58:19 +01:00
parent 9ae055cb40
commit 1d76fff16b

168
atrip.org
View File

@ -1778,14 +1778,24 @@ specialDistribution(Info info, std::vector<ABCTuple> const& allTuples) {
std::map<size_t, std::vector<ABCTuple> > container3d; std::map<size_t, std::vector<ABCTuple> > container3d;
// build container-n-d's // build container-n-d's
for (auto t: allTuples) { for (auto const& t: allTuples) {
// one which node(s) are the tuple elements located... // one which node(s) are the tuple elements located...
// put them into the right container // put them into the right container
auto nt = getTupleNodes(t, nNodes); auto _nodes = getTupleNodes(t, nNodes);
if ( nt.size() == 1) container1d[nt[0]].push_back(t); switch (_nodes.size()) {
if ( nt.size() == 2) container2d[nt[0] + nNodes*nt[1]].push_back(t); case 1:
if ( nt.size() == 3) container1d[_nodes[0]].push_back(t);
container3d[nt[0] + nNodes*nt[1] + nNodes*nNodes*nt[2]].push_back(t); case 2:
container2d[ _nodes[0]
+ nNodes * _nodes[1]
].push_back(t);
case 3:
container3d[ _nodes[0]
+ nNodes * _nodes[1]
+ nNodes * nNodes * _nodes[2]
].push_back(t);
}
} }
if (info.nodeId == 0) if (info.nodeId == 0)
@ -1793,9 +1803,9 @@ specialDistribution(Info info, std::vector<ABCTuple> const& allTuples) {
// DISTRIBUTE 1-d containers // DISTRIBUTE 1-d containers
// every tuple which is only located at one node belongs to this node // every tuple which is only located at one node belongs to this node
{ {
auto const& tuplesVec = container1d[info.nodeId]; auto const& _tuplesVec = container1d[info.nodeId];
nodeTuples.resize(tuplesVec.size()); nodeTuples.resize(_tuplesVec.size());
std::copy(tuplesVec.begin(), tuplesVec.end(), nodeTuples.begin()); std::copy(_tuplesVec.begin(), _tuplesVec.end(), nodeTuples.begin());
} }
if (info.nodeId == 0) if (info.nodeId == 0)
@ -1803,87 +1813,105 @@ specialDistribution(Info info, std::vector<ABCTuple> const& allTuples) {
// DISTRIBUTE 2-d containers // DISTRIBUTE 2-d containers
//the tuples which are located at two nodes are half/half given to these nodes //the tuples which are located at two nodes are half/half given to these nodes
for (auto &m: container2d) { for (auto &m: container2d) {
size_t idx = m.first%nNodes;
size_t idy = m.first/nNodes;
size_t myNode = idx;
// either idx or idy is my node auto const& _tuplesVec = m.second;
if (idx != info.nodeId && idy != info.nodeId) continue; const
if (idy == info.nodeId) myNode = idy; size_t idx = m.first % nNodes
// remeber: m.first = idy * nNodes + idx
, idy = m.first / nNodes
, n_half = _tuplesVec.size() / 2
, size = nodeTuples.size()
;
auto tuplesVec = m.second; size_t nextra, nbegin, nend;
auto n = tuplesVec.size() / 2; if (info.nodeId == idx) {
auto size = nodeTuples.size(); nextra = n_half;
if (myNode == idx) { nbegin = 0 * n_half;
nodeTuples.resize(size + n); nend = n_half;
std::copy(tuplesVec.begin(), } else if (info.nodeId == idy) {
tuplesVec.begin() + n, nextra = _tuplesVec.size() - n_half;
nodeTuples.begin() + size); nbegin = 1 * n_half;
nend = _tuplesVec.size();
} else { } else {
auto ny = tuplesVec.size() - n; // either idx or idy is my node
nodeTuples.resize(size + ny); continue;
std::copy(tuplesVec.begin() + n,
tuplesVec.end(),
nodeTuples.begin() + size);
} }
nodeTuples.resize(size + nextra);
std::copy(_tuplesVec.begin() + nbegin,
_tuplesVec.begin() + nend,
nodeTuples.begin() + size);
} }
if (info.nodeId == 0) if (info.nodeId == 0)
std::cout << "\tBuilding 3-d containers\n"; std::cout << "\tBuilding 3-d containers\n";
// DISTRIBUTE 3-d containers // DISTRIBUTE 3-d containers
// similar game for the tuples which belong to three different nodes for (auto const& m: container3d){
for (auto m: container3d){ auto const& _tuplesVec = m.second;
auto tuplesVec = m.second;
auto idx = m.first%nNodes;
auto idy = (m.first/nNodes)%nNodes;
auto idz = m.first/nNodes/nNodes;
if (idx != info.nodeId && idy != info.nodeId && idz != info.nodeId) continue;
size_t nx = tuplesVec.size() / 3; const
size_t n, nbegin, nend; size_t idx = m.first % nNodes
, idy = (m.first / nNodes) % nNodes
// remember: m.first = idx + idy * nNodes + idz * nNodes^2
, idz = m.first / nNodes / nNodes
, n_third = _tuplesVec.size() / 3
, size = nodeTuples.size()
;
size_t nextra, nbegin, nend;
if (info.nodeId == idx) { if (info.nodeId == idx) {
n = nx; nextra = n_third;
nbegin = 0; nbegin = 0 * n_third;
nend = n; nend = nextra;
} else if (info.nodeId == idy) { } else if (info.nodeId == idy) {
n = nx; nextra = n_third;
nbegin = n; nbegin = 1 * n_third;
nend = n + n; nend = 2 * nextra;
} else if (info.nodeId == idz) {
nextra = _tuplesVec.size() - 2 * n_third;
nbegin = 2 * n_third;
nend = _tuplesVec.size();
} else { } else {
n = tuplesVec.size() - 2 * nx; // either idx or idy or idz is my node
nbegin = 2 * nx; continue;
nend = 2 * nx + n;
} }
auto size = nodeTuples.size(); nodeTuples.resize(size + nextra);
nodeTuples.resize(size + n); std::copy(_tuplesVec.begin() + nbegin,
std::copy(tuplesVec.begin() + nbegin, _tuplesVec.begin() + nend,
tuplesVec.begin() + nend,
nodeTuples.begin() + size); nodeTuples.begin() + size);
} }
if (info.nodeId == 0) if (info.nodeId == 0) std::cout << "\tswapping tuples...\n";
std::cout << "\tsorting...\n"; /*
// sort part of group-and-sort algorithm * sort part of group-and-sort algorithm
// every tuple on a given node is sorted in a way that * every tuple on a given node is sorted in a way that
// the 'home elements' are the fastest index. * the 'home elements' are the fastest index.
// 1:yyy 2:yyn(x) 3:yny(x) 4:ynn(x) 5:nyy 6:nyn(x) 7:nny 8:nnn * 1:yyy 2:yyn(x) 3:yny(x) 4:ynn(x) 5:nyy 6:nyn(x) 7:nny 8:nnn
size_t n = info.nodeId; */
size_t myNode = info.nodeId;
for (auto &nt: nodeTuples){ for (auto &nt: nodeTuples){
if ( isOnNode(nt[0], nNodes) == n ){ // 1234 if ( isOnNode(nt[0], nNodes) == myNode ){ // 1234
if ( isOnNode(nt[2], nNodes) != n ){ // 24 if ( isOnNode(nt[2], nNodes) != myNode ){ // 24
size_t x(nt[0]); nt[0] = nt[2]; nt[2] = x; // switch first and last size_t const x(nt[0]);
nt[0] = nt[2]; // switch first and last
nt[2] = x;
} }
else if ( isOnNode(nt[1], nNodes) != n){ // 3 else if ( isOnNode(nt[1], nNodes) != myNode){ // 3
size_t x(nt[0]); nt[0] = nt[1]; nt[1] = x; // switch first two size_t const x(nt[0]);
nt[0] = nt[1]; // switch first two
nt[1] = x;
} }
} else { } else {
if ( isOnNode(nt[1], nNodes) == n // 56 if ( isOnNode(nt[1], nNodes) == myNode // 56
&& isOnNode(nt[2], nNodes) != n){ // 6 && isOnNode(nt[2], nNodes) != myNode
size_t x(nt[1]); nt[1] = nt[2]; nt[2] = x; // switch last two ) { // 6
size_t const x(nt[1]);
nt[1] = nt[2]; // switch last two
nt[2] = x;
} }
} }
} }
@ -1968,11 +1996,11 @@ std::vector<ABCTuple> main(MPI_Comm universe, size_t Nv) {
std::vector<ABCTuple> std::vector<ABCTuple>
nodeTuples = makeDistribution nodeTuples = makeDistribution
? specialDistribution(Info{ nNodes ? specialDistribution(Info { nNodes
, Nv , Nv
, np , np
, nodeInfos[rank].nodeId , nodeInfos[rank].nodeId
}, },
getAllTuplesList(Nv)) getAllTuplesList(Nv))
: std::vector<ABCTuple>() : std::vector<ABCTuple>()
; ;