xmap

Pairs a program's source with the C text and the JVM bytecode it compiles to: which call wrote which lines. A function of strings and records, with no I/O.

use xmap/xmap

let built = xmap.explore(spec, raw)           # Result[Built, String], gaps inside
let strict = xmap.explore_strict(spec, raw)   # the first gap as the error
let text = xmap.to_xmap(b)                    # the `.xmap` rows the explorer page reads

spec names the program (Spec) and raw is what the compilers printed (Raw): the source, the C text and dawn __emitc --map's table, the JVM table of dawn __emit --map, the listing javap -c -p -s wrote, and for a Tile IR kernel its recording and golden text. The caller runs the compilers; nothing here starts a process or reads a file.

FunctionWhat it answers
explore(spec, raw)the program mapped, with every gap listed in gaps; an error only when a part of raw cannot be read at all
explore_strict(spec, raw)the same, or the first gap as the error
parse_raw(spec, raw), map_program(spec, inputs)the two halves of explore, for a caller that wants to change one part in between
to_xmap(built), pane_text(pane)the .xmap text and a pane's text
parse_spec(name, text), raw_files()the spec.txt convention the static page's raw directory uses

A gap is a place where the maps and the text do not line up: a call one map has and the other lacks, a pc range with no instruction, a column past the end of its line, a method javap does not list. A call with a gap is shown without its lines in that pane; the pane's text is always whole.

Changes between versions: CHANGELOG.md.

API

xmap/dawnmap

CFn

type CFn = { first: Int, last: Int, module: String, origin: String, symbol: String }

A fn row of a C map: the lines [first, last] of the whole C text the function was written to (from 1), and the module, origin and symbol.

CCall

type CCall = { first: Option[Int], line: Option[Int], clo: Option[Int], chi: Option[Int], module: String, lo: Option[Int], hi: Option[Int], nlo: Option[Int], what: String }

A call row of a C map: the C lines it spans (first to line, the last one carrying columns clo to chi, half-open), and where the call is in its module's source (code point offsets lo to hi, its name at nlo).

CMap

type CMap = { fns: List[CFn], calls: List[CCall] }

A C map's rows.

JFn

type JFn = { k: Int, len: Int, module: String, origin: String, symbol: String }

A fn row of a JVM map: its method's number k and the byte length len of its code, and the module, origin and symbol (owner.name:descriptor).

JCall

type JCall = { k: Option[Int], pclo: Option[Int], pchi: Option[Int], ipc: Option[Int], module: String, lo: Option[Int], hi: Option[Int], nlo: Option[Int], what: String }

A call row of a JVM map: the method k it is in, the pc range [pclo, pchi) of its bytecode, and the pc of the instruction that implements it (ipc).

JMap

type JMap = { fns: List[JFn], calls: List[JCall] }

A JVM map's rows.

dawnmap.parse_c

fn parse_c(text: String) -> Result[CMap, String]

A C map, or why text is not one.

dawnmap.parse_jvm

fn parse_jvm(text: String) -> Result[JMap, String]

A JVM map, or why text is not one.

xmap/javap

Method

type Method = { lines: List[String], pcs: List[Int], line_of: Map[Int, Int] }

One member's block of the listing: its lines, the instruction pcs in ascending order, and the index into lines of the line each pc is on.

Listing

type Listing = { methods: Map[(String, String), Method] }

A listing's members by (name, descriptor).

javap.parse_listing

fn parse_listing(text: String) -> Listing

The members of text, a javap -c -p -s listing.

javap.find_method

fn find_method(l: Listing, name: String, desc: String) -> Option[Method]

The member name with descriptor desc, if the listing has it.

xmap/panes

Out

type Out = { lines: List[(Int, Int)], marks: List[(Int, Int, Int)], key: List[Int] }

One call's account of one pane: the runs of lines it wrote itself (1-based, half-open), the columns it holds on a line ((line, from, to), 0-based, half-open; C only), and the lines of the instructions that implement it (bytecode only).

PaneBuild

