/ concept-collection / turing-surface
Sign in
concept-collection / turing-surface
281 lines · 8.4 KBBlameHistoryRaw
1/**
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 }
140 /**
141 * Multi-output call statement: `[a, b] = f(x, y)`. For `isBuiltin: true`
142 * the builtin's `transfer(argTypes, nargout)` typed the slots during
143 * lowering; args arrive ANF'd. The planner accepts this only for the
144 * batched transforms (`synth`/`analys`), where output k is the transform
145 * of argument k.
146 */
147 export interface MultiAssignCall {
148 kind: 'MultiAssignCall';
149 cName: string;
150 name: string;
151 isBuiltin?: boolean;
152 args: IRExpr[];
153 outputs: ReadonlyArray<{
154 ty: Type;
155 binding: { name: string; cName: string } | null;
156 }>;
157 span: Span;
158 }
160 /** Any other IR statement kind — rejected by the planner. */
161 export interface OtherStmt {
162 kind:
163 | 'ExprStmt' | 'If' | 'While' | 'ReturnFromFunction' | 'Break'
164 | 'Continue' | 'TypeComment' | 'MemberStore'
165 | 'IndexStore' | 'IndexSliceStore' | 'CellIndexStore';
166 span: Span;
167 }
169 export type IRStmt = Assign | For | MultiAssignCall | OtherStmt;
171 export interface IRFunc {
172 name: string;
173 cName: string;
174 /** Parameter source names. */
175 params: string[];
176 /** Parameter cNames, parallel to `params`. */
177 cParams: string[];
178 paramTypes: Type[];
179 /** Output source names. */
180 outputs: string[];
181 /** Output cNames, parallel to `outputs`. */
182 cOutputs: string[];
183 outputTypes: Type[];
184 body: IRStmt[];
185 span: Span;
186 }
188 export interface IRProgram {
189 topLevelStmts: IRStmt[];
190 functions: Map<string, IRFunc>;
191 }
194declare module 'numbl-src/numbl-core/parser/index.ts' {
195 export interface AbstractSyntaxTree {
196 body: unknown[];
197 }
198 export function parseMFile(input: string, fileName?: string): AbstractSyntaxTree;
199 export class SyntaxError extends Error {}
202declare module 'numbl-src/numbl-core/jit/index.ts' {
203 import type { AbstractSyntaxTree } from 'numbl-src/numbl-core/parser/index.ts';
204 import type { IRProgram, IRFunc, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
205 import type { Type, NumericType, Sign } from 'numbl-src/numbl-core/jit/lowering/types.ts';
207 export interface WorkspaceFile {
208 name: string;
209 source: string;
210 ast?: AbstractSyntaxTree;
211 }
213 export class Workspace {
214 constructor(mainFile: string, searchPaths?: ReadonlyArray<string>);
215 addFile(file: WorkspaceFile): void;
216 finalize(): void;
217 }
219 export interface EnvEntry {
220 cName: string;
221 ty: Type;
222 maybeUnassigned?: boolean;
223 }
225 export class Lowerer {
226 constructor(workspace: Workspace);
227 /** Pre-bindable variable scope: seed host-provided values here. */
228 env: Map<string, EnvEntry>;
229 specializations: Map<string, IRFunc>;
230 lowerProgram(ast: AbstractSyntaxTree): IRProgram;
231 }
233 /** Thrown for MATLAB the JIT pipeline cannot lower; carries a source span. */
234 export class UnsupportedConstruct extends Error {
235 span?: Span;
236 }
237 export class JitTypeError extends Error {
238 span?: Span;
239 }
241 export function tensorDouble(shape: number[], exact?: Float64Array): NumericType;
242 export function scalarDouble(sign?: Sign, exact?: number): NumericType;
243 export function isMultiElement(t: NumericType): boolean;
246declare module 'numbl-src/numbl-core/jit/lowering/specialize.ts' {
247 import type { Lowerer } from 'numbl-src/numbl-core/jit/index.ts';
248 import type { IRFunc, IRExpr, Span } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
249 import type { Type } from 'numbl-src/numbl-core/jit/lowering/types.ts';
251 /**
252 * Lower one user function for a concrete argument-type signature. Called with
253 * a `Lowerer` as `this` (numbl's own JIT does the same), so specializations
254 * accumulate in `lowerer.specializations`.
255 */
256 export function specializeUserFunction(
257 this: Lowerer,
258 decl: unknown,
259 argTypes: Type[],
260 specSource?: string,
261 definingFile?: string,
262 preSeedOutput?: { name: string; ty: Type; initExpr: IRExpr },
263 nargout?: number,
264 callSiteSpan?: Span,
265 ): IRFunc;
268declare module 'numbl-src/numbl-core/jit/codegen/inlinePass.ts' {
269 import type { IRProgram } from 'numbl-src/numbl-core/jit/lowering/ir.ts';
270 /** Folds single-use ANF temps into their consumer, in place. */
271 export function inlinePass(prog: IRProgram): void;
274declare module 'numbl-src/numbl-core/jit/builtins/index.ts' {
275 export interface Builtin {
276 name: string;
277 /** Safe to evaluate one output element from one input element per slot. */
278 elementwise?: boolean;
279 }
280 export function getBuiltin(name: string): Builtin | undefined;
moveopenescclose