From 6a7030b81a658fb74d68d059a3576e5cec3dfdfb Mon Sep 17 00:00:00 2001 From: Matthias Hochsteger Date: Thu, 26 Sep 2019 16:15:50 +0200 Subject: [PATCH] Activate multithreading when meshing from GUI - Meshing options for parallelization and number of threads - RegionTaskManager() to locally start the TaskManager --- libsrc/core/taskmanager.hpp | 35 ++++++++++++++++++++++++++++++++++ libsrc/meshing/delaunay.cpp | 23 ++++++++++++---------- libsrc/meshing/meshfunc.cpp | 1 + libsrc/meshing/meshtype.hpp | 3 +++ libsrc/meshing/python_mesh.hpp | 4 ++++ ng/dialog.tcl | 20 +++++++++++++++---- ng/ngpkg.cpp | 3 +++ ng/onetcl.cpp | 22 +++++++++++++++++---- ng/variables.tcl | 5 +++++ 9 files changed, 98 insertions(+), 18 deletions(-) diff --git a/libsrc/core/taskmanager.hpp b/libsrc/core/taskmanager.hpp index f0b67746..e5a7313b 100644 --- a/libsrc/core/taskmanager.hpp +++ b/libsrc/core/taskmanager.hpp @@ -133,6 +133,41 @@ namespace ngcore NGCORE_API int EnterTaskManager (); NGCORE_API void ExitTaskManager (int num_threads); + class RegionTaskManager + { + int nthreads_before; + int nthreads; + bool started_taskmanager; + + public: + RegionTaskManager(int anthreads=TaskManager::GetMaxThreads()) + : nthreads(anthreads) + { + if(task_manager || nthreads==0) + { + // already running, no need to do anything + started_taskmanager = false; + return; + } + else + { + nthreads_before = TaskManager::GetMaxThreads(); + TaskManager::SetNumThreads(nthreads); + nthreads = EnterTaskManager(); + started_taskmanager = true; + } + } + + ~RegionTaskManager() + { + if(started_taskmanager) + { + ExitTaskManager(nthreads); + TaskManager::SetNumThreads(nthreads_before); + } + } + }; + NETGEN_INLINE int TasksPerThread (int tpt) { // return task_manager ? tpt*task_manager->GetNumThreads() : 1; diff --git a/libsrc/meshing/delaunay.cpp b/libsrc/meshing/delaunay.cpp index e562b6a6..01ed9dad 100644 --- a/libsrc/meshing/delaunay.cpp +++ b/libsrc/meshing/delaunay.cpp @@ -1092,19 +1092,22 @@ namespace netgen // tempmesh.PrintMemInfo(cout); // tempmesh.Save ("tempmesh.vol"); - for (int i = 1; i <= 4; i++) - { - tempmesh.FindOpenElements (); + { + RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0); + for (int i = 1; i <= 4; i++) + { + tempmesh.FindOpenElements (); - PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); - tempmesh.CalcSurfacesOfNode (); + PrintMessage (5, "Num open: ", tempmesh.GetNOpenElements()); + tempmesh.CalcSurfacesOfNode (); - tempmesh.FreeOpenElementsEnvironment (1); + tempmesh.FreeOpenElementsEnvironment (1); - MeshOptimize3d meshopt(mp); - // tempmesh.CalcSurfacesOfNode(); - meshopt.SwapImprove(tempmesh, OPT_CONFORM); - } + MeshOptimize3d meshopt(mp); + // tempmesh.CalcSurfacesOfNode(); + meshopt.SwapImprove(tempmesh, OPT_CONFORM); + } + } MeshQuality3d (tempmesh); diff --git a/libsrc/meshing/meshfunc.cpp b/libsrc/meshing/meshfunc.cpp index 970f92d6..4b92ed8f 100644 --- a/libsrc/meshing/meshfunc.cpp +++ b/libsrc/meshing/meshfunc.cpp @@ -645,6 +645,7 @@ namespace netgen // const CSGeometry * geometry) { static Timer t("OptimizeVolume"); RegionTimer reg(t); + RegionTaskManager rtm(mp.parallel_meshing ? mp.nthreads : 0); int i; diff --git a/libsrc/meshing/meshtype.hpp b/libsrc/meshing/meshtype.hpp index 11c4d8f5..236d8a16 100644 --- a/libsrc/meshing/meshtype.hpp +++ b/libsrc/meshing/meshtype.hpp @@ -1316,6 +1316,9 @@ namespace netgen /// bool autozrefine = false; + bool parallel_meshing = true; + int nthreads = 4; + Flags geometrySpecificParameters; /// MeshingParameters (); diff --git a/libsrc/meshing/python_mesh.hpp b/libsrc/meshing/python_mesh.hpp index cf4fb1f2..d28c3211 100644 --- a/libsrc/meshing/python_mesh.hpp +++ b/libsrc/meshing/python_mesh.hpp @@ -172,6 +172,10 @@ inline void CreateMPfromKwargs(MeshingParameters& mp, py::kwargs kwargs, bool th mp.inverttrigs = py::cast(kwargs.attr("pop")("inverttrigs")); if(kwargs.contains("autozrefine")) mp.autozrefine = py::cast(kwargs.attr("pop")("autozrefine")); + if(kwargs.contains("parallel_meshing")) + mp.parallel_meshing = py::cast(kwargs.attr("pop")("parallel_meshing")); + if(kwargs.contains("nthreads")) + mp.nthreads = py::cast(kwargs.attr("pop")("nthreads")); if(kwargs.size()) { if(throw_if_not_all_parsed) diff --git a/ng/dialog.tcl b/ng/dialog.tcl index 3a7706dd..8c0bf730 100644 --- a/ng/dialog.tcl +++ b/ng/dialog.tcl @@ -183,7 +183,7 @@ proc meshingoptionsdialog { } { ttk::labelframe $f.bts -borderwidth 3 -relief groove -text "Additional meshing options" pack $f.bts -fill x -pady 15 ttk::frame $f.bts.btnframe - ttk::checkbutton $f.bts.btnframe.parthread -text "Parallel meshing thread" \ + ttk::checkbutton $f.bts.btnframe.parthread -text "Separate meshing thread" \ -variable options.parthread ttk::checkbutton $f.bts.btnframe.second -text "Second order elements" \ -variable options.secondorder @@ -214,9 +214,21 @@ proc meshingoptionsdialog { } { #ttk::frame $f.bts.sbox #pack $f.bts.sbox -anchor w -pady 10 - ttk::label $f.bts.btnframe.l -text "Element order" - ttk::spinbox $f.bts.btnframe.elementorder2 -from 1 -to 20 -textvariable options.elementorder -width 2 - pack $f.bts.btnframe.elementorder2 $f.bts.btnframe.l -anchor w -side left + ttk::frame $f.bts.btnframe.elorder + ttk::label $f.bts.btnframe.elorder.l -text "Element order" + ttk::spinbox $f.bts.btnframe.elorder.elementorder2 -from 1 -to 20 -textvariable options.elementorder -width 2 + pack $f.bts.btnframe.elorder -fill x + pack $f.bts.btnframe.elorder.elementorder2 $f.bts.btnframe.elorder.l -anchor w -side left + + ttk::frame $f.bts.btnframe.pm + ttk::checkbutton $f.bts.btnframe.pm.parallel_meshing -text "Parallel meshing" \ + -variable options.parallel_meshing + pack $f.bts.btnframe.pm -fill x -pady 5 + pack $f.bts.btnframe.pm.parallel_meshing -anchor w + + ttk::label $f.bts.btnframe.pm.lnthreads -text "Number of meshing threads" + ttk::spinbox $f.bts.btnframe.pm.nthreads -from 1 -to 128 -textvariable options.nthreads -width 2 + pack $f.bts.btnframe.pm.nthreads $f.bts.btnframe.pm.lnthreads -anchor w -side left diff --git a/ng/ngpkg.cpp b/ng/ngpkg.cpp index a0226cf3..5e92ebe0 100644 --- a/ng/ngpkg.cpp +++ b/ng/ngpkg.cpp @@ -1224,6 +1224,9 @@ namespace netgen printmessage_importance = atoi (Tcl_GetVar (interp, "::options.printmsg", 0)); printdots = (printmessage_importance >= 4); + mparam.parallel_meshing = atoi (Tcl_GetVar (interp, "::options.parallel_meshing", 0)); + mparam.nthreads = atoi (Tcl_GetVar (interp, "::options.nthreads", 0)); + //BaseMoveableMem::totalsize = 0; // 1048576 * atoi (Tcl_GetVar (interp, "::options.memory", 0)); if (mesh) diff --git a/ng/onetcl.cpp b/ng/onetcl.cpp index 2a9585d5..a2cfe027 100644 --- a/ng/onetcl.cpp +++ b/ng/onetcl.cpp @@ -73,6 +73,8 @@ const char * ngscript[] = {"" ,"set options.inverttets 0\n" ,"set options.inverttrigs 0\n" ,"set options.autozrefine 0\n" +,"set options.parallel_meshing 1\n" +,"set options.nthreads 4\n" ,"set options.meshsize 1000\n" ,"set options.minmeshsize 0\n" ,"set options.curvaturesafety 2\n" @@ -403,6 +405,8 @@ const char * ngscript[] = {"" ,"puts $datei \"options.opterrpow ${options.opterrpow}\"\n" ,"puts $datei \"options.grading ${options.grading}\"\n" ,"puts $datei \"options.printmsg ${options.printmsg}\"\n" +,"puts $datei \"options.parallel_meshing ${options.parallel_meshing}\"\n" +,"puts $datei \"options.nthreads ${options.nthreads}\"\n" ,"puts $datei \"geooptions.drawcsg ${geooptions.drawcsg}\"\n" ,"puts $datei \"geooptions.detail ${geooptions.detail}\"\n" ,"puts $datei \"geooptions.accuracy ${geooptions.accuracy}\"\n" @@ -1540,7 +1544,7 @@ const char * ngscript[] = {"" ,"ttk::labelframe $f.bts -borderwidth 3 -relief groove -text \"Additional meshing options\"\n" ,"pack $f.bts -fill x -pady 15\n" ,"ttk::frame $f.bts.btnframe\n" -,"ttk::checkbutton $f.bts.btnframe.parthread -text \"Parallel meshing thread\" \\\n" +,"ttk::checkbutton $f.bts.btnframe.parthread -text \"Separate meshing thread\" \\\n" ,"-variable options.parthread\n" ,"ttk::checkbutton $f.bts.btnframe.second -text \"Second order elements\" \\\n" ,"-variable options.secondorder\n" @@ -1558,9 +1562,19 @@ const char * ngscript[] = {"" ,"-variable options.autozrefine\n" ,"pack $f.bts.btnframe -anchor center\n" ,"pack $f.bts.btnframe.parthread $f.bts.btnframe.second $f.bts.btnframe.quad $f.bts.btnframe.invtets $f.bts.btnframe.invtrigs $f.bts.btnframe.azref -anchor w\n" -,"ttk::label $f.bts.btnframe.l -text \"Element order\"\n" -,"ttk::spinbox $f.bts.btnframe.elementorder2 -from 1 -to 20 -textvariable options.elementorder -width 2\n" -,"pack $f.bts.btnframe.elementorder2 $f.bts.btnframe.l -anchor w -side left\n" +,"ttk::frame $f.bts.btnframe.elorder\n" +,"ttk::label $f.bts.btnframe.elorder.l -text \"Element order\"\n" +,"ttk::spinbox $f.bts.btnframe.elorder.elementorder2 -from 1 -to 20 -textvariable options.elementorder -width 2\n" +,"pack $f.bts.btnframe.elorder -fill x\n" +,"pack $f.bts.btnframe.elorder.elementorder2 $f.bts.btnframe.elorder.l -anchor w -side left\n" +,"ttk::frame $f.bts.btnframe.pm\n" +,"ttk::checkbutton $f.bts.btnframe.pm.parallel_meshing -text \"Parallel meshing\" \\\n" +,"-variable options.parallel_meshing\n" +,"pack $f.bts.btnframe.pm -fill x -pady 5\n" +,"pack $f.bts.btnframe.pm.parallel_meshing -anchor w\n" +,"ttk::label $f.bts.btnframe.pm.lnthreads -text \"Number of meshing threads\"\n" +,"ttk::spinbox $f.bts.btnframe.pm.nthreads -from 1 -to 128 -textvariable options.nthreads -width 2\n" +,"pack $f.bts.btnframe.pm.nthreads $f.bts.btnframe.pm.lnthreads -anchor w -side left\n" ,"set f $w.nb.meshsize\n" ,"ttk::frame $f.f2\n" ,"pack $f.f2 -pady 10\n" diff --git a/ng/variables.tcl b/ng/variables.tcl index 63609766..cdc95856 100644 --- a/ng/variables.tcl +++ b/ng/variables.tcl @@ -47,6 +47,9 @@ set options.opterrpow 2 set options.grading 0.5 set options.printmsg 2 +set options.parallel_meshing 1 +set options.nthreads 4 + set debug.slowchecks 0 set debug.debugoutput 0 set debug.haltexistingline 0 @@ -427,6 +430,8 @@ proc saveoptions { } { puts $datei "options.opterrpow ${options.opterrpow}" puts $datei "options.grading ${options.grading}" puts $datei "options.printmsg ${options.printmsg}" + puts $datei "options.parallel_meshing ${options.parallel_meshing}" + puts $datei "options.nthreads ${options.nthreads}" puts $datei "geooptions.drawcsg ${geooptions.drawcsg}" puts $datei "geooptions.detail ${geooptions.detail}" puts $datei "geooptions.accuracy ${geooptions.accuracy}"