From: Anthony Geay Date: Wed, 29 Apr 2020 09:25:15 +0000 (+0200) Subject: WIP X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=e48540f06dae28dbc59aa3be9de1a514267275db;p=tools%2Fmedcoupling.git WIP --- diff --git a/src/ParaMEDMEM/CommInterface.cxx b/src/ParaMEDMEM/CommInterface.cxx index 6fda70ddd..b61c05bd7 100644 --- a/src/ParaMEDMEM/CommInterface.cxx +++ b/src/ParaMEDMEM/CommInterface.cxx @@ -62,22 +62,18 @@ namespace MEDCoupling \endverbatim */ + void CommInterface::gatherArrays(MPI_Comm comm, int root, const DataArrayIdType *array, std::vector< MCAuto >& arraysOut) const + { + this->gatherArraysT2(comm,root,array,arraysOut); + } + /*! * Generalized AllGather collective communication. * This method send input \a array to all procs. */ void CommInterface::allGatherArrays(MPI_Comm comm, const DataArrayIdType *array, std::vector< MCAuto >& arraysOut) const { - std::unique_ptr result, resultIndex; - int size(this->allGatherArrays(comm,array,result,resultIndex)); - arraysOut.resize(size); - for(int i = 0 ; i < size ; ++i) - { - arraysOut[i] = DataArrayIdType::New(); - mcIdType nbOfEltPack(resultIndex[i+1]-resultIndex[i]); - arraysOut[i]->alloc(nbOfEltPack,1); - std::copy(result.get()+resultIndex[i],result.get()+resultIndex[i+1],arraysOut[i]->getPointer()); - } + this->allGatherArraysT2(comm,array,arraysOut); } /*! @@ -86,18 +82,7 @@ namespace MEDCoupling */ int CommInterface::allGatherArrays(MPI_Comm comm, const DataArrayIdType *array, std::unique_ptr& result, std::unique_ptr& resultIndex) const { - int size; - this->commSize(comm,&size); - std::unique_ptr nbOfElems(new mcIdType[size]); - mcIdType nbOfCellsRequested(array->getNumberOfTuples()); - this->allGather(&nbOfCellsRequested,1,MPI_ID_TYPE,nbOfElems.get(),1,MPI_ID_TYPE,comm); - mcIdType nbOfCellIdsSum(std::accumulate(nbOfElems.get(),nbOfElems.get()+size,0)); - result.reset(new mcIdType[nbOfCellIdsSum]); - std::unique_ptr nbOfElemsInt( CommInterface::ToIntArray(nbOfElems,size) ); - std::unique_ptr offsetsIn( CommInterface::ComputeOffset(nbOfElemsInt,size) ); - this->allGatherV(array->begin(),nbOfCellsRequested,MPI_ID_TYPE,result.get(),nbOfElemsInt.get(),offsetsIn.get(),MPI_ID_TYPE,comm); - resultIndex = ComputeOffsetFull(nbOfElems,size); - return size; + return this->allGatherArraysT(comm,array,result,resultIndex); } void CommInterface::allToAllArrays(MPI_Comm comm, const std::vector< MCAuto >& arrays, std::vector< MCAuto >& arraysOut) const diff --git a/src/ParaMEDMEM/CommInterface.hxx b/src/ParaMEDMEM/CommInterface.hxx index e969f9394..a59fce0b9 100644 --- a/src/ParaMEDMEM/CommInterface.hxx +++ b/src/ParaMEDMEM/CommInterface.hxx @@ -101,6 +101,8 @@ namespace MEDCoupling int getCount(MPI_Status *status, MPI_Datatype datatype, int *count) const { return MPI_Get_count(status, datatype, count); } int broadcast(void* buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm) const { return MPI_Bcast(buffer, count, datatype, root, comm); } + int gather(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, int root, MPI_Comm comm) const { return MPI_Gather(sendbuf,sendcount,sendtype,recvbuf,recvcount,recvtype,root,comm); } + int gatherV(const void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, const int recvcounts[], const int displs[], MPI_Datatype recvtype, int root, MPI_Comm comm) const { return MPI_Gatherv(sendbuf,sendcount,sendtype,recvbuf,recvcounts,displs,recvtype,root,comm); } int allGather(void* sendbuf, int sendcount, MPI_Datatype sendtype, void* recvbuf, int recvcount, MPI_Datatype recvtype, MPI_Comm comm) const { return MPI_Allgather(sendbuf,sendcount, sendtype, recvbuf, recvcount, recvtype, comm); } @@ -118,11 +120,96 @@ namespace MEDCoupling MPI_Op op, int root, MPI_Comm comm) const { return MPI_Reduce(sendbuf, recvbuf, count, datatype, op, root, comm); } int allReduce(void* sendbuf, void* recvbuf, int count, MPI_Datatype datatype, MPI_Op op, MPI_Comm comm) const { return MPI_Allreduce(sendbuf, recvbuf, count, datatype, op, comm); } public: + void gatherArrays(MPI_Comm comm, int root, const DataArrayIdType *array, std::vector< MCAuto >& arraysOut) const; void allGatherArrays(MPI_Comm comm, const DataArrayIdType *array, std::vector< MCAuto >& arraysOut) const; int allGatherArrays(MPI_Comm comm, const DataArrayIdType *array, std::unique_ptr& result, std::unique_ptr& resultIndex) const; void allToAllArrays(MPI_Comm comm, const std::vector< MCAuto >& arrays, std::vector< MCAuto >& arraysOut) const; void allToAllArrays(MPI_Comm comm, const std::vector< MCAuto >& arrays, std::vector< MCAuto >& arraysOut) const; void allToAllArrays(MPI_Comm comm, const std::vector< MCAuto >& arrays, MCAuto& arraysOut) const; + + template + int gatherArraysT(MPI_Comm comm, int root, const typename Traits::ArrayType *array, std::unique_ptr& result, std::unique_ptr& resultIndex, int& rank) const + { + using DataArrayT = typename Traits::ArrayType; + int size; + this->commSize(comm,&size); + rank = -1; + this->commRank(comm,&rank); + std::unique_ptr nbOfElems; + if(rank==0) + nbOfElems.reset(new mcIdType[size]); + mcIdType nbOfCellsRequested(array->getNumberOfTuples()); + this->gather(&nbOfCellsRequested,1,MPI_ID_TYPE,nbOfElems.get(),1,MPI_ID_TYPE,root,comm); + mcIdType nbOfCellIdsSum(std::accumulate(nbOfElems.get(),nbOfElems.get()+size,0)); + if(rank==0) + result.reset(new T[nbOfCellIdsSum]); + std::unique_ptr nbOfElemsInt,offsetsIn; + if(rank==0) + { + nbOfElemsInt = CommInterface::ToIntArray(nbOfElems,size); + offsetsIn = CommInterface::ComputeOffset(nbOfElemsInt,size); + } + this->gatherV(array->begin(),nbOfCellsRequested,ParaTraits::MPIDataType,result.get(),nbOfElemsInt.get(),offsetsIn.get(),ParaTraits::MPIDataType,root,comm); + resultIndex = ComputeOffsetFull(nbOfElems,size); + return size; + } + + template + void gatherArraysT2(MPI_Comm comm, int root, const typename Traits::ArrayType *array, std::vector< MCAuto::ArrayType> >& arraysOut) const + { + using DataArrayT = typename Traits::ArrayType; + std::unique_ptr result; + std::unique_ptr resultIndex; + int rank(-1); + int size(this->gatherArraysT(comm,root,array,result,resultIndex,rank)); + arraysOut.resize(size); + for(int i = 0 ; i < size ; ++i) + { + arraysOut[i] = DataArrayT::New(); + if(rank == 0) + { + mcIdType nbOfEltPack(resultIndex[i+1]-resultIndex[i]); + arraysOut[i]->alloc(nbOfEltPack,1); + std::copy(result.get()+resultIndex[i],result.get()+resultIndex[i+1],arraysOut[i]->getPointer()); + } + } + } + + template + int allGatherArraysT(MPI_Comm comm, const typename Traits::ArrayType *array, std::unique_ptr& result, std::unique_ptr& resultIndex) const + { + using DataArrayT = typename Traits::ArrayType; + int size; + this->commSize(comm,&size); + std::unique_ptr nbOfElems(new mcIdType[size]); + mcIdType nbOfCellsRequested(array->getNumberOfTuples()); + this->allGather(&nbOfCellsRequested,1,MPI_ID_TYPE,nbOfElems.get(),1,MPI_ID_TYPE,comm); + mcIdType nbOfCellIdsSum(std::accumulate(nbOfElems.get(),nbOfElems.get()+size,0)); + result.reset(new T[nbOfCellIdsSum]); + std::unique_ptr nbOfElemsInt( CommInterface::ToIntArray(nbOfElems,size) ); + std::unique_ptr offsetsIn( CommInterface::ComputeOffset(nbOfElemsInt,size) ); + this->allGatherV(array->begin(),nbOfCellsRequested,ParaTraits::MPIDataType,result.get(),nbOfElemsInt.get(),offsetsIn.get(),ParaTraits::MPIDataType,comm); + resultIndex = ComputeOffsetFull(nbOfElems,size); + return size; + } + + template + void allGatherArraysT2(MPI_Comm comm, const typename Traits::ArrayType *array, std::vector< MCAuto::ArrayType> >& arraysOut) const + { + using DataArrayT = typename Traits::ArrayType; + std::unique_ptr result; + std::unique_ptr resultIndex; + int size(this->allGatherArraysT(comm,array,result,resultIndex)); + arraysOut.resize(size); + for(int i = 0 ; i < size ; ++i) + { + arraysOut[i] = DataArrayT::New(); + mcIdType nbOfEltPack(resultIndex[i+1]-resultIndex[i]); + arraysOut[i]->alloc(nbOfEltPack,1); + std::copy(result.get()+resultIndex[i],result.get()+resultIndex[i+1],arraysOut[i]->getPointer()); + } + } + template int allToAllArraysT2(MPI_Comm comm, const std::vector< MCAuto::ArrayType> >& arrays, MCAuto::ArrayType>& arrayOut, std::unique_ptr& nbOfElems2, mcIdType& nbOfComponents) const { diff --git a/src/ParaMEDMEM/ParaDataArray.hxx b/src/ParaMEDMEM/ParaDataArray.hxx index a6052f1a6..af7700738 100644 --- a/src/ParaMEDMEM/ParaDataArray.hxx +++ b/src/ParaMEDMEM/ParaDataArray.hxx @@ -42,7 +42,7 @@ namespace MEDCoupling std::size_t getHeapMemorySizeWithoutChildren() const override; std::vector getDirectChildrenWithNull() const override; void checkOKOneComponent(const std::string& msg); - private: + protected: MCAuto::ArrayType> _seq_da; }; @@ -50,7 +50,7 @@ namespace MEDCoupling class ParaDataArrayDiscrete : public ParaDataArrayTemplate { public: - typename Traits::ArrayType *buildComplement() const; + typename Traits::ArrayType *buildComplement(T nbOfElems) const; protected: ParaDataArrayDiscrete(typename Traits::ArrayType *seqDa):ParaDataArrayTemplate(seqDa) { } }; diff --git a/src/ParaMEDMEM/ParaDataArray.txx b/src/ParaMEDMEM/ParaDataArray.txx index 83598a43f..898a41946 100644 --- a/src/ParaMEDMEM/ParaDataArray.txx +++ b/src/ParaMEDMEM/ParaDataArray.txx @@ -21,6 +21,7 @@ #pragma once #include "ParaDataArray.hxx" +#include "CommInterface.hxx" #include @@ -61,11 +62,40 @@ namespace MEDCoupling } /*! - Parallel version of DataArrayInt::buildComplement. + Parallel version of DataArrayInt::buildComplement. Returns result on proc 0. Not allocated DataArrayT is returned for all procs. */ template - typename Traits::ArrayType *ParaDataArrayDiscrete::buildComplement() const + typename Traits::ArrayType *ParaDataArrayDiscrete::buildComplement(T nbOfElems) const { + using DataArrayT = typename Traits::ArrayType; + this->checkOKOneComponent("ParaDataArray::buildComplement"); + MPI_Comm comm(MPI_COMM_WORLD); + CommInterface ci; + int size; + ci.commSize(comm,&size); + std::vector< MCAuto > idsCaptured(size); + for(int curRk = 0 ; curRk < size ; ++curRk) + { + mcIdType curStart(0),curEnd(0); + DataArrayTools::GetSlice(0,nbOfElems,1,static_cast(curRk),static_cast(size),curStart,curEnd); + MCAuto idsInGlobalIds(this->_seq_da->findIdsInRange(curStart,curEnd)); + idsCaptured[curRk] = this->_seq_da->selectByTupleIdSafe(idsInGlobalIds->begin(),idsInGlobalIds->end()); + } + // communication : 1 arrays are going to be all2allized : ids + MCAuto aggregatedIds; + { + std::vector< MCAuto > myRkIdsCaptured; + ci.allToAllArraysT(comm,idsCaptured,myRkIdsCaptured); + aggregatedIds = DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(myRkIdsCaptured)); + } + aggregatedIds->sort(); + aggregatedIds = aggregatedIds->buildUnique(); + int rank(-1); + ci.commRank(comm,&rank); + T vmin(std::numeric_limits::max()),vmax(-std::numeric_limits::max()); + DataArrayTools::GetSlice(0,nbOfElems,1,static_cast(rank),static_cast(size),vmin,vmax); + MCAuto retIds(aggregatedIds->findIdsNotInRange(vmin,vmax)); + MCAuto ret(aggregatedIds->selectByTupleIdSafe(retIds->begin(),retIds->end())); return nullptr; }