From 3ff2b5e349b6f8b4211de6ccb4ad8fb41322febb Mon Sep 17 00:00:00 2001
From: boeschf <48126478+boeschf@users.noreply.github.com>
Date: Tue, 8 Nov 2022 08:30:16 +0100
Subject: [PATCH] guard for zero random variables (#2031)

---
 arbor/backends/gpu/rand.cpp | 11 +++++++++--
 arbor/util/pimpl.hpp        |  4 ++++
 arbor/util/pimpl_src.hpp    |  5 ++++-
 3 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/arbor/backends/gpu/rand.cpp b/arbor/backends/gpu/rand.cpp
index 513394f7..9fa173ab 100644
--- a/arbor/backends/gpu/rand.cpp
+++ b/arbor/backends/gpu/rand.cpp
@@ -15,13 +15,17 @@ namespace gpu {
 
 void random_numbers::instantiate(mechanism& m, std::size_t value_width_padded,
     const mechanism_layout& pos_data, arb_seed_type seed) {
-
     using util::make_span;
 
+    // bail out if there are no random variables
+    if (m.mech_.n_random_variables == 0) return;
+
     // Allocate view pointers for random nubers
     std::size_t num_random_numbers_per_cv = m.mech_.n_random_variables;
     std::size_t random_number_storage = num_random_numbers_per_cv*cbprng::cache_size();
-    for (auto& v : random_numbers_) v.resize(num_random_numbers_per_cv);
+    for (auto& v : random_numbers_) {
+        v.resize(num_random_numbers_per_cv);
+    }
 
     // Allocate bulk storage
     std::size_t count = random_number_storage*value_width_padded;
@@ -44,6 +48,9 @@ void random_numbers::instantiate(mechanism& m, std::size_t value_width_padded,
 }
 
 void random_numbers::update(mechanism& m) {
+    // bail out if there are no random variables
+    if (!impl_) return;
+
     // Assign new random numbers by selecting the next cache
     const auto counter = random_number_update_counter_++;
     const auto cache_idx = cbprng::cache_index(counter);
diff --git a/arbor/util/pimpl.hpp b/arbor/util/pimpl.hpp
index 740ce7d4..ef59b50a 100644
--- a/arbor/util/pimpl.hpp
+++ b/arbor/util/pimpl.hpp
@@ -17,6 +17,8 @@ class pimpl
     
     pimpl() noexcept;
 
+    pimpl(T* ptr) noexcept;
+
     template<typename... Args>
     pimpl(Args&&... args);
 
@@ -30,6 +32,8 @@ class pimpl
     const T* operator->() const noexcept;
     T&       operator*() noexcept;
     const T& operator*() const noexcept;
+
+    operator bool() const noexcept { return (bool)m; }
 };
 
 
diff --git a/arbor/util/pimpl_src.hpp b/arbor/util/pimpl_src.hpp
index 98fd0de4..646820a4 100644
--- a/arbor/util/pimpl_src.hpp
+++ b/arbor/util/pimpl_src.hpp
@@ -16,6 +16,9 @@ pimpl<T>::~pimpl() = default;
 template<typename T>
 pimpl<T>::pimpl() noexcept = default;
 
+template<typename T>
+pimpl<T>::pimpl(T* ptr) noexcept : m{ptr} {}
+
 template<typename T>
 template<typename... Args>
 pimpl<T>::pimpl(Args&&... args)
@@ -41,7 +44,7 @@ const T& pimpl<T>::operator*() const noexcept { return *m.get(); }
 
 template<typename T, typename... Args>
 pimpl<T> make_pimpl(Args&&... args) {
-    return pimpl<T>{std::forward<Args>(args)...};
+    return {new T{std::forward<Args>(args)...}};
 }
 
 } // namespace util
-- 
GitLab