/ concept-collection / turing-surface
Sign in
concept-collection / turing-surface
282 lines · 8.6 KBCodeBlameHistory
2 * The numbl compiler surface this project depends on.
3 *
4 * We reach past numbl's published entry points into its JIT internals (parser,
5 * lowerer, IR, inline pass), which its package `exports` map does not expose.
6 * Those imports resolve through the `numbl-src` alias in vite.config.ts; these
7 * declarations are what TypeScript checks against.
8 *
9 * Declaring the surface here rather than type-checking numbl's sources
10 * directly keeps this project's compiler settings independent of numbl's, and
11 * pins the exact contract we rely on. If numbl changes one of these shapes,
12 * the build breaks here with a clear diff rather than deep inside its tree.
13 *
14 * Only the nodes the WGSL backend actually walks are spelled out; every other
15 * IR kind is collapsed into a catch-all so that unhandled constructs are
16 * rejected with a message instead of being silently mis-compiled.
17 */
19declare module 'numbl-src/numbl-core/jit/lowering/types.ts' {
20 export type Sign =
21 | 'positive' | 'nonneg' | 'negative' | 'nonpositive'
22 | 'zero' | 'nonzero' | 'unknown';
24 export type DimInfo = { kind: 'exact'; value: number } | { kind: 'unknown' };
26 export type NumericExact =
27 | number
28 | Float64Array
29 | { re: number; im: number }
30 | { re: Float64Array; im: Float64Array };
32 export interface NumericType {
33 kind: 'Numeric';
34 elem: 'double' | 'logical' | 'char' | string;
35 isComplex: boolean;
36 dims: DimInfo[];
37 /** Present iff every dim is exact. */
38 shape?: number[];
39 sign: Sign;
40 exact?: NumericExact;
41 }
43 /** Everything the WGSL backend rejects. */
44 export interface NonNumericType {
45 kind: 'Void' | 'Unknown' | 'String' | 'Handle' | 'Struct' | 'Class' | 'Cell';
46 }
48 export type Type = NumericType | NonNumericType;
50 export function isMultiElement(t: NumericType): boolean;
51 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
52 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
55declare module 'numbl-src/numbl-core/jit/lowering/ir.ts' {
56 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
58 export interface Span {
59 file: string;
60 start: number;
61 end: number;
62 }
64 export interface NumLit {
65 kind: 'NumLit';
66 value: number;
67 ty: Type;
68 span: Span;
69 }
70 export interface Var {
71 kind: 'Var';
72 name: string;
73 cName: string;
74 ty: Type;
75 span: Span;
76 }
77 export interface Binary {
78 kind: 'Binary';
79 builtin: string;
80 left: IRExpr;
81 right: IRExpr;
82 ty: Type;
83 span: Span;
84 }
85 export interface Unary {
86 kind: 'Unary';
87 builtin: string;
88 operand: IRExpr;
89 ty: Type;
90 span: Span;
91 }
92 export interface Call {
93 kind: 'Call';
94 cName: string;
95 name: string;
96 args: IRExpr[];
97 ty: Type;
98 span: Span;
99 }
100 /** Any other IR expression kind — rejected by the WGSL emitter. */
101 export interface OtherExpr {
102 kind:
103 | 'ImagLit' | 'StringLit' | 'TensorBuild' | 'TensorConcat' | 'CellLit'
104 | 'CellEmpty' | 'CellIndexLoad' | 'HandleLit' | 'HandleCaptureLoad'
105 | 'StructLit' | 'MemberLoad' | 'IndexLoad' | 'IndexSlice' | 'EndRef'
106 | 'MakeRange';
107 ty: Type;
108 span: Span;
109 }
111 export type IRExpr = NumLit | Var | Binary | Unary | Call | OtherExpr;
113 export interface Assign {
114 kind: 'Assign';
115 name: string;
116 cName: string;
117 ty: Type;
118 expr: IRExpr;
119 span: Span;
120 }
121 /**
122 * A counted loop. The planner unrolls it, so only the fields that decide
123 * the trip count and the loop variable's value are spelled out. `step` is
124 * already a literal number in the IR — numbl rejects a non-literal step
125 * during lowering — while `start` and `end` are expressions that must carry
126 * an exact value for the planner to accept the loop.
127 */
128 export interface For {
129 kind: 'For';
130 /** Loop variable, as written in the .m. */
131 varName: string;
132 /** Loop variable's cName, the key the planner binds its value under. */
133 cVar: string;
134 start: IRExpr;
135 step: number;
136 end: IRExpr;
137 body: IRStmt[];
138 span: Span;
139 }
141 * A multi-output call statement, `[a, b] = f(...)`. For a user function
142 * (`isBuiltin` false or absent) `cName` is the callee's specialization and
143 * the call is expanded into the caller (src/mgpu/inlineCalls.ts); a
144 * multi-output builtin is rejected by the planner.
145 */
146 export interface MultiAssignCall {
147 kind: 'MultiAssignCall';
148 /** Mangled specialization cName (user function) or builtin name. */
149 cName: string;
150 /** Source-level callee name, for diagnostics. */
151 name: string;
152 isBuiltin?: boolean;
153 args: IRExpr[];
154 /** One entry per output slot; `binding` null for an ignored output. */
155 outputs: ReadonlyArray<{
156 ty: Type;
157 binding: { name: string; cName: string } | null;
158 }>;
159 span: Span;
160 }
0af3386Reaction-diffusion on spherical-harmonic surfacesJeremy Magland 161 /** Any other IR statement kind — rejected by the planner. */
162 export interface OtherStmt {
163 kind:
164 | 'ExprStmt' | 'If' | 'While' | 'ReturnFromFunction' | 'Break'
59f3e22Factor the solver out of the models; add BiCGSTAB and GMRESJeremy Magland 165 | 'Continue' | 'TypeComment' | 'MemberStore'
0af3386Reaction-diffusion on spherical-harmonic surfacesJeremy Magland 166 | 'IndexStore' | 'IndexSliceStore' | 'CellIndexStore';
167 span: Span;
168 }
59f3e22Factor the solver out of the models; add BiCGSTAB and GMRESJeremy Magland 170 export type IRStmt = Assign | For | MultiAssignCall | OtherStmt;
172 export interface IRFunc {
173 name: string;
174 cName: string;
175 /** Parameter source names. */
176 params: string[];
177 /** Parameter cNames, parallel to `params`. */
178 cParams: string[];
179 paramTypes: Type[];
180 /** Output source names. */
181 outputs: string[];
182 /** Output cNames, parallel to `outputs`. */
183 cOutputs: string[];
184 outputTypes: Type[];
185 body: IRStmt[];
186 span: Span;
187 }
189 export interface IRProgram {
190 topLevelStmts: IRStmt[];
191 functions: Map<string, IRFunc>;
192 }
195declare module 'numbl-src/numbl-core/parser/index.ts' {
196 export interface AbstractSyntaxTree {
197 body: unknown[];
198 }
199 export function parseMFile(input: string, fileName?: string): AbstractSyntaxTree;
200 export class SyntaxError extends Error {}
203declare module 'numbl-src/numbl-core/jit/index.ts' {
204 import type { AbstractSyntaxTree } from 'numbl-src/numbl-core/parser/index.ts';
205 import type { IRProgram, IRFunc, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
206 import type { Type, NumericType, Sign } from 'numbl-src/numbl-core/jit/lowering/types.ts';
208 export interface WorkspaceFile {
209 name: string;
210 source: string;
211 ast?: AbstractSyntaxTree;
212 }
214 export class Workspace {
215 constructor(mainFile: string, searchPaths?: ReadonlyArray<string>);
216 addFile(file: WorkspaceFile): void;
217 finalize(): void;
218 }
220 export interface EnvEntry {
221 cName: string;
222 ty: Type;
223 maybeUnassigned?: boolean;
224 }
226 export class Lowerer {
227 constructor(workspace: Workspace);
228 /** Pre-bindable variable scope: seed host-provided values here. */
229 env: Map<string, EnvEntry>;
230 specializations: Map<string, IRFunc>;
231 lowerProgram(ast: AbstractSyntaxTree): IRProgram;
232 }
234 /** Thrown for MATLAB the JIT pipeline cannot lower; carries a source span. */
235 export class UnsupportedConstruct extends Error {
236 span?: Span;
237 }
238 export class JitTypeError extends Error {
239 span?: Span;
240 }
242 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
243 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
244 export function isMultiElement(t: NumericType): boolean;
247declare module 'numbl-src/numbl-core/jit/lowering/specialize.ts' {
248 import type { Lowerer } from 'numbl-src/numbl-core/jit/index.ts';
249 import type { IRFunc, IRExpr, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
250 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
252 /**
253 * Lower one user function for a concrete argument-type signature. Called with
254 * a `Lowerer` as `this` (numbl's own JIT does the same), so specializations
255 * accumulate in `lowerer.specializations`.
256 */
257 export function specializeUserFunction(
258 this: Lowerer,
259 decl: unknown,
260 argTypes: Type[],
261 specSource?: string,
262 definingFile?: string,
263 preSeedOutput?: { name: string; ty: Type; initExpr: IRExpr },
264 nargout?: number,
265 callSiteSpan?: Span,
266 ): IRFunc;
269declare module 'numbl-src/numbl-core/jit/codegen/inlinePass.ts' {
270 import type { IRProgram } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
271 /** Folds single-use ANF temps into their consumer, in place. */
272 export function inlinePass(prog: IRProgram): void;
275declare module 'numbl-src/numbl-core/jit/builtins/index.ts' {
276 export interface Builtin {
277 name: string;
278 /** Safe to evaluate one output element from one input element per slot. */
279 elementwise?: boolean;
280 }
281 export function getBuiltin(name: string): Builtin | undefined;
moveopenescclose