From: Anthony Geay Date: Mon, 27 Apr 2020 22:12:14 +0000 (+0200) Subject: Make it templated X-Git-Tag: V9_5_0b1~7 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=500d4341ddefa1910ea2a0fe48005c559c44e226;p=tools%2Fmedcoupling.git Make it templated --- diff --git a/src/ParaMEDMEM/ParaUMesh.cxx b/src/ParaMEDMEM/ParaUMesh.cxx index 7e3060892..e5ea86c62 100644 --- a/src/ParaMEDMEM/ParaUMesh.cxx +++ b/src/ParaMEDMEM/ParaUMesh.cxx @@ -133,81 +133,22 @@ MCAuto ParaUMesh::getCellIdsLyingOnNodes(const DataArrayIdType DataArrayIdType *ParaUMesh::redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const { - MPI_Comm comm(MPI_COMM_WORLD); - CommInterface ci; - std::unique_ptr allGlobalCellIds,allGlobalCellIdsIndex; - int size(ci.allGatherArrays(comm,globalCellIds,allGlobalCellIds,allGlobalCellIdsIndex)); - // Prepare ParaUMesh parts to be sent : compute for each proc the contribution of current rank. - std::vector< MCAuto > globalCellIdsToBeSent(size); - std::vector< MCAuto > fieldToBeSent(size); - for(int curRk = 0 ; curRk < size ; ++curRk) - { - mcIdType offset(allGlobalCellIdsIndex[curRk]); - MCAuto globalCellIdsOfCurProc(DataArrayIdType::New()); - globalCellIdsOfCurProc->useArray(allGlobalCellIds.get()+offset,false,DeallocType::CPP_DEALLOC,allGlobalCellIdsIndex[curRk+1]-offset,1); - // the key call is here : compute for rank curRk the cells to be sent - MCAuto globalCellIdsCaptured(_cell_global->buildIntersection(globalCellIdsOfCurProc));// OK for the global cellIds - MCAuto localCellIdsCaptured(_cell_global->findIdForEach(globalCellIdsCaptured->begin(),globalCellIdsCaptured->end())); - globalCellIdsToBeSent[curRk] = globalCellIdsCaptured; - fieldToBeSent[curRk] = fieldValueToRed->selectByTupleIdSafe(localCellIdsCaptured->begin(),localCellIdsCaptured->end()); - } - // Receive - std::vector< MCAuto > globalCellIdsReceived; - ci.allToAllArrays(comm,globalCellIdsToBeSent,globalCellIdsReceived); - std::vector< MCAuto > fieldValueReceived; - ci.allToAllArrays(comm,fieldToBeSent,fieldValueReceived); - // use globalCellIdsReceived to reorganize everything - MCAuto aggregatedCellIds( DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(globalCellIdsReceived)) ); - MCAuto aggregatedCellIdsSorted(aggregatedCellIds->copySorted()); - MCAuto idsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedCellIdsSorted,aggregatedCellIds)); - MCAuto cellIdsOfSameNodeIds(aggregatedCellIdsSorted->indexOfSameConsecutiveValueGroups()); - MCAuto n2o_cells(idsIntoAggregatedIds->selectByTupleIdSafe(cellIdsOfSameNodeIds->begin(),cellIdsOfSameNodeIds->end()-1));//new == new ordering so that global cell ids are sorted . old == coarse ordering implied by the aggregation - // - MCAuto fieldAggregated(DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(fieldValueReceived))); - MCAuto ret(fieldAggregated->selectByTupleIdSafe(n2o_cells->begin(),n2o_cells->end())); - return ret.retn(); + return this->redistributeCellFieldT(globalCellIds,fieldValueToRed); +} + +DataArrayDouble *ParaUMesh::redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayDouble *fieldValueToRed) const +{ + return this->redistributeCellFieldT(globalCellIds,fieldValueToRed); } DataArrayIdType *ParaUMesh::redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const { - MPI_Comm comm(MPI_COMM_WORLD); - CommInterface ci; - std::unique_ptr allGlobalCellIds,allGlobalCellIdsIndex; - int size(ci.allGatherArrays(comm,globalCellIds,allGlobalCellIds,allGlobalCellIdsIndex)); - // Prepare ParaUMesh parts to be sent : compute for each proc the contribution of current rank. - std::vector< MCAuto > globalNodeIdsToBeSent(size); - std::vector< MCAuto > fieldToBeSent(size); - for(int curRk = 0 ; curRk < size ; ++curRk) - { - mcIdType offset(allGlobalCellIdsIndex[curRk]); - MCAuto globalCellIdsOfCurProc(DataArrayIdType::New()); - globalCellIdsOfCurProc->useArray(allGlobalCellIds.get()+offset,false,DeallocType::CPP_DEALLOC,allGlobalCellIdsIndex[curRk+1]-offset,1); - // the key call is here : compute for rank curRk the cells to be sent - MCAuto globalCellIdsCaptured(_cell_global->buildIntersection(globalCellIdsOfCurProc));// OK for the global cellIds - MCAuto localCellIdsCaptured(_cell_global->findIdForEach(globalCellIdsCaptured->begin(),globalCellIdsCaptured->end())); - MCAuto meshPart(_mesh->buildPartOfMySelf(localCellIdsCaptured->begin(),localCellIdsCaptured->end(),true)); - MCAuto o2n(meshPart->zipCoordsTraducer());// OK for the mesh - MCAuto n2o(o2n->invertArrayO2N2N2O(meshPart->getNumberOfNodes())); - MCAuto globalNodeIdsPart(_node_global->selectByTupleIdSafe(n2o->begin(),n2o->end())); // OK for the global nodeIds - globalNodeIdsToBeSent[curRk] = globalNodeIdsPart; - fieldToBeSent[curRk] = fieldValueToRed->selectByTupleIdSafe(n2o->begin(),n2o->end()); - } - // Receive - std::vector< MCAuto > globalNodeIdsReceived; - ci.allToAllArrays(comm,globalNodeIdsToBeSent,globalNodeIdsReceived); - std::vector< MCAuto > fieldValueReceived; - ci.allToAllArrays(comm,fieldToBeSent,fieldValueReceived); - // firstly deal with nodes. - MCAuto aggregatedNodeIds( DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(globalNodeIdsReceived)) ); - MCAuto aggregatedNodeIdsSorted(aggregatedNodeIds->copySorted()); - MCAuto nodeIdsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedNodeIdsSorted,aggregatedNodeIds)); - MCAuto idxOfSameNodeIds(aggregatedNodeIdsSorted->indexOfSameConsecutiveValueGroups()); - MCAuto n2o_nodes(nodeIdsIntoAggregatedIds->selectByTupleIdSafe(idxOfSameNodeIds->begin(),idxOfSameNodeIds->end()-1));//new == new ordering so that global node ids are sorted . old == coarse ordering implied by the aggregation - // - MCAuto fieldAggregated(DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(fieldValueReceived))); - MCAuto ret(fieldAggregated->selectByTupleIdSafe(n2o_nodes->begin(),n2o_nodes->end())); - // - return ret.retn(); + return this->redistributeNodeFieldT(globalCellIds,fieldValueToRed); +} + +DataArrayDouble *ParaUMesh::redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayDouble *fieldValueToRed) const +{ + return this->redistributeNodeFieldT(globalCellIds,fieldValueToRed); } /*! diff --git a/src/ParaMEDMEM/ParaUMesh.hxx b/src/ParaMEDMEM/ParaUMesh.hxx index d8a938718..ec404a653 100644 --- a/src/ParaMEDMEM/ParaUMesh.hxx +++ b/src/ParaMEDMEM/ParaUMesh.hxx @@ -40,7 +40,9 @@ namespace MEDCoupling static ParaUMesh *New(MEDCouplingUMesh *mesh, DataArrayIdType *globalCellIds, DataArrayIdType *globalNodeIds); MCAuto getCellIdsLyingOnNodes(const DataArrayIdType *globalNodeIds, bool fullyIn) const; ParaUMesh *redistributeCells(const DataArrayIdType *globalCellIds) const; + DataArrayDouble *redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayDouble *fieldValueToRed) const; DataArrayIdType *redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; + DataArrayDouble *redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayDouble *fieldValueToRed) const; DataArrayIdType *redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; MEDCouplingUMesh *getMesh() { return _mesh; } DataArrayIdType *getGlobalCellIds() { return _cell_global; } @@ -55,5 +57,88 @@ namespace MEDCoupling MCAuto _mesh; MCAuto _cell_global; MCAuto _node_global; + private: + template + typename Traits::ArrayType *redistributeCellFieldT(const DataArrayIdType *globalCellIds, const typename Traits::ArrayType *fieldValueToRed) const + { + using DataArrayT = typename Traits::ArrayType; + MPI_Comm comm(MPI_COMM_WORLD); + CommInterface ci; + std::unique_ptr allGlobalCellIds,allGlobalCellIdsIndex; + int size(ci.allGatherArrays(comm,globalCellIds,allGlobalCellIds,allGlobalCellIdsIndex)); + // Prepare ParaUMesh parts to be sent : compute for each proc the contribution of current rank. + std::vector< MCAuto > globalCellIdsToBeSent(size); + std::vector< MCAuto > fieldToBeSent(size); + for(int curRk = 0 ; curRk < size ; ++curRk) + { + mcIdType offset(allGlobalCellIdsIndex[curRk]); + MCAuto globalCellIdsOfCurProc(DataArrayIdType::New()); + globalCellIdsOfCurProc->useArray(allGlobalCellIds.get()+offset,false,DeallocType::CPP_DEALLOC,allGlobalCellIdsIndex[curRk+1]-offset,1); + // the key call is here : compute for rank curRk the cells to be sent + MCAuto globalCellIdsCaptured(_cell_global->buildIntersection(globalCellIdsOfCurProc));// OK for the global cellIds + MCAuto localCellIdsCaptured(_cell_global->findIdForEach(globalCellIdsCaptured->begin(),globalCellIdsCaptured->end())); + globalCellIdsToBeSent[curRk] = globalCellIdsCaptured; + fieldToBeSent[curRk] = fieldValueToRed->selectByTupleIdSafe(localCellIdsCaptured->begin(),localCellIdsCaptured->end()); + } + // Receive + std::vector< MCAuto > globalCellIdsReceived; + ci.allToAllArrays(comm,globalCellIdsToBeSent,globalCellIdsReceived); + std::vector< MCAuto > fieldValueReceived; + ci.allToAllArrays(comm,fieldToBeSent,fieldValueReceived); + // use globalCellIdsReceived to reorganize everything + MCAuto aggregatedCellIds( DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(globalCellIdsReceived)) ); + MCAuto aggregatedCellIdsSorted(aggregatedCellIds->copySorted()); + MCAuto idsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedCellIdsSorted,aggregatedCellIds)); + MCAuto cellIdsOfSameNodeIds(aggregatedCellIdsSorted->indexOfSameConsecutiveValueGroups()); + MCAuto n2o_cells(idsIntoAggregatedIds->selectByTupleIdSafe(cellIdsOfSameNodeIds->begin(),cellIdsOfSameNodeIds->end()-1));//new == new ordering so that global cell ids are sorted . old == coarse ordering implied by the aggregation + // + MCAuto fieldAggregated(DataArrayT::Aggregate(FromVecAutoToVecOfConst(fieldValueReceived))); + MCAuto ret(fieldAggregated->selectByTupleIdSafe(n2o_cells->begin(),n2o_cells->end())); + return ret.retn(); + } + + template + typename Traits::ArrayType *redistributeNodeFieldT(const DataArrayIdType *globalCellIds, const typename Traits::ArrayType *fieldValueToRed) const + { + using DataArrayT = typename Traits::ArrayType; + MPI_Comm comm(MPI_COMM_WORLD); + CommInterface ci; + std::unique_ptr allGlobalCellIds,allGlobalCellIdsIndex; + int size(ci.allGatherArrays(comm,globalCellIds,allGlobalCellIds,allGlobalCellIdsIndex)); + // Prepare ParaUMesh parts to be sent : compute for each proc the contribution of current rank. + std::vector< MCAuto > globalNodeIdsToBeSent(size); + std::vector< MCAuto > fieldToBeSent(size); + for(int curRk = 0 ; curRk < size ; ++curRk) + { + mcIdType offset(allGlobalCellIdsIndex[curRk]); + MCAuto globalCellIdsOfCurProc(DataArrayIdType::New()); + globalCellIdsOfCurProc->useArray(allGlobalCellIds.get()+offset,false,DeallocType::CPP_DEALLOC,allGlobalCellIdsIndex[curRk+1]-offset,1); + // the key call is here : compute for rank curRk the cells to be sent + MCAuto globalCellIdsCaptured(_cell_global->buildIntersection(globalCellIdsOfCurProc));// OK for the global cellIds + MCAuto localCellIdsCaptured(_cell_global->findIdForEach(globalCellIdsCaptured->begin(),globalCellIdsCaptured->end())); + MCAuto meshPart(_mesh->buildPartOfMySelf(localCellIdsCaptured->begin(),localCellIdsCaptured->end(),true)); + MCAuto o2n(meshPart->zipCoordsTraducer());// OK for the mesh + MCAuto n2o(o2n->invertArrayO2N2N2O(meshPart->getNumberOfNodes())); + MCAuto globalNodeIdsPart(_node_global->selectByTupleIdSafe(n2o->begin(),n2o->end())); // OK for the global nodeIds + globalNodeIdsToBeSent[curRk] = globalNodeIdsPart; + fieldToBeSent[curRk] = fieldValueToRed->selectByTupleIdSafe(n2o->begin(),n2o->end()); + } + // Receive + std::vector< MCAuto > globalNodeIdsReceived; + ci.allToAllArrays(comm,globalNodeIdsToBeSent,globalNodeIdsReceived); + std::vector< MCAuto > fieldValueReceived; + ci.allToAllArrays(comm,fieldToBeSent,fieldValueReceived); + // firstly deal with nodes. + MCAuto aggregatedNodeIds( DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(globalNodeIdsReceived)) ); + MCAuto aggregatedNodeIdsSorted(aggregatedNodeIds->copySorted()); + MCAuto nodeIdsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedNodeIdsSorted,aggregatedNodeIds)); + MCAuto idxOfSameNodeIds(aggregatedNodeIdsSorted->indexOfSameConsecutiveValueGroups()); + MCAuto n2o_nodes(nodeIdsIntoAggregatedIds->selectByTupleIdSafe(idxOfSameNodeIds->begin(),idxOfSameNodeIds->end()-1));//new == new ordering so that global node ids are sorted . old == coarse ordering implied by the aggregation + // + MCAuto fieldAggregated(DataArrayT::Aggregate(FromVecAutoToVecOfConst(fieldValueReceived))); + MCAuto ret(fieldAggregated->selectByTupleIdSafe(n2o_nodes->begin(),n2o_nodes->end())); + // + return ret.retn(); + } }; } diff --git a/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i b/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i index 4c1ff6dae..d2eb770f4 100644 --- a/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i +++ b/src/ParaMEDMEM_Swig/ParaMEDMEMCommon.i @@ -163,7 +163,9 @@ namespace MEDCoupling static ParaUMesh *New(MEDCouplingUMesh *mesh, DataArrayIdType *globalCellIds, DataArrayIdType *globalNodeIds); ParaUMesh *redistributeCells(const DataArrayIdType *globalCellIds) const; DataArrayIdType *redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; + DataArrayDouble *redistributeCellField(const DataArrayIdType *globalCellIds, const DataArrayDouble *fieldValueToRed) const; DataArrayIdType *redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayIdType *fieldValueToRed) const; + DataArrayDouble *redistributeNodeField(const DataArrayIdType *globalCellIds, const DataArrayDouble *fieldValueToRed) const; %extend { ParaUMesh(MEDCouplingUMesh *mesh, DataArrayIdType *globalCellIds, DataArrayIdType *globalNodeIds)