From: ageay Date: Mon, 17 Dec 2012 11:49:23 +0000 (+0000) Subject: Improvement of perf of zipConnectivityTraducer. X-Git-Tag: V6_main_FINAL~451 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=d3741fd8b48ee3f47e28924150ae0c363c1ac3db;p=tools%2Fmedcoupling.git Improvement of perf of zipConnectivityTraducer. --- diff --git a/src/MEDCoupling/MEDCouplingMemArray.cxx b/src/MEDCoupling/MEDCouplingMemArray.cxx index 0ea82aef1..e2db30e71 100644 --- a/src/MEDCoupling/MEDCouplingMemArray.cxx +++ b/src/MEDCoupling/MEDCouplingMemArray.cxx @@ -1261,7 +1261,7 @@ DataArrayDouble *DataArrayDouble::getDifferentValues(double prec, int limitTuple findCommonTuples(prec,limitTupleId,c0,cI0); MEDCouplingAutoRefCountObjectPtr c(c0),cI(cI0); int newNbOfTuples=-1; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0,cI0,newNbOfTuples); + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfTuples(),c0->begin(),cI0->begin(),cI0->end(),newNbOfTuples); return renumberAndReduce(o2n->getConstPointer(),newNbOfTuples); } @@ -4202,22 +4202,22 @@ void DataArrayInt::changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, Data * * @param nbOfOldTuples is the number of tuples in initial array. * @param arr is the list of tuples ids grouped by 'arrI' array - * @param arrI is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. + * @param arrIBg is the entry point of 'arr' array. arrI->getNumberOfTuples()-1 is the number of common groups > 1 tuple. + * @param arrIEnd is the entry point of 'arr' array (end not included) * @param newNbOfTuples output parameter that retrieves the new number of tuples after surjection application */ -DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) +DataArrayInt *DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception) { - if(!arr || !arrI) + if(!arr || !arrIBg || !arrIEnd) throw INTERP_KERNEL::Exception("DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2 : presence of NULL ref of DataArrayInt in input !"); MEDCouplingAutoRefCountObjectPtr ret=DataArrayInt::New(); ret->alloc(nbOfOldTuples,1); int *pt=ret->getPointer(); std::fill(pt,pt+nbOfOldTuples,-1); - int nbOfGrps=arrI->getNumberOfTuples()-1; - const int *cIPtr=arrI->getConstPointer(); - const int *cPtr=arr->getConstPointer(); + int nbOfGrps=((int)std::distance(arrIBg,arrIEnd))-1; + const int *cIPtr=arrIBg; for(int i=0;i=0 && cPtr[j]=0 && arr[j] >& ranges) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *checkAndPreparePermutation() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void changeSurjectiveFormat(int targetNb, DataArrayInt *&arr, DataArrayInt *&arrI) const throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT static DataArrayInt *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const int *arr, const int *arrIBg, const int *arrIEnd, int &newNbOfTuples) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *buildPermArrPerLevel() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isIdentity() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool isUniform(int val) const throw(INTERP_KERNEL::Exception); diff --git a/src/MEDCoupling/MEDCouplingPointSet.cxx b/src/MEDCoupling/MEDCouplingPointSet.cxx index f2acae753..20d6d509a 100644 --- a/src/MEDCoupling/MEDCouplingPointSet.cxx +++ b/src/MEDCoupling/MEDCouplingPointSet.cxx @@ -257,7 +257,7 @@ DataArrayInt *MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat(const { if(!_coords) throw INTERP_KERNEL::Exception("MEDCouplingPointSet::buildNewNumberingFromCommonNodesFormat : no coords specified !"); - return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm,commIndex,newNbOfNodes); + return DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(getNumberOfNodes(),comm->begin(),commIndex->begin(),commIndex->end(),newNbOfNodes); } /* diff --git a/src/MEDCoupling/MEDCouplingUMesh.cxx b/src/MEDCoupling/MEDCouplingUMesh.cxx index 3e9083a64..20a77bf5f 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.cxx +++ b/src/MEDCoupling/MEDCouplingUMesh.cxx @@ -1384,14 +1384,12 @@ bool MEDCouplingUMesh::areCellsFrom2MeshEqual(const MEDCouplingUMesh *other, int */ bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const { - std::set cand(candidates.begin(),candidates.end()); - cand.erase(-1); - if(cand.size()<=1) + if(candidates.size()<1) return false; bool ret=false; - std::set::const_iterator iter=cand.begin(); + std::vector::const_iterator iter=candidates.begin(); int start=(*iter++); - for(;iter!=cand.end();iter++) + for(;iter!=candidates.end();iter++) { int status=areCellsEqual(start,*iter,compType); if(status!=0) @@ -1419,7 +1417,7 @@ bool MEDCouplingUMesh::areCellsEqualInPool(const std::vector& candidates, i * The nth set is [res.begin()+resI[n];res.begin()+resI[n+1]) with 0<=n -void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const +void MEDCouplingUMesh::findCommonCellsBase(int startCellId, int compType, std::vector& res, std::vector& resI) const { res.clear(); resI.clear(); resI.push_back(0); @@ -1434,7 +1432,7 @@ void MEDCouplingUMesh::findCommonCellsBase(int compType, std::vector& res, const int *connI=getNodalConnectivityIndex()->getConstPointer(); const double *coords=getCoords()->getConstPointer(); std::vector isFetched(nbOfCells); - for(int k=0;k& res, * \warning This method modifies can modify significantly the geometric type order in \a this. * In view of the MED file writing, a renumbering of cells in \a this (using MEDCouplingUMesh::sortCellsInMEDFileFrmt) should be necessary. */ -DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception) +DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType, int startCellId) throw(INTERP_KERNEL::Exception) { - int spaceDim=getSpaceDimension(); + checkConnectivityFullyDefined(); int nbOfCells=getNumberOfCells(); std::vector commonCells; - std::vector commonCellsI; - switch(spaceDim) + std::vector commonCellsI(1,0); + MEDCouplingAutoRefCountObjectPtr revNodal=DataArrayInt::New(),revNodalI=DataArrayInt::New(); + getReverseNodalConnectivity(revNodal,revNodalI); + const int *revNodalPtr=revNodal->getConstPointer(),*revNodalIPtr=revNodalI->getConstPointer(); + const int *connPtr=getNodalConnectivity()->getConstPointer(),*connIPtr=getNodalConnectivityIndex()->getConstPointer(); + std::vector isFetched(nbOfCells,false); + if(startCellId==0) { - case 3: - { - findCommonCellsBase<3>(compType,commonCells,commonCellsI); - break; - } - case 2: - { - findCommonCellsBase<2>(compType,commonCells,commonCellsI); - break; - } - case 1: - { - findCommonCellsBase<1>(compType,commonCells,commonCellsI); - break; - } - default: - throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3."); + for(int i=0;i(),-1)); + std::vector v,v2; + if(connOfNode!=connPtr+connIPtr[i+1]) + { + const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); + v2.insert(v2.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1]); + connOfNode++; + } + for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) + if(*connOfNode>=0) + { + v=v2; + const int *locRevNodal=std::find(revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],i); + std::vector::iterator it=std::set_intersection(v.begin(),v.end(),locRevNodal,revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); + v2.resize(std::distance(v2.begin(),it)); + } + if(v2.size()>1) + { + if(areCellsEqualInPool(v2,compType,commonCells)) + { + int pos=commonCellsI.back(); + commonCellsI.push_back((int)commonCells.size()); + for(std::vector::const_iterator it=commonCells.begin()+pos;it!=commonCells.end();it++) + isFetched[*it]=true; + } + } + } + } + } + else + { + for(int i=startCellId;i(),-1)); + std::vector v,v2; + if(connOfNode!=connPtr+connIPtr[i+1]) + { + v2.insert(v2.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1]); + connOfNode++; + } + for(;connOfNode!=connPtr+connIPtr[i+1] && v2.size()>1;connOfNode++) + if(*connOfNode>=0) + { + v=v2; + std::vector::iterator it=std::set_intersection(v.begin(),v.end(),revNodalPtr+revNodalIPtr[*connOfNode],revNodalPtr+revNodalIPtr[*connOfNode+1],v2.begin()); + v2.resize(std::distance(v2.begin(),it)); + } + if(v2.size()>1) + { + if(areCellsEqualInPool(v2,compType,commonCells)) + { + int pos=commonCellsI.back(); + commonCellsI.push_back((int)commonCells.size()); + for(std::vector::const_iterator it=commonCells.begin()+pos;it!=commonCells.end();it++) + isFetched[*it]=true; + } + } + } + } } + // BuildOld2NewArrayFromSurjectiveFormat2(); DataArrayInt *ret=DataArrayInt::New(); ret->alloc(nbOfCells,1); int *retPtr=ret->getPointer(); @@ -1564,8 +1616,8 @@ DataArrayInt *MEDCouplingUMesh::zipConnectivityTraducer(int compType) throw(INTE bool MEDCouplingUMesh::areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception) { MEDCouplingAutoRefCountObjectPtr mesh=MergeUMeshesOnSameCoords(this,other); - MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType); int nbOfCells=getNumberOfCells(); + MEDCouplingAutoRefCountObjectPtr o2n=mesh->zipConnectivityTraducer(compType,nbOfCells); arr=o2n->substr(nbOfCells); arr->setName(other->getName()); int tmp; @@ -1589,27 +1641,27 @@ bool MEDCouplingUMesh::areCellsIncludedIn2(const MEDCouplingUMesh *other, DataAr int spaceDim=mesh->getSpaceDimension(); std::vector commonCells; std::vector commonCellsI; + int thisNbCells=getNumberOfCells(); switch(spaceDim) { case 3: { - findCommonCellsBase<3>(7,commonCells,commonCellsI); + findCommonCellsBase<3>(thisNbCells,7,commonCells,commonCellsI); break; } case 2: { - findCommonCellsBase<2>(7,commonCells,commonCellsI); + findCommonCellsBase<2>(thisNbCells,7,commonCells,commonCellsI); break; } case 1: { - findCommonCellsBase<1>(7,commonCells,commonCellsI); + findCommonCellsBase<1>(thisNbCells,7,commonCells,commonCellsI); break; } default: throw INTERP_KERNEL::Exception("Invalid spaceDimension : must be 1, 2 or 3."); } - int thisNbCells=getNumberOfCells(); int otherNbCells=other->getNumberOfCells(); MEDCouplingAutoRefCountObjectPtr arr2=DataArrayInt::New(); arr2->alloc(otherNbCells,1); @@ -6144,7 +6196,7 @@ void MEDCouplingUMesh::MergeNodesOnUMeshesSharingSameCoords(const std::vector tmp1(comm),tmp2(commI); int oldNbOfNodes=coo->getNumberOfTuples(); int newNbOfNodes; - MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm,commI,newNbOfNodes); + MEDCouplingAutoRefCountObjectPtr o2n=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(oldNbOfNodes,comm->begin(),commI->begin(),commI->end(),newNbOfNodes); if(oldNbOfNodes==newNbOfNodes) return ; MEDCouplingAutoRefCountObjectPtr newCoords=coo->renumberAndReduce(o2n->getConstPointer(),newNbOfNodes); diff --git a/src/MEDCoupling/MEDCouplingUMesh.hxx b/src/MEDCoupling/MEDCouplingUMesh.hxx index 7da64ee50..99033bf51 100644 --- a/src/MEDCoupling/MEDCouplingUMesh.hxx +++ b/src/MEDCoupling/MEDCouplingUMesh.hxx @@ -108,7 +108,7 @@ namespace ParaMEDMEM MEDCOUPLING_EXPORT DataArrayInt *getNodeIdsInUse(int& nbrOfNodesInUse) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT DataArrayInt *zipCoordsTraducer() throw(INTERP_KERNEL::Exception); - MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception); + MEDCOUPLING_EXPORT DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool areCellsIncludedIn(const MEDCouplingUMesh *other, int compType, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT bool areCellsIncludedIn2(const MEDCouplingUMesh *other, DataArrayInt *& arr) const throw(INTERP_KERNEL::Exception); MEDCOUPLING_EXPORT void getReverseNodalConnectivity(DataArrayInt *revNodal, DataArrayInt *revNodalIndx) const throw(INTERP_KERNEL::Exception); @@ -252,7 +252,7 @@ namespace ParaMEDMEM DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation2D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); DataArrayDouble *fillExtCoordsUsingTranslAndAutoRotation3D(const MEDCouplingUMesh *mesh1D, bool isQuad) const throw(INTERP_KERNEL::Exception); template - void findCommonCellsBase(int compType, std::vector& res, std::vector& resI) const; + void findCommonCellsBase(int startCellId, int compType, std::vector& res, std::vector& resI) const; bool areCellsEqualInPool(const std::vector& candidates, int compType, std::vector& result) const; MEDCouplingUMesh *buildPartOfMySelfKeepCoords(const int *begin, const int *end) const; MEDCouplingUMesh *buildPartOfMySelfKeepCoords2(int start, int end, int step) const; diff --git a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx index 12109cc70..fe80e977c 100644 --- a/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx +++ b/src/MEDCoupling/Test/MEDCouplingBasicsTest4.cxx @@ -1892,13 +1892,13 @@ void MEDCouplingBasicsTest4::testDAIBuildOld2NewArrayFromSurjectiveFormat2() b->alloc(3,1); std::copy(arrI,arrI+3,b->getPointer()); int newNbTuple=-1; - DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a,b,newNbTuple); + DataArrayInt *ret=DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(10,a->begin(),b->begin(),b->end(),newNbTuple); const int expected[10]={0,1,2,0,3,4,5,4,6,4}; CPPUNIT_ASSERT_EQUAL(10,ret->getNbOfElems()); CPPUNIT_ASSERT_EQUAL(7,newNbTuple); CPPUNIT_ASSERT_EQUAL(1,ret->getNumberOfComponents()); CPPUNIT_ASSERT(std::equal(expected,expected+10,ret->getConstPointer())); - CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a,b,newNbTuple),INTERP_KERNEL::Exception); + CPPUNIT_ASSERT_THROW(DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(9,a->begin(),b->begin(),b->end(),newNbTuple),INTERP_KERNEL::Exception); ret->decrRef(); b->decrRef(); a->decrRef(); diff --git a/src/MEDCoupling_Swig/MEDCouplingCommon.i b/src/MEDCoupling_Swig/MEDCouplingCommon.i index daa41c36c..bc1b34711 100644 --- a/src/MEDCoupling_Swig/MEDCouplingCommon.i +++ b/src/MEDCoupling_Swig/MEDCouplingCommon.i @@ -1412,7 +1412,7 @@ namespace ParaMEDMEM DataArrayInt *sortCellsInMEDFileFrmt() throw(INTERP_KERNEL::Exception); DataArrayInt *convertCellArrayPerGeoType(const DataArrayInt *da) const throw(INTERP_KERNEL::Exception); DataArrayInt *computeFetchedNodeIds() const throw(INTERP_KERNEL::Exception); - DataArrayInt *zipConnectivityTraducer(int compType) throw(INTERP_KERNEL::Exception); + DataArrayInt *zipConnectivityTraducer(int compType, int startCellId=0) throw(INTERP_KERNEL::Exception); DataArrayInt *computeNbOfNodesPerCell() const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); MEDCouplingUMesh *buildDescendingConnectivity2(DataArrayInt *desc, DataArrayInt *descIndx, DataArrayInt *revDesc, DataArrayInt *revDescIndx) const throw(INTERP_KERNEL::Exception); @@ -4610,10 +4610,14 @@ namespace ParaMEDMEM return self->iterator(); } - static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, const DataArrayInt *arr, const DataArrayInt *arrI) throw(INTERP_KERNEL::Exception) + static PyObject *BuildOld2NewArrayFromSurjectiveFormat2(int nbOfOldTuples, PyObject *arr, PyObject *arrI) throw(INTERP_KERNEL::Exception) { int newNbOfTuples=-1; - DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arr,arrI,newNbOfTuples); + int szArr,szArrI,sw,iTypppArr,iTypppArrI; + std::vector stdvecTyyppArr,stdvecTyyppArrI; + const int *arrPtr=convertObjToPossibleCpp1_Safe(arr,sw,szArr,iTypppArr,stdvecTyyppArr); + const int *arrIPtr=convertObjToPossibleCpp1_Safe(arrI,sw,szArrI,iTypppArrI,stdvecTyyppArrI); + DataArrayInt *ret0=ParaMEDMEM::DataArrayInt::BuildOld2NewArrayFromSurjectiveFormat2(nbOfOldTuples,arrPtr,arrIPtr,arrIPtr+szArrI,newNbOfTuples); PyObject *ret=PyTuple_New(2); PyTuple_SetItem(ret,0,SWIG_NewPointerObj((void*)ret0,SWIGTYPE_p_ParaMEDMEM__DataArrayInt,SWIG_POINTER_OWN | 0)); PyTuple_SetItem(ret,1,PyInt_FromLong(newNbOfTuples));