[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Getfem-commits] (no subject)
From: |
Andriy Andreykiv |
Subject: |
[Getfem-commits] (no subject) |
Date: |
Wed, 30 Jan 2019 09:33:49 -0500 (EST) |
branch: partitions_initiation
commit 53a1931c59fdc88c88190f79fbda98f5724da2cc
Author: Andriy.Andreykiv <address@hidden>
Date: Wed Jan 30 15:33:07 2019 +0100
- safer omp_distribute component extraction (in Debug)
- default number of threads and partitions is 1, increasing threads
automatically increases partitions unless specific number of partitions was
requested.
- corrected constructions with universal references
---
src/getfem/getfem_omp.h | 51 +++++++++++++++++++++++++++++--------------------
src/getfem_omp.cc | 27 ++++++++++++++------------
2 files changed, 45 insertions(+), 33 deletions(-)
diff --git a/src/getfem/getfem_omp.h b/src/getfem/getfem_omp.h
index faffba4..17e8a7e 100644
--- a/src/getfem/getfem_omp.h
+++ b/src/getfem/getfem_omp.h
@@ -159,6 +159,15 @@ namespace getfem
template<typename T, typename thread_policy, typename tag>
class omp_distribute_impl;
+ template<class V>
+ inline auto safe_component(V &v, size_type i) -> decltype(v[i]){
+ GMM_ASSERT2(i < v.size(),
+ i << "-th partition is not available. "
+ "Probably on_thread_update "
+ "should have been called first");
+ return v[i];
+ }
+
template <typename T, typename thread_policy>
class omp_distribute_impl<T, thread_policy, general_tag> {
private:
@@ -183,37 +192,41 @@ namespace getfem
template <class... args>
explicit omp_distribute_impl(args&&... value){
- thread_values.reserve(thread_policy::num_threads());
- for (size_type i = 0; i != thread_policy::num_threads(); ++i){
- thread_values.emplace_back(value...);
+ thread_values.reserve(num_threads());
+ for (size_type i = 0; i != num_threads(); ++i){
+ thread_values.emplace_back(std::forward<args>(value)...);
}
}
operator T& (){
- return thread_values[thread_policy::this_thread()];
+ return operator()(this_thread());
}
operator const T& () const {
- return thread_values[thread_policy::this_thread()];
+ return operator()(this_thread());
}
T& thrd_cast(){
- return thread_values[thread_policy::this_thread()];
+ return operator()(this_thread());
}
const T& thrd_cast() const {
- return thread_values[thread_policy::this_thread()];
+ return operator()(this_thread());
}
T& operator()(size_type i) {
- return thread_values[i];
+ return safe_component(thread_values, i);
+ }
+
+ const T& operator()(size_type i) const {
+ return safe_component(thread_values, i);
}
void on_thread_update() {
- if (thread_values.size() == thread_policy::num_threads()) return;
+ if (thread_values.size() == num_threads()) return;
GLOBAL_OMP_GUARD
- if (thread_values.size() != thread_policy::num_threads()) {
- thread_values.resize(thread_policy::num_threads());
+ if (thread_values.size() != num_threads()) {
+ thread_values.resize(num_threads());
}
}
@@ -225,17 +238,13 @@ namespace getfem
return thread_policy::this_thread();
}
- const T& operator()(size_type i) const {
- return thread_values[i];
- }
-
T& operator = (const T& x){
if (me_is_multithreaded_now()){
- thread_values[thread_policy::this_thread()] = x;
+ thrd_cast() = x;
}
else all_threads() = x;
- return thread_values[thread_policy::this_thread()];
+ return *this;
}
all_values_proxy all_threads(){
@@ -254,7 +263,7 @@ namespace getfem
template <class... args>
explicit omp_distribute_impl(args&&... value)
- : base(value...)
+ : base(std::forward<args>(value)...)
{}
T& operator[](size_type i){
@@ -281,7 +290,7 @@ namespace getfem
template <class... Args>
explicit omp_distribute_impl(Args&&... value)
- : base(value...)
+ : base(std::forward<Args>(value)...)
{}
operator bool () const {
@@ -319,7 +328,7 @@ namespace getfem
template <class... args>
explicit omp_distribute(args&&... value)
- : base(value...)
+ : base(std::forward<args>(value)...)
{}
auto operator = (const T& x) -> decltype(std::declval<base>() = x){
@@ -503,4 +512,4 @@ namespace getfem
#endif
-} /* end of namespace getfem. */
+} /* end of namespace getfem. */
\ No newline at end of file
diff --git a/src/getfem_omp.cc b/src/getfem_omp.cc
index 5097a4c..438bc5e 100644
--- a/src/getfem_omp.cc
+++ b/src/getfem_omp.cc
@@ -179,11 +179,20 @@ namespace getfem{
}
void partition_master::check_threads(){
+ GLOBAL_OMP_GUARD
+ auto must_update = false;
if (nb_user_threads != true_thread_policy::num_threads()){
- update_partitions();
nb_user_threads = true_thread_policy::num_threads();
+ must_update = true;
+ }
+ if (nb_partitions < nb_user_threads && !partitions_set_by_user){
+ nb_partitions = nb_user_threads;
+ must_update = true;
+ }
+ if (must_update){
+ update_partitions();
+ dal::singletons_manager::on_partitions_change();
}
- if (!partitions_set_by_user) set_nb_partitions(max_concurrency());
}
void partition_master::set_nb_partitions(size_type n){
@@ -202,13 +211,14 @@ namespace getfem{
}
partition_iterator partition_master::begin(){
- check_threads();
+ GMM_ASSERT1(nb_user_threads == true_thread_policy::num_threads(),
+ "The number of omp threads was changed outside
partition_master"
+ "Please use getfem::set_num_threads for this");
current_partition = *(std::begin(partitions.thrd_cast()));
return partition_iterator{*this, std::begin(partitions.thrd_cast())};
}
partition_iterator partition_master::end(){
- check_threads();
return partition_iterator{*this, std::end(partitions.thrd_cast())};
}
@@ -222,14 +232,7 @@ namespace getfem{
}
partition_master::partition_master()
- : nb_user_threads{true_thread_policy::num_threads()},
- nb_partitions{1} // keeping at 1 to allow the user setting it
- // to a number below max_concurrency.
- // If the user doesn't set it, it will be set
- // to max_concurrency before the fist parallel
- // section (reducing nb_partitions is not allowed
- // to preserve global storage)
- {
+ : nb_user_threads{1}, nb_partitions{1} {
partitions_updated = false;
update_partitions();
}