QMCPACK
ParallelExecutorOPENMP.hpp
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 // This file is distributed under the University of Illinois/NCSA Open Source
3 // License. See LICENSE file in top directory for details.
4 //
5 // Copyright (c) 2020 QMCPACK developers.
6 //
7 // File developed by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
8 // Ye Luo, yeluo@anl.gov, Argonne National Laboratory
9 //
10 // File created by: Peter Doak, doakpw@ornl.gov, Oak Ridge National Lab
11 ////////////////////////////////////////////////////////////////////////////////
12 
13 
14 /** @file
15  * @brief implementation of openmp specialization of ParallelExecutor
16  */
17 #ifndef QMCPLUSPLUS_PARALLELEXECUTOR_OPENMP_HPP
18 #define QMCPLUSPLUS_PARALLELEXECUTOR_OPENMP_HPP
19 
20 #include <stdexcept>
21 #include <string>
22 #include <iostream>
23 
25 #include "Concurrency/OpenMP.h"
26 
27 namespace qmcplusplus
28 {
29 /** implements parallel tasks executed by threads in an OpenMP thread pool.
30  *
31  * This specialization throws below the top openmp theading level
32  * exception must be caught at thread level or terminate is called.
33  *
34  */
35 template<>
36 template<typename F, typename... Args>
37 void ParallelExecutor<Executor::OPENMP>::operator()(int num_tasks, F&& f, Args&&... args)
38 {
39  const std::string nesting_error{"ParallelExecutor should not be used for nested openmp threading\n"};
40  if (omp_get_level() > 0)
41  throw std::runtime_error(nesting_error);
42  int nested_throw_count = 0;
43  int throw_count = 0;
44 #pragma omp parallel for reduction(+ : nested_throw_count, throw_count)
45  for (int task_id = 0; task_id < num_tasks; ++task_id)
46  {
47  try
48  {
49  f(task_id, std::forward<Args>(args)...);
50  }
51  catch (const std::runtime_error& re)
52  {
53  if (nesting_error == re.what())
54  ++nested_throw_count;
55  else
56  {
57  std::cerr << re.what() << std::flush;
58  ++throw_count;
59  }
60  }
61  catch (...)
62  {
63  ++throw_count;
64  }
65  }
66  if (throw_count > 0)
67  throw std::runtime_error("Unexpected exception thrown in threaded section");
68  else if (nested_throw_count > 0)
69  throw std::runtime_error(nesting_error);
70 }
71 
72 } // namespace qmcplusplus
73 
74 #endif
helper functions for EinsplineSetBuilder
Definition: Configuration.h:43
void operator()(int num_tasks, F &&f, Args &&... args)
Concurrently execute an arbitrary function/kernel with task id and arbitrary args.
omp_int_t omp_get_level()
Definition: OpenMP.h:28