Skip to content

Commit

Permalink
plugin engine: remove registration api and add env var
Browse files Browse the repository at this point in the history
  • Loading branch information
caitlinross committed Nov 2, 2021
1 parent e2f037a commit 00c3fbd
Show file tree
Hide file tree
Showing 14 changed files with 137 additions and 151 deletions.
6 changes: 5 additions & 1 deletion docs/user_guide/source/engines/plugin.rst
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ To build your plugin, your CMake should look something like:
target_link_libraries(PluginEngineWrite adios2::cxx11 adios2::core)
When using the Plugin Engine, ADIOS will check for your plugin at the path specified in the ``ADIOS2_PLUGIN_PATH`` environment variable.
If ``ADIOS2_PLUGIN_PATH`` is not set, ADIOS will warn you about it, and then look for your plugin in the current working directory.
If ``ADIOS2_PLUGIN_PATH`` is not set, and a path is not specified in the settings for the Plugin Engine (see below steps for using a plugin in your application), then the usual ``dlopen`` search is performed (see `dlopen man page <https://man7.org/linux/man-pages/man3/dlopen.3.html>`_).

The following steps show how to use your engine plugin in your application.
``examplePluginEngine_write.cpp`` and ``examplePluginEngine_read.cpp`` are an example of how to use the engine plugins described above.
Expand All @@ -88,10 +88,14 @@ The key steps to use your plugin are:

io.SetParameters({{"PluginName", "WritePlugin"}});
io.SetParameters({{"PluginLibrary", "PluginEngineWrite"}});
// also possible to use the path here instead of setting ADIOS2_PLUGIN_PATH
// io.SetParameters({{"PluginLibrary", "/path/to/libPluginEngineWrite.so"}})

.. note::
You don't need to add the ``lib`` prefix or the shared library ending (e.g., ``.so``, ``.dll``, etc.).
ADIOS will add these when searching for your plugin library.
If you do at the prefix/suffix, ADIOS should still be able to find your plugin.


At this point you can open the engine and use it as you would any other ADIOS engine.
You also shouldn't need to make any changes to your CMake files for your application.
16 changes: 12 additions & 4 deletions examples/plugins/engine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,22 @@
# accompanying file Copyright.txt for details.
#------------------------------------------------------------------------------#

add_library(PluginEngineWriteExample
ExampleWritePlugin.cpp
)
target_link_libraries(PluginEngineWriteExample adios2::cxx11 adios2_core)

add_library(PluginEngineReadExample
ExampleReadPlugin.cpp
)
target_link_libraries(PluginEngineReadExample adios2::cxx11 adios2_core)

add_executable(examplePluginEngine_write
examplePluginEngine_write.cpp
ExampleWritePlugin.h ExampleWritePlugin.cpp
)
target_link_libraries(examplePluginEngine_write adios2::cxx11 adios2_core)
target_link_libraries(examplePluginEngine_write adios2::cxx11)

add_executable(examplePluginEngine_read
examplePluginEngine_read.cpp
ExampleReadPlugin.h ExampleReadPlugin.cpp
)
target_link_libraries(examplePluginEngine_read adios2::cxx11 adios2_core)
target_link_libraries(examplePluginEngine_read adios2::cxx11)
14 changes: 14 additions & 0 deletions examples/plugins/engine/ExampleReadPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,3 +133,17 @@ void ExampleReadPlugin::DoClose(const int transportIndex) {}
} // end namespace engine
} // end namespace core
} // end namespace adios2

extern "C" {

adios2::core::engine::ExampleReadPlugin *EngineCreate(adios2::core::IO &io,
const std::string &name,
const adios2::Mode mode,
adios2::helper::Comm comm)
{
return new adios2::core::engine::ExampleReadPlugin(io, name, mode,
comm.Duplicate());
}

void EngineDestroy(adios2::core::engine::ExampleReadPlugin *obj) { delete obj; }
}
9 changes: 9 additions & 0 deletions examples/plugins/engine/ExampleReadPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,13 @@ class ExampleReadPlugin : public PluginEngineInterface
} // end namespace engine
} // end namespace core
} // end namespace adios2

extern "C" {

adios2::core::engine::ExampleReadPlugin *
EngineCreate(adios2::core::IO &io, const std::string &name,
const adios2::Mode mode, adios2::helper::Comm comm);
void EngineDestroy(adios2::core::engine::ExampleReadPlugin *obj);
}

#endif /* EXAMPLEREADPLUGIN_H_ */
16 changes: 16 additions & 0 deletions examples/plugins/engine/ExampleWritePlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,19 @@ void ExampleWritePlugin::WriteVarsFromIO()
} // end namespace engine
} // end namespace core
} // end namespace adios2

