#include "IndexRearrangementForStreams.h" #include "Communication/Communicator.h" #include "Parameter/Parameter.h" #include <GridGenerator/grid/Grid.h> #include <GridGenerator/grid/GridBuilder/GridBuilder.h> #include <algorithm> #include <iostream> IndexRearrangementForStreams::IndexRearrangementForStreams(std::shared_ptr<Parameter> para, std::shared_ptr<GridBuilder> builder, vf::gpu::CommunicationRoutine &communicator) : para(para), builder(builder), communicator(communicator) { } void IndexRearrangementForStreams::initCommunicationArraysForCommAfterFinetoCoarseX(uint level, int indexOfProcessNeighbor, int direction) const { std::cout << "communication: reorder send indices X "; std::vector<uint> sendIndicesForCommAfterFtoCPositions = initSendIndicesForCommAfterFToCX(level, indexOfProcessNeighbor, direction); std::cout << "mpi send and receive "; std::vector<uint> recvIndicesForCommAfterFtoCPositions = exchangeIndicesForCommAfterFtoCX( level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions); std::cout << "reorder receive indices "; initRecvIndicesForCommAfterFToCX(level, indexOfProcessNeighbor, direction, recvIndicesForCommAfterFtoCPositions); copyProcessNeighborToCommAfterFtoCX(level, indexOfProcessNeighbor); std::cout << "done." << std::endl; } void IndexRearrangementForStreams::initCommunicationArraysForCommAfterFinetoCoarseY(uint level, int indexOfProcessNeighbor, int direction) const { std::cout << "communication: reorder send indices Y "; std::vector<uint> sendIndicesForCommAfterFtoCPositions = initSendIndicesForCommAfterFToCY(level, indexOfProcessNeighbor, direction); std::cout << "mpi send and receive "; std::vector<uint> recvIndicesForCommAfterFtoCPositions = exchangeIndicesForCommAfterFtoCY( level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions); std::cout << "reorder receive indices "; initRecvIndicesForCommAfterFToCY(level, indexOfProcessNeighbor, direction, recvIndicesForCommAfterFtoCPositions); copyProcessNeighborToCommAfterFtoCY(level, indexOfProcessNeighbor); std::cout << "done." << std::endl; } void IndexRearrangementForStreams::initCommunicationArraysForCommAfterFinetoCoarseZ(uint level, int indexOfProcessNeighbor, int direction) const { std::cout << "communication: reorder send indices Z "; std::vector<uint> sendIndicesForCommAfterFtoCPositions = initSendIndicesForCommAfterFToCZ(level, indexOfProcessNeighbor, direction); std::cout << "mpi send and receive "; std::vector<uint> recvIndicesForCommAfterFtoCPositions = exchangeIndicesForCommAfterFtoCZ( level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions); std::cout << "reorder receive indices "; initRecvIndicesForCommAfterFToCZ(level, indexOfProcessNeighbor, direction, recvIndicesForCommAfterFtoCPositions); copyProcessNeighborToCommAfterFtoCZ(level, indexOfProcessNeighbor); std::cout << "done." << std::endl; } std::vector<uint> IndexRearrangementForStreams::initSendIndicesForCommAfterFToCX(uint level, int indexOfProcessNeighbor, int direction) const { para->initProcessNeighborsAfterFtoCX(level); std::vector<uint> sendIndicesForCommAfterFtoCPositions; reorderSendIndicesForCommAfterFtoCX(direction, level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions); para->setSendProcessNeighborsAfterFtoCX( para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes, level, indexOfProcessNeighbor); return sendIndicesForCommAfterFtoCPositions; } std::vector<uint> IndexRearrangementForStreams::initSendIndicesForCommAfterFToCY(uint level, int indexOfProcessNeighbor, int direction) const { para->initProcessNeighborsAfterFtoCY(level); std::vector<uint> sendIndicesForCommAfterFtoCPositions; reorderSendIndicesForCommAfterFtoCY(direction, level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions); para->setSendProcessNeighborsAfterFtoCY( para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes, level, indexOfProcessNeighbor); return sendIndicesForCommAfterFtoCPositions; } std::vector<uint> IndexRearrangementForStreams::initSendIndicesForCommAfterFToCZ(uint level, int indexOfProcessNeighbor, int direction) const { para->initProcessNeighborsAfterFtoCZ(level); std::vector<uint> sendIndicesForCommAfterFtoCPositions; reorderSendIndicesForCommAfterFtoCZ(direction, level, indexOfProcessNeighbor, sendIndicesForCommAfterFtoCPositions); para->setSendProcessNeighborsAfterFtoCZ( para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes, level, indexOfProcessNeighbor); return sendIndicesForCommAfterFtoCPositions; } std::vector<uint> IndexRearrangementForStreams::exchangeIndicesForCommAfterFtoCX( uint level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { // fill the receive vector with zeros as placeholders (0 is never a valid fluid node) // give vector an arbitrary size (larger than needed) // TODO: Find a better way std::vector<uint> recvIndicesForCommAfterFtoCPositions( (size_t)para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes * 2, 0); communicator.receive_send( recvIndicesForCommAfterFtoCPositions.data(), (int)recvIndicesForCommAfterFtoCPositions.size(), para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].rankNeighbor, sendIndicesForCommAfterFtoCPositions.data(), (int)sendIndicesForCommAfterFtoCPositions.size(), para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].rankNeighbor); // resize receiving vector to correct size (remove all zeros) auto it = std::find(recvIndicesForCommAfterFtoCPositions.begin(), recvIndicesForCommAfterFtoCPositions.end(), 0); recvIndicesForCommAfterFtoCPositions.erase(it, recvIndicesForCommAfterFtoCPositions.end()); return recvIndicesForCommAfterFtoCPositions; } std::vector<uint> IndexRearrangementForStreams::exchangeIndicesForCommAfterFtoCY( uint level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { // fill the receive vector with zeros as placeholders (0 is never a valid fluid node) // give vector an arbitrary size (larger than needed) // TODO: Find a better way std::vector<uint> recvIndicesForCommAfterFtoCPositions( (size_t)para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes * 2, 0); communicator.receive_send( recvIndicesForCommAfterFtoCPositions.data(), (int)recvIndicesForCommAfterFtoCPositions.size(), para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].rankNeighbor, sendIndicesForCommAfterFtoCPositions.data(), (int)sendIndicesForCommAfterFtoCPositions.size(), para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].rankNeighbor); // resize receiving vector to correct size (remove all zeros) auto it = std::find(recvIndicesForCommAfterFtoCPositions.begin(), recvIndicesForCommAfterFtoCPositions.end(), 0); recvIndicesForCommAfterFtoCPositions.erase(it, recvIndicesForCommAfterFtoCPositions.end()); return recvIndicesForCommAfterFtoCPositions; } std::vector<uint> IndexRearrangementForStreams::exchangeIndicesForCommAfterFtoCZ( uint level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { // fill the receive vector with zeros as placeholders (0 is never a valid fluid node) // give vector an arbitrary size (larger than needed) // TODO: Find a better way std::vector<uint> recvIndicesForCommAfterFtoCPositions( (size_t)para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes * 2, 0); communicator.receive_send( recvIndicesForCommAfterFtoCPositions.data(), (int)recvIndicesForCommAfterFtoCPositions.size(), para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor, sendIndicesForCommAfterFtoCPositions.data(), (int)sendIndicesForCommAfterFtoCPositions.size(), para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor); // resize receiving vector to correct size (remove all zeros) auto it = std::find(recvIndicesForCommAfterFtoCPositions.begin(), recvIndicesForCommAfterFtoCPositions.end(), 0); recvIndicesForCommAfterFtoCPositions.erase(it, recvIndicesForCommAfterFtoCPositions.end()); return recvIndicesForCommAfterFtoCPositions; } void IndexRearrangementForStreams::initRecvIndicesForCommAfterFToCX( uint level, int indexOfProcessNeighbor, int direction, std::vector<uint> &recvIndicesForCommAfterFtoCPositions) const { reorderRecvIndicesForCommAfterFtoCX(direction, level, indexOfProcessNeighbor, recvIndicesForCommAfterFtoCPositions); para->setRecvProcessNeighborsAfterFtoCX( para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes, level, indexOfProcessNeighbor); } void IndexRearrangementForStreams::initRecvIndicesForCommAfterFToCY( uint level, int indexOfProcessNeighbor, int direction, std::vector<uint> &recvIndicesForCommAfterFtoCPositions) const { reorderRecvIndicesForCommAfterFtoCY(direction, level, indexOfProcessNeighbor, recvIndicesForCommAfterFtoCPositions); para->setRecvProcessNeighborsAfterFtoCY( para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes, level, indexOfProcessNeighbor); } void IndexRearrangementForStreams::initRecvIndicesForCommAfterFToCZ( uint level, int indexOfProcessNeighbor, int direction, std::vector<uint> &recvIndicesForCommAfterFtoCPositions) const { reorderRecvIndicesForCommAfterFtoCZ(direction, level, indexOfProcessNeighbor, recvIndicesForCommAfterFtoCPositions); para->setRecvProcessNeighborsAfterFtoCZ( para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes, level, indexOfProcessNeighbor); } void IndexRearrangementForStreams::copyProcessNeighborToCommAfterFtoCX(uint level, int indexOfProcessNeighbor) const { // init f[0]* para->getParD(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] = para->getParD(level)->sendProcessNeighborX[indexOfProcessNeighbor].f[0]; para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] = para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].f[0]; para->getParD(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] = para->getParD(level)->recvProcessNeighborX[indexOfProcessNeighbor].f[0]; para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].f[0] = para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].f[0]; // init index* para->getParD(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index = para->getParD(level)->sendProcessNeighborX[indexOfProcessNeighbor].index; para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index = para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].index; para->getParD(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index = para->getParD(level)->recvProcessNeighborX[indexOfProcessNeighbor].index; para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].index = para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].index; // rank neighbor para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].rankNeighbor = para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].rankNeighbor; para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].rankNeighbor = para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].rankNeighbor; } void IndexRearrangementForStreams::copyProcessNeighborToCommAfterFtoCY(uint level, int indexOfProcessNeighbor) const { // init f[0]* para->getParD(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] = para->getParD(level)->sendProcessNeighborY[indexOfProcessNeighbor].f[0]; para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] = para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].f[0]; para->getParD(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] = para->getParD(level)->recvProcessNeighborY[indexOfProcessNeighbor].f[0]; para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].f[0] = para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].f[0]; // init index* para->getParD(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index = para->getParD(level)->sendProcessNeighborY[indexOfProcessNeighbor].index; para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index = para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].index; para->getParD(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index = para->getParD(level)->recvProcessNeighborY[indexOfProcessNeighbor].index; para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].index = para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].index; // rank neighbor para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].rankNeighbor = para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].rankNeighbor; para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].rankNeighbor = para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].rankNeighbor; } void IndexRearrangementForStreams::copyProcessNeighborToCommAfterFtoCZ(uint level, int indexOfProcessNeighbor) const { // init f[0]* para->getParD(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] = para->getParD(level)->sendProcessNeighborZ[indexOfProcessNeighbor].f[0]; para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] = para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].f[0]; para->getParD(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] = para->getParD(level)->recvProcessNeighborZ[indexOfProcessNeighbor].f[0]; para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].f[0] = para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].f[0]; // init index* para->getParD(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index = para->getParD(level)->sendProcessNeighborZ[indexOfProcessNeighbor].index; para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index = para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].index; para->getParD(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index = para->getParD(level)->recvProcessNeighborZ[indexOfProcessNeighbor].index; para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].index = para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].index; // rank neighbor para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].rankNeighbor = para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor; para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].rankNeighbor = para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].rankNeighbor; } void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoCX( int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int *sendIndices = para->getParH(level)->sendProcessNeighborX[indexOfProcessNeighbor].index; int &numberOfSendNodesAfterFtoC = para->getParH(level)->sendProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes; reorderSendIndicesForCommAfterFtoC(sendIndices, numberOfSendNodesAfterFtoC, direction, level, sendIndicesForCommAfterFtoCPositions); } void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoCY( int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int *sendIndices = para->getParH(level)->sendProcessNeighborY[indexOfProcessNeighbor].index; int &numberOfSendNodesAfterFtoC = para->getParH(level)->sendProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes; reorderSendIndicesForCommAfterFtoC(sendIndices, numberOfSendNodesAfterFtoC, direction, level, sendIndicesForCommAfterFtoCPositions); } void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoCZ( int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int *sendIndices = para->getParH(level)->sendProcessNeighborZ[indexOfProcessNeighbor].index; int &numberOfSendNodesAfterFtoC = para->getParH(level)->sendProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes; reorderSendIndicesForCommAfterFtoC(sendIndices, numberOfSendNodesAfterFtoC, direction, level, sendIndicesForCommAfterFtoCPositions); } void IndexRearrangementForStreams::reorderSendIndicesForCommAfterFtoC( int *sendIndices, int &numberOfSendNodesAfterFtoC, int direction, int level, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { *logging::out << logging::Logger::INFO_INTERMEDIATE << "reorder send indices for communication after fine to coarse: level: " << level << " direction: " << direction; if (para->getParH(level)->intCF.kCF == 0 || para->getParH(level)->intFC.kFC == 0) *logging::out << logging::Logger::LOGGER_ERROR << "reorderSendIndicesForCommAfterFtoC(): para->getParH(level)->intCF needs to be initialized before calling " "this function " << "\n"; int sparseIndexSend; std::vector<int> sendIndicesAfterFtoC; std::vector<int> sendIndicesOther; uint numberOfSendIndices = builder->getNumberOfSendIndices(direction, level); // iCellFCC for (uint posInSendIndices = 0; posInSendIndices < numberOfSendIndices; posInSendIndices++) { sparseIndexSend = sendIndices[posInSendIndices]; if (isSparseIndexInICellFCC(para->getParH(level)->intFC.kFC, sparseIndexSend, level)) { addUniqueIndexToCommunicationVectors(sendIndicesAfterFtoC, sparseIndexSend, sendIndicesForCommAfterFtoCPositions, posInSendIndices); } } // iCellCFC std::vector<uint> nodesCFC; aggregateNodesInICellCFC(level, nodesCFC); for (auto sparseIndex : nodesCFC) findIfSparseIndexIsInSendIndicesAndAddToCommVectors(sparseIndex, sendIndices, numberOfSendIndices, sendIndicesAfterFtoC, sendIndicesForCommAfterFtoCPositions); numberOfSendNodesAfterFtoC = (int)sendIndicesAfterFtoC.size(); findIndicesNotInCommAfterFtoC(numberOfSendIndices, sendIndices, sendIndicesAfterFtoC, sendIndicesOther); // copy new vectors back to sendIndices array for (int i = 0; i < numberOfSendNodesAfterFtoC; i++) sendIndices[i] = sendIndicesAfterFtoC[i]; for (uint i = 0; i < (uint)sendIndicesOther.size(); i++) sendIndices[i + numberOfSendNodesAfterFtoC] = sendIndicesOther[i]; *logging::out << logging::Logger::INFO_INTERMEDIATE << "... Process " << " " << communicator.getPID() << " numberOfSendNodesAfterFtoC: " << numberOfSendNodesAfterFtoC << "\n "; if (numberOfSendNodesAfterFtoC + sendIndicesOther.size() != numberOfSendIndices) { *logging::out << logging::Logger::LOGGER_ERROR << "reorderSendIndicesForCommAfterFtoC(): incorrect number of nodes" << "\n"; std::cout << "numberOfSendNodesAfterFtoC = " << numberOfSendNodesAfterFtoC << ", sendOrIndicesOther.size() = " << sendIndicesOther.size() << ", numberOfSendOrRecvIndices = " << numberOfSendIndices << std::endl; } } bool IndexRearrangementForStreams::isSparseIndexInICellFCC(uint sizeOfICellFCC, int sparseIndex, int level) const { for (uint j = 0; j < sizeOfICellFCC; j++) { if (sparseIndex < 0) return false; if (para->getParH(level)->intFC.ICellFCC[j] == (uint)sparseIndex) { return true; } } return false; } void IndexRearrangementForStreams::aggregateNodesInICellCFC(int level, std::vector<uint> &nodesCFC) const { uint sparseIndex; uint *neighborX = para->getParH(level)->neighborX; uint *neighborY = para->getParH(level)->neighborY; uint *neighborZ = para->getParH(level)->neighborZ; for (uint x = 0; x < para->getParH(level)->intCF.kCF; x++) { sparseIndex = para->getParH(level)->intCF.ICellCFC[x]; nodesCFC.push_back(sparseIndex); nodesCFC.push_back(neighborX[sparseIndex]); nodesCFC.push_back(neighborY[sparseIndex]); nodesCFC.push_back(neighborZ[sparseIndex]); nodesCFC.push_back(neighborY[neighborX[sparseIndex]]); nodesCFC.push_back(neighborZ[neighborX[sparseIndex]]); nodesCFC.push_back(neighborZ[neighborY[sparseIndex]]); nodesCFC.push_back(neighborZ[neighborY[neighborX[sparseIndex]]]); } // remove duplicate nodes std::sort(nodesCFC.begin(), nodesCFC.end()); auto iterator = std::unique(nodesCFC.begin(), nodesCFC.end()); nodesCFC.erase(iterator, nodesCFC.end()); } void IndexRearrangementForStreams::addUniqueIndexToCommunicationVectors( std::vector<int> &sendIndicesAfterFtoC, int &sparseIndexSend, std::vector<unsigned int> &sendIndicesForCommAfterFtoCPositions, uint &posInSendIndices) const { // add index to corresponding vectors, but omit indices which are already in sendIndicesAfterFtoC if (std::find(sendIndicesAfterFtoC.begin(), sendIndicesAfterFtoC.end(), sparseIndexSend) == sendIndicesAfterFtoC.end()) { sendIndicesAfterFtoC.push_back(sparseIndexSend); sendIndicesForCommAfterFtoCPositions.push_back(posInSendIndices); } } void IndexRearrangementForStreams::findIfSparseIndexIsInSendIndicesAndAddToCommVectors( int sparseIndex, int *sendIndices, uint numberOfSendIndices, std::vector<int> &sendIndicesAfterFtoC, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int sparseIndexSend; for (uint posInSendIndices = 0; posInSendIndices < numberOfSendIndices; posInSendIndices++) { sparseIndexSend = sendIndices[posInSendIndices]; if (sparseIndex == sparseIndexSend) { addUniqueIndexToCommunicationVectors(sendIndicesAfterFtoC, sparseIndex, sendIndicesForCommAfterFtoCPositions, posInSendIndices); break; } } } void IndexRearrangementForStreams::findIndicesNotInCommAfterFtoC(const uint &numberOfSendOrRecvIndices, int *sendOrReceiveIndices, std::vector<int> &sendOrReceiveIndicesAfterFtoC, std::vector<int> &sendOrIndicesOther) const { int sparseIndexSend; for (uint posInSendIndices = 0; posInSendIndices < numberOfSendOrRecvIndices; posInSendIndices++) { sparseIndexSend = sendOrReceiveIndices[posInSendIndices]; if (std::find(sendOrReceiveIndicesAfterFtoC.begin(), sendOrReceiveIndicesAfterFtoC.end(), sparseIndexSend) == sendOrReceiveIndicesAfterFtoC.end()) sendOrIndicesOther.push_back(sparseIndexSend); } } void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoCX( int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int *recvIndices = para->getParH(level)->recvProcessNeighborX[indexOfProcessNeighbor].index; int &numberOfRecvNodesAfterFtoC = para->getParH(level)->recvProcessNeighborsAfterFtoCX[indexOfProcessNeighbor].numberOfNodes; reorderRecvIndicesForCommAfterFtoC(recvIndices, numberOfRecvNodesAfterFtoC, direction, level, sendIndicesForCommAfterFtoCPositions); } void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoCY( int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int *recvIndices = para->getParH(level)->recvProcessNeighborY[indexOfProcessNeighbor].index; int &numberOfRecvNodesAfterFtoC = para->getParH(level)->recvProcessNeighborsAfterFtoCY[indexOfProcessNeighbor].numberOfNodes; reorderRecvIndicesForCommAfterFtoC(recvIndices, numberOfRecvNodesAfterFtoC, direction, level, sendIndicesForCommAfterFtoCPositions); } void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoCZ( int direction, int level, int indexOfProcessNeighbor, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { int *recvIndices = para->getParH(level)->recvProcessNeighborZ[indexOfProcessNeighbor].index; int &numberOfRecvNodesAfterFtoC = para->getParH(level)->recvProcessNeighborsAfterFtoCZ[indexOfProcessNeighbor].numberOfNodes; reorderRecvIndicesForCommAfterFtoC(recvIndices, numberOfRecvNodesAfterFtoC, direction, level, sendIndicesForCommAfterFtoCPositions); } void IndexRearrangementForStreams::reorderRecvIndicesForCommAfterFtoC( int *recvIndices, int &numberOfRecvNodesAfterFtoC, int direction, int level, std::vector<uint> &sendIndicesForCommAfterFtoCPositions) const { *logging::out << logging::Logger::INFO_INTERMEDIATE << "reorder receive indices for communication after fine to coarse: level: " << level << " direction: " << direction; std::cout << "\n n send indices: " << (uint)sendIndicesForCommAfterFtoCPositions.size() << std::endl; if (sendIndicesForCommAfterFtoCPositions.size() == 0) *logging::out << logging::Logger::INFO_HIGH << "reorderRecvIndicesForCommAfterFtoC(): sendIndicesForCommAfterFtoCPositions is empty." << "\n"; uint numberOfRecvIndices = builder->getNumberOfReceiveIndices(direction, level); std::vector<int> recvIndicesAfterFtoC; std::vector<int> recvIndicesOther; // find recvIndices for Communication after fine to coarse for (uint vectorPos : sendIndicesForCommAfterFtoCPositions) recvIndicesAfterFtoC.push_back(recvIndices[vectorPos]); findIndicesNotInCommAfterFtoC(numberOfRecvIndices, recvIndices, recvIndicesAfterFtoC, recvIndicesOther); numberOfRecvNodesAfterFtoC = (int)recvIndicesAfterFtoC.size(); // copy new vectors back to recvIndices array for (int i = 0; i < numberOfRecvNodesAfterFtoC; i++) recvIndices[i] = recvIndicesAfterFtoC[i]; for (uint i = 0; i < (uint)recvIndicesOther.size(); i++) recvIndices[i + numberOfRecvNodesAfterFtoC] = recvIndicesOther[i]; *logging::out << logging::Logger::INFO_INTERMEDIATE << "... Process " << " " << communicator.getPID() << " numberOfRecvNodesAfterFtoC: " << numberOfRecvNodesAfterFtoC << "\n "; if (numberOfRecvNodesAfterFtoC + recvIndicesOther.size() != numberOfRecvIndices) { *logging::out << logging::Logger::LOGGER_ERROR << "reorderRecvIndicesForCommAfterFtoC(): incorrect number of nodes" << "\n"; std::cout << "numberOfRecvNodesAfterFtoC = " << numberOfRecvNodesAfterFtoC << ", recvIndicesOther.size() = " << recvIndicesOther.size() << ", numberOfRecvIndices = " << numberOfRecvIndices << std::endl; } }