Deactivating parallelism for 2D/1D + corrections for non parallel run + adding ParallelCompute function in Python

This commit is contained in:
Yoann Audouin 2022-09-09 09:52:50 +02:00
parent 3f96b31757
commit 446efab777
5 changed files with 70 additions and 20 deletions

View File

@ -48,6 +48,7 @@
#include <TopoDS_Iterator.hxx>
#include "memoire.h"
#include <chrono>
#ifdef WIN32
#include <windows.h>
@ -247,6 +248,9 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
TopAbs_ShapeEnum previousShapeType = TopAbs_VERTEX;
std::vector<std::future<void>> pending;
int nbThreads = aMesh.GetNbThreads();
auto begin = std::chrono::high_resolution_clock::now();
smIt = shapeSM->getDependsOnIterator(includeSelf, !complexShapeFirst);
while ( smIt->more() )
@ -258,13 +262,17 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
const TopAbs_ShapeEnum shapeType = shape.ShapeType();
if ( !aMesh.HasShapeToMesh() && shapeType == TopAbs_VERTEX )
continue;
if(shapeType==TopAbs_FACE||shapeType==TopAbs_EDGE)
aMesh.SetNbThreads(0);
else
aMesh.SetNbThreads(nbThreads);
//DEBUG std::cout << "Shape Type" << shapeType << " previous" << previousShapeType << std::endl;
if (aMesh.IsParallel() && shapeType != previousShapeType) {
if ((aMesh.IsParallel()||nbThreads!=0) && shapeType != previousShapeType) {
// Waiting for all threads for the previous type to end
for(auto &it: pending){
it.wait();
}
std::string file_name;
switch(previousShapeType){
case TopAbs_FACE:
@ -276,6 +284,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
case TopAbs_VERTEX:
file_name = "Mesh0D.med";
break;
case TopAbs_SOLID:
default:
file_name = "";
break;
@ -306,10 +315,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
shapeSM, aShapeOnly, allowedSubShapes,
aShapesId));
} else {
auto begin2 = std::chrono::high_resolution_clock::now();
compute_function(1 ,smToCompute, computeEvent,
shapeSM, aShapeOnly, allowedSubShapes,
aShapesId);
if (smToCompute->GetComputeState() == SMESH_subMesh::FAILED_TO_COMPUTE &&
( shapeType != TopAbs_EDGE || !SMESH_Algo::isDegenerated( TopoDS::Edge( shape ))))
ret = false;
@ -328,6 +341,14 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
}
aMesh.GetMeshDS()->Modified();
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
std::cout << "Time for All: " << elapsed.count()*1e-9 << std::endl;
// Pool of thread for computation
if(aMesh.IsParallel())
aMesh.DeletePoolThreads();
return ret;
}
else
@ -338,7 +359,7 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// the most complex shapes and collect sub-meshes with algos that
// DO support sub-meshes
// ================================================================
auto begin = std::chrono::high_resolution_clock::now();
list< SMESH_subMesh* > smWithAlgoSupportingSubmeshes[4]; // for each dim
// map to sort sm with same dim algos according to dim of
@ -534,7 +555,12 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
continue;
sm->SetAllowedSubShapes( fillAllowed( shapeSM, aShapeOnly, allowedSubShapes ));
setCurrentSubMesh( sm );
auto begin = std::chrono::high_resolution_clock::now();
sm->ComputeStateEngine( computeEvent );
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
std::cout << "Time for seq:alldim:compute: " << elapsed.count()*1e-9 << std::endl;
setCurrentSubMesh( NULL );
sm->SetAllowedSubShapes( nullptr );
if ( aShapesId )
@ -547,6 +573,10 @@ bool SMESH_Gen::Compute(SMESH_Mesh & aMesh,
// mesh the rest sub-shapes starting from vertices
// -----------------------------------------------
ret = Compute( aMesh, aShape, aFlags | UPWARD, aDim, aShapesId, allowedSubShapes );
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
std::cout << "Time for All: " << elapsed.count()*1e-9 << std::endl;
}
MEMOSTAT;

View File

@ -394,6 +394,7 @@ class SMESH_EXPORT SMESH_Mesh
void SetNbThreads(int nbThreads){_NbThreads=nbThreads;};
void InitPoolThreads(){_pool = new ctpl::thread_pool(_NbThreads);};
void DeletePoolThreads(){delete _pool;};
bool IsParallel(){return _NbThreads > 0;}

View File