extern "C" {

adios2::core::engine::ExampleWritePlugin *
EngineCreate(adios2::core::IO &io, const std::string &name,
const adios2::Mode mode, adios2::helper::Comm comm)
{
return new adios2::core::engine::ExampleWritePlugin(io, name, mode,
comm.Duplicate());
}

void EngineDestroy(adios2::core::engine::ExampleWritePlugin *obj)
{
delete obj;
}
}
9 changes: 9 additions & 0 deletions examples/plugins/engine/ExampleWritePlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,13 @@ class ExampleWritePlugin : public PluginEngineInterface
} // end namespace engine
} // end namespace core
} // end namespace adios2

extern "C" {

adios2::core::engine::ExampleWritePlugin *
EngineCreate(adios2::core::IO &io, const std::string &name,
const adios2::Mode mode, adios2::helper::Comm comm);
void EngineDestroy(adios2::core::engine::ExampleWritePlugin *obj);
}

#endif /* EXAMPLEWRITEPLUGIN_H_ */
10 changes: 2 additions & 8 deletions examples/plugins/engine/examplePluginEngine_read.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
#include <vector>

#include "adios2.h"
#include "adios2/engine/plugin/PluginEngine.h"

#include "ExampleReadPlugin.h"

void testStreaming(adios2::Engine &reader, std::vector<float> &myFloats,
adios2::Variable<float> &var)
Expand Down Expand Up @@ -58,10 +55,6 @@ int main(int argc, char *argv[])

std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

/** Register Plugin with the PluginEngine **/
adios2::core::engine::PluginEngine::RegisterPlugin<
adios2::core::engine::ExampleReadPlugin>("MyPlugin");

