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 to ``1`` 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. to ``Ninja`` or ``Visual Studio 16 2019``) to override the default generator (and the compiler in the case of Windows).