OpWrite nodes allow users to write custom, dynamic Ops in C++.
The OpWrite node type has been modelled after the OpScript node type, with regards to its parameter interface and general functionality, including the ability for deferred execution of the custom Op in question.
By default, the OpWrite node type is disabled. You can set the
KATANA_ENABLE_OPWRITE_NODE environment variable to
launching Katana to make it available.
The first time an OpWrite node needs to cook a location, a temporary dynamic
library will be compiled with the provided source code. This will literally
.so file on Linux, or a
.dll file on Windows. Each OpWrite node
instance will compile its own dynamic library, with its own source code. The
dynamic library will be loaded and executed to cook targeted locations.
When an OpWrite node is added to the node graph, a template program is offered
in its code.cpp parameter. This is the source code that will be compiled.
The same API that is used when writing standard C++ Op plug-ins can be used
inside OpWrite nodes. A
function is provided as part of the template program, which the user is to fill
cook() function needs to be thread-safe, as it may be
invoked from multiple threads concurrently.
Static variables can be defined; they will be initialized when the dynamic library is first loaded. However, if memory is allocated at library load time, it should be freed when the library is unloaded as well, or else unrecoverable memory leaks will occur.
The dynamic libraries will be unloaded in these situations:
When caches are flushed in Katana.
When changes in the OpWrite node’s parameters invalidate the node, which means a new dynamic library needs to be compiled and loaded.
A CMake template script is also provided in the cmake.txt parameter. Usually the CMake script will remain unchanged, however, if external libraries are required, users will need to make adjustments to include such libraries.
Motivation For Using OpWrite Nodes¶
The OpWrite node type is good for prototyping C++ Ops that could then be converted into specific, standard Katana plug-ins. Developers that are not familiar with the Lua programming language, but are familiar with C++, may find that prototyping Ops in C++ with OpWrite nodes is easier than with OpScript nodes.
OpWrite nodes provide extra freedom when using external libraries. Any external C/C++ library can be loaded. This is not the case for OpScript nodes, where the use of external libraries is more limited (e.g. inability for loading networking libraries, or generally libraries that require shared linking against the Lua core library that Katana does not ship, as it is linked statically).
In regards to performance, building the dynamic libraries takes time (1 or 2 seconds for a small program, but it could take longer if the program grows large). Therefore, only if the cumulative time spent in the cook function is comparable to the compilation time will there be a performance gain (compared to the same algorithm implemented in Lua in an OpScript node).
In order to use the OpWrite node type, CMake, a build generator, and a compiler need to be available.
On Linux, the
CXX environment variables will be respected in
order to find the current compiler. On Windows, Visual Studio 2017 will be used
by default (set
KATANA_OPWRITE_CMAKE_GENERATOR for choosing a different
compiler on Windows).
KATANA_ENABLE_OPWRITE_NODE: Set to
1to enable the node type.
KATANA_OPWRITE_CMAKE_GENERATOR: By default,
Makefilewill be used on Linux;
Visual Studio 15 2017 Win64will be used on Windows. Users can set this environment variable (e.g. to
Visual Studio 16 2019) to override the default generator (and the compiler in the case of Windows).