Module Tolk.Render
Nodes as text: expressions and program listings.
render writes the value a node computes as a one-line expression, which diagnostics and kernel names print for indices and sizes. render_uir writes a graph one node a line, as diagnostics print it. Ops.pp prints a node as the calls that build it.
render ~simplify u is u written as an expression, after Shape.simplify if simplify (default true). Each node is written from its sources:
- a
Op.t.Param,Op.t.BufferorOp.t.Allocis its name, orp,borafollowed by its slot if it has none; - an
Op.t.Afteris its first source, and anOp.t.Specialits name; - a
Op.t.Rangeisrfollowed byOps.range_str, and an unbounded loop, of typeDtype.t.Void, isloopfollowed by the first part of its identity; - a constant, or a cast of one, is its value as
Dtype.pp_constwrites it:3,1.5,True,Invalid; - any other cast is the type's name in parentheses before its operand:
(float)(x); Op.t.Neg,Op.t.Recip,Op.t.Max,Op.t.Mulacc,Op.t.Where,Op.t.TruncdivandOp.t.Truncmodare(-x),(1/x),max(x, y),(x*y+z),(x if c else y),truncdiv(x, y)andtruncmod(x, y);- a movement is its source followed by
.reshape,.expand,.pad,.shrinkor.permuteand its argument as a tuple:(4,8),((0, 2),(1, 3)),(1, 0); Op.t.Add,Op.t.Sub,Op.t.Mul,Op.t.Div,Op.t.Mod,Op.t.Shl,Op.t.Shr,Op.t.And,Op.t.Or,Op.t.Xor,Op.t.Cmplt,Op.t.CmpneandOp.t.Cmpeqare+,-,*,//,%,<<,>>,&,|,^,<,!=and==between their operands, in parentheses. An operand loses its own parentheses where precedence makes them redundant: from the tightest,* // %, then+ -,<< >>,&,^and|. Operations of equal precedence associate to the left, so(a+b)+cis(a+b+c)anda-(b+c)keeps its parentheses. A comparison keeps its operands' parentheses, and its own within any operation;- an
Op.t.Indexor anOp.t.Stageis each source after the first between brackets, without their outer parentheses:[i][j]; - a load through an index is the indexed storage followed by the index:
buf[i], and(buf[i] if g else alt)when guarded byg; - a stack is its sources between braces, separated by commas:
{a,b}; - any other node is written as
Ops.ppprints it.
Raises Invalid_argument if simplify and the symbolic rules are not installed, as Shape.simplify; so does writing a movement whose argument sizes are nodes, or an integer that Bigint.to_string refuses.
srender s is an integer s in decimal, and a node s as render writes it.
render_uir uops writes the nodes uops, in order, one line each, as %i = op srcs : arg: its position among the lines, from 0; its operation in lower case, in its colour (Helpers.colored); its sources, separated by commas; and its argument after " : ", if it writes one. A constant has no line and is written in its users, as is a stack of constants, as a tuple of them; any other source is written %i. Lines are separated by newlines; the last is not ended.
The argument is written as:
- for a constant,
invalid,trueorfalse, or its value asDtype.pp_constwrites it, a constant being of a weak type or boolean (Ops.const); - for storage and variables, its name in double quotes if it has one, then
dtype=andslot=, and thenbounds=[lo,hi],addrspace=(but global memory),device=(bare if a word of letters, digits,_and:, else asOps.pp_devicewrites it) andvolatile=true, where they apply; - for a range, its axis type and the parts of its identity, separated by spaces:
LOOP 1 2; - for a kernel's sink, its name, and nothing for any other sink;
- for a call,
name='f'andprecompile=true, where they apply; - for a reduction,
op=addand, unless0,pop=n; - for a cast, the type's
Dtype.name; for a copy to one device, its name; for a hardware index, its name; - for any other argument, the literal
Ops.pp_argwrites.
Raises Not_found if a source that has a line is not among uops.