Fabric 101 for Programmers

January 12, 2016

If you’re a programmer looking to jump into Fabric for the first time, this blog is aimed at you. We’ve been producing a lot of introductory material for less technical people (check out the tutorial forums) but we wanted to produce something that would serve as a good general introduction for coders that are familiar with graphics programming. This blog has been shared in our forums as well, so if you’d like to see more information in here, just let us know.


Fabric Engine Components

Fabric is a broad framework with many components. The following is a summary list of the major ones.

  • Fabric Core
    Fabric’s core execution engine. This contains the compiler, the KL lexer and parser, GPU Compute and many more services required for Fabric to run.
  • KL
    Fabric’s own language, short for Kernel Language. KL is the basis of all features and applications implemented on top of Fabric.
  • Canvas
    Fabric’s visual programming system for KL. Less tech-savvy users can write KL by connecting nodes in a purely visual environment.
  • DCC Integrations
    Fabric runs in several digital content creation tools such as Autodesk Maya, for example. Running Fabric inside these authoring applications allows tools and gadgets to be used in any environment. This really is: Write once, deploy everywhere.
  • C/C++ API
    The programming interface for interacting with Fabric and/or integrating Fabric in other applications. It introduces RTVals (Registered Type Values), a powerful feature that allows you to invoke KL functions directly in C/C++.
  • EDK
    The C/C++ extension development kit to extend the KL language by binding existing C or C++ libraries. The EDK allows you to reuse existing code without having to rewrite it in KL.

Fabric Core

The Fabric Core is the core execution engine performing at run time. The Core manages KL extensions, compiles KL code and much more. You don’t need to interact with the Core directly if you aren’t using the C/C++ API. For more information on the Core please see Core Overview. The Core’s features include:

  • Just-in-time compilation through LLVM.
  • Optimization on target. This means all of the features of the current CPU can be utilized to execute the code as fast as possible.
  • Multi-level-optimization of machine code at run time. This allows users to see results quickly (less optimized) while a highly optimized version of the code is compiled in the background and is swapped transparently when finished.
  • Guarded vs. unguarded – The Core can be started as guarded or unguarded. In guarded mode array accesses are guarded (i.e. bounds-checked). This will slightly decrease run time performance but will also provide errors when any array accesses are out-of-bounds.
  • Task scheduling using Threading Building Blocks.
  • Caching of machine code results to a configurable storage location. This speeds up launch times in scenarios without code changes.
  • Code obfuscation – allowing you to distribute KL code in a non-human-readable fashion. The code won’t be optimized yet so optimization to target hardware will still be taken into account.
  • Memory management – STL-like simple-to-use array and dictionary data structures with excellent performance characteristics, reference-counted containers as well as a safe way to access to externally managed memory.
  • GPU Compute – support for KL on Nvidia GPUs, please see the GPU Compute Guide for more information.

Fabric KL

KL is Fabric’s programming language. KL stands for Kernel Language.

To learn about KL in more detail, please visit the KL Programming Guide.

Before diving in to the details of the language, we will present some simple examples. We don’t expect you to understand all the details of the examples, but hopefully they will give you a basic idea of what KL programs look like as well as some of what is possible with KL.

Hello World
1
2
3
4
5
6
7
/*
** Example: Hello World
*/
operator entry() {
  report("Hello, world!");
}
Fibonacci Sequence
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* Recursively compute the Fibonacci sequence.
** The first term is returned with n = 0
*/
function Integer fibonacci(Integer n) {
  if (n <= 1)
    return 1; // The first two terms (n=0 or n=1) are 1
  else
    return fibonacci(n - 2) + fibonacci(n - 1);
}
operator entry() {
  for (Integer i = 0; i < 10; ++i)
    report(fibonacci(i));
}

KL offers a broad range of features including:


Fabric Canvas

Canvas is Fabric’s visual programming system. All features of Canvas are essentially metaphors to programming. Canvas is a node-based system, where nodes represent function invocations. To learn more about Canvas in general please see the Canvas User Guide or the Canvas Programmer Guide.

image 1

 

 


Canvas and KL

Canvas nodes can either contain a sub graph (in programming: a function invoking other functions) or a piece of code (in programming: a function implementation) – these are called Graph Nodes and Function Nodes.

image 2

 

The deepest nodes in a graph are always Function Nodes. When the compiler hits a Canvas graph essentially it walks all the way down to the leaf node, and then builds up code for all of the higher level graphs, until the complete KL function representing the highest level Canvas graph is built. This has a bunch of nice consequences:

  • There’s no compromise in performance between writing pure KL and intermixing applications with Canvas graphs – it’s all KL in the end.
  • Less technical users can work in a purely visual environment while tech savvy users can fall back to write code in the IDE directly.
  • As with KL, Canvas resulting code is optimized in multiple stages, so that users can get very fast feedback when performing changes and receive higher performance after the code has executed several times.
  • Canvas takes care of data compatibility when connecting nodes, data types are typically shown as colored lines, thus less technical users can work in a trial-and-error kind of way and still come up with very well performing implementations.
  • Canvas nodes and graphs can be saved to a json text file and shared with other users, thus enabling maximum re-use of built functionality.

