From 1950f7fd36d29c0d6e2cc35b695c3e5dcd1032c9 Mon Sep 17 00:00:00 2001 From: Christophe Bourcier Date: Thu, 19 Jan 2017 14:41:14 +0100 Subject: [PATCH] Adding multithread computation (available since MeshGems-2.4-2) By default, 4 threads are used (same default as in CADSurf). --- idl/BLSURFPlugin_Algorithm.idl | 9 ++ src/BLSURFPlugin/BLSURFPluginBuilder.py | 7 ++ src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx | 3 + src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx | 21 +++++ src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx | 3 + .../BLSURFPlugin_Hypothesis_i.cxx | 25 ++++++ .../BLSURFPlugin_Hypothesis_i.hxx | 3 + src/GUI/BLSURFPlugin_msg_en.ts | 4 + src/GUI/BLSURFPlugin_msg_fr.ts | 4 + src/GUI/BLSURFPlugin_msg_ja.ts | 4 + tests/CMakeLists.txt | 1 + tests/test_cadsurf_multithread.py | 83 +++++++++++++++++++ 12 files changed, 167 insertions(+) create mode 100644 tests/test_cadsurf_multithread.py diff --git a/idl/BLSURFPlugin_Algorithm.idl b/idl/BLSURFPlugin_Algorithm.idl index 545282a..141982f 100644 --- a/idl/BLSURFPlugin_Algorithm.idl +++ b/idl/BLSURFPlugin_Algorithm.idl @@ -353,6 +353,15 @@ module BLSURFPlugin void SetMaxNumberOfPointsPerPatch( in long nb ) raises (SALOME::SALOME_Exception); long GetMaxNumberOfPointsPerPatch(); + + /*! + * Set max_number_of_threads parameter + * + * Set the maximum of threads to use for multithreading mesh computation. + */ + void SetMaxNumberOfThreads( in long nb ) raises (SALOME::SALOME_Exception); + long GetMaxNumberOfThreads(); + /*! * Set respect_geometry parameter * diff --git a/src/BLSURFPlugin/BLSURFPluginBuilder.py b/src/BLSURFPlugin/BLSURFPluginBuilder.py index 8fcb6e9..af4e99d 100644 --- a/src/BLSURFPlugin/BLSURFPluginBuilder.py +++ b/src/BLSURFPlugin/BLSURFPluginBuilder.py @@ -251,6 +251,13 @@ class BLSURF_Algorithm(Mesh_Algorithm): def SetMaxNumberOfPointsPerPatch( self, nb ): self.Parameters().SetMaxNumberOfPointsPerPatch( nb ) + ## Set max_number_of_threads parameter + # + # Set the maximum of threads to use for multithreading mesh computation + # + def SetMaxNumberOfThreads( self, nb ): + self.Parameters().SetMaxNumberOfThreads( nb ) + ## Set respect_geometry parameter # # This patch independent option can be deactivated to allow MeshGems-CADSurf diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx index 3679c02..0cb1a1b 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx @@ -1918,6 +1918,9 @@ bool BLSURFPlugin_BLSURF::compute(SMESH_Mesh& aMesh, cad_t *c = cad_new(ctx); dcad_t *dcad = dcad_new(c); + // To enable multithreading + cad_set_thread_safety(c, 1); + /* Now fill the CAD object with data from your CAD * environement. This is the most complex part of a successfull * integration. diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx index 6790461..818b589 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.cxx @@ -121,6 +121,7 @@ BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, int studyId, SMESH_G }; const char* intOptionNames[] = { "max_number_of_points_per_patch", // default = 100000 + "max_number_of_threads", // default = 4 "" // mark of end }; const char* doubleOptionNames[] = { // "surface_intersections_processing_max_cost",// default = 15 @@ -206,6 +207,7 @@ BLSURFPlugin_Hypothesis::BLSURFPlugin_Hypothesis(int hypId, int studyId, SMESH_G _defaultOptionValues["enforce_cad_edge_sizes" ] = "no"; _defaultOptionValues["jacobian_rectification_respect_geometry"] = "yes"; _defaultOptionValues["max_number_of_points_per_patch" ] = "0"; + _defaultOptionValues["max_number_of_threads" ] = "4"; _defaultOptionValues["rectify_jacobian" ] = "yes"; _defaultOptionValues["respect_geometry" ] = "yes"; _defaultOptionValues["tiny_edge_avoid_surface_intersections" ] = "yes"; @@ -555,6 +557,25 @@ int BLSURFPlugin_Hypothesis::GetMaxNumberOfPointsPerPatch() } //============================================================================= +void BLSURFPlugin_Hypothesis::SetMaxNumberOfThreads( int nb ) + throw (std::invalid_argument) +{ + if ( nb < 0 ) + throw std::invalid_argument( SMESH_Comment("Invalid number of threads: ") << nb ); + + if ( GetMaxNumberOfThreads() != nb ) + { + SetOptionValue("max_number_of_threads", SMESH_Comment( nb )); + NotifySubMeshesHypothesisModification(); + } +} +//============================================================================= +int BLSURFPlugin_Hypothesis::GetMaxNumberOfThreads() +{ + return ToInt( GetOptionValue("max_number_of_threads", GET_DEFAULT())); +} +//============================================================================= + void BLSURFPlugin_Hypothesis::SetRespectGeometry( bool toRespect ) { if ( GetRespectGeometry() != toRespect ) diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx index 2f5299b..1ed9675 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis.hxx @@ -163,6 +163,9 @@ public: void SetMaxNumberOfPointsPerPatch( int nb ) throw (std::invalid_argument); int GetMaxNumberOfPointsPerPatch(); + void SetMaxNumberOfThreads( int nb ) throw (std::invalid_argument); + int GetMaxNumberOfThreads(); + void SetRespectGeometry( bool toRespect ); bool GetRespectGeometry(); diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx index 395ef2e..b8c6677 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.cxx @@ -854,6 +854,28 @@ CORBA::Long BLSURFPlugin_Hypothesis_i::GetMaxNumberOfPointsPerPatch() } //============================================================================= +void BLSURFPlugin_Hypothesis_i::SetMaxNumberOfThreads( CORBA::Long nb ) throw (SALOME::SALOME_Exception) +{ + if ( GetMaxNumberOfThreads() != nb ) + { + try { + this->GetImpl()->SetMaxNumberOfThreads(nb); + + } catch (const std::invalid_argument& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } catch (SALOME_Exception& ex) { + THROW_SALOME_CORBA_EXCEPTION( ex.what() ,SALOME::BAD_PARAM ); + } + SMESH::TPythonDump() << _this() << ".SetMaxNumberOfThreads( " << nb << " )"; + } +} +//============================================================================= +CORBA::Long BLSURFPlugin_Hypothesis_i::GetMaxNumberOfThreads() +{ + return this->GetImpl()->GetMaxNumberOfThreads(); +} +//============================================================================= + void BLSURFPlugin_Hypothesis_i::SetRespectGeometry( CORBA::Boolean toRespect ) { if ( GetRespectGeometry() != toRespect ) @@ -1193,6 +1215,9 @@ void BLSURFPlugin_Hypothesis_i::SetOptionValue(const char* optionName, const cha else if ( name == "max_number_of_points_per_patch" ) SetMaxNumberOfPointsPerPatch( GetImpl()->ToInt( optionValue )); + else if ( name == "max_number_of_threads" ) + SetMaxNumberOfThreads( GetImpl()->ToInt( optionValue )); + else if ( name == "rectify_jacobian" ) SetJacobianRectification( GetImpl()->ToBool( optionValue )); diff --git a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx index d711253..6a55caa 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx +++ b/src/BLSURFPlugin/BLSURFPlugin_Hypothesis_i.hxx @@ -144,6 +144,9 @@ public: void SetMaxNumberOfPointsPerPatch( CORBA::Long nb ) throw (SALOME::SALOME_Exception); CORBA::Long GetMaxNumberOfPointsPerPatch(); + void SetMaxNumberOfThreads( CORBA::Long nb ) throw (SALOME::SALOME_Exception); + CORBA::Long GetMaxNumberOfThreads(); + void SetRespectGeometry( CORBA::Boolean toRespect ); CORBA::Boolean GetRespectGeometry(); diff --git a/src/GUI/BLSURFPlugin_msg_en.ts b/src/GUI/BLSURFPlugin_msg_en.ts index caa0fa0..a866bd4 100644 --- a/src/GUI/BLSURFPlugin_msg_en.ts +++ b/src/GUI/BLSURFPlugin_msg_en.ts @@ -629,6 +629,10 @@ The smaller this distance is, the closer the mesh is to the exact surface (only max_number_of_points_per_patch Maximal number of points per patch + + max_number_of_threads + Maximal number of threads + rectify_jacobian Rectify Jacobian diff --git a/src/GUI/BLSURFPlugin_msg_fr.ts b/src/GUI/BLSURFPlugin_msg_fr.ts index f93cdd5..259cd86 100755 --- a/src/GUI/BLSURFPlugin_msg_fr.ts +++ b/src/GUI/BLSURFPlugin_msg_fr.ts @@ -629,6 +629,10 @@ Plus la distance est petite, plus le maillage sera proche de la surface (disponi max_number_of_points_per_patch Nombre de points maximal par patch + + max_number_of_threads + Nombre de threads maximal + rectify_jacobian Ajustement du Jacobien diff --git a/src/GUI/BLSURFPlugin_msg_ja.ts b/src/GUI/BLSURFPlugin_msg_ja.ts index 37bc0e1..96534dd 100644 --- a/src/GUI/BLSURFPlugin_msg_ja.ts +++ b/src/GUI/BLSURFPlugin_msg_ja.ts @@ -618,6 +618,10 @@ max_number_of_points_per_patch 1パッチの最大点数 + + max_number_of_threads + Maximal number of threads + rectify_jacobian ヤコビアンの修正 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b663c63..07dec00 100755 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -18,6 +18,7 @@ # SET(BLSURFPLUGIN_TEST_FILES + test_cadsurf_multithread.py test_enforced_internal_vertex.py test_enforced_vertex.py test_periodicity_2D_precad.py diff --git a/tests/test_cadsurf_multithread.py b/tests/test_cadsurf_multithread.py new file mode 100644 index 0000000..62e8f0a --- /dev/null +++ b/tests/test_cadsurf_multithread.py @@ -0,0 +1,83 @@ +# -*- coding: utf-8 -*- + +import os +import sys +import salome +import time + +salome.salome_init() +theStudy = salome.myStudy + +### +### GEOM component +### + +import GEOM +from salome.geom import geomBuilder +import math +import SALOMEDS + + +geompy = geomBuilder.New(theStudy) + +O = geompy.MakeVertex(0, 0, 0) +OX = geompy.MakeVectorDXDYDZ(1, 0, 0) +OY = geompy.MakeVectorDXDYDZ(0, 1, 0) +OZ = geompy.MakeVectorDXDYDZ(0, 0, 1) +flight_solid_brep_1 = geompy.ImportBREP(os.path.join(os.getenv("DATA_DIR"),"Shapes/Brep/flight_solid.brep" )) +geompy.addToStudy( O, 'O' ) +geompy.addToStudy( OX, 'OX' ) +geompy.addToStudy( OY, 'OY' ) +geompy.addToStudy( OZ, 'OZ' ) +geompy.addToStudy( flight_solid_brep_1, 'flight_solid.brep_1' ) + +### +### SMESH component +### + +import SMESH, SALOMEDS +from salome.smesh import smeshBuilder + +smesh = smeshBuilder.New(theStudy) + +Mesh_1 = smesh.Mesh(flight_solid_brep_1) +MG_CADSurf = Mesh_1.Triangle(algo=smeshBuilder.MG_CADSurf) +MG_CADSurf_Parameters_1 = MG_CADSurf.Parameters() +MG_CADSurf_Parameters_1.SetPhySize( 1 ) +MG_CADSurf_Parameters_1.SetMaxSize( 1 ) +MG_CADSurf_Parameters_1.SetGradation( 1.05 ) +MG_CADSurf_Parameters_1.SetAngleMesh( 1 ) +MG_CADSurf_Parameters_1.SetChordalError( 2.40018 ) +# 4 procs are used by default +# => No need to set an option + +time0 = time.time() +isDone = Mesh_1.Compute() +time1 = time.time() + +time_multithread = time1-time0 + +print "Time in 4 proc: %.3s"%(time_multithread) + +Mesh_2 = smesh.Mesh(flight_solid_brep_1) +MG_CADSurf = Mesh_2.Triangle(algo=smeshBuilder.MG_CADSurf) +MG_CADSurf_Parameters_2 = MG_CADSurf.Parameters() +MG_CADSurf_Parameters_2.SetPhySize( 1 ) +MG_CADSurf_Parameters_2.SetMaxSize( 1 ) +MG_CADSurf_Parameters_2.SetGradation( 1.05 ) +MG_CADSurf_Parameters_2.SetAngleMesh( 1 ) +MG_CADSurf_Parameters_2.SetChordalError( 2.40018 ) +# Use only one thread +MG_CADSurf_Parameters_2.SetMaxNumberOfThreads( 1 ) + +time2 = time.time() +isDone = Mesh_2.Compute() +time3 = time.time() + +time_singlethread = time3-time2 +print "Time in 1 proc: %.3s"%(time_singlethread) + +assert time_multithread < time_singlethread/2. + +if salome.sg.hasDesktop(): + salome.sg.updateObjBrowser(True) -- 2.39.2