Skip to main content

Regions, code and colors

8. Regions​

A region is a hierarchical tree whose leaves are individual PE tiles. Interior nodes represent replication, union, or attribute application.

Creating regions​

PrimitiveDescription
tile()Single PE at origin (0, 0)
tile(x y)Single PE at position (x, y)
rect(x y w h)w × h rectangle at (x, y)
rect(x y w h 'xdim 'ydim)Rectangle with named dimensions
let single = tile()
let block = rect(0 0 8 4)
let named = rect(0 0 8 4 'col 'row)

Paint numbers rows as the fabric does, from the north edge: a PE's row ID is its Paint y, and row 0 is the northernmost row. Paint calls the +Y direction up, so U is the router's south port and D its north port. R is east (+X) and L is west.


9. Code Attachment​

region : code('kernel_name)
region : code('kernel_name [param:value ...])

Attaches a compiled kernel to all PEs in the region. Paint looks for kernel_name.<suffix> on the library search path, one suffix at a time: .w (Tungsten), then .yeti (Yeti, the assembly language the Tungsten compiler emits; the compiler assembles it). The suffixes named by compiler= are tried first, in that order. .casm, .csl, and .mk are not compilation backends.

  • The parameter dictionary may be omitted when the kernel needs no bindings; code('kernel_name) and code('kernel_name []) are equivalent.
  • Parameters are passed as key-value pairs in [...]. For a .w kernel each key names one of its parameters or sockets, and Paint compiles the placement with one set=key=value per pair.
  • Every placement of the same source must pass the same parameters in the same order.
  • Colors are passed by name: tx:mycolor.
  • Numeric values are passed directly: N:4.
  • Geo-variables use @ prefix: idx:@rank.
  • Symbol variables ($ prefix) are not parameter values: Paint passes $name through as text, and the compiler rejects it. They are used with link().
t : code('no_params)
t : code('send [tx:txcolor N:N])
t : code('compute [rx:rxcolor tx:txcolor N:N W:W])
t : code('kernel [idx:@rank])

Paint does not support overlapping code regions on the same PE. It rejects a union of two regions with different code on one PE (intersect at (x, y) between two regions with distinct code attached). Call code() once per region: Paint does not reject a second code() on the same region, and places both kernels at the same addresses.

Code union​

region : codeunion('kernel [param:value ...])

codeunion attaches a kernel to PEs that a code() region already covers, for kernel overlays; no tutorial uses it. The kernel receives the parameters of the overlapping code() as well as its own: a codeunion('pk [jd:7]) tile over a code('kernel [id:5]) tile compiles pk with id=5 jd=7. Paint links both kernels at the same addresses.


10. Colors​

let c = color() (* allocate a symbolic color *)
let c5 = color(5) (* pin to physical color 5; Paint warns *)

A color is one of the router's 24 virtual channels. Each color has its own buffer, so a blocked color does not block the others, but all colors share the bandwidth of each link. The paint engine's built-in solver assigns physical color IDs to symbolic colors, avoiding conflicts.

color(N) pins a color to physical number N, and Paint warns deprecated use of hard-coded color assignment; let the solver choose instead. A pinned color must suit its use: only 16 colors can switch (Switch Positions), only color 10 can be the fabric adder, and message-passing banks take 14–18 and 19–23.

Color pairs​

region : colorpair(c1 c2)

Makes the color solver number c1 and c2 as partners: c1 == c2 ^ 1. A swap modifier reads a color's partner, so pair every color whose rules swap. Without the pair, a swap reads whichever color the solver numbered c ^ 1.

Multiple colors​

Up to 24 physical colors are available on each PE. Colors can be shared across non-overlapping regions.

Paint does not yet report a color budget it cannot meet. When a PE needs more than 24 colors, more than 16 switching colors, or a pinned color that cannot do the job (such as color(10) with switch positions), Paint aborts with double free or corruption and names nothing.

Binding a list allocates one color per name:

let [a b c d] = color() (* four distinct colors *)