2424 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
2525 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2626 DEALINGS IN THE SOFTWARE.
27-
28- Extension: thread-based parallelization
27+
28+ Extension: thread-based parallelization
2929 Author: Moritz Dannhauer
3030 Date: August 2017
3131*/
@@ -58,6 +58,7 @@ ALGORITHM_PARAMETER_DEF(Fields, RemoveColinearPoints);
5858ALGORITHM_PARAMETER_DEF (Fields, StreamlineMethod);
5959ALGORITHM_PARAMETER_DEF (Fields, AutoParameters);
6060ALGORITHM_PARAMETER_DEF (Fields, NumStreamlines);
61+ ALGORITHM_PARAMETER_DEF (Fields, UseMultithreading);
6162
6263GenerateStreamLinesAlgo::GenerateStreamLinesAlgo ()
6364{
@@ -73,6 +74,8 @@ GenerateStreamLinesAlgo::GenerateStreamLinesAlgo()
7374
7475 // For output
7576 addParameter (Parameters::NumStreamlines, 0 );
77+
78+ addParameter (Parameters::UseMultithreading, true );
7679}
7780
7881namespace detail
@@ -163,7 +166,7 @@ class GenerateStreamLinesAlgoP : public Core::Thread::Interruptible
163166
164167 public:
165168 GenerateStreamLinesAlgoP (const AlgorithmBase* algo) :
166- algo_ (algo), numprocessors_(Parallel::NumCores()), barrier_(" FEMVolRHSBuilder Barrier" , numprocessors_),
169+ algo_ (algo), numprocessors_(Parallel::NumCores()), barrier_(" FEMVolRHSBuilder Barrier" , numprocessors_),
167170 tolerance_ (0 ), step_size_(0 ), max_steps_(0 ), direction_(0 ), value_(SeedIndex), remove_colinear_pts_(false ),
168171 method_(AdamsBashforth), seed_field_(0 ), seed_mesh_(0 ), field_(0 ), mesh_(0 ), ofield_(0 ), omesh_(0 )
169172 {}
@@ -193,17 +196,17 @@ class GenerateStreamLinesAlgoP : public Core::Thread::Interruptible
193196
194197 VField* ofield_;
195198 VMesh* omesh_;
196-
199+
197200 FieldHandle input_;
198- std::vector<bool > success_;
199- FieldList outputs_;
201+ std::vector<bool > success_;
202+ FieldList outputs_;
200203 VMesh::Node::index_type global_dimension_;
201204 void parallel (int proc);
202205 FieldHandle StreamLinesForCertainSeeds (VMesh::Node::index_type from, VMesh::Node::index_type to, int proc_num);
203206};
204207
205208FieldHandle GenerateStreamLinesAlgoP::StreamLinesForCertainSeeds (VMesh::Node::index_type from, VMesh::Node::index_type to, int proc_num)
206- {
209+ {
207210 FieldHandle out;
208211 try
209212 {
@@ -217,7 +220,7 @@ FieldHandle GenerateStreamLinesAlgoP::StreamLinesForCertainSeeds(VMesh::Node::in
217220 out = CreateField (fi);
218221 VField* ofield=out->vfield ();
219222 VMesh* omesh=out->vmesh ();
220-
223+
221224 StreamLineIntegrators BI;
222225 BI.nodes_ .reserve (max_steps_); // storage for points
223226 BI.tolerance2_ = tolerance_ * tolerance_; // square error tolerance
@@ -228,7 +231,7 @@ FieldHandle GenerateStreamLinesAlgoP::StreamLinesForCertainSeeds(VMesh::Node::in
228231 // Try to find the streamline for each seed point.
229232 // VMesh::size_type num_seeds = seed_mesh_->num_nodes();
230233 VMesh::Node::array_type newnodes (2 );
231-
234+
232235 for (VMesh::Node::index_type idx=from; idx<to; ++idx)
233236 {
234237 checkForInterruption ();
@@ -344,7 +347,7 @@ FieldHandle GenerateStreamLinesAlgoP::StreamLinesForCertainSeeds(VMesh::Node::in
344347 }
345348 }
346349
347- if (proc_num==0 )
350+ if (proc_num==0 )
348351 algo_->update_progress_max (idx,to);
349352 }
350353
@@ -378,14 +381,14 @@ FieldHandle GenerateStreamLinesAlgoP::StreamLinesForCertainSeeds(VMesh::Node::in
378381void GenerateStreamLinesAlgoP::parallel (int proc_num)
379382{
380383 success_[proc_num] = true ;
381-
384+
382385 for (int q=0 ; q<numprocessors_;q++)
383386 if (success_[q] == false ) return ;
384-
387+
385388 const index_type start_gd = (global_dimension_ * proc_num)/numprocessors_+1 ;
386389 const index_type end_gd = (global_dimension_ * (proc_num+1 ))/numprocessors_;
387-
388- outputs_[proc_num]=StreamLinesForCertainSeeds (start_gd, end_gd, proc_num);
390+
391+ outputs_[proc_num]=StreamLinesForCertainSeeds (start_gd, end_gd, proc_num);
389392}
390393
391394bool GenerateStreamLinesAlgoP::run (FieldHandle input,
@@ -401,15 +404,17 @@ bool GenerateStreamLinesAlgoP::run(FieldHandle input,
401404 omesh_ = output->vmesh ();
402405 tolerance_ = algo_->get (Parameters::StreamlineTolerance).toDouble ();
403406 step_size_ = algo_->get (Parameters::StreamlineStepSize).toDouble ();
404- max_steps_ = algo_->get (Parameters::StreamlineMaxSteps).toInt ();
407+ max_steps_ = algo_->get (Parameters::StreamlineMaxSteps).toInt ();
405408 direction_ = convertDirectionOption (algo_->getOption (Parameters::StreamlineDirection));
406409 value_ = convertValue (algo_->getOption (Parameters::StreamlineValue));
407410 remove_colinear_pts_ = algo_->get (Parameters::RemoveColinearPoints).toBool ();
408- method_ = method;
411+ method_ = method;
409412 input_=input;
410413 global_dimension_=seed_mesh_->num_nodes ();
411414 if (global_dimension_<numprocessors_ || numprocessors_<1 ) numprocessors_=1 ;
412415 if (numprocessors_>16 ) numprocessors_=16 ; // request from Dan White to limit the number of threads
416+ if (!algo_->get (Parameters::UseMultithreading).toBool ())
417+ numprocessors_ = 1 ;
413418 success_.resize (numprocessors_,true );
414419 outputs_.resize (numprocessors_, nullptr );
415420
@@ -422,7 +427,7 @@ bool GenerateStreamLinesAlgoP::run(FieldHandle input,
422427 JoinFieldsAlgo algo;
423428 algo.set (JoinFieldsAlgo::MergeNodes,false );
424429 algo.runImpl (outputs_, output);
425-
430+
426431 return true ;
427432}
428433
@@ -458,9 +463,9 @@ class GenerateStreamLinesAccAlgo {
458463 VMesh* mesh_;
459464
460465 void parallel (int proc_num);
461- FieldHandle StreamLinesForCertainSeeds (VMesh::Node::index_type from, VMesh::Node::index_type to, int proc_num);
462- std::vector<bool > success_;
463- FieldList outputs_;
466+ FieldHandle StreamLinesForCertainSeeds (VMesh::Node::index_type from, VMesh::Node::index_type to, int proc_num);
467+ std::vector<bool > success_;
468+ FieldList outputs_;
464469 FieldHandle input_;
465470 VMesh::Node::index_type global_dimension_;
466471 const AlgorithmBase* algo_;
@@ -470,15 +475,15 @@ void GenerateStreamLinesAccAlgo::parallel(int proc_num)
470475{
471476 success_[proc_num] = true ;
472477 for (int q=0 ; q<numprocessors_;q++)
473- if (success_[q] == false ) return ;
478+ if (success_[q] == false ) return ;
474479 const index_type start_gd = (global_dimension_ * proc_num)/numprocessors_;
475480 const index_type end_gd = (global_dimension_ * (proc_num+1 ))/numprocessors_;
476- outputs_[proc_num]=StreamLinesForCertainSeeds (start_gd, end_gd, proc_num);
481+ outputs_[proc_num]=StreamLinesForCertainSeeds (start_gd, end_gd, proc_num);
477482}
478483
479484
480485FieldHandle GenerateStreamLinesAccAlgo::StreamLinesForCertainSeeds (VMesh::Node::index_type from, VMesh::Node::index_type to, int proc_num)
481- {
486+ {
482487 FieldInformation fi (input_);
483488 fi.make_curvemesh ();
484489 fi.make_lineardata ();
@@ -500,7 +505,7 @@ FieldHandle GenerateStreamLinesAccAlgo::StreamLinesForCertainSeeds(VMesh::Node::
500505
501506 // Try to find the streamline for each seed point.
502507 for (VMesh::Node::index_type idx=from; idx<to; ++idx)
503- {
508+ {
504509 seed_mesh_->get_center (seed, idx);
505510
506511 // Is the seed point inside the field?
@@ -654,10 +659,14 @@ bool GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo, FieldHandle inpu
654659 max_steps_ = algo_->get (Parameters::StreamlineMaxSteps).toInt ();
655660 direction_ = convertDirectionOption (algo_->getOption (Parameters::StreamlineDirection));
656661 value_ = convertValue (algo_->getOption (Parameters::StreamlineValue));
657- remove_colinear_pts_ = algo_->get (Parameters::RemoveColinearPoints).toBool ();
662+ remove_colinear_pts_ = algo_->get (Parameters::RemoveColinearPoints).toBool ();
658663 global_dimension_=seed_mesh_->num_nodes ();
659- if (global_dimension_<numprocessors_) numprocessors_=1 ;
660- if (numprocessors_>16 ) numprocessors_=16 ;
664+ if (global_dimension_<numprocessors_)
665+ numprocessors_ = 1 ;
666+ if (!algo_->get (Parameters::UseMultithreading).toBool ())
667+ numprocessors_ = 1 ;
668+ if (numprocessors_ > 16 )
669+ numprocessors_ = 16 ;
661670 success_.resize (numprocessors_,true );
662671 outputs_.resize (numprocessors_, nullptr );
663672 Parallel::RunTasks ([this ](int i) { parallel (i); }, numprocessors_);
@@ -670,8 +679,8 @@ bool GenerateStreamLinesAccAlgo::run(const AlgorithmBase* algo, FieldHandle inpu
670679 JFalgo.set (JoinFieldsAlgo::Tolerance,1e-8 );
671680 JFalgo.set (JoinFieldsAlgo::MergeNodes,false );
672681 JFalgo.runImpl (outputs_, output);
673-
674- return true ;
682+
683+ return true ;
675684}
676685
677686
@@ -831,7 +840,7 @@ bool GenerateStreamLinesAlgo::runImpl(FieldHandle input, FieldHandle seeds, Fiel
831840 bool success = false ;
832841
833842 if (method == 5 )
834- {
843+ {
835844 detail::GenerateStreamLinesAccAlgo algo;
836845 success = algo.run (this ,input,seeds,output);
837846 }
0 commit comments