// Copyright (C) 2020-2023 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // Author : Anthony Geay (EDF R&D) #pragma once #include "ParaDataArray.hxx" #include "CommInterface.hxx" #include "MEDCouplingMemArray.txx" #include namespace MEDCoupling { template ParaDataArrayTemplate::ParaDataArrayTemplate(typename Traits::ArrayType *seqDa) { this->_seq_da.takeRef(seqDa); } template std::size_t ParaDataArrayTemplate::getHeapMemorySizeWithoutChildren() const { return 0; } template std::vector ParaDataArrayTemplate::getDirectChildrenWithNull() const { return { this->_seq_da }; } template void ParaDataArrayTemplate::checkOKOneComponent(const std::string& msg) const { if(this->_seq_da.isNull()) { std::ostringstream oss; oss << msg << " : nullptr internal pointer !"; throw INTERP_KERNEL::Exception(oss.str()); } this->_seq_da->checkAllocated(); if( this->_seq_da->getNumberOfComponents()!=1 ) { std::ostringstream oss; oss << msg << " : internal seq dataarray does not contain one component as expected !"; throw INTERP_KERNEL::Exception(oss.str()); } } /*! Parallel version of DataArrayInt::buildComplement. Returns result on proc 0. Not allocated DataArrayT is returned for all procs. */ template DataArrayIdType *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) { T curStart(0),curEnd(0); DataArrayTools::GetSlice(0,nbOfElems,1,ToIdType(curRk),ToIdType(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 = DataArrayT::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,ToIdType(rank),ToIdType(size),vmin,vmax); aggregatedIds->applyLin(1,-vmin); MCAuto seqComp(aggregatedIds->buildComplement(ToIdType(vmax-vmin))); seqComp->applyLin(1,ToIdType(vmin)); // std::vector< MCAuto > arraysOut; ci.gatherArrays(comm,0,seqComp,arraysOut); MCAuto ret(DataArrayIdType::Aggregate(FromVecAutoToVecOfConst(arraysOut))); return ret.retn(); } }