OpWrite
Introduction
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.
Note
By default, the OpWrite node type is disabled. You can set the
KATANA_ENABLE_OPWRITE_NODE
environment variable to 1
before
launching Katana to make it available.
Technical Description
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
create a .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 void cook(Foundry::Katana::GeolibCookInterface&)
function is provided as part of the template program, which the user is to fill
in.
Warning
The 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).
Requirements
In order to use the OpWrite node type, CMake, a build generator, and a compiler need to be available.
On Linux, the CC
and CXX
environment variables will be respected in
order to find the current compiler. On Windows, Visual Studio 2022 will be used
by default (set KATANA_OPWRITE_CMAKE_GENERATOR
for choosing a different
compiler on Windows).
Environment Variables
KATANA_ENABLE_OPWRITE_NODE
: Set to1
to enable the node type.KATANA_OPWRITE_CMAKE_GENERATOR
: By default,Makefile
will be used on Linux;Visual Studio 17 2022
will be used on Windows. Users can set this environment variable (e.g. toNinja
orVisual Studio 16 2019
) to override the default generator (and the compiler in the case of Windows).