Skip to content

Lua API

Soulaymen Chouri edited this page Jan 28, 2018 · 1 revision

CGraph Lua API

There two main components:

  • Graph
  • Nodes

Tensors are nodes, operations are nodes. A Graph can contain a single Tensor or an operation.

1. Setup

When using the Lua API, the library should be compiled as a shared object. Must be placed somewhere Lua can find it. Do not import the library yourself unless you know what you are doing. Use the CGraph.lua helper which provides advanced features for ease of graph construction via metatables.

2. Importing the library

local CGraph = require 'CGraph'

3. Graphs

CGraph.graph(name, rootNode)
  • name is the desired graph name (used as a filename as well when exporting the Graph to DOT)
  • rootNode is the root node, the first node to be evaluated.
  • Output: Graph

The result is a Graph object, that overrides the __index metatable.

It contains the following attributes:

  • name Graph's name
  • root The root node
  • cdata Pointer to C API Graph structure
  • vars List of defined variables.

And the following methods

  • setVar(name, value) Define the variable name with the value value. Value must be a Node.
  • getNativeVar(name) Returns the C API Node value of the variable name. Better not to use it.
  • getVar(name) Returns the value of the variable name, or nil if it does not exist.
  • eval() Evaluates the graph and returns a result object. The result object can either contain a Tensor result or an error result (see below)
  • plot() Generates a DOT graph description that can be plotted with graphviz.
  • diff(var, newName) Calculates and returns the derivative of the graph with respect to given variable name. The new graph's name is newName.
  • free() Deallocates all resources allocated by the graph, including nodes! So you should not use same node references between multiple graphs.

When evaluating the graph, you use a non-implemented operator, or run into dimensional issues. In that case, the output of the graph will be an error object that contains:

  • error An error enum value
  • message Description of the issue
  • node The node responsible of the issue.

If you plot the graph after running the issue, you can see in the graph's visualization which node is responsible for the error.

Additionally, when plotting the graph, if a variable is bound to a Node (you have called graph:setVar) its value will be plotted as well (similar to the picture above).

Example:

https://i.imgur.com/hpqPPmD.png

4. Creating Tensors and Variables

There are 3 types of tensors

  • Double
  • Vector
  • Matrix

In CGraph, matrixes are row major.

The create a Tensor use the following functions:

  • CGraph.double(value) Creates a scalar tensor with value = value.
  • CGraph.vector(len, value) Creates a Vector with len = len and value which is an array of doubles = value.
  • CGraph.matrix(rows, cols, value) Creates a matrix with rows = rows and cols = cols. Value is also an array of doubles and #value == rows*cols must be true.

To create a variable:

  • CGraph.variable(name)

You can then set its value through its parent graph like graph:setVar('x', CGraph.double(3.14))

5. Creating Operations

CGraph automatically overrides the following metamethods:

  • __unm: -a
  • __add: a + b
  • __sub: a - b
  • __mul: a * b
  • __div: a / b
  • __pow: a ^ b
  • __tostring: print(a)

Additionally, you can use the following functions:

  • CGraph.pow
  • CGraph.dot
  • CGraph.inv
  • CGraph.tr
  • CGraph.log
  • CGraph.exp
  • CGraph.sin
  • CGraph.cos
  • CGraph.tan
  • CGraph.tanh