type PaneBuild = { text: List[String], outs: List[Out], gaps: List[String] }

A pane's text with an account of every call of the table (in row order), and what could not be accounted.

panes.origin_of

fn origin_of(name: String) -> String

The name a function has in the maps' origin column.

panes.ranges

fn ranges(xs: List[Int]) -> List[(Int, Int)]

Sorted, distinct line numbers as half-open runs.

panes.c_pane

fn c_pane(prog: String, fn_name: String, ctext: List[String], cmap: CMap, module: String, table: List[Call], src: Src) -> PaneBuild

The C pane of fn_name (the functions of the whole module when it is "") of program prog: the text of each function copied from ctext (the whole C text, by lines), and every call's lines and columns in it.

panes.jvm_pane

fn jvm_pane(prog: String, fn_name: String, listing: Listing, jmap: JMap, module: String, table: List[Call], src: Src) -> PaneBuild

The JVM pane of fn_name (the whole module's methods when it is "") of program prog: each method's block of the javap listing, and every call's lines in it.

panes.chomp

fn chomp(s: String) -> String

s without the newlines it ends with.

panes.tile_pane

fn tile_pane(prog: String, golden: String, table: List[Call]) -> PaneBuild

The Tile IR pane of kernel prog: the golden's text, and the lines each call of the recording wrote.

xmap/source

Src

type Src = { text: String, lines: List[String], starts: List[Int] }

A source text, cut into its lines, with the offset each line starts at.

source.src_of

fn src_of(text: String) -> Src

text read as a source.

source.at

fn at(src: Src, off: Int) -> (Int, Int)

The (line, col), both from 1, of code point offset off.

source.off

fn off(src: Src, line: Int, col: Int) -> Int

The offset of line:col, the inverse of at.

source.pos

fn pos(p: (Int, Int)) -> String

line:col.

source.span_text

fn span_text(src: Src, lo: Int, hi: Int) -> String

line:col-line:col, the shape .xmap writes a span in.

source.ident_at

fn ident_at(src: Src, off: Int) -> Option[String]

The identifier that starts at off, or None when none does.

source.text_between

fn text_between(src: Src, lo: Int, hi: Int) -> String

The text from offset lo up to hi.

xmap/table

Call

type Call = { id: Int, parent: Int, name: String, lo: Int, hi: Int, nlo: Int, nhi: Int, lines: List[String] }

One call of the table. id is its row (source order, from 0) and parent the row of the call that holds it, -1 at the top. The span [lo, hi) and the name's [nlo, nhi) are code point offsets into the source. lines is what the Tile IR recording says the call wrote (a-b words), empty otherwise.

TileCall

type TileCall = { name: String, lo: (Int, Int), hi: (Int, Int), nlo: (Int, Int), nhi: (Int, Int), lines: List[String] }

A call row of flash_attn.map, before its positions are offsets.

TileMap

type TileMap = { first: Int, last: Int, calls: List[TileCall] }

flash_attn.map read: the lines first to last of the kernel's source its function is on, and its calls.

table.parse_tile_map

fn parse_tile_map(text: String) -> Result[TileMap, String]

flash_attn.map as a TileMap, or why text is not one. The calls carry, get and set are what a var is to the Tile IR (its loop arguments, its reads, its assignments): a host map has no call for any of them, they wrote no Tile IR line of their own, and a click on one would light nothing, so they are left out.

table.tree

fn tree(rows: List[Call]) -> List[Call]

rows in source order, numbered from 0, each with its innermost enclosing call by span as its parent.

table.table_from_tile

fn table_from_tile(src: Src, t: TileMap) -> List[Call]

The calls of the Tile IR recording as the table, in the source's own coordinates.

table.table_from_maps

fn table_from_maps(src: Src, module: String, first: Int, last: Int, c: CMap, j: JMap) -> (List[Call], List[String])

The calls of module on lines first to last that both host maps have a row for, in source order with the tree read off their spans, and a message for each call only one of the maps has.

table.spelled

fn spelled(name: String, text: String) -> Bool

Whether the source text at a call's name span is how that call is spelled: the callee's own name, an operator for the arithmetic calls (a + b is add, addi, idx_add...), or, for the three calls a var makes (carry where a loop opens it, get where it is read, set where it is assigned), the variable's name or the loop's for. A lit is also spelled by the bare number it was made from (mma(a, b, 0.0)), which has no call of its own.

table.check_table

fn check_table(src: Src, table: List[Call], first: Int, last: Int) -> List[String]

What is wrong with table as a table of the function on lines first to last of src, one message for each fault, in call order.

table.children_of

fn children_of(table: List[Call]) -> List[List[Int]]

The row numbers of the calls each call holds directly, by row.

xmap/xmap

Spec

type Spec = { name: String, path: String, fn_name: String, module: String, kernel: Bool }

Which program to map and how: its name, the path its source is shown by, the function the page shows ("": the whole file), the module the compilers named it (the file's stem for a single file; main for a project) and whether it is a Tile IR kernel (its table and its Tile IR pane then come from the recording).

Raw

type Raw = { source: String, ctext: String, cmap: String, jmap: String, javap: String, tile_map: String, golden: String }

What the compilers printed, as text: the source, the C text and its map, the JVM map and javap -c -p -s of the class, and, for a kernel, the Tile IR recording and the golden Tile IR text ("" otherwise).

Inputs

type Inputs = { src: Src, ctext: List[String], c_total: Int, cmap: CMap, jmap: JMap, listing: Listing, j_total: Int, tile: Option[TileMap], tile_text: String }

The raw material parsed. A caller that wants to change one part (a test that injects a defect) changes it here and calls map_program.

Pane

type Pane = { kind: String, file: String, total: Int, text: List[String], outs: List[Out] }

One pane: its kind (tile, c or jvm), the file name its text is kept under, how many lines the program's whole output had (what the pane shows is the function's share of it), its text and its account of every call.

Built

type Built = { name: String, path: String, src: Src, first: Int, last: Int, calls: List[Call], panes: List[Pane], gaps: List[String], skipped: Int }

A program mapped: its source and the lines of it the table covers, the calls, the panes in the order of the tabs, the gaps found and how many calls the host maps have in the function that the table does not (the calls a Tile IR kernel's host run made that its recording does not list).

Files

type Files = { source: String, tile_map: String, golden: String }

The paths of the files a program's raw material comes from beyond the compilers' own output: its source, and for a kernel the Tile IR recording and the golden Tile IR text ("" for a program that has none).

xmap.raw_files

fn raw_files() -> List[String]

The names the raw files of one program have in its directory, which the caller reads: the C text, the C map, the JVM map and the javap listing.

xmap.parse_spec

fn parse_spec(name: String, text: String) -> Result[(Spec, Files), String]

A program's spec.txt, which says what its raw material is. One key value row to a line: source <path> and module <name> always, fn <name> when the page shows one function (the whole file otherwise), and tile-map <path> with tile-golden <path> for a Tile IR kernel. name is the program's, which is its directory's.

xmap.parse_raw

fn parse_raw(spec: Spec, raw: Raw) -> Result[Inputs, String]

raw parsed, or why one of its parts is not what it claims to be.

xmap.map_program

fn map_program(spec: Spec, inp: Inputs) -> Built

The program spec names, mapped from parsed inputs.

xmap.explore

fn explore(spec: Spec, raw: Raw) -> Result[Built, String]

The program spec names, mapped from what the compilers printed, with its gaps listed. An error only when a part of raw cannot be read at all.

xmap.explore_strict

fn explore_strict(spec: Spec, raw: Raw) -> Result[Built, String]

explore, or the first gap as the error.

xmap.strict

fn strict(b: Built) -> Result[Built, String]

b, or its first gap as the error.

xmap.to_xmap

fn to_xmap(b: Built) -> String

b in the .xmap format, one row to a line.

xmap.pane_text

fn pane_text(p: Pane) -> String

A pane's text as the file .xmap names it holds it.