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 2019 will be used by default (set KATANA_OPWRITE_CMAKE_GENERATOR for choosing a different compiler on Windows).

Environment Variables

  • KATANA_ENABLE_OPWRITE_NODE: Set to 1 to enable the node type.

  • KATANA_OPWRITE_CMAKE_GENERATOR: By default, Makefile will be used on Linux; Visual Studio 16 2019 will be used on Windows. Users can set this environment variable (e.g. to Ninja or Visual Studio 17 2022) to override the default generator (and the compiler in the case of Windows).