2 // Copyright (C) 2020-2023 CEA, EDF
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // Author : Anthony Geay (EDF R&D)
22 #include "ParaSkyLineArray.hxx"
23 #include "ProcessorGroup.hxx"
24 #include "MPIProcessorGroup.hxx"
25 #include "Topology.hxx"
26 #include "BlockTopology.hxx"
27 #include "CommInterface.hxx"
28 #include "MEDCouplingMemArray.hxx"
38 using namespace MEDCoupling;
40 ParaSkyLineArray *ParaSkyLineArray::New(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds)
42 return new ParaSkyLineArray(ska,globalIds);
45 MEDCouplingSkyLineArray *ParaSkyLineArray::getSkyLineArray() const
47 return this->_ska.iAmATrollConstCast();
50 DataArrayIdType *ParaSkyLineArray::getGlobalIdsArray() const
52 return this->_global_ids.iAmATrollConstCast();
55 ParaSkyLineArray::ParaSkyLineArray(MEDCouplingSkyLineArray *ska, DataArrayIdType *globalIds)
58 _global_ids.takeRef(globalIds);
60 _global_ids.checkNotNull();
61 if(_ska->getNumberOf() != _global_ids->getNumberOfTuples())
63 std::ostringstream oss; oss << "ParaSkyLineArray constructor : mismatch between # globalIds (" << _global_ids->getNumberOfTuples() << ") and len of indices in SkyLineArray (" << _ska->getNumberOf() << ").";
64 throw INTERP_KERNEL::Exception(oss.str());
68 std::size_t ParaSkyLineArray::getHeapMemorySizeWithoutChildren() const
73 std::vector<const BigMemoryObject *> ParaSkyLineArray::getDirectChildrenWithNull() const
75 return {_ska,_global_ids};
78 MCAuto<ParaSkyLineArray> ParaSkyLineArray::equiRedistribute(mcIdType nbOfEntities) const
80 MPI_Comm comm(MPI_COMM_WORLD);
83 ci.commSize(comm,&size);
84 std::vector< MCAuto<MEDCouplingSkyLineArray> > skToBeSent(size);
85 std::vector< MCAuto<DataArrayIdType> > idsCaptured(size);
86 for(int curRk = 0 ; curRk < size ; ++curRk)
88 mcIdType curStart(0),curEnd(0);
89 DataArrayIdType::GetSlice(0,nbOfEntities,1,curRk,size,curStart,curEnd);
90 MCAuto<DataArrayIdType> idsInGlobalIds(_global_ids->findIdsInRange(curStart,curEnd));
91 idsCaptured[curRk] = _global_ids->selectByTupleIdSafe(idsInGlobalIds->begin(),idsInGlobalIds->end());
93 DataArrayIdType *tmpValues(nullptr),*tmpIndex(nullptr);
94 DataArrayIdType::ExtractFromIndexedArrays(idsInGlobalIds->begin(),idsInGlobalIds->end(),this->_ska->getValuesArray(),this->_ska->getIndexArray(),tmpValues,tmpIndex);
95 MCAuto<DataArrayIdType> tmpValues2(tmpValues),tmpIndex2(tmpIndex);
96 skToBeSent[curRk] = MEDCouplingSkyLineArray::New(tmpIndex,tmpValues);
99 // communication : 3 arrays are going to be all2allized : ids, SkyLine index and SyLine values
100 MCAuto<DataArrayIdType> aggregatedIds,indices,values;
102 std::vector< MCAuto<DataArrayIdType> > myRkIdsCaptured;
103 ci.allToAllArrays(comm,idsCaptured,myRkIdsCaptured);
104 aggregatedIds = DataArrayIdType::Aggregate(FromVecAutoToVecOfConst<DataArrayIdType>(myRkIdsCaptured));
107 std::vector< MCAuto<DataArrayIdType> > myRkSkIndex;
108 std::vector< MCAuto<DataArrayIdType> > indexToBeSent(MEDCouplingSkyLineArray::RetrieveVecIndex(skToBeSent));
109 ci.allToAllArrays(comm,indexToBeSent,myRkSkIndex);
110 indices = DataArrayIdType::AggregateIndexes(FromVecAutoToVecOfConst<DataArrayIdType>(myRkSkIndex));
113 std::vector< MCAuto<DataArrayIdType> > myRkSkValues;
114 std::vector< MCAuto<DataArrayIdType> > valuesToBeSent(MEDCouplingSkyLineArray::RetrieveVecValues(skToBeSent));
115 ci.allToAllArrays(comm,valuesToBeSent,myRkSkValues);
116 values = DataArrayIdType::Aggregate(FromVecAutoToVecOfConst<DataArrayIdType>(myRkSkValues));
118 // Reorder results coming from other procs
119 MCAuto<DataArrayIdType> aggregatedIdsSort(aggregatedIds->deepCopy()); aggregatedIdsSort->sort();
120 MCAuto<DataArrayIdType> idsIntoAggregatedIds(DataArrayIdType::FindPermutationFromFirstToSecondDuplicate(aggregatedIdsSort,aggregatedIds));
121 MCAuto<DataArrayIdType> indicesSorted,valuesSorted;
123 DataArrayIdType *indicesSortedTmp(nullptr),*valuesSortedTmp(nullptr);
124 DataArrayIdType::ExtractFromIndexedArrays(idsIntoAggregatedIds->begin(),idsIntoAggregatedIds->end(),values,indices,valuesSortedTmp,indicesSortedTmp);
125 indicesSorted = indicesSortedTmp; valuesSorted=valuesSortedTmp;
127 MCAuto<DataArrayIdType> idxOfSameIds(aggregatedIdsSort->indexOfSameConsecutiveValueGroups());
129 MCAuto<DataArrayIdType> globalIdsOut(aggregatedIdsSort->buildUnique());
130 MCAuto<MEDCouplingSkyLineArray> skOut(MEDCouplingSkyLineArray::New(indicesSorted,valuesSorted));
131 skOut = skOut->groupPacks(idxOfSameIds);//group partial packs coming from different procs
132 skOut = skOut->uniqueNotSortedByPack();//remove duplicates
133 MCAuto<ParaSkyLineArray> ret(ParaSkyLineArray::New(skOut,globalIdsOut));