@ -65,7 +65,7 @@ using namespace std;
//#define PRINT_WHO_COMPUTE_WHAT
#endif
#define PRINT_WHO_COMPUTE_WHAT
//#define PRINT_WHO_COMPUTE_WHAT
//=============================================================================
/*!
* \brief Allocate some memory at construction and release it at destruction.
@ -1519,6 +1519,7 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event)
break;
}
TopoDS_Shape shape = _subShape;
if(!_father->IsParallel())
algo->SubMeshesToCompute().assign( 1, this );
// check submeshes needed
// In parallel there would be no submesh to check

View File

@ -1863,8 +1863,28 @@ class Mesh(metaclass = MeshMeta):
geom = self.geom
return self.smeshpyD.Evaluate(self.mesh, geom)
def ParallelCompute(self, nbThreads, geom=0, discardModifs=False, refresh=False):
"""
Parallel computation of the mesh and return the status of the computation
The mesh must contains have be constructed using create_parallel_mesh
def Compute(self, geom=0, discardModifs=False, refresh=False, nbThreads=0):
Parameters:
nbThreads: Number of threads to use for a parallel computation
geom: geomtrical shape on which mesh data should be computed
discardModifs: if True and the mesh has been edited since
a last total re-compute and that may prevent successful partial re-compute,
then the mesh is cleaned before Compute()
refresh: if *True*, Object Browser is automatically updated (when running in GUI)
Returns:
True or False
"""
if (nbThreads <= 1):
raise ValueError("nbThreads must be greater than 1")
self.mesh.SetNbThreads(nbThreads)
return self.Compute(geom=geom, discardModifs=discardModifs, refresh=refresh)
def Compute(self, geom=0, discardModifs=False, refresh=False):
"""
Compute the mesh and return the status of the computation
@ -1886,8 +1906,6 @@ class Mesh(metaclass = MeshMeta):
try:
if discardModifs and self.mesh.HasModificationsToDiscard(): # issue 0020693
self.mesh.Clear()
# Setting parallel parameters
self.mesh.SetNbThreads(nbThreads)
ok = self.smeshpyD.Compute(self.mesh, geom)
except SALOME.SALOME_Exception as ex:
print("Mesh computation failed, exception caught:")

View File

@ -133,15 +133,15 @@ bool StdMeshers_Regular_1D::CheckHypothesis( SMESH_Mesh& aMesh,
// find non-auxiliary hypothesis
const SMESHDS_Hypothesis *theHyp = 0;
set< string > propagTypes;
std::cout << "For shape " << aShape.HashCode(1) << " of type "<< aShape.ShapeType() <<
"CheckHypothesis" << std::endl;
for(auto hyp:hyps){
SMESH_Comment hypStr;
hypStr << hyp << " " << hyp->GetName() << " ";
((SMESHDS_Hypothesis*)hyp)->SaveTo( hypStr.Stream() );
hypStr << " ";
std::cout << hypStr << std::endl;
}
//std::cout << "For shape " << aShape.HashCode(1) << " of type "<< aShape.ShapeType() <<
// "CheckHypothesis" << std::endl;
// for(auto hyp:hyps){
// SMESH_Comment hypStr;
// hypStr << hyp << " " << hyp->GetName() << " ";
// ((SMESHDS_Hypothesis*)hyp)->SaveTo( hypStr.Stream() );
// hypStr << " ";
// std::cout << hypStr << std::endl;
// }
list <const SMESHDS_Hypothesis * >::const_iterator h = hyps.begin();
for ( ; h != hyps.end(); ++h ) {
if ( static_cast<const SMESH_Hypothesis*>(*h)->IsAuxiliary() ) {
@ -1218,7 +1218,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
const SMDS_MeshNode * nLast = SMESH_Algo::VertexNode( VLast, meshDS );
if ( !nFirst || !nLast ){
theMesh.Unlock();
std::cout << "exit no node" << std::endl;
//std::cout << "exit no node" << std::endl;
return error( COMPERR_BAD_INPUT_MESH, "No node on vertex");
}
// remove elements created by e.g. pattern mapping (PAL21999)
@ -1265,7 +1265,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
BRepAdaptor_Curve C3d( E );
if ( ! computeInternalParameters( theMesh, C3d, length, f, l, params, reversed, true )) {
theMesh.Unlock();
std::cout << "exit Compute internal failed" << std::endl;
//std::cout << "exit Compute internal failed" << std::endl;
return false;
}
@ -1358,7 +1358,7 @@ bool StdMeshers_Regular_1D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & t
}
}
theMesh.Unlock();
std::cout << "exit normal" << std::endl;
//std::cout << "exit normal" << std::endl;
return true;
}