From 5d3c1425f83862a5a3616e3128f70341637216ba Mon Sep 17 00:00:00 2001 From: Yoann Audouin Date: Tue, 30 Aug 2022 09:42:21 +0200 Subject: [PATCH] Adding SetNbThreads in Python to set if compute will be done in parallel --- idl/SMESH_Mesh.idl | 48 ++++++++++++++++++---------------- src/SMESH/SMESH_Mesh.hxx | 6 +++++ src/SMESH/SMESH_subMesh.cxx | 9 ++----- src/SMESH_I/SMESH_2smeshpy.cxx | 2 +- src/SMESH_I/SMESH_Mesh_i.cxx | 18 ++++++++++--- src/SMESH_I/SMESH_Mesh_i.hxx | 6 +++-- src/SMESH_SWIG/smeshBuilder.py | 5 +++- 7 files changed, 57 insertions(+), 37 deletions(-) diff --git a/idl/SMESH_Mesh.idl b/idl/SMESH_Mesh.idl index bfbb0cdd5..e70b3d842 100644 --- a/idl/SMESH_Mesh.idl +++ b/idl/SMESH_Mesh.idl @@ -156,7 +156,7 @@ module SMESH Geom_BALL, Geom_LAST }; - + /*! * ElementOrder points out entities of what order are requested */ @@ -238,7 +238,7 @@ module SMESH DRS_FAIL // general failure (exception etc.) }; - /*! + /*! * \brief A structure containing information about MED file */ struct MedFileInfo @@ -263,7 +263,7 @@ module SMESH */ const long EXTRUSION_FLAG_BOUNDARY = 1; const long EXTRUSION_FLAG_SEW = 2; - + /*! * Structure used in mesh edit preview data (MeshPreviewStruct) */ @@ -344,7 +344,7 @@ module SMESH /*! * Get geom shape to mesh. A result should not be nil. Use HasShapeToMesh() - * to know if a returned shape + * to know if a returned shape */ GEOM::GEOM_Object GetShapeToMesh() raises (SALOME::SALOME_Exception); @@ -457,7 +457,7 @@ module SMESH in SMESH_GroupBase aGroup2, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Union of list of groups * New group is created. All mesh elements that are @@ -476,7 +476,7 @@ module SMESH in SMESH_GroupBase aGroup2, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Intersection of list of groups * New group is created. All mesh elements that are @@ -495,7 +495,7 @@ module SMESH in SMESH_GroupBase aToolGroup, in string name ) raises (SALOME::SALOME_Exception); - + /*! * Cut of lists of groups * New group is created. All mesh elements that are present in @@ -505,14 +505,14 @@ module SMESH in ListOfGroups aToolGroups, in string name) raises (SALOME::SALOME_Exception); - + /*! * Create a group of entities basing on nodes of other groups. * \param [in] aListOfGroups - list of either groups, sub-meshes or filters. * \param [in] anElemType - a type of elements to include to the new group. * \param [in] name - a name of the new group. * \param [in] nbCommonNodes - criterion of inclusion of an element to the new group. - * \param [in] underlyingOnly - if \c True, an element is included to the + * \param [in] underlyingOnly - if \c True, an element is included to the * new group provided that it is based on nodes of an element of * \a aListOfGroups * \return SMESH_Group - the created group @@ -679,12 +679,12 @@ module SMESH * med files in 4.0.0 (default format) or 3.2.1 or 3.3.1 formats. * The minor must be between 0 and the current minor version of MED file library. * If version is equal to -1, the version is not changed (default). - * - autoDimension : if @c True, a space dimension for export is defined by mesh + * - autoDimension : if @c True, a space dimension for export is defined by mesh * configuration; for example a planar mesh lying on XOY plane - * will be exported as a mesh in 2D space. + * will be exported as a mesh in 2D space. * If @a autoDimension == @c False, the space dimension is 3. * - fields : list of GEOM fields defined on the shape to mesh. - * - geomAssocFields : each character of this string means a need to export a + * - geomAssocFields : each character of this string means a need to export a * corresponding field; correspondence between fields and characters is following: * - 'v' stands for _vertices_ field; * - 'e' stands for _edges_ field; @@ -724,7 +724,7 @@ module SMESH * encoded in 10*major+minor (for instance, code for med 3.2.1 is 32) */ long_array GetMEDVersionsCompatibleForAppend(); - + /*! * Export Mesh to different Formats * (UNV supported version is I-DEAS 10) @@ -735,17 +735,17 @@ module SMESH in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportSTL( in string file, in boolean isascii ) raises (SALOME::SALOME_Exception); - void ExportCGNS( in SMESH_IDSource meshPart, + void ExportCGNS( in SMESH_IDSource meshPart, in string file, in boolean overwrite, in boolean groupElemsByType) raises (SALOME::SALOME_Exception); - void ExportGMF( in SMESH_IDSource meshPart, + void ExportGMF( in SMESH_IDSource meshPart, in string file, in boolean withRequiredGroups) raises (SALOME::SALOME_Exception); - void ExportPartToDAT( in SMESH_IDSource meshPart, + void ExportPartToDAT( in SMESH_IDSource meshPart, in string file, in boolean renumer ) raises (SALOME::SALOME_Exception); - void ExportPartToUNV( in SMESH_IDSource meshPart, + void ExportPartToUNV( in SMESH_IDSource meshPart, in string file, in boolean renumer ) raises (SALOME::SALOME_Exception); void ExportPartToSTL( in SMESH_IDSource meshPart, @@ -857,10 +857,10 @@ module SMESH smIdType_array GetNodesId() raises (SALOME::SALOME_Exception); - + /*! * Returns type of mesh element - */ + */ ElementType GetElementType( in smIdType id, in boolean iselem ) raises (SALOME::SALOME_Exception); @@ -875,7 +875,7 @@ module SMESH smIdType_array GetSubMeshNodesId(in long ShapeID, in boolean all ) raises (SALOME::SALOME_Exception); - + ElementType GetSubMeshElementType(in long ShapeID) raises (SALOME::SALOME_Exception); @@ -899,6 +899,10 @@ module SMESH */ boolean SetMeshOrder(in submesh_array_array theSubMeshArray); + /*! + * \brief Set Number of Threads + */ + void SetNbThreads(in long nbThreads); /*! * Get mesh description @@ -939,7 +943,7 @@ module SMESH long GetShapeID(in smIdType id); /*! - * For given element returns ID of result shape after + * For given element returns ID of result shape after * ::FindShape() from SMESH_MeshEditor * If there is not element for given ID - returns -1 */ @@ -1072,7 +1076,7 @@ module SMESH */ smIdType_array GetElementsByType( in ElementType theType ) raises (SALOME::SALOME_Exception); - + /*! * Returns type of mesh element (same as SMESH_Mesh::GetElementType() ) */ diff --git a/src/SMESH/SMESH_Mesh.hxx b/src/SMESH/SMESH_Mesh.hxx index 46a6ddc27..2b8632abb 100644 --- a/src/SMESH/SMESH_Mesh.hxx +++ b/src/SMESH/SMESH_Mesh.hxx @@ -385,9 +385,14 @@ class SMESH_EXPORT SMESH_Mesh std::ostream& Dump(std::ostream & save); + // Data for parallel computation + void Lock() {_my_lock.lock();}; void Unlock() {_my_lock.unlock();}; + int GetNbThreads(){return _NbThreads;}; + void SetNbThreads(int nbThreads){_NbThreads=nbThreads;}; + // Temporary folder used during parallel Computation boost::filesystem::path tmp_folder; @@ -439,6 +444,7 @@ protected: // Mutex for multhitreading write in SMESH_Mesh std::mutex _my_lock; + int _NbThreads=0; protected: SMESH_Mesh(); diff --git a/src/SMESH/SMESH_subMesh.cxx b/src/SMESH/SMESH_subMesh.cxx index 651b74af3..751cf8b79 100644 --- a/src/SMESH/SMESH_subMesh.cxx +++ b/src/SMESH/SMESH_subMesh.cxx @@ -271,8 +271,7 @@ bool SMESH_subMesh::IsMeshComputed() const TopExp_Explorer exp( _subShape, (TopAbs_ShapeEnum) type ); for ( ; exp.More(); exp.Next() ) { - SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ); - if ( smDS ) + if ( SMESHDS_SubMesh * smDS = meshDS->MeshElements( exp.Current() ) ) { bool computed = (dim > 0) ? smDS->NbElements() : smDS->NbNodes(); if ( computed ) @@ -1595,7 +1594,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) } else { - // TODO: Replace by call to ParallelCompute ret = algo->Compute((*_father), shape); } // algo can set _computeError of submesh @@ -1656,7 +1654,6 @@ bool SMESH_subMesh::ComputeStateEngine(compute_event event) bool isComputeErrorSet = !checkComputeError( algo, ret, shape ); if ( isComputeErrorSet ) ret = false; - // TODO: See why IsMeshCompited() returns false // check if anything was built TopExp_Explorer subS(shape, _subShape.ShapeType()); if ( ret ) @@ -2053,9 +2050,7 @@ bool SMESH_subMesh::checkComputeError(SMESH_Algo* theAlgo, if ( !_computeError || _computeError->IsOK() ) { // no error description is set to this sub-mesh, check if any mesh is computed - //TODO: See why this does not work - //_computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; - _computeState = COMPUTE_OK; + _computeState = IsMeshComputed() ? COMPUTE_OK : FAILED_TO_COMPUTE; if ( _computeState != COMPUTE_OK ) { if ( _subShape.ShapeType() == TopAbs_EDGE && diff --git a/src/SMESH_I/SMESH_2smeshpy.cxx b/src/SMESH_I/SMESH_2smeshpy.cxx index 03a600094..a062e3d2f 100644 --- a/src/SMESH_I/SMESH_2smeshpy.cxx +++ b/src/SMESH_I/SMESH_2smeshpy.cxx @@ -2212,7 +2212,7 @@ bool _pyMesh::NeedMeshAccess( const Handle(_pyCommand)& theCommand ) "GetElemNode","IsMediumNode","IsMediumNodeOfAnyElem","ElemNbEdges","ElemNbFaces", "GetElemFaceNodes", "GetFaceNormal", "FindElementByNodes", "IsPoly","IsQuadratic","BaryCenter","GetHypothesisList", "SetAutoColor", "GetAutoColor", - "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder" + "Clear", "ConvertToStandalone", "GetMeshOrder", "SetMeshOrder", "SetNbThreads" ,"" }; // <- mark of end sameMethods.Insert( names ); } diff --git a/src/SMESH_I/SMESH_Mesh_i.cxx b/src/SMESH_I/SMESH_Mesh_i.cxx index b307c7bbb..a7abda6db 100644 --- a/src/SMESH_I/SMESH_Mesh_i.cxx +++ b/src/SMESH_I/SMESH_Mesh_i.cxx @@ -2506,7 +2506,7 @@ void SMESH_Mesh_i::CheckGeomModif( bool theIsBreakLink ) } old2newShapeMap.Bind( group->GetShape(), groupsData.back()._shape ); } - + } } // store assigned hypotheses @@ -6170,8 +6170,8 @@ SMESH::SMESH_Mesh_ptr SMESH_Mesh_i::GetMesh() /*! * \brief Return false if GetMeshInfo() return incorrect information that may * happen if mesh data is not yet fully loaded from the file of study. - * - * + * + * */ //================================================================================ @@ -7037,6 +7037,16 @@ TListOfListOfInt SMESH_Mesh_i::findConcurrentSubMeshes() return res; } +//============================================================================= +/*! + * \brief Set the number of threads for a parallel computation + */ +//============================================================================= +void SMESH_Mesh_i::SetNbThreads(int nbThreads){ + _impl->SetNbThreads(nbThreads); +} + + //============================================================================= /*! * \brief Convert submesh ids into submesh interfaces @@ -7229,7 +7239,7 @@ smIdType SMESH_MeshPartDS::MinNodeID() const { if ( _meshDS ) return _meshDS->MinNodeID(); return NbNodes() == 0 ? 0 : (*_elements[ SMDSAbs_Node ].begin())->GetID(); -} +} // ------------------------------------------------------------------------------------- smIdType SMESH_MeshPartDS::MaxElementID() const { diff --git a/src/SMESH_I/SMESH_Mesh_i.hxx b/src/SMESH_I/SMESH_Mesh_i.hxx index 8a50d1226..25892ca9d 100644 --- a/src/SMESH_I/SMESH_Mesh_i.hxx +++ b/src/SMESH_I/SMESH_Mesh_i.hxx @@ -226,7 +226,7 @@ public: const char* file, CORBA::Boolean withRequiredGroups); - + template void ExportPartToMEDCommon(SPECLS& speCls, SMESH::SMESH_IDSource_ptr meshPart, @@ -571,7 +571,7 @@ public: * Persistence of geometry tick */ int& MainShapeTick() { return _mainShapeTick; } - + /*! * Sets list of notebook variables used for Mesh operations separated by ":" symbol @@ -673,6 +673,8 @@ private: SMESH::submesh_array_array& theSubMeshOrder, const bool theIsDump); + void SetNbThreads(int nbThreads); + /*! * \brief Finds concurrent sub-meshes */ diff --git a/src/SMESH_SWIG/smeshBuilder.py b/src/SMESH_SWIG/smeshBuilder.py index 62db88951..19ae2a934 100644 --- a/src/SMESH_SWIG/smeshBuilder.py +++ b/src/SMESH_SWIG/smeshBuilder.py @@ -1864,7 +1864,7 @@ class Mesh(metaclass = MeshMeta): return self.smeshpyD.Evaluate(self.mesh, geom) - def Compute(self, geom=0, discardModifs=False, refresh=False): + def Compute(self, geom=0, discardModifs=False, refresh=False, nbThreads=0): """ Compute the mesh and return the status of the computation @@ -1874,6 +1874,7 @@ class Mesh(metaclass = MeshMeta): 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) + nbThreads: Number of threads to use for a parallel computation Returns: True or False @@ -1885,6 +1886,8 @@ 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:")