/ concept-collection / turing-surface-cache
Sign in
concept-collection / turing-surface-cache
turing-surface-cache / src / mgpu / numbl.d.ts
366 lines · 10.9 KBBlameHistoryRaw
1/**
2 * The numbl compiler surface this project depends on.
3 *
4 * We reach past numbl's published entry points into its internals — the JIT
5 * side (parser, lowerer, IR, inline pass) that compiles the models, and the
6 * interpreter side (executeCode, runtime values) that evaluates the
7 * geometries — which its package `exports` map does not expose. Those imports
8 * resolve through the `numbl-src` alias in vite.config.ts; these declarations
9 * are what TypeScript checks against.
10 *
11 * Declaring the surface here rather than type-checking numbl's sources
12 * directly keeps this project's compiler settings independent of numbl's, and
13 * pins the exact contract we rely on. If numbl changes one of these shapes,
14 * the build breaks here with a clear diff rather than deep inside its tree.
15 *
16 * Only the nodes the WGSL backend actually walks are spelled out; every other
17 * IR kind is collapsed into a catch-all so that unhandled constructs are
18 * rejected with a message instead of being silently mis-compiled.
19 */
21declare module 'numbl-src/numbl-core/jit/lowering/types.ts' {
22 export type Sign =
23 | 'positive' | 'nonneg' | 'negative' | 'nonpositive'
24 | 'zero' | 'nonzero' | 'unknown';
26 export type DimInfo = { kind: 'exact'; value: number } | { kind: 'unknown' };
28 export type NumericExact =
29 | number
30 | Float64Array
31 | { re: number; im: number }
32 | { re: Float64Array; im: Float64Array };
34 export interface NumericType {
35 kind: 'Numeric';
36 elem: 'double' | 'logical' | 'char' | string;
37 isComplex: boolean;
38 dims: DimInfo[];
39 /** Present iff every dim is exact. */
40 shape?: number[];
41 sign: Sign;
42 exact?: NumericExact;
43 }
45 /** Everything the WGSL backend rejects. */
46 export interface NonNumericType {
47 kind: 'Void' | 'Unknown' | 'String' | 'Handle' | 'Struct' | 'Class' | 'Cell';
48 }
50 export type Type = NumericType | NonNumericType;
52 export function isMultiElement(t: NumericType): boolean;
53 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
54 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
57declare module 'numbl-src/numbl-core/jit/lowering/ir.ts' {
58 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
60 export interface Span {
61 file: string;
62 start: number;
63 end: number;
64 }
66 export interface NumLit {
67 kind: 'NumLit';
68 value: number;
69 ty: Type;
70 span: Span;
71 }
72 export interface Var {
73 kind: 'Var';
74 name: string;
75 cName: string;
76 ty: Type;
77 span: Span;
78 }
79 export interface Binary {
80 kind: 'Binary';
81 builtin: string;
82 left: IRExpr;
83 right: IRExpr;
84 ty: Type;
85 span: Span;
86 }
87 export interface Unary {
88 kind: 'Unary';
89 builtin: string;
90 operand: IRExpr;
91 ty: Type;
92 span: Span;
93 }
94 export interface Call {
95 kind: 'Call';
96 cName: string;
97 name: string;
98 args: IRExpr[];
99 ty: Type;
100 span: Span;
101 }
102 /** Any other IR expression kind — rejected by the WGSL emitter. */
103 export interface OtherExpr {
104 kind:
105 | 'ImagLit' | 'StringLit' | 'TensorBuild' | 'TensorConcat' | 'CellLit'
106 | 'CellEmpty' | 'CellIndexLoad' | 'HandleLit' | 'HandleCaptureLoad'
107 | 'StructLit' | 'MemberLoad' | 'IndexLoad' | 'IndexSlice' | 'EndRef'
108 | 'MakeRange';
109 ty: Type;
110 span: Span;
111 }
113 export type IRExpr = NumLit | Var | Binary | Unary | Call | OtherExpr;
115 export interface Assign {
116 kind: 'Assign';
117 name: string;
118 cName: string;
119 ty: Type;
120 expr: IRExpr;
121 span: Span;
122 }
123 /**
124 * A counted loop. The planner unrolls it, so only the fields that decide
125 * the trip count and the loop variable's value are spelled out. `step` is
126 * already a literal number in the IR — numbl rejects a non-literal step
127 * during lowering — while `start` and `end` are expressions that must carry
128 * an exact value for the planner to accept the loop.
129 */
130 export interface For {
131 kind: 'For';
132 /** Loop variable, as written in the .m. */
133 varName: string;
134 /** Loop variable's cName, the key the planner binds its value under. */
135 cVar: string;
136 start: IRExpr;
137 step: number;
138 end: IRExpr;
139 body: IRStmt[];
140 span: Span;
141 }
142 /**
143 * Multi-output call statement: `[a, b] = f(x, y)`. For `isBuiltin: true`
144 * the builtin's `transfer(argTypes, nargout)` typed the slots during
145 * lowering; args arrive ANF'd. The planner accepts this only for the
146 * batched transforms (`synth`/`analys`), where output k is the transform
147 * of argument k.
148 */
149 export interface MultiAssignCall {
150 kind: 'MultiAssignCall';
151 cName: string;
152 name: string;
153 isBuiltin?: boolean;
154 args: IRExpr[];
155 outputs: ReadonlyArray<{
156 ty: Type;
157 binding: { name: string; cName: string } | null;
158 }>;
159 span: Span;
160 }
162 /** Any other IR statement kind — rejected by the planner. */
163 export interface OtherStmt {
164 kind:
165 | 'ExprStmt' | 'If' | 'While' | 'ReturnFromFunction' | 'Break'
166 | 'Continue' | 'TypeComment' | 'MemberStore'
167 | 'IndexStore' | 'IndexSliceStore' | 'CellIndexStore';
168 span: Span;
169 }
171 export type IRStmt = Assign | For | MultiAssignCall | OtherStmt;
173 export interface IRFunc {
174 name: string;
175 cName: string;
176 /** Parameter source names. */
177 params: string[];
178 /** Parameter cNames, parallel to `params`. */
179 cParams: string[];
180 paramTypes: Type[];
181 /** Output source names. */
182 outputs: string[];
183 /** Output cNames, parallel to `outputs`. */
184 cOutputs: string[];
185 outputTypes: Type[];
186 body: IRStmt[];
187 span: Span;
188 }
190 export interface IRProgram {
191 topLevelStmts: IRStmt[];
192 functions: Map<string, IRFunc>;
193 }
196declare module 'numbl-src/numbl-core/parser/index.ts' {
197 export interface ParseSpan {
198 start: number;
199 end: number;
200 }
202 /** The one parse-tree node this project inspects (src/geom/geometry.ts,
203 * finding `shape` and its argument names). */
204 export interface FunctionStmt {
205 type: 'Function';
206 name: string;
207 params: string[];
208 outputs: string[];
209 span: ParseSpan;
210 }
212 /** Any other statement in a file's body — opaque to this project. Its
213 * `type` is some other literal; narrowing to FunctionStmt goes through an
214 * explicit type guard rather than the discriminant. */
215 export interface OtherParseStmt {
216 type: string;
217 span: ParseSpan;
218 }
220 export type Stmt = FunctionStmt | OtherParseStmt;
222 export interface AbstractSyntaxTree {
223 body: Stmt[];
224 }
225 export function parseMFile(input: string, fileName?: string): AbstractSyntaxTree;
226 export class SyntaxError extends Error {}
229declare module 'numbl-src/numbl-core/runtime/types.ts' {
230 /** A numeric array: f64 data in column-major order, with its shape. */
231 export class RuntimeTensor {
232 readonly kind: 'tensor';
233 data: Float64Array;
234 /** Present iff the value is complex. */
235 imag: Float64Array | undefined;
236 shape: number[];
237 constructor(data: Float64Array, shape: number[], imag?: Float64Array);
238 }
240 /** Every other value kind the interpreter can hold, collapsed. */
241 export interface OtherRuntimeValue {
242 readonly kind: string;
243 }
245 export type RuntimeValue =
246 | number
247 | boolean
248 | string
249 | RuntimeTensor
250 | OtherRuntimeValue;
252 export function isRuntimeTensor(value: RuntimeValue): value is RuntimeTensor;
255declare module 'numbl-src/numbl-core/executeCode.ts' {
256 import type { RuntimeValue } from 'numbl-src/numbl-core/runtime/types.ts';
258 export interface ExecOptions {
259 /** Variables pre-bound in the script's workspace before it runs. */
260 initialVariableValues?: Record<string, RuntimeValue>;
261 displayResults?: boolean;
262 onOutput?: (text: string) => void;
263 /** null opts out of scanning a working directory for .m files. */
264 implicitCwdPath?: string | null;
265 }
267 export interface ExecWorkspaceFile {
268 name: string;
269 source: string;
270 }
272 export interface ExecResult {
273 output: string[];
274 /** The script's workspace after it ran. */
275 variableValues: Record<string, RuntimeValue>;
276 }
278 /** Run a script through numbl's interpreter (with its JS-JIT), CPU-side. */
279 export function executeCode(
280 source: string,
281 options?: ExecOptions,
282 workspaceFiles?: ExecWorkspaceFile[],
283 mainFileName?: string,
284 ): ExecResult;
287declare module 'numbl-src/numbl-core/jit/index.ts' {
288 import type { AbstractSyntaxTree } from 'numbl-src/numbl-core/parser/index.ts';
289 import type { IRProgram, IRFunc, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
290 import type { Type, NumericType, Sign } from 'numbl-src/numbl-core/jit/lowering/types.ts';
292 export interface WorkspaceFile {
293 name: string;
294 source: string;
295 ast?: AbstractSyntaxTree;
296 }
298 export class Workspace {
299 constructor(mainFile: string, searchPaths?: ReadonlyArray<string>);
300 addFile(file: WorkspaceFile): void;
301 finalize(): void;
302 }
304 export interface EnvEntry {
305 cName: string;
306 ty: Type;
307 maybeUnassigned?: boolean;
308 }
310 export class Lowerer {
311 constructor(workspace: Workspace);
312 /** Pre-bindable variable scope: seed host-provided values here. */
313 env: Map<string, EnvEntry>;
314 specializations: Map<string, IRFunc>;
315 lowerProgram(ast: AbstractSyntaxTree): IRProgram;
316 }
318 /** Thrown for MATLAB the JIT pipeline cannot lower; carries a source span. */
319 export class UnsupportedConstruct extends Error {
320 span?: Span;
321 }
322 export class JitTypeError extends Error {
323 span?: Span;
324 }
326 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
327 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
328 export function isMultiElement(t: NumericType): boolean;
331declare module 'numbl-src/numbl-core/jit/lowering/specialize.ts' {
332 import type { Lowerer } from 'numbl-src/numbl-core/jit/index.ts';
333 import type { IRFunc, IRExpr, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
334 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
336 /**
337 * Lower one user function for a concrete argument-type signature. Called with
338 * a `Lowerer` as `this` (numbl's own JIT does the same), so specializations
339 * accumulate in `lowerer.specializations`.
340 */
341 export function specializeUserFunction(
342 this: Lowerer,
343 decl: unknown,
344 argTypes: Type[],
345 specSource?: string,
346 definingFile?: string,
347 preSeedOutput?: { name: string; ty: Type; initExpr: IRExpr },
348 nargout?: number,
349 callSiteSpan?: Span,
350 ): IRFunc;
353declare module 'numbl-src/numbl-core/jit/codegen/inlinePass.ts' {
354 import type { IRProgram } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
355 /** Folds single-use ANF temps into their consumer, in place. */
356 export function inlinePass(prog: IRProgram): void;
359declare module 'numbl-src/numbl-core/jit/builtins/index.ts' {
360 export interface Builtin {
361 name: string;
362 /** Safe to evaluate one output element from one input element per slot. */
363 elementwise?: boolean;
364 }
365 export function getBuiltin(name: string): Builtin | undefined;
moveopenescclose