Starting with v0.4.1 SOL comes with the option to add user defined plugins. To
use the SOL SDK you first need to install nec-sol install sdk
. Then go to
the path where sol is installed (usually under .local/lib/python*/sol
), go
to the sdk folder. Within the example folder you can find different kinds of SOL
plugins.
You can build these examples using:
cmake -DCMAKE_MODULE_PATH=/path/to/sol/sdk /path/to/sol/sdk/examples/type/
make
To test if your plugin works, you need to copy it to /path/to/sol/lib64
and run python3 -m sol
. It will display an overview of all loaded plugins.
##############################################################################
SOL Compiler Plugins:
Devices: [x86, ve]
Frameworks: [pytorch, dl4j, onnx]
Deployments: [static_lib, shared_lib]
Backends: [dfp::ncc, dnn::mkl, dnn::veblas, dnn::cublas, dnn::dnnl, dfp::ispc, dnn::veasl, dnn::vednn]
Jits: [gcc, ncc, dot, ispc, python]
SOL Runtime Plugins:
x86 [dfp::ispc, none]
ve [dnn::veblas, dnn::veasl, dnn::vednn, none]
##############################################################################
If your plugin is not shown within this view, please run SOL_LOG=TRACE python3 -m sol
and check why SOL rejects your plugin. The most common reason
is that SOL can’t find depending shared libraries or your plugin was compiled
for another version of SOL. To ensure compatibility, SOL rejects all plugins
whose version differs EVEN between minor releases!
SOL plugins are versions and can only be loaded for the specific version they have been build for. Further, SOL plugins enforce specific namespace conventions. The following macros can be used to register the necessary callbacks within the SOL plugin:
#define SOL_REGISTER_PLUGIN()
#define SOL_REGISTER_BACKEND("MyBackend")
#define SOL_REGISTER_BACKEND_COMPILER("MyBackend",
/* Enables this backend for MyDevice and OtherDevice */
{"MyDevice", "OtherDevice"},
/* generates files as FILENAME.custom.cpp and compiles them to
FILENAME.custom.o */
{".custom", ".cpp"},
{
/* Can be used received the Backend as:
heuristic<MyFancyOp>({Layout::NCP, Layout::OIP})
and gets populated as:
sol.config['heuristic::mybackend::myfancyop::ncp::oip'] */
Heuristic<MyFancyOp>({Layout::NCP, Layout::OIP}, 100),
Heuristic<MyFancyOp>({Layout::NCP, Layout::PIO}, 120)
}
)
#define SOL_REGISTER_BACKEND_RUNTIME("MyBackend",
{"MyDevice", "OtherDevice"}
)
#define SOL_REGISTER_DEPLOYMENT("MyDeployment")
#define SOL_REGISTER_DEPLOYMENT_COMPILER("MyDeployment")
#define SOL_REGISTER_DEVICE("MyDevice")
#define SOL_REGISTER_DEVICE_COMPILER("MyDevice", "MyJit")
#define SOL_REGISTER_DEVICE_RUNTIME("MyDevice")
#define SOL_REGISTER_FRAMEWORK("MyFramework")
#define SOL_REGISTER_FRAMEWORK_COMPILER("MyFramework")
#define SOL_REGISTER_FRAMEWORK_RUNTIME("MyFramework")
#define SOL_REGISTER_FRAMEWORK_RUNTIME("MyFramework", "MyDevice")
#define SOL_REGISTER_JIT("MyJit")
#define SOL_REGISTER_JIT_COMPILER("MyJit")
#define SOL_REGISTER_LAYERS(
Operation::registerOperation<MyFancyOp>();
)
In theory you can mix all of these components within one plugin, but it is not
recommended to do that. Please take a look at the examples provided in
/path/to/sol/sdk/examples
to see how these functions are used and how
the namespace needs to be setup.
SOL_REGISTER_PLUGIN_INIT
can be used to do plugin specific initializations, i.e.:
SOL_REGISTER_PLUGIN_INIT(
mylib_init();
sol::reportVersion("MyLib", MYLIB_VERSION_STRING);
)
Plugins will be loaded in the following order:
libsol-jit-*.so
libsol-device-*.so
libsol-layers-*.so
libsol-backend-*.so
libsol-framework-*.so
libsol-deployment-*.so
Further, the runtime system will load libsol-framework-*-DEVICETYPE.so
libraries when creating a device context. These can be necessary if SOL shall
share the same memory space with the framework. If no such library exists, SOL
will use it’s default memory allocators.