Language basics
Paint is a description language for the instantiation, layout, and
interconnection of kernels on the Cerebras wafer-scale fabric. A .paint
file declares tiles, attaches compiled kernels, configures physical routing
colors, and composes regions into a complete floorplan that the build
system transforms into a machine image.
1. Lexical Elements
New to Paint's syntax? Reading Paint in the
introduction explains calls without commas, 'name strings and : updates
with a worked example.
Tokens
- Numbers: Decimal integer literals (
42), decimal floats (1.5) and hexadecimal integers (0x2A). Integers are 32-bit signed and floats 32-bit. There are no negative literals; write0-1for −1 (see Syntax rules that differ from C and Python). - Identifiers: Start with a letter or
_, may contain digits and trailing apostrophes:myVar,x',tile_0. Unicode Greek letters and combining marks are also accepted. - Strings: Double-quoted (
"hello world"), a quoted name ('name), or parenthesised ('(hello world)). A quoted name takes letters, digits and_ - . : @ * ', and stops at any other character:'a-1is the stringa-1. Names, tags and kernel names are usually written as quoted names. - Route rules:
[SRC>DST]— direction brackets (see §11).
Whitespace
Spaces, tabs, carriage returns, and newlines are whitespace. Tokens are separated by whitespace; there are no statement terminators.
2. Comments
(* This is a comment.
It can span multiple lines. *)
Comments open with (* and close with *). They do not nest.
3. Types
Paint is dynamically typed. The runtime types are:
| Type | Literal examples | Description |
|---|---|---|
| Integer | 42, 0xFF | 32-bit signed integer; wraps without a message |
| Float | 3.14 | 32-bit floating-point |
| String | "hello", 'name | Character string |
| Symbol | $filter0_cfg | Reference to a kernel symbol table entry; not a string |
| Region | tile(), rect(0 0 4 2) | A tree of PE tiles |
| Color | color() | A routing color handle |
| Route table | [L>R] | A routing configuration |
| Array | [1 2 3] | Ordered sequence of values |
| Dictionary | [a:1 b:2] | Key-value mapping, stored as an array of alternating keys and values: arraylen([a:1 b:2]) is 4 |
| Function | define f(x) { ... } | User-defined function |
| Void | — | No value |
| Orientation | orient('R) | Router direction: 'R, 'U, 'L, 'D or 'C |
4. Variables and Assignment
Local variables
let a = 4 + 1
a = a + 1
Use let to declare any variable, including inside a function. Bare assignment
updates an existing binding; it cannot declare one.
Let binding (region declaration)
let x = tile()
let introduces a new binding in the current scope.
Curried assignment (: operator)
a : b(c) (* equivalent to: a = b(a c) *)
The : operator is syntactic sugar that inserts the left-hand side as the
first argument. This is the idiomatic way to apply attributes to regions:
let t = tile()
t : code('add [N:4])
t : paint(mycolor [C>R])
t : name('t)
5. Expressions and Operators
Infix operators (by precedence, low to high)
| Operator | Description |
|---|---|
== | Equality comparison (returns 0 or 1) |
+, - | Addition, subtraction |
*, /, //, % | Multiply, divide, integer divide, modulo |
Function calls
f(a b c) (* call f with three arguments *)
f(a b(c)) (* call f with two arguments: a and b(c) *)
Important: the opening parenthesis must be adjacent to the function name (no whitespace); otherwise it is a grouping parenthesis.
Grouping
(a + b) * c
Syntax rules that differ from C and Python
| You write | You get |
|---|---|
let a = -1 | A parse error: there is no unary minus. Write 0-1. |
[0 -2 4], f(x -1) | a -1 inside a list is a - 1: the array [-2 4], and a call with one argument. Write [0 (0-2) 4]. |
max (3) | Two expressions, max and (3): let n = max (3) makes n the function max. With more values inside, such as rect (0 0 2 2), Paint stops with list is not a member of ex and no line number. |
(0-7)//2, (0-7)%2 | −3 and −1: // truncates toward zero and % takes the sign of the left operand, as in C. |
2147483647 + 1 | −2147483648: integers wrap at 32 bits without a message. |
hstackrep(r 1.5*2) | An error: a count argument takes an integer, and int(x) converts a float. |
6. Function Definitions
define name(arg1 arg2 ...) {
(* body *)
}
Functions are first-class values. The body is a sequence of expressions; the last expression's value is returned. Functions capture their enclosing scope (closures).
define make_tile(kernel color N) {
let t = tile()
t : code(kernel [N:N tx:color])
t : paint(color [C>R])
t
}
7. Includes
include "filename.paint"
Includes the contents of another paint file. Paint searches the library
paths specified via the lib= command-line option.