getfem-commits
[Top][All Lists]
Advanced

[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();
   }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]