Loading a Module Collection
The key piece of a module collection is the load_modules
function. When a
user starts a run with PluginPlay one of the first things they do is initialize
a ModuleManager
instance. The code to do this looks something like:
// Initialize ModuleManager
ModuleManager mm;
library1::load_modules(mm);
library2::load_modules(mm);
where load_modules(mm)
calls load the module collections provided by the
various libraries.
Public API
As far as the public API for load_modules
goes, the declaration is simple:
/*
* 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 <pluginplay/pluginplay.hpp>
namespace pluginplay_examples {
void load_modules(pluginplay::ModuleManager& mm);
}
In particular note that by forward declaring the load_modules
function it is
not necessary for the user to know the types of your modules and more
importantly any libraries you use to implement them.
Note
If your modules use property types defined elsewhere (such as in centralized community resources like NWChemEx/SimDE) and your module-specific inputs are standard C++ types (or types found in the property types) this is your entire public API!!!
Implementation
The actual implementation of load_modules
typically consists of two parts:
loading the modules and setting the default submodules.
Modules are loaded into the ModuleManager
by calling add_module
. For
your convenience the ModuleManager
has an overload of add_module
which
takes a template type parameter that is the type of your module (as in the name
of the class which contains the algorithm) and a module key. The module key is
how users will refer to your module, e.g., when they want to run your module
they will call ModuleManager::run_as
providing your module’s key. If your
module requires more detailed set-up other overloads exist that will bind to
existing instances.
Continuing with our electric field examples, adding our modules to the
ModuleManager
looks like:
#include "load_modules.hpp"
#include "modules.hpp"
namespace pluginplay_examples {
void load_modules(pluginplay::ModuleManager& mm) {
using coulombs_law_float = TemplatedCoulombsLaw<float>;
mm.add_module<ClassicalForce>("Classical Force");
mm.add_module<CoulombsLaw>("Coulomb's Law");
mm.add_module<ScreenedCoulombsLaw>("Coulomb's Law with screening");
mm.add_module<coulombs_law_float>("Single-precision Coulomb's law");
}
} // namespace pluginplay_examples
Once you have added all your modules the next step is to set the default
submodules. In our examples, the ClassicalForce
module needed a submodule
which can compute electric fields. Presently we have already loaded three such
modules; their keys are:
“Coulomb’s Law”
“Coulomb’s Law with screening”
“Single-precision Coulomb’s law”
If by default we want the ClassicalForce
module we loaded under the key
“Force” to use a CoulombsLaw
module we can accomplish this by:
mm.change_submod("Classical Force", "electric field", "Coulomb's Law");
Note
It is not necessary to set all submodules in the load_modules
function.
In particular if your module depends on a property that none of your modules
can compute you would not set that submodule. In this case, it will be the
responsability of the caller to set the submodule.
The entire implementation of our load_modules
function looks like:
/*
* 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.
*/
#include "load_modules.hpp"
#include "modules.hpp"
namespace pluginplay_examples {
void load_modules(pluginplay::ModuleManager& mm) {
using coulombs_law_float = TemplatedCoulombsLaw<float>;
mm.add_module<ClassicalForce>("Classical Force");
mm.add_module<CoulombsLaw>("Coulomb's Law");
mm.add_module<ScreenedCoulombsLaw>("Coulomb's Law with screening");
mm.add_module<coulombs_law_float>("Single-precision Coulomb's law");
mm.change_submod("Classical Force", "electric field", "Coulomb's Law");
}
} // namespace pluginplay_examples