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