Canvas-only features

Since Canvas essentially is a code generation layer it is capable of providing some additional high level services. These include:

  • Variables are special nodes which essentially represent stateful containers which survive the execution of the graph. Variables are particularly interesting for simulations. Please see Variables for Programmers for more information.
  • Caching allows users to define points in the graph where execution will only happen once if none of the upstream nodes or values change. This means that expensive operations won’t happen more than once or based on changes. The code generation layer automatically puts in stateful containers for the users which take care of this logic. Please see Caching for Programmers.
    image 3
  • Polymorphic nodes contain subgraphs which don’t specify their data type requirements. The compiler can then decide if the generated code will build correctly for a given data type combination. The Add node, for example, contains the simple code section
    Add Node
    dfgEntry {
        result = lhs + rhs;
    }

    This will build for any data type which supports the + operator.
    image 4
    For more information please see Polymorphic nodes for programmers.


Canvas and the DFG

Canvas graphs are data flow graphs (short: DFG). Data flow graphs are completely stateless. The reasoning behind this is that the same data flow graph can operate on several pieces of data, which is especially interesting for parallel execution scenarios. Variables and Caches as mentioned above represent state, however their memory is not owned by the data flow graph itself, but by the so called Binding, which combines a data flow graph with the data to operate on. Please see the section below concerning the C/C++ API for more details.


Fabric Standalone

Fabric ships with a C++ and Qt based application, called Fabric Standalone. It’s essentially a test environment to build Canvas graphs, write KL code and test small KL- and Canvas-based applications. It also comes with access to a timeline and a 3D viewport. Fabric ships a collection of samples for Canvas to allow people to dive into the topics quickly. For more information on the UI, please see Canvas UI Guide.

image 5

All of the UI widgets used in the Fabric Standalone are available on github, please see https://github.com/fabric-engine/FabricUI. Any other application deploying Canvas is based on this repository. This ensures the same look and feel in any application and makes it much easier for users to switch environments.


Canvas for Python

Even though it’s not available yet it makes sense to mention that future versions of Fabric will come with a complete mapping of the UI to PySide, to allow you to build applications rapidly in Python. We believe that quickly iterating on application and user interface services in Python while solving performance critical elements with KL and Canvas is a strong combination.


Canvas in other applications

Canvas can be integrated into any C or C++ application. Given its initial focus is visual effects and film, Fabric Software has integrated Canvas into the major 3D digital content creation tools (short: DCC) such as Autodesk Maya. In each of these applications, Canvas graphs are hooked in and represented as a native feature. In Maya, a Canvas graph is represented by a single hypergraph node which encompasses the logic. To learn more about Canvas inside Maya, please see Fabric for Maya.

image 6

Integrating Fabric inside of DCCs means that functionality and tools become portable, and given that Canvas nodes and graphs can be saved to JSON files, users can build functionality in one DCC, and then move it to another one without any cost.


Fabric and C/C++

All of Fabric’s features are available as a C and C++ API. This includes access to the Core, KL data types and their methods as well as Canvas and the data flow graph (DFG). Topics include:

  • CAPI and the Fabric Client (see CAPI Programming Guide).
  • RTVals – Registered Type Values. A RTVal is essentially a C/C++ container for an instantiated KL data type. With a RTVal you can instantiate KL types and interact with them, get access to their members and invoke methods on them. This is very useful for re-using functionality implemented in KL. For more information on RTVals, please see RTVal Programming Guide.
  • DFG. Through the C/C++ API you can build data flow graphs and interact with them, fill in values, execute them and pull out results. This is essentially what the DCC integrations do. For more information on the DFG C/C++ API please see Canvas Core API. Additional we provide basic hello world type samples, which can be found here: Github DFG Trainingmaterial. Furthermore, we make all of the DCC integration code available – see Fabric For Maya Source Code for example.

Fabric EDK

EDK stands for the Extension Development Kit. Extensions are essentially plugins to the Fabric Core which extend the KL language with new data types and functions. KL extensions can be implemented purely in KL (see the KL Math Extension for example) or can be built as a mixture of KL definitions and C/C++ implementations. This is particularly useful when wrapping existing C or C++ libraries to KL. For more information on this, please see the Extension Authoring Guide.

To automate most of this process we provide a command line utility called KL2EDK. It can be used to generate headers and implementations of C/C++ stubs to map an existing API to KL.

Additionally to KL2EDK we also provide a command line utility called KL2DFG, which can generate the json files for Canvas based on a KL extension. This means that with KL2DFG you can quickly generate a library of nodes out of KL code. Thus, together with KL2EDK, it provides a quick path from an existing C/C++ directly API to a fully visual programming environment.