From b02f920d7712cb9b4537e52ab29f0e9f40e6447a Mon Sep 17 00:00:00 2001 From: "Ryan M. Richard" Date: Wed, 12 Jun 2024 15:55:27 -0500 Subject: [PATCH 1/4] refactoring to expose cache to user --- .../module_manager/module_manager.hpp | 2 + .../module_manager_class.hpp} | 10 +- include/pluginplay/plugin/plugin.hpp | 2 +- include/pluginplay/pluginplay.hpp | 2 +- .../pluginplay/printing/document_modules.hpp | 2 +- .../detail_/module_manager_pimpl.hpp | 139 ++++-------------- .../detail_/module_manager_pimpl.ipp | 116 +++++++++++++++ .../{ => module_manager}/module_manager.cpp | 8 +- .../export_module_manager.cpp | 4 +- .../pluginplay/examples/load_modules.hpp | 2 +- .../pluginplay/examples/workflow.hpp | 2 +- .../detail_/module_manager_pimpl.cpp | 6 +- .../{ => module_manager}/module_manager.cpp | 2 +- tests/python/unit_tests/module/__init__.py | 0 .../unit_tests/{ => module}/test_module.py | 0 .../{ => module}/test_module_base.py | 0 .../unit_tests/module_manager/__init__.py | 0 .../test_module_manager.py | 0 tests/python/unit_tests/modules.hpp | 2 +- tests/python/unit_tests/test_pluginplay.cpp | 2 +- 20 files changed, 176 insertions(+), 125 deletions(-) create mode 100644 include/pluginplay/module_manager/module_manager.hpp rename include/pluginplay/{module_manager.hpp => module_manager/module_manager_class.hpp} (96%) rename src/pluginplay/{ => module_manager}/detail_/module_manager_pimpl.hpp (58%) create mode 100644 src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp rename src/pluginplay/{ => module_manager}/module_manager.cpp (91%) rename src/python/{ => module_manager}/export_module_manager.cpp (96%) rename tests/cxx/unit_tests/pluginplay/{ => module_manager}/detail_/module_manager_pimpl.cpp (98%) rename tests/cxx/unit_tests/pluginplay/{ => module_manager}/module_manager.cpp (97%) create mode 100644 tests/python/unit_tests/module/__init__.py rename tests/python/unit_tests/{ => module}/test_module.py (100%) rename tests/python/unit_tests/{ => module}/test_module_base.py (100%) create mode 100644 tests/python/unit_tests/module_manager/__init__.py rename tests/python/unit_tests/{ => module_manager}/test_module_manager.py (100%) diff --git a/include/pluginplay/module_manager/module_manager.hpp b/include/pluginplay/module_manager/module_manager.hpp new file mode 100644 index 000000000..4d1268ba7 --- /dev/null +++ b/include/pluginplay/module_manager/module_manager.hpp @@ -0,0 +1,2 @@ +#pragma once +#include \ No newline at end of file diff --git a/include/pluginplay/module_manager.hpp b/include/pluginplay/module_manager/module_manager_class.hpp similarity index 96% rename from include/pluginplay/module_manager.hpp rename to include/pluginplay/module_manager/module_manager_class.hpp index 91ae90a9d..7aa73ad3d 100644 --- a/include/pluginplay/module_manager.hpp +++ b/include/pluginplay/module_manager/module_manager_class.hpp @@ -17,6 +17,7 @@ #pragma once #include #include +#include #include #include #include @@ -50,12 +51,19 @@ class ModuleManager { /// Type of module key container using key_container_type = std::vector; + /// Type of the cache + using cache_type = cache::ModuleManagerCache; + + /// Type of a pointer to the cache + using cache_pointer = std::shared_ptr; + ///@{ /** @name Ctors and assignment operators * */ ModuleManager(); - ModuleManager(runtime_ptr runtime); + ModuleManager(runtime_ptr runtime, + cache_pointer cache = std::make_shared()); // ModuleManager(const ModuleManager& rhs); // ModuleManager& operator=(const ModuleManager& rhs) { // return *this = std::move(ModuleManager(rhs)); diff --git a/include/pluginplay/plugin/plugin.hpp b/include/pluginplay/plugin/plugin.hpp index e6ba75c6a..3cfc10202 100644 --- a/include/pluginplay/plugin/plugin.hpp +++ b/include/pluginplay/plugin/plugin.hpp @@ -15,7 +15,7 @@ */ #pragma once -#include +#include #include #define DECLARE_PLUGIN(plugin_name) \ diff --git a/include/pluginplay/pluginplay.hpp b/include/pluginplay/pluginplay.hpp index 69742c3b2..b64a872ce 100644 --- a/include/pluginplay/pluginplay.hpp +++ b/include/pluginplay/pluginplay.hpp @@ -27,7 +27,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/include/pluginplay/printing/document_modules.hpp b/include/pluginplay/printing/document_modules.hpp index 347ba2c08..e3dc6d212 100644 --- a/include/pluginplay/printing/document_modules.hpp +++ b/include/pluginplay/printing/document_modules.hpp @@ -20,7 +20,7 @@ #include #include -#include +#include #include namespace pluginplay::printing { diff --git a/src/pluginplay/detail_/module_manager_pimpl.hpp b/src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp similarity index 58% rename from src/pluginplay/detail_/module_manager_pimpl.hpp rename to src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp index 5f60ddb18..3b20ed622 100644 --- a/src/pluginplay/detail_/module_manager_pimpl.hpp +++ b/src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp @@ -15,16 +15,15 @@ */ #pragma once -#include "../module/detail_/module_pimpl.hpp" +#include "../../module/detail_/module_pimpl.hpp" #include #include #include #include -#include +#include #include -namespace pluginplay { -namespace detail_ { +namespace pluginplay::detail_ { /** @brief The class that implements the ModuleManager. * @@ -35,12 +34,15 @@ namespace detail_ { * that it is easier to test the implementation. */ struct ModuleManagerPIMPL { + /// Type *this implements + using module_manager_type = ModuleManager; + ///@{ /// Type of a pointer to a module's implemenation - using module_base_ptr = typename ModuleManager::module_base_ptr; + using module_base_ptr = module_manager_type::module_base_ptr; /// Type of a pointer to a read-only module implementation - using const_module_base_ptr = typename ModuleManager::const_module_base_ptr; + using const_module_base_ptr = module_manager_type::const_module_base_ptr; /// Type of a map from the module implementation's type to the /// implementation @@ -50,16 +52,22 @@ struct ModuleManagerPIMPL { using shared_module = std::shared_ptr; /// Type of a map holding usable modules - using module_map = utilities::CaseInsensitiveMap; + using module_map = module_manager_type::module_map; /// Type of a map holding the default module key for a given property type using default_map = std::map; /// The type of the runtime - using runtime_type = parallelzone::runtime::RuntimeView; + using runtime_type = module_manager_type::runtime_type; /// A pointer to a runtime - using runtime_ptr = std::shared_ptr; + using runtime_ptr = module_manager_type::runtime_ptr; + + /// Type of the cache + using cache_type = module_manager_type::cache_type; + + /// Type of a pointer to the cache + using cache_pointer = module_manager_type::cache_pointer; /// Type of a map from key to Python implementation // TODO: remove when a more elegant solution is determined @@ -67,9 +75,12 @@ struct ModuleManagerPIMPL { ///@} - ModuleManagerPIMPL(runtime_ptr runtime) : m_runtime_(runtime) {} + ModuleManagerPIMPL() : + ModuleManagerPIMPL(std::make_shared(), + std::make_shared()) {} - ModuleManagerPIMPL() : m_runtime_(std::make_shared()) {} + ModuleManagerPIMPL(runtime_ptr runtime, cache_pointer cache) : + m_runtime_(runtime), m_pcaches(cache) {} /// Makes a deep copy of this instance on the heap // auto clone() { return std::make_unique(*this); } @@ -106,11 +117,7 @@ struct ModuleManagerPIMPL { * @param key The module key for the module to use as the default */ void set_default(const std::type_info& type, type::input_map inputs, - type::key key) { - if(!count(key)) m_modules.at(key); // Throws a consistent error - m_defaults[std::type_index(type)] = key; - m_inputs[std::type_index(type)] = std::move(inputs); - } + type::key key); /** @brief This function actually adds a module to the list of available * modules. @@ -118,31 +125,7 @@ struct ModuleManagerPIMPL { * @param key The key under which the module will be registered. * @param base The instance containing the algorithm */ - void add_module(type::key key, module_base_ptr base) { - assert_unique_key_(key); - auto uuid = utility::generate_uuid(); - auto internal_cache = m_caches.get_or_make_user_cache(uuid); - base->set_cache(internal_cache); - base->set_runtime(m_runtime_); - base->set_uuid(uuid); - auto module_cache = m_caches.get_or_make_module_cache(key); - std::unique_ptr pimpl; - if(base->is_python()) { - // This is a hacky patch to allow multiple python modules to be - // added while avoiding the type_index collisions. - // TODO: remove when a more elegant solution is determined - m_py_bases[key] = base; - pimpl = - std::make_unique(m_py_bases[key], module_cache); - } else { - std::type_index type(base->type()); - if(!m_bases.count(type)) m_bases[type] = base; - pimpl = std::make_unique(m_bases[type], module_cache); - } - auto ptr = std::make_shared(std::move(pimpl)); - ptr->set_name(key); - m_modules.emplace(std::move(key), ptr); - } + void add_module(type::key key, module_base_ptr base); /** @brief Unloads the specified module. * @@ -165,13 +148,7 @@ struct ModuleManagerPIMPL { * @param old_key The key for the module to copy * @param new_key The key under which the new module will live */ - void copy_module(const type::key& old_key, type::key new_key) { - assert_unique_key_(new_key); - Module mod = m_modules.at(old_key)->unlocked_copy(); - auto ptr = std::make_shared(std::move(mod)); - ptr->set_name(new_key); - m_modules.emplace(std::move(new_key), ptr); - } + void copy_module(const type::key& old_key, type::key new_key); /** @brief Returns a module, filling in all non-set submodules with defaults * if a ready default exists. @@ -179,27 +156,7 @@ struct ModuleManagerPIMPL { * @param key The module you want * @return A shared_ptr to the requested module */ - shared_module at(const type::key& key) { - if(!count(key)) { - const std::string msg = - "ModuleManager has no module with key: '" + key + "'"; - throw std::out_of_range(msg); - } - auto mod = m_modules.at(key); - // Loop over submodules filling them in from the defaults - for(auto& [k, v] : mod->submods()) { - const auto& type = v.type(); - // Only change non-ready submodules - if(!v.ready() && m_defaults.count(type)) { - // Recursive to make sure that that module gets filled in - auto default_mod = at(m_defaults.at(type)); - // Only change if the module is also ready - if(default_mod->ready(m_inputs.at(type))) - mod->change_submod(k, default_mod); - } - } - return mod; - } + shared_module at(const type::key& key); ///@{ /** @name Comparison operators @@ -207,35 +164,7 @@ struct ModuleManagerPIMPL { * @param rhs * @return */ - bool operator==(const ModuleManagerPIMPL& rhs) const { - // Try to get out early - if(m_bases.size() != rhs.m_bases.size()) return false; - if(m_modules.size() != rhs.m_modules.size()) return false; - if(m_defaults.size() != rhs.m_defaults.size()) return false; - - // TODO: Remove with the rest of the python hack - if(m_py_bases.size() != rhs.m_py_bases.size()) return false; - for(const auto& [k, v] : rhs.m_py_bases) { - if(!m_py_bases.count(k)) return false; - if(*m_py_bases.at(k) != *v) return false; - } - - // Skip checking the values b/c implementations are compared by type - for(const auto& [k, v] : rhs.m_bases) { - if(!m_bases.count(k)) return false; - } - - // Need to check the values b/c user may have switched options - for(const auto& [k, v] : rhs.m_modules) { - if(!m_modules.count(k)) return false; - if(*m_modules.at(k) != *v) return false; - } - - // Easy since not pointers - if(m_defaults != rhs.m_defaults) return false; - - return true; - } + bool operator==(const ModuleManagerPIMPL& rhs) const; bool operator!=(const ModuleManagerPIMPL& rhs) const { return !((*this) == rhs); @@ -245,12 +174,7 @@ struct ModuleManagerPIMPL { runtime_type& get_runtime() const { return *m_runtime_; } - ModuleManager::key_container_type keys() const { - ModuleManager::key_container_type keys; - keys.reserve(m_modules.size()); - for(const auto& [k, v] : m_modules) keys.push_back(k); - return keys; - } + ModuleManager::key_container_type keys() const; ///@} ///@{ @@ -270,7 +194,7 @@ struct ModuleManagerPIMPL { py_base_map m_py_bases; // These are the results of the modules running in the user's states - cache::ModuleManagerCache m_caches; + cache_pointer m_pcaches; // A map of property types default_map m_defaults; @@ -288,5 +212,6 @@ struct ModuleManagerPIMPL { } }; -} // namespace detail_ -} // namespace pluginplay +} // namespace pluginplay::detail_ + +#include "module_manager_pimpl.ipp" \ No newline at end of file diff --git a/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp b/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp new file mode 100644 index 000000000..fcd88c4ce --- /dev/null +++ b/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp @@ -0,0 +1,116 @@ +// This file meant only for inclusion in module_manager_pimpl.hpp + +#pragma once + +namespace pluginplay::detail_ { + +inline void ModuleManagerPIMPL::set_default(const std::type_info& type, + type::input_map inputs, + type::key key) { + if(!count(key)) m_modules.at(key); // Throws a consistent error + m_defaults[std::type_index(type)] = key; + m_inputs[std::type_index(type)] = std::move(inputs); +} + +inline void ModuleManagerPIMPL::add_module(type::key key, + module_base_ptr base) { + assert_unique_key_(key); + auto uuid = utility::generate_uuid(); + base->set_runtime(m_runtime_); + base->set_uuid(uuid); + + cache::ModuleManagerCache::module_cache_pointer module_cache; + if(m_pcaches) { + auto internal_cache = m_pcaches->get_or_make_user_cache(uuid); + base->set_cache(internal_cache); + module_cache = m_pcaches->get_or_make_module_cache(key); + } + + std::unique_ptr pimpl; + if(base->is_python()) { + // This is a hacky patch to allow multiple python modules to be + // added while avoiding the type_index collisions. + // TODO: remove when a more elegant solution is determined + m_py_bases[key] = base; + pimpl = std::make_unique(m_py_bases[key], module_cache); + } else { + std::type_index type(base->type()); + if(!m_bases.count(type)) m_bases[type] = base; + pimpl = std::make_unique(m_bases[type], module_cache); + } + auto ptr = std::make_shared(std::move(pimpl)); + ptr->set_name(key); + m_modules.emplace(std::move(key), ptr); +} + +inline void ModuleManagerPIMPL::copy_module(const type::key& old_key, + type::key new_key) { + assert_unique_key_(new_key); + Module mod = m_modules.at(old_key)->unlocked_copy(); + auto ptr = std::make_shared(std::move(mod)); + ptr->set_name(new_key); + m_modules.emplace(std::move(new_key), ptr); +} + +inline ModuleManagerPIMPL::shared_module ModuleManagerPIMPL::at( + const type::key& key) { + if(!count(key)) { + const std::string msg = + "ModuleManager has no module with key: '" + key + "'"; + throw std::out_of_range(msg); + } + auto mod = m_modules.at(key); + // Loop over submodules filling them in from the defaults + for(auto& [k, v] : mod->submods()) { + const auto& type = v.type(); + // Only change non-ready submodules + if(!v.ready() && m_defaults.count(type)) { + // Recursive to make sure that that module gets filled in + auto default_mod = at(m_defaults.at(type)); + // Only change if the module is also ready + if(default_mod->ready(m_inputs.at(type))) + mod->change_submod(k, default_mod); + } + } + return mod; +} + +inline bool ModuleManagerPIMPL::operator==( + const ModuleManagerPIMPL& rhs) const { + // Try to get out early + if(m_bases.size() != rhs.m_bases.size()) return false; + if(m_modules.size() != rhs.m_modules.size()) return false; + if(m_defaults.size() != rhs.m_defaults.size()) return false; + + // TODO: Remove with the rest of the python hack + if(m_py_bases.size() != rhs.m_py_bases.size()) return false; + for(const auto& [k, v] : rhs.m_py_bases) { + if(!m_py_bases.count(k)) return false; + if(*m_py_bases.at(k) != *v) return false; + } + + // Skip checking the values b/c implementations are compared by type + for(const auto& [k, v] : rhs.m_bases) { + if(!m_bases.count(k)) return false; + } + + // Need to check the values b/c user may have switched options + for(const auto& [k, v] : rhs.m_modules) { + if(!m_modules.count(k)) return false; + if(*m_modules.at(k) != *v) return false; + } + + // Easy since not pointers + if(m_defaults != rhs.m_defaults) return false; + + return true; +} + +inline ModuleManager::key_container_type ModuleManagerPIMPL::keys() const { + ModuleManager::key_container_type keys; + keys.reserve(m_modules.size()); + for(const auto& [k, v] : m_modules) keys.push_back(k); + return keys; +} + +} // namespace pluginplay::detail_ \ No newline at end of file diff --git a/src/pluginplay/module_manager.cpp b/src/pluginplay/module_manager/module_manager.cpp similarity index 91% rename from src/pluginplay/module_manager.cpp rename to src/pluginplay/module_manager/module_manager.cpp index c3de54479..91bb21695 100644 --- a/src/pluginplay/module_manager.cpp +++ b/src/pluginplay/module_manager/module_manager.cpp @@ -16,7 +16,7 @@ #include "detail_/module_manager_pimpl.hpp" #include "module/detail_/module_pimpl.hpp" -#include "pluginplay/module_manager.hpp" +#include namespace pluginplay { @@ -30,9 +30,9 @@ using CIM = utilities::CaseInsensitiveMap; ModuleManager::ModuleManager() : pimpl_(std::make_unique()) {} -ModuleManager::ModuleManager(runtime_ptr runtime) : - pimpl_(std::make_unique(runtime)) {} -ModuleManager::ModuleManager(ModuleManager&& rhs) noexcept = default; +ModuleManager::ModuleManager(runtime_ptr runtime, cache_pointer cache) : + pimpl_(std::make_unique(runtime, cache)) {} +ModuleManager::ModuleManager(ModuleManager&& rhs) noexcept = default; ModuleManager& ModuleManager::operator=(ModuleManager&& rhs) noexcept = default; ModuleManager::~ModuleManager() noexcept = default; diff --git a/src/python/export_module_manager.cpp b/src/python/module_manager/export_module_manager.cpp similarity index 96% rename from src/python/export_module_manager.cpp rename to src/python/module_manager/export_module_manager.cpp index 141f44c08..7f453948a 100644 --- a/src/python/export_module_manager.cpp +++ b/src/python/module_manager/export_module_manager.cpp @@ -14,11 +14,11 @@ * limitations under the License. */ -#include "export_pluginplay.hpp" +#include "../export_pluginplay.hpp" #include "module/py_module_base.hpp" #include #include -#include +#include #include #include diff --git a/tests/cxx/unit_tests/pluginplay/examples/load_modules.hpp b/tests/cxx/unit_tests/pluginplay/examples/load_modules.hpp index 4e40b3578..5527357ef 100644 --- a/tests/cxx/unit_tests/pluginplay/examples/load_modules.hpp +++ b/tests/cxx/unit_tests/pluginplay/examples/load_modules.hpp @@ -26,7 +26,7 @@ #pragma once #include "writing_a_module.hpp" #include "writing_a_property_type.hpp" -#include +#include /* Populating the ModuleManager * ---------------------------- diff --git a/tests/cxx/unit_tests/pluginplay/examples/workflow.hpp b/tests/cxx/unit_tests/pluginplay/examples/workflow.hpp index 694c376ec..07591adfe 100644 --- a/tests/cxx/unit_tests/pluginplay/examples/workflow.hpp +++ b/tests/cxx/unit_tests/pluginplay/examples/workflow.hpp @@ -26,7 +26,7 @@ */ #pragma once #include "load_modules.hpp" -#include +#include /* Running a Computation * --------------------- diff --git a/tests/cxx/unit_tests/pluginplay/detail_/module_manager_pimpl.cpp b/tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp similarity index 98% rename from tests/cxx/unit_tests/pluginplay/detail_/module_manager_pimpl.cpp rename to tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp index 394a56fc6..80a0c1da0 100644 --- a/tests/cxx/unit_tests/pluginplay/detail_/module_manager_pimpl.cpp +++ b/tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp @@ -14,8 +14,8 @@ * limitations under the License. */ -#include "../examples/writing_a_module.hpp" -#include "pluginplay/detail_/module_manager_pimpl.hpp" +#include "../../examples/writing_a_module.hpp" +#include "pluginplay/module_manager/detail_/module_manager_pimpl.hpp" #include using namespace pluginplay; @@ -38,7 +38,7 @@ TEST_CASE("ModuleManagerPIMPL : Default ctor") { TEST_CASE("ModuleManagerPIMPL : Runtime") { SECTION("ctor") { auto runtime = std::make_shared(); - ModuleManagerPIMPL pimple(runtime); + ModuleManagerPIMPL pimple(runtime, nullptr); auto& internal_runtime = pimple.get_runtime(); REQUIRE(&internal_runtime == runtime.get()); } diff --git a/tests/cxx/unit_tests/pluginplay/module_manager.cpp b/tests/cxx/unit_tests/pluginplay/module_manager/module_manager.cpp similarity index 97% rename from tests/cxx/unit_tests/pluginplay/module_manager.cpp rename to tests/cxx/unit_tests/pluginplay/module_manager/module_manager.cpp index bd05a0e3c..8294e8586 100644 --- a/tests/cxx/unit_tests/pluginplay/module_manager.cpp +++ b/tests/cxx/unit_tests/pluginplay/module_manager/module_manager.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "pluginplay/module_manager.hpp" +#include #include "test_common.hpp" #include diff --git a/tests/python/unit_tests/module/__init__.py b/tests/python/unit_tests/module/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/python/unit_tests/test_module.py b/tests/python/unit_tests/module/test_module.py similarity index 100% rename from tests/python/unit_tests/test_module.py rename to tests/python/unit_tests/module/test_module.py diff --git a/tests/python/unit_tests/test_module_base.py b/tests/python/unit_tests/module/test_module_base.py similarity index 100% rename from tests/python/unit_tests/test_module_base.py rename to tests/python/unit_tests/module/test_module_base.py diff --git a/tests/python/unit_tests/module_manager/__init__.py b/tests/python/unit_tests/module_manager/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/tests/python/unit_tests/test_module_manager.py b/tests/python/unit_tests/module_manager/test_module_manager.py similarity index 100% rename from tests/python/unit_tests/test_module_manager.py rename to tests/python/unit_tests/module_manager/test_module_manager.py diff --git a/tests/python/unit_tests/modules.hpp b/tests/python/unit_tests/modules.hpp index d3d61d42e..f9ef42afb 100644 --- a/tests/python/unit_tests/modules.hpp +++ b/tests/python/unit_tests/modules.hpp @@ -17,7 +17,7 @@ #pragma once #include "property_types.hpp" #include -#include +#include namespace test_pluginplay { diff --git a/tests/python/unit_tests/test_pluginplay.cpp b/tests/python/unit_tests/test_pluginplay.cpp index 9f720ea03..f42b8ea1f 100644 --- a/tests/python/unit_tests/test_pluginplay.cpp +++ b/tests/python/unit_tests/test_pluginplay.cpp @@ -21,7 +21,7 @@ #include "property_types.hpp" #include "python/test_python.hpp" #include "test_pluginplay.hpp" -#include +#include #include #include From 6bac4ac2cedad34e62b520cfc377c6c28812dbc1 Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 13 Jun 2024 14:05:55 -0500 Subject: [PATCH 2/4] cache is accessible now --- include/pluginplay/module_manager.hpp | 280 ++++++++++++++++++ .../module_manager/module_manager.hpp | 18 +- .../module_manager/module_manager_class.hpp | 20 +- .../detail_/module_manager_pimpl.hpp | 6 +- ...e_manager.cpp => module_manager_class.cpp} | 14 + src/python/cache/export_cache.hpp | 13 + .../cache/export_module_manager_cache.cpp | 12 + src/python/export_pluginplay.cpp | 3 + src/python/export_pluginplay.hpp | 1 - .../module_manager/export_module_manager.hpp | 12 + ...er.cpp => export_module_manager_class.cpp} | 17 +- .../detail_/module_manager_pimpl.cpp | 7 + ...e_manager.cpp => module_manager_class.cpp} | 8 +- ...anager.py => test_module_manager_class.py} | 13 +- 14 files changed, 413 insertions(+), 11 deletions(-) create mode 100644 include/pluginplay/module_manager.hpp rename src/pluginplay/module_manager/{module_manager.cpp => module_manager_class.cpp} (88%) create mode 100644 src/python/cache/export_cache.hpp create mode 100644 src/python/cache/export_module_manager_cache.cpp create mode 100644 src/python/module_manager/export_module_manager.hpp rename src/python/module_manager/{export_module_manager.cpp => export_module_manager_class.cpp} (78%) rename tests/cxx/unit_tests/pluginplay/module_manager/{module_manager.cpp => module_manager_class.cpp} (93%) rename tests/python/unit_tests/module_manager/{test_module_manager.py => test_module_manager_class.py} (94%) diff --git a/include/pluginplay/module_manager.hpp b/include/pluginplay/module_manager.hpp new file mode 100644 index 000000000..677f344df --- /dev/null +++ b/include/pluginplay/module_manager.hpp @@ -0,0 +1,280 @@ +/* + * Copyright 2022 NWChemEx-Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#include +#include +#include +#include +#include + +namespace pluginplay { + +namespace detail_ { +struct ModuleManagerPIMPL; +} + +/** @brief Class responsible for manipulating + * + */ +class ModuleManager { +public: + /// The type of a pointer to a read/write module + using module_base_ptr = std::shared_ptr; + + /// The type of a pointer to a read-only module + using const_module_base_ptr = std::shared_ptr; + + /// Type of a map holding usable modules + using module_map = utilities::CaseInsensitiveMap>; + + /// The type of the runtime + using runtime_type = parallelzone::runtime::RuntimeView; + + /// A pointer to a runtime + using runtime_ptr = std::shared_ptr; + + /// Type of module key container + using key_container_type = std::vector; + + /// Type of + + ///@{ + /** @name Ctors and assignment operators + * + */ + ModuleManager(); + ModuleManager(runtime_ptr runtime, + cache_pointer cache = std::make_shared <); + // ModuleManager(const ModuleManager& rhs); + // ModuleManager& operator=(const ModuleManager& rhs) { + // return *this = std::move(ModuleManager(rhs)); + // } + ModuleManager(ModuleManager&& rhs) noexcept; + ModuleManager& operator=(ModuleManager&& rhs) noexcept; + ///@} + + /// Standard dtor + ~ModuleManager() noexcept; + + /** @brief Returns an iterator to the first element of the module map + * + * @return Iterator to the first element of the map + */ + module_map::iterator begin() noexcept; + + /** @brief Returns an iterator to the past-the-end element of the module map + * + * @return Iterator to the past-the-end element of the map + */ + module_map::iterator end() noexcept; + + /** @brief Used to see if we have a module + * + * @param key + * @return + */ + type::size count(type::key key) const noexcept; + + /** @brief Gets the number of modules loaded. + * + * @return Number of modules loaded. + */ + type::size size() const noexcept; + + template + void add_module(type::key module_key); + + /** @brief Used to add a new module to the list + * + * @param module_key + * @param base + */ + + void add_module(type::key module_key, module_base_ptr base); + + ///@{ + /** @name Module retrievers + * + * @param module_key + * @return + */ + Module& at(const type::key& module_key) { + const auto& rv = const_cast(*this).at(module_key); + return const_cast(rv); + } + const Module& at(const type::key& module_key) const; + ///@} + + /** @brief Makes a "deep copy" of a module + * + * This function will copy the module stored under @p old_key and store the + * copy under @p new_key. The copy will be unlocked, with a deep copy of + * @p old_key 's inputs and submodules. Deep copy in this context meaning + * that changing @p new_key 's inputs or submodules will not affect the + * module stored under @p old_key. + * + * @param[in] old_key The key for the module which is being copied. + * @param[in] new_key The key for the resulting copy. + * + * @throw std::bad_alloc if an allocation error arises. + */ + void copy_module(const type::key& old_key, type::key new_key); + + /** @brief Unloads the specified module. + * + * This function unloads the module with the specified key. After this + * operation the key is free to be used again. Calling this function does + * NOT clean any data out of the cache. This function is a no-op if @p key + * does not exist. + * + * @param[in] key The key for the module which should be erased. + */ + void erase(const type::key& key); + + /** @brief Changes the key a module is stored under. + * + * This function can be used to rename the key a module is stored under. + * After a call to this function there will be no module stored under + * @p old_key. + * + * @param[in] old_key The key we are renaming. + * @param[in] new_key The value for the new key. + * + * @throw std::bad_alloc if there is an allocation error. + */ + void rename_module(const type::key& old_key, type::key new_key); + + /** @brief Defines the default module for a particular property type + * + * @tparam T The type of the property type the default is for + * @param key The module key of the default module + */ + template + void set_default(type::key key) { + auto temp = T::inputs(); + type::input_map inps(temp.begin(), temp.end()); + set_default_(typeid(T), std::move(inps), std::move(key)); + } + + /** @brief Changes the value of an input bound to a module + * + * @tparam T + * @param key + * @param option + * @param new_value + */ + template + void change_input(const type::key& key, const type::key& option, + T&& new_value) { + at(key).change_input(option, std::forward(new_value)); + } + + /** @brief Changes the submodule a module calls. + * + * Modules can call other modules at predesignated callback points. Each of + * these callback points has a key associated with it. This function allows + * the user to change which module is called at a particular callback point + * by specifying the key of the module, the callback point's key, and the + * key for tne new submodule. + * + * @param[in] module_key The key for the module whose submodule is being + * changed. + * @param[in] callback_key The name of the callback point in the module + * assigned to @p module_key + * @param[in] submod_key The key for the submodule to call. + * + * @throw std::out_of_range if any of the keys do not refer to valid, + * already present modules or callback points. Weak + * throw guarantee. + */ + void change_submod(const type::key& module_key, + const type::key& callback_key, + const type::key& submod_key); + + /** @brief Runs a given module + * + * @tparam T + * @tparam Args + * @param key + * @param args + * @return + */ + template + auto run_as(const type::key& key, Args&&... args) { + return at(key).run_as(std::forward(args)...); + } + + /** @brief Sets the runtime of the module mananger and its modules. + * + * @param[in] runtime A shared_ptr to a @p runtime_type instance with which + * the module manager is currently associated. + * + * @throw None No throw guarantee. + */ + void set_runtime(runtime_ptr runtime) noexcept; + + /** @brief Provides the runtime of the module manager. + * + * @return The runtime object with which the module manager is currently + * associated. + * + * @throw std::runtime_error if there is no runtime. Strong throw + * guarantee. + */ + runtime_type& get_runtime() const noexcept; + + /** @brief Returns the keys of all the modules in the module manager. + * + * @return A vector of keys for all the modules in the module manager. + * + * @throw std::bad_alloc if an allocation error arises. + */ + key_container_type keys() const; + +private: + /** @brief Checks whether pimpl_ is not null. + * + * @return False if pimpl_ is a null pointer and true otherwise. + * + * @throw None No throw guarantee. + */ + bool has_pimpl_() const noexcept; + + /// Bridges the gap between the set_default and the PIMPL + void set_default_(const std::type_info& type, type::input_map inps, + type::key key); + + /// The object that actually implements the ModuleManager + std::unique_ptr pimpl_; +}; // End class ModuleManager + +//------------------------------------------------------------------------------ +// Inline Implementations +//------------------------------------------------------------------------------ + +template +void ModuleManager::add_module(type::key module_key) { + add_module(std::move(module_key), std::make_shared()); +} + +inline void ModuleManager::rename_module(const type::key& old_key, + type::key new_key) { + copy_module(old_key, std::move(new_key)); + erase(old_key); +} + +} // namespace pluginplay diff --git a/include/pluginplay/module_manager/module_manager.hpp b/include/pluginplay/module_manager/module_manager.hpp index 4d1268ba7..68fd741e8 100644 --- a/include/pluginplay/module_manager/module_manager.hpp +++ b/include/pluginplay/module_manager/module_manager.hpp @@ -1,2 +1,18 @@ +/* + * Copyright 2024 NWChemEx Community + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #pragma once -#include \ No newline at end of file +#include diff --git a/include/pluginplay/module_manager/module_manager_class.hpp b/include/pluginplay/module_manager/module_manager_class.hpp index 7aa73ad3d..3249514f4 100644 --- a/include/pluginplay/module_manager/module_manager_class.hpp +++ b/include/pluginplay/module_manager/module_manager_class.hpp @@ -28,7 +28,7 @@ namespace detail_ { struct ModuleManagerPIMPL; } -/** @brief Class responsible for manipulating +/** @brief Class responsible for holding and managing modules. * */ class ModuleManager { @@ -250,7 +250,25 @@ class ModuleManager { */ key_container_type keys() const; + /** @brief Does *this have a cache set? + * + * + * @return True if *this has a place where it can cache input/result pairs + * and false otherwise. + * + * @throw none No throw guarantee. + */ + bool has_cache() const noexcept; + private: + /** @brief Does *this have a PIMPL? + * + * @return False if pimpl_ is set to a null pointer and true otherwise. + * + * @throw None No throw guarantee. + */ + bool has_pimpl_() const noexcept; + /// Bridges the gap between the set_default and the PIMPL void set_default_(const std::type_info& type, type::input_map inps, type::key key); diff --git a/src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp b/src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp index 3b20ed622..8ebba6c1e 100644 --- a/src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp +++ b/src/pluginplay/module_manager/detail_/module_manager_pimpl.hpp @@ -80,7 +80,7 @@ struct ModuleManagerPIMPL { std::make_shared()) {} ModuleManagerPIMPL(runtime_ptr runtime, cache_pointer cache) : - m_runtime_(runtime), m_pcaches(cache) {} + m_pcaches(cache), m_runtime_(runtime) {} /// Makes a deep copy of this instance on the heap // auto clone() { return std::make_unique(*this); } @@ -175,6 +175,8 @@ struct ModuleManagerPIMPL { runtime_type& get_runtime() const { return *m_runtime_; } ModuleManager::key_container_type keys() const; + + bool has_cache() const noexcept { return static_cast(m_pcaches); } ///@} ///@{ @@ -214,4 +216,4 @@ struct ModuleManagerPIMPL { } // namespace pluginplay::detail_ -#include "module_manager_pimpl.ipp" \ No newline at end of file +#include "module_manager_pimpl.ipp" diff --git a/src/pluginplay/module_manager/module_manager.cpp b/src/pluginplay/module_manager/module_manager_class.cpp similarity index 88% rename from src/pluginplay/module_manager/module_manager.cpp rename to src/pluginplay/module_manager/module_manager_class.cpp index 91bb21695..ed83cd81d 100644 --- a/src/pluginplay/module_manager/module_manager.cpp +++ b/src/pluginplay/module_manager/module_manager_class.cpp @@ -82,4 +82,18 @@ ModuleManager::runtime_type& ModuleManager::get_runtime() const noexcept { ModuleManager::key_container_type ModuleManager::keys() const { return pimpl_->keys(); } + +bool ModuleManager::has_cache() const noexcept { + // Relies on short-circuiting to not dereference pimpl + return has_pimpl_() && pimpl_->has_cache(); +} + +// ----------------------------------------------------------------------------- +// -- Private Methods +// ----------------------------------------------------------------------------- + +bool ModuleManager::has_pimpl_() const noexcept { + return static_cast(pimpl_); +} + } // namespace pluginplay diff --git a/src/python/cache/export_cache.hpp b/src/python/cache/export_cache.hpp new file mode 100644 index 000000000..686c58aeb --- /dev/null +++ b/src/python/cache/export_cache.hpp @@ -0,0 +1,13 @@ +#pragma once +#include "../export_pluginplay.hpp" + +namespace pluginplay { + +void export_module_manager_cache(py_module_reference m); + +inline void export_cache(py_module_reference m) { + auto m_cache = m.def_submodule("cache"); + export_module_manager_cache(m_cache); +} + +} // namespace pluginplay diff --git a/src/python/cache/export_module_manager_cache.cpp b/src/python/cache/export_module_manager_cache.cpp new file mode 100644 index 000000000..ac4b4db16 --- /dev/null +++ b/src/python/cache/export_module_manager_cache.cpp @@ -0,0 +1,12 @@ +#include "export_cache.hpp" +#include +namespace pluginplay { + +void export_module_manager_cache(py_module_reference m) { + py_class_type>( + m, "ModuleManagerCache") + .def(pybind11::init<>()); +} + +} // namespace pluginplay diff --git a/src/python/export_pluginplay.cpp b/src/python/export_pluginplay.cpp index 982982423..0ab0ff243 100644 --- a/src/python/export_pluginplay.cpp +++ b/src/python/export_pluginplay.cpp @@ -15,8 +15,10 @@ */ #include "any/export_any.hpp" +#include "cache/export_cache.hpp" #include "fields/export_fields.hpp" #include "module/export_module.hpp" +#include "module_manager/export_module_manager.hpp" #include "printing/export_printing.hpp" #include "python/export_python.hpp" #include @@ -25,6 +27,7 @@ namespace pluginplay { PYBIND11_MODULE(pluginplay, m) { any::export_any(m); + export_cache(m); export_fields(m); python::export_python(m); export_module(m); diff --git a/src/python/export_pluginplay.hpp b/src/python/export_pluginplay.hpp index b7852d35d..36c132768 100644 --- a/src/python/export_pluginplay.hpp +++ b/src/python/export_pluginplay.hpp @@ -37,7 +37,6 @@ using py_class_type = pybind11::class_; // -- Declarations of exports for top-level classes // ----------------------------------------------------------------------------- -void export_module_manager(py_module_reference m); void export_submodule_request(py_module_reference m); void export_printing(py_module_reference m); diff --git a/src/python/module_manager/export_module_manager.hpp b/src/python/module_manager/export_module_manager.hpp new file mode 100644 index 000000000..17393fbcf --- /dev/null +++ b/src/python/module_manager/export_module_manager.hpp @@ -0,0 +1,12 @@ +#pragma once +#include "../export_pluginplay.hpp" + +namespace pluginplay { + +void export_module_manager_class(py_module_reference m); + +inline void export_module_manager(py_module_reference m) { + export_module_manager_class(m); +} + +} // namespace pluginplay diff --git a/src/python/module_manager/export_module_manager.cpp b/src/python/module_manager/export_module_manager_class.cpp similarity index 78% rename from src/python/module_manager/export_module_manager.cpp rename to src/python/module_manager/export_module_manager_class.cpp index 7f453948a..045741ee2 100644 --- a/src/python/module_manager/export_module_manager.cpp +++ b/src/python/module_manager/export_module_manager_class.cpp @@ -14,7 +14,7 @@ * limitations under the License. */ -#include "../export_pluginplay.hpp" +#include "export_module_manager.hpp" #include "module/py_module_base.hpp" #include #include @@ -24,15 +24,23 @@ namespace pluginplay { -void export_module_manager(py_module_reference m) { - using at_fxn = Module& (ModuleManager::*)(const type::key&); - using runtime_type = typename ModuleManager::runtime_type; +void export_module_manager_class(py_module_reference m) { + using at_fxn = Module& (ModuleManager::*)(const type::key&); + using runtime_type = typename ModuleManager::runtime_type; + using cache_type = typename ModuleManager::cache_type; + using cache_pointer = typename ModuleManager::cache_pointer; using py_obj = pybind11::object; using python::PythonWrapper; py_class_type(m, "ModuleManager") .def(pybind11::init<>()) + .def(pybind11::init([](runtime_type rv, cache_pointer cache) { + auto prv = std::make_shared(rv); + return ModuleManager(prv, cache); + }), + pybind11::arg("rv"), + pybind11::arg("cache") = std::make_shared()) .def("count", &ModuleManager::count) .def("size", &ModuleManager::size) .def( @@ -63,6 +71,7 @@ void export_module_manager(py_module_reference m) { .def("get_runtime", &ModuleManager::get_runtime, pybind11::return_value_policy::reference_internal) .def("keys", &ModuleManager::keys) + .def("has_cache", &ModuleManager::has_cache) .def("__getitem__", [](ModuleManager& self, const type::key& key) { return self.at(key); }); diff --git a/tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp b/tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp index 80a0c1da0..5ce286a28 100644 --- a/tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp +++ b/tests/cxx/unit_tests/pluginplay/module_manager/detail_/module_manager_pimpl.cpp @@ -246,3 +246,10 @@ TEST_CASE("ModuleManagerPIMPL : keys") { REQUIRE(pimpl1.keys().at(1) == "rectangle"); } } + +TEST_CASE("ModuleManagerPIMPL : has_cache") { + ModuleManagerPIMPL pimpl0; + ModuleManagerPIMPL pimpl1(nullptr, nullptr); + REQUIRE(pimpl0.has_cache()); + REQUIRE_FALSE(pimpl1.has_cache()); +} diff --git a/tests/cxx/unit_tests/pluginplay/module_manager/module_manager.cpp b/tests/cxx/unit_tests/pluginplay/module_manager/module_manager_class.cpp similarity index 93% rename from tests/cxx/unit_tests/pluginplay/module_manager/module_manager.cpp rename to tests/cxx/unit_tests/pluginplay/module_manager/module_manager_class.cpp index 8294e8586..d1520703c 100644 --- a/tests/cxx/unit_tests/pluginplay/module_manager/module_manager.cpp +++ b/tests/cxx/unit_tests/pluginplay/module_manager/module_manager_class.cpp @@ -14,9 +14,9 @@ * limitations under the License. */ -#include #include "test_common.hpp" #include +#include TEST_CASE("ModuleManager") { pluginplay::ModuleManager mm; @@ -71,4 +71,10 @@ TEST_CASE("ModuleManager") { REQUIRE(keys[0] == "a key"); REQUIRE(keys[1] == "b key"); } + + SECTION("has_cache") { + REQUIRE(mm.has_cache()); + pluginplay::ModuleManager no_cache(nullptr, nullptr); + REQUIRE_FALSE(no_cache.has_cache()); + } } diff --git a/tests/python/unit_tests/module_manager/test_module_manager.py b/tests/python/unit_tests/module_manager/test_module_manager_class.py similarity index 94% rename from tests/python/unit_tests/module_manager/test_module_manager.py rename to tests/python/unit_tests/module_manager/test_module_manager_class.py index c6c0e6f67..621b3c382 100644 --- a/tests/python/unit_tests/module_manager/test_module_manager.py +++ b/tests/python/unit_tests/module_manager/test_module_manager_class.py @@ -28,11 +28,21 @@ def run_(self, inputs, submods): pt = test_pp.OneInOneOut() i0, = pt.unwrap_inputs(inputs) rv = self.results() - return pt.wrap_results(rv, i0) + return pt.wrap_results(rv, i0) # class TestModuleManager(unittest.TestCase): + def test_ctor(self): + rv = parallelzone.runtime.RuntimeView() + has_runtime_and_cache = pp.ModuleManager(rv) + self.assertEqual(rv, has_runtime_and_cache.get_runtime()) + self.assertTrue(has_runtime_and_cache.has_cache()) + + has_runtime_only = pp.ModuleManager(rv, None) + self.assertEqual(rv, has_runtime_only.get_runtime()) + self.assertFalse(has_runtime_only.has_cache()) + def test_count(self): # Defaulted is always false self.assertFalse(self.defaulted.count('not a key')) @@ -220,4 +230,5 @@ def test_keys(self): def setUp(self): self.defaulted = pp.defaulted_mm() self.has_mods = test_pp.get_mm() + self.corr_total = 10 # This should be the correct number of modules From 7e699c10c3e127e4fa2f1d66b302395450fabaf6 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Thu, 13 Jun 2024 19:20:29 +0000 Subject: [PATCH 3/4] Committing clang-format changes --- .../detail_/module_manager_pimpl.ipp | 16 ++++++++++++++++ .../module_manager/module_manager_class.cpp | 2 +- src/python/cache/export_cache.hpp | 16 ++++++++++++++++ src/python/cache/export_module_manager_cache.cpp | 16 ++++++++++++++++ .../module_manager/export_module_manager.hpp | 16 ++++++++++++++++ tests/python/unit_tests/module/__init__.py | 13 +++++++++++++ .../python/unit_tests/module_manager/__init__.py | 13 +++++++++++++ 7 files changed, 91 insertions(+), 1 deletion(-) diff --git a/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp b/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp index fcd88c4ce..cb43d932f 100644 --- a/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp +++ b/src/pluginplay/module_manager/detail_/module_manager_pimpl.ipp @@ -1,3 +1,19 @@ +/* + * Copyright 2024 NWChemEx-Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + // This file meant only for inclusion in module_manager_pimpl.hpp #pragma once diff --git a/src/pluginplay/module_manager/module_manager_class.cpp b/src/pluginplay/module_manager/module_manager_class.cpp index ed83cd81d..23294778e 100644 --- a/src/pluginplay/module_manager/module_manager_class.cpp +++ b/src/pluginplay/module_manager/module_manager_class.cpp @@ -32,7 +32,7 @@ ModuleManager::ModuleManager() : pimpl_(std::make_unique()) {} ModuleManager::ModuleManager(runtime_ptr runtime, cache_pointer cache) : pimpl_(std::make_unique(runtime, cache)) {} -ModuleManager::ModuleManager(ModuleManager&& rhs) noexcept = default; +ModuleManager::ModuleManager(ModuleManager&& rhs) noexcept = default; ModuleManager& ModuleManager::operator=(ModuleManager&& rhs) noexcept = default; ModuleManager::~ModuleManager() noexcept = default; diff --git a/src/python/cache/export_cache.hpp b/src/python/cache/export_cache.hpp index 686c58aeb..4dd955af4 100644 --- a/src/python/cache/export_cache.hpp +++ b/src/python/cache/export_cache.hpp @@ -1,3 +1,19 @@ +/* + * Copyright 2024 NWChemEx-Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #pragma once #include "../export_pluginplay.hpp" diff --git a/src/python/cache/export_module_manager_cache.cpp b/src/python/cache/export_module_manager_cache.cpp index ac4b4db16..9d8ae2816 100644 --- a/src/python/cache/export_module_manager_cache.cpp +++ b/src/python/cache/export_module_manager_cache.cpp @@ -1,3 +1,19 @@ +/* + * Copyright 2024 NWChemEx-Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #include "export_cache.hpp" #include namespace pluginplay { diff --git a/src/python/module_manager/export_module_manager.hpp b/src/python/module_manager/export_module_manager.hpp index 17393fbcf..b66f741f2 100644 --- a/src/python/module_manager/export_module_manager.hpp +++ b/src/python/module_manager/export_module_manager.hpp @@ -1,3 +1,19 @@ +/* + * Copyright 2024 NWChemEx-Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + #pragma once #include "../export_pluginplay.hpp" diff --git a/tests/python/unit_tests/module/__init__.py b/tests/python/unit_tests/module/__init__.py index e69de29bb..15622f72d 100644 --- a/tests/python/unit_tests/module/__init__.py +++ b/tests/python/unit_tests/module/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2024 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/tests/python/unit_tests/module_manager/__init__.py b/tests/python/unit_tests/module_manager/__init__.py index e69de29bb..15622f72d 100644 --- a/tests/python/unit_tests/module_manager/__init__.py +++ b/tests/python/unit_tests/module_manager/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2024 NWChemEx-Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. From 2fa5437f9d06324638a3793e7dce3e359aa0e2e5 Mon Sep 17 00:00:00 2001 From: ryan Date: Thu, 13 Jun 2024 14:42:02 -0500 Subject: [PATCH 4/4] remove redundant header --- include/pluginplay/module_manager.hpp | 280 -------------------------- 1 file changed, 280 deletions(-) delete mode 100644 include/pluginplay/module_manager.hpp diff --git a/include/pluginplay/module_manager.hpp b/include/pluginplay/module_manager.hpp deleted file mode 100644 index 677f344df..000000000 --- a/include/pluginplay/module_manager.hpp +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Copyright 2022 NWChemEx-Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once -#include -#include -#include -#include -#include - -namespace pluginplay { - -namespace detail_ { -struct ModuleManagerPIMPL; -} - -/** @brief Class responsible for manipulating - * - */ -class ModuleManager { -public: - /// The type of a pointer to a read/write module - using module_base_ptr = std::shared_ptr; - - /// The type of a pointer to a read-only module - using const_module_base_ptr = std::shared_ptr; - - /// Type of a map holding usable modules - using module_map = utilities::CaseInsensitiveMap>; - - /// The type of the runtime - using runtime_type = parallelzone::runtime::RuntimeView; - - /// A pointer to a runtime - using runtime_ptr = std::shared_ptr; - - /// Type of module key container - using key_container_type = std::vector; - - /// Type of - - ///@{ - /** @name Ctors and assignment operators - * - */ - ModuleManager(); - ModuleManager(runtime_ptr runtime, - cache_pointer cache = std::make_shared <); - // ModuleManager(const ModuleManager& rhs); - // ModuleManager& operator=(const ModuleManager& rhs) { - // return *this = std::move(ModuleManager(rhs)); - // } - ModuleManager(ModuleManager&& rhs) noexcept; - ModuleManager& operator=(ModuleManager&& rhs) noexcept; - ///@} - - /// Standard dtor - ~ModuleManager() noexcept; - - /** @brief Returns an iterator to the first element of the module map - * - * @return Iterator to the first element of the map - */ - module_map::iterator begin() noexcept; - - /** @brief Returns an iterator to the past-the-end element of the module map - * - * @return Iterator to the past-the-end element of the map - */ - module_map::iterator end() noexcept; - - /** @brief Used to see if we have a module - * - * @param key - * @return - */ - type::size count(type::key key) const noexcept; - - /** @brief Gets the number of modules loaded. - * - * @return Number of modules loaded. - */ - type::size size() const noexcept; - - template - void add_module(type::key module_key); - - /** @brief Used to add a new module to the list - * - * @param module_key - * @param base - */ - - void add_module(type::key module_key, module_base_ptr base); - - ///@{ - /** @name Module retrievers - * - * @param module_key - * @return - */ - Module& at(const type::key& module_key) { - const auto& rv = const_cast(*this).at(module_key); - return const_cast(rv); - } - const Module& at(const type::key& module_key) const; - ///@} - - /** @brief Makes a "deep copy" of a module - * - * This function will copy the module stored under @p old_key and store the - * copy under @p new_key. The copy will be unlocked, with a deep copy of - * @p old_key 's inputs and submodules. Deep copy in this context meaning - * that changing @p new_key 's inputs or submodules will not affect the - * module stored under @p old_key. - * - * @param[in] old_key The key for the module which is being copied. - * @param[in] new_key The key for the resulting copy. - * - * @throw std::bad_alloc if an allocation error arises. - */ - void copy_module(const type::key& old_key, type::key new_key); - - /** @brief Unloads the specified module. - * - * This function unloads the module with the specified key. After this - * operation the key is free to be used again. Calling this function does - * NOT clean any data out of the cache. This function is a no-op if @p key - * does not exist. - * - * @param[in] key The key for the module which should be erased. - */ - void erase(const type::key& key); - - /** @brief Changes the key a module is stored under. - * - * This function can be used to rename the key a module is stored under. - * After a call to this function there will be no module stored under - * @p old_key. - * - * @param[in] old_key The key we are renaming. - * @param[in] new_key The value for the new key. - * - * @throw std::bad_alloc if there is an allocation error. - */ - void rename_module(const type::key& old_key, type::key new_key); - - /** @brief Defines the default module for a particular property type - * - * @tparam T The type of the property type the default is for - * @param key The module key of the default module - */ - template - void set_default(type::key key) { - auto temp = T::inputs(); - type::input_map inps(temp.begin(), temp.end()); - set_default_(typeid(T), std::move(inps), std::move(key)); - } - - /** @brief Changes the value of an input bound to a module - * - * @tparam T - * @param key - * @param option - * @param new_value - */ - template - void change_input(const type::key& key, const type::key& option, - T&& new_value) { - at(key).change_input(option, std::forward(new_value)); - } - - /** @brief Changes the submodule a module calls. - * - * Modules can call other modules at predesignated callback points. Each of - * these callback points has a key associated with it. This function allows - * the user to change which module is called at a particular callback point - * by specifying the key of the module, the callback point's key, and the - * key for tne new submodule. - * - * @param[in] module_key The key for the module whose submodule is being - * changed. - * @param[in] callback_key The name of the callback point in the module - * assigned to @p module_key - * @param[in] submod_key The key for the submodule to call. - * - * @throw std::out_of_range if any of the keys do not refer to valid, - * already present modules or callback points. Weak - * throw guarantee. - */ - void change_submod(const type::key& module_key, - const type::key& callback_key, - const type::key& submod_key); - - /** @brief Runs a given module - * - * @tparam T - * @tparam Args - * @param key - * @param args - * @return - */ - template - auto run_as(const type::key& key, Args&&... args) { - return at(key).run_as(std::forward(args)...); - } - - /** @brief Sets the runtime of the module mananger and its modules. - * - * @param[in] runtime A shared_ptr to a @p runtime_type instance with which - * the module manager is currently associated. - * - * @throw None No throw guarantee. - */ - void set_runtime(runtime_ptr runtime) noexcept; - - /** @brief Provides the runtime of the module manager. - * - * @return The runtime object with which the module manager is currently - * associated. - * - * @throw std::runtime_error if there is no runtime. Strong throw - * guarantee. - */ - runtime_type& get_runtime() const noexcept; - - /** @brief Returns the keys of all the modules in the module manager. - * - * @return A vector of keys for all the modules in the module manager. - * - * @throw std::bad_alloc if an allocation error arises. - */ - key_container_type keys() const; - -private: - /** @brief Checks whether pimpl_ is not null. - * - * @return False if pimpl_ is a null pointer and true otherwise. - * - * @throw None No throw guarantee. - */ - bool has_pimpl_() const noexcept; - - /// Bridges the gap between the set_default and the PIMPL - void set_default_(const std::type_info& type, type::input_map inps, - type::key key); - - /// The object that actually implements the ModuleManager - std::unique_ptr pimpl_; -}; // End class ModuleManager - -//------------------------------------------------------------------------------ -// Inline Implementations -//------------------------------------------------------------------------------ - -template -void ModuleManager::add_module(type::key module_key) { - add_module(std::move(module_key), std::make_shared()); -} - -inline void ModuleManager::rename_module(const type::key& old_key, - type::key new_key) { - copy_module(old_key, std::move(new_key)); - erase(old_key); -} - -} // namespace pluginplay