try
{
/** ADIOS class factory of IO class objects */
Expand All @@ -73,7 +66,8 @@ int main(int argc, char *argv[])

/** Engine derived class, spawned to start IO operations */
io.SetEngine("Plugin");
io.SetParameters({{"PluginName", "MyPlugin"}});
io.SetParameters({{"PluginName", "ReadPlugin"}});
io.SetParameters({{"PluginLibrary", "PluginEngineRead"}});
adios2::Engine reader = io.Open("TestPlugin", adios2::Mode::Read);

auto var = io.InquireVariable<float>("data");
Expand Down
10 changes: 2 additions & 8 deletions examples/plugins/engine/examplePluginEngine_write.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@
#include <vector>

#include "adios2.h"
#include "adios2/engine/plugin/PluginEngine.h"

#include "ExampleWritePlugin.h"

void testStreaming(adios2::Engine &writer, std::vector<float> &myFloats,
adios2::Variable<float> &var)
Expand Down Expand Up @@ -49,10 +46,6 @@ int main(int argc, char *argv[])
std::vector<float> myFloats = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
const std::size_t Nx = myFloats.size();

/** Register Plugin with the PluginEngine **/
adios2::core::engine::PluginEngine::RegisterPlugin<
adios2::core::engine::ExampleWritePlugin>("MyPlugin");

try
{
/** ADIOS class factory of IO class objects */
Expand All @@ -69,7 +62,8 @@ int main(int argc, char *argv[])

/** Engine derived class, spawned to start IO operations */
io.SetEngine("Plugin");
io.SetParameters({{"PluginName", "MyPlugin"}});
io.SetParameters({{"PluginName", "WritePlugin"}});
io.SetParameters({{"PluginLibrary", "PluginEngineWrite"}});
adios2::Engine writer = io.Open("TestPlugin", adios2::Mode::Write);

if (streaming)
Expand Down
93 changes: 33 additions & 60 deletions source/adios2/engine/plugin/PluginEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,14 @@
#include "PluginEngineInterface.h"

#include <functional>
#include <map>
#include <memory>
#include <stdexcept>
#include <utility>

#include "adios2/helper/adiosDynamicBinder.h"

#include <adios2sys/SystemTools.hxx>

namespace adios2
{
namespace core
Expand All @@ -31,27 +32,12 @@ namespace engine

struct PluginEngine::Impl
{
using Registry =
std::map<std::string, std::pair<EngineCreateFun, EngineDestroyFun>>;
static Registry m_Registry;

std::string m_PluginName;
std::string m_PluginName = "UserPlugin";
std::unique_ptr<helper::DynamicBinder> m_Binder;
EngineCreateFun m_HandleCreate;
EngineDestroyFun m_HandleDestroy;
PluginEngineInterface *m_Plugin = nullptr;
};
PluginEngine::Impl::Registry PluginEngine::Impl::m_Registry;

/******************************************************************************/

void PluginEngine::RegisterPlugin(const std::string pluginName,
EngineCreateFun create,
EngineDestroyFun destroy)
{
PluginEngine::Impl::m_Registry.emplace(pluginName,
std::make_pair(create, destroy));
}

/******************************************************************************/

Expand Down Expand Up @@ -80,56 +66,43 @@ void PluginEngine::EndStep() { m_Impl->m_Plugin->EndStep(); }
void PluginEngine::Init()
{
auto paramPluginNameIt = m_IO.m_Parameters.find("PluginName");
if (paramPluginNameIt == m_IO.m_Parameters.end())
if (paramPluginNameIt != m_IO.m_Parameters.end())
{
m_Impl->m_PluginName = paramPluginNameIt->second;
}

std::string pluginPath;
adios2sys::SystemTools::GetEnv("ADIOS2_PLUGIN_PATH", pluginPath);

auto paramPluginLibraryIt = m_IO.m_Parameters.find("PluginLibrary");
if (paramPluginLibraryIt == m_IO.m_Parameters.end())
{
throw std::invalid_argument("PluginEngine: PluginName must be "
"specified in engine parameters");
throw std::invalid_argument(
"PluginEngine: PluginLibrary must be specified in "
"engine parameters if no PluginName "
"is specified");
}
m_Impl->m_PluginName = paramPluginNameIt->second;
std::string &pluginLibrary = paramPluginLibraryIt->second;

// First we check to see if we can find the plugin currently registerd
auto registryEntryIt =
PluginEngine::Impl::m_Registry.find(m_Impl->m_PluginName);
m_Impl->m_Binder.reset(
new helper::DynamicBinder(pluginLibrary, pluginPath));

if (registryEntryIt != PluginEngine::Impl::m_Registry.end())
m_Impl->m_HandleCreate = reinterpret_cast<EngineCreatePtr>(
m_Impl->m_Binder->GetSymbol("EngineCreate"));
if (!m_Impl->m_HandleCreate)
{
m_Impl->m_HandleCreate = registryEntryIt->second.first;
m_Impl->m_HandleDestroy = registryEntryIt->second.second;
throw std::runtime_error("PluginEngine: Unable to locate "
"EngineCreate symbol in specified plugin "
"library");
}
else

m_Impl->m_HandleDestroy = reinterpret_cast<EngineDestroyPtr>(
m_Impl->m_Binder->GetSymbol("EngineDestroy"));
if (!m_Impl->m_HandleDestroy)
{
// It's not currently registered so try to load it from a shared
// library
//
auto paramPluginLibraryIt = m_IO.m_Parameters.find("PluginLibrary");
if (paramPluginLibraryIt == m_IO.m_Parameters.end())
{
throw std::invalid_argument(
"PluginEngine: PluginLibrary must be specified in "
"engine parameters if no PluginName "
"is specified");
}
std::string &pluginLibrary = paramPluginLibraryIt->second;

m_Impl->m_Binder.reset(new helper::DynamicBinder(pluginLibrary));

m_Impl->m_HandleCreate = reinterpret_cast<EngineCreatePtr>(
m_Impl->m_Binder->GetSymbol("EngineCreate"));
if (!m_Impl->m_HandleCreate)
{
throw std::runtime_error("PluginEngine: Unable to locate "
"EngineCreate symbol in specified plugin "
"library");
}

m_Impl->m_HandleDestroy = reinterpret_cast<EngineDestroyPtr>(
m_Impl->m_Binder->GetSymbol("EngineDestroy"));
if (!m_Impl->m_HandleDestroy)
{
throw std::runtime_error("PluginEngine: Unable to locate "
"EngineDestroy symbol in specified plugin "
"library");
}
throw std::runtime_error("PluginEngine: Unable to locate "
"EngineDestroy symbol in specified plugin "
"library");
}
}

Expand Down
21 changes: 0 additions & 21 deletions source/adios2/engine/plugin/PluginEngine.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
#include <memory> // for unique_ptr
#include <string> // for string
#include <type_traits> // for add_pointer
#include <vector> // for vector

#include "adios2/common/ADIOSMacros.h"
#include "adios2/common/ADIOSTypes.h"
#include "adios2/core/Engine.h"
#include "adios2/core/IO.h"
#include "adios2/core/Variable.h"
#include "adios2/core/VariableCompound.h"
#include "adios2/helper/adiosComm.h"

namespace adios2
Expand All @@ -49,23 +47,6 @@ class PluginEngine : public Engine
using EngineDestroyFun =
std::function<std::remove_pointer<EngineDestroyPtr>::type>;

static void RegisterPlugin(const std::string pluginName,
EngineCreateFun create,
EngineDestroyFun destroy);
static void RegisterPlugin(const std::string pluginName,
EngineCreatePtr create, EngineDestroyPtr destroy)
{
RegisterPlugin(pluginName, EngineCreateFun(create),
EngineDestroyFun(destroy));
}

// This is just a shortcut method to handle the case where the class type is
// directly available to the caller so a simple new and delete call is
// sufficient to create and destroy the engine object
template <typename T>
static void RegisterPlugin(const std::string name);

public:
PluginEngine(IO &io, const std::string &name, const Mode mode,
helper::Comm comm);
virtual ~PluginEngine();
Expand Down Expand Up @@ -99,6 +80,4 @@ class PluginEngine : public Engine
} // end namespace core
} // end namespace adios2

#include "PluginEngine.inl"

#endif /* ADIOS2_ENGINE_PLUGIN_PLUGINENGINE_H_ */
Loading

0 comments on commit 00c3fbd

Please sign in to comment.