Skip to main content

Module spatial_emit

Module spatial_emit 

Source
Expand description

Spatial source emission for a counted loop — the bridge from the certified fabric IR to the open Plasticine toolchain (Spatial → PIR → plastiroute → Tungsten; Koeplinger et al., PLDI 2018; the chain is mirrored at gitlab.com/dataplane-ai). P4 of the Plasticine lane.

A LoopFabric is one Foreach controller: its carried state registers become Regs, the induction variable the counter, the body cells vals in SSA order, a predicated select a mux, and the next-state sources the register writes at the end of the iteration (computed first, assigned after — the parallel register-update semantics the fabric has). Every LOGOS Int is a 64-bit Long. What this emitter does not spell (sequence tiles, heap islands, the wider FuncUnit family) is refused TYPED so a program never reaches the toolchain with silently different meaning.

Structs§

GdaColumn
One array a scatter row term reads, as the GDA app declares it: its name, its axis and its host data.
GdaPar
The knobs of Spatial’s GDA regression app (pir/regression/GDA.scala): the rows a tile of the data loads (ts), how many such tiles run at once (op), the rows of a tile reduced at once (mp1), the covariance rows one rank-1 update writes at once (mp2), and the lanes of the loads, the store and the column loops (ip).
GemmUnroll
Emit a Spatial REGRESSION-HARNESS GEMM app for C[m×n] = A[m×k] · B[k×n] — the structure of Spatial’s own regression/GEMM.scala (an output tile its × ts accumulated over k in ts-chunks by a MemReduce, an ip-lane Reduce per dot product) with OUR shape and tiles, so a LOGOS matmul runs through the public chain as the toolchain’s authors would write it. Host data are small residues so the 32-bit sums stay exact and the harness’s PASS line means equality. Typed refusal when the tiles do not divide the shape (the template streams whole tiles). How wide each loop of the GEMM nest runs. Spatial’s own regression variants set exactly these, and a factor left at 1 is a loop we run serially where the hand-written app runs it wide.
KmeansPar
The knobs of Spatial’s Kmeans regression app (pir/regression/Kmeans.scala): the points a tile loads (ts), the lanes of the loads, the store and the feature loops (ip), how many tiles run at once (op), and how many points, centroids and centroid updates run at once (mp1, mp2, mp3).
MapColumn
One column of a zip map as the app declares it: its name, its element type and the host data the program fills it with.
MapPar
The knobs of Spatial’s BlackScholes regression app (pir/regression/BlackScholes.scala): the tile ts of every column each outer iteration streams through FIFOs, how many tiles run at once (op), and the lanes of the loads, the map and the store (ip).
OuterPar
The knobs of Spatial’s OuterProduct regression app (pir/regression/OuterProduct.scala): the tiles of the two vectors (ts1, ts2), the lanes of the loads and the store (ip), the lanes of the tile’s column and row loops (ip1, ip2), and how many tiles of each vector run at once (op1, op2).
ZipColumn
One column of a zip sum as the app declares it: its name (a Scala identifier the app does not otherwise use) and the host data the program fills it with.
ZipPar
The knobs of Spatial’s reduce-over-tiles regression apps (pir/regression/DotProduct.scala, TPCHQ6.scala): the tile ts each outer iteration loads of every column, how many tiles run at once (op), and the lanes of the loads and of the inner reduce (ip).

Functions§

emit_spatial_counted_loop
Emit Spatial source for the counted loop lf of LOGOS function fn_name as a standalone SpatialApp (arguments from the command line, the result printed), or a typed reason it cannot.
emit_spatial_counted_loop_test
Emit a Spatial REGRESSION-HARNESS app (class <class_name> extends SpatialTest) for the counted loop: the sample params are its runtimeArgs, the VM’s answer gold is checked on the host, and the harness’s PASS: true (<class_name>) line is what the toolchain ledger parses. Values are 64-bit Long: PIR’s Tungsten codegen lowers Fix(true,64,0) to C long, so the simulation computes what the VM computes (the ISCA’17 FU is 32-bit; a silicon run would need the narrower type).
emit_spatial_gda_test
Emit a Spatial REGRESSION-HARNESS scatter accumulation S = Σ_{r<R} d_r d_rᵀ (C × C) with the structure of Spatial’s own GDA app — the column-axis arrays loaded once, a MemReduce over ts-row tiles of the row-axis arrays and of the row-major data, inside it a MemReduce over the tile’s rows that computes each row’s d into subTile and its outer product into sigmaTile — at our shape, over the program’s own data. The app computes in Spatial’s 32-bit Int; a sum that would wrap there (where the VM’s 64-bit Int does not) is refused, as is a tile that does not divide the rows.
emit_spatial_gemm_test
emit_spatial_gemm_test_with
The same emission with the loop widths given explicitly — the form the parity corpus uses to reproduce a Spatial variant’s exact configuration.
emit_spatial_kmeans_test
Emit a Spatial REGRESSION-HARNESS k-means clustering with the structure of Spatial’s own Kmeans app — the centroids loaded from the first K points, iters epochs each a MemReduce over ts-point tiles of a MemReduce over the tile’s points (each point’s distance to every centroid a Reduce over the features, the nearest found by a min and an index reduce, the point added to its centroid’s row as a one-hot tile), then every centroid set to its row over its count — at our shape and the app’s runtime arguments, over the program’s own data, written at the app’s X = Int (the app’s kmeans[T:Num] instantiated). The app keeps each centroid’s count as a last feature of every point fixed at 1 (D = f + 1 columns), where the program keeps counts; equally near centroids go to the last (the app’s max of the matching indices) or, for a program keeping the first, to the first (a min). The gold is the clustering the program computes, evaluated on the host the way the accelerator computes it, the nearest centroid chosen by distance and then by index whichever way the host folds. The app computes in Spatial’s 32-bit Int; a distance or a sum that would wrap there is refused, as is a tile that does not divide the points.
emit_spatial_outer_test
Emit a Spatial REGRESSION-HARNESS outer product out[i][j] = a[i]·b[j] (m × n) with the structure of Spatial’s own OuterProduct app — a ts1-tile of a per outer iteration, a ts2-tile of b per inner one, the ts1 × ts2 product tile computed in SRAM and stored whole — at our shape. Host data are small residues; the harness’s PASS line means equality. Typed refusal when a tile does not divide its vector or a tile loop is wider than its tile.
emit_spatial_zip_map_test
Emit a Spatial REGRESSION-HARNESS zip map out[t] = f(c₀[t], c₁[t], …) with the structure of Spatial’s own BlackScholes app: per ts-element tile, a FIFO of every column loaded in the order the program declares its columns (declared, a permutation of the columns, which are in the order the term reads them), an ip-lane Foreach dequeuing one element of every column and enqueuing the term’s value, the output tile stored, op tiles at once — at our length, over the program’s own data, with the variant’s PIR arguments (pir_args, the suffix its pirArgs override appends). The term is printed as its DAG: a function the program calls twice is two copies, as Spatial stages it, and a subterm used twice is computed once. The app computes in Spatial’s 32-bit Int and Float; a term whose Int would wrap there or whose Real would leave the Float’s range is refused, as is a division by zero on any path (the host’s gold would trap), a tile that does not divide the length, or a map wider than its tile. The gold is the host’s own evaluation of the term: a Float result passes within 0.1% (and 0.001) of it, an Int one exactly.
emit_spatial_zip_sum_test
Emit a Spatial REGRESSION-HARNESS zip sum Σ_{t<n} f(c₀[t], c₁[t], …) with the structure of Spatial’s own reduce-over-tiles apps (DotProduct, TPCHQ6): a ts-element tile of every column loaded in parallel, op tiles reduced at once, each tile’s sum an ip-lane Reduce of the term (the body of spatial.lib.ML.sum_flat) — at our length, over the program’s own column data, so the app’s gold is the LOGOS program’s answer. The app computes in Spatial’s 32-bit Int, as the regression apps do; a sum that would wrap there (where the VM’s 64-bit Int does not) is refused, as is a tile that does not divide the length or a reduce wider than its tile.