Skip to main content

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; write 0-1 for −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-1 is the string a-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:

TypeLiteral examplesDescription
Integer42, 0xFF32-bit signed integer; wraps without a message
Float3.1432-bit floating-point
String"hello", 'nameCharacter string
Symbol$filter0_cfgReference to a kernel symbol table entry; not a string
Regiontile(), rect(0 0 4 2)A tree of PE tiles
Colorcolor()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
Functiondefine f(x) { ... }User-defined function
Void—No value
Orientationorient('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)​

OperatorDescription
==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 writeYou get
let a = -1A 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.