Skip to main content

Runefile

The primary way to create a Rune is by using a text file in the YAML format, referred to as a Runefile, to declare how a machine learning pipeline is configured.

A typical Runefile.
image: runicos/base

pipeline:
rand:
capability: RAND
outputs:
- type: F32
dimensions: [1]

mod360:
proc-block: "hotg-ai/rune#proc_blocks/modulo"
inputs:
- rand
outputs:
- type: F32
dimensions: [1]
args:
modulus: 360.0

sine:
model: "./sinemodel.tflite"
inputs:
- mod360
outputs:
- type: F32
dimensions: [1]

serial:
out: serial
inputs:
- rand

identity:
proc-block: "./identity"
inputs:
- mod360
- sine
outputs:
- type: F32
dimensions: [1]
- type: F32
dimensions: [1]

debug_output:
out: serial
inputs:
- rand
- identity.0 # mod360
- identity.1 # The sine output

The sections on this reference page are organized to reflect the structure of the Runefile itself.

Image​

The first item in a Runefile is the image. This specifies the functionality that will be provided to the Rune by the runtime.

The only image supported at the moment is runicos/base.

image: runicos/base

Pipeline​

The main concept in a Runefile is that of the "pipeline". This is a directed acyclic graph specifying how data is transformed as it passes through the Rune.

The pipeline is a dictionary of key-value pairs where the key attaches a name to a particular stage.

Common Properties​

There are several types of stages, but most will share some common properties.

Arguments​

A stage may specify args that can be used to modify how data is generated or transformed. This is a free-form dictionary of key-value pairs where the value can be a primitive type (e.g. numbers and strings) or a list of primitive types.

Examples of this may be providing the sample rate to an audio capability or the list of labels to use when classifying.

pipeline:
audio:
capability: SOUND
args:
hz: 16000

label:
proc-block: "hotg-ai/rune#proc_blocks/label"
args:
labels:
- silence
- unknown
- up
- down
- left
- right

For more advanced use cases like using a well-known enum or calculated expressions, a "verbatim" argument value may be used. This is a string containing valid Rust syntax, prefixed with an @ symbol (e.g. @PixelFormat::Grayscale or @244*244*3).

Inputs​

The inputs property contains a list of strings specifying which stages a particular stage may receive input from. This is typically just the stage's name, but in cases when a stage may have multiple outputs the desired output may be specified using dot syntax.

Here is an example where the debug stage accepts data from rand and the outputs 0 and 1 from the identity stage:

pipeline:
debug:
out: serial
inputs:
- rand
- identity.0
- identity.1

Outputs​

Each stage which outputs data must specify the type of that data using the outputs property. This specifies the data type and shape of a tensor.

A stage may have multiple outputs. For example, if using a proc block to classify the two most confident inputs and return both the labels and confidence values.

pipeline:
label:
proc-block: "hotg-ai/rune#proc_blocks/label"
outputs:
- type: F32
dimensions: [2]
- type: UTF8
dimensions: [2]

Supported types are:

NameKindDescription
u8IntegerAn 8-bit unsigned integer
i8IntegerAn 8-bit signed integer
u16IntegerA 16-bit unsigned integer
i16IntegerA 16-bit signed integer
u32IntegerA 32-bit unsigned integer
i32IntegerA 32-bit signed integer
u64IntegerA 64-bit unsigned integer
i64IntegerA 64-bit signed integer
f32FloatA 32-bit floating point number
f64FloatA 64-bit floating point number
utf8StringAn arbitrary-length string constant

The dimensions property specifies the shape of a tensor (multi-dimensional array) in row-major order.

Capabilities​

A capability stage is how information from the outside world enters the Rune. This may take the form of an image from the device's camera or samples from an audio file.

pipeline:
rand:
capability: RAND
outputs:
- type: F32
dimensions: [1]

Capabilities have the following properties:

Capabilities are specified using a capability key which dictates what type of capability it is.

Supported capability types are:

NameDescriptionSupported Arguments
ACCELSamples from an accelerometer as 3 `f32`s, X, Y, and Z.
RANDrandom data generated from the runtime's random number generator
RAWraw data from an opaque user-specified source
SOUND16-bit Pulse Code Modulated audio samples
  • hz - the sample rate in Hertz
IMAGEAn image
  • width - the image's width in pixels
  • height - the image's height in pixels
  • pixel-format - the format used by the pixels. Possible values are:
    • @PixelFormat::Grayscale
    • @PixelFormat::RGB
    • @PixelFormat::BGR

Models​

A model stage is specified by giving it a model: ./path/to/model.tflite property which points to the location of a TensorFlow Lite model on disk, relative to the Runefile.

pipeline:
sine:
model: "./sinemodel.tflite"
inputs:
- random
outputs:
- type: F32
dimensions: [1]

Models have the following properties:

Procedural Blocks​

A procedural block (aka "proc block") is a Rust crate which exposes functionality for transforming data from one form to another. Proc block stages are differentiated using a proc-block: hotg-ai/rune#proc_blocks/label property.

The proc block identifier takes on the form, path@version#sub_path, where path is the only required piece.

The path piece may be interpreted slightly differently depending on its form:

  • A single identifier (e.g. rune-label-proc-block) is interpreted as a crate on crates.io
  • A path beginning with ./ points to a crate on disk relative to the Runefile
  • A full URL is interpreted as the path to a git repository on the internet and will be used as a git dependency
  • A path of the form hotg-ai/rune is shorthand for a GitHub repository

More formally, a proc block path matches the following regex:

(?x)
(?P<base>[\w\d:/_.-]+)
(?:@(?P<version>[\w\d./-]+))?
(?:\#(?P<sub_path>[\w\d._/-]+))?

Common properties supported by proc blocks are:

Some well-known proc blocks are:

NameDescriptionInputs/OutputsArguments
ModuloCalculates the modulus of each element in a tensor(any)
  • modulus - the modulus to use

Outputs​

An output is the mechanism used to pass information processed by the Rune to the outside world (e.g. the host application). Outputs are differentiated using a output: serial property, where the value specifies the type of output.

pipeline:
serial:
out: serial
inputs:
- rand

Common properties supported by outputs are:

Some well-known outputs are:

NameDescriptionInputsArguments
SERIALA user-defined component which accepts JSON-formatted UTF-8 strings(any)