@openfluke/welvet 0.2.0 → 0.74.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,148 @@
1
+ /**
2
+ * benchmark.ts
3
+ * TypeScript port of benchmark_training.html
4
+ */
5
+
6
+ import { loadLoomWASM } from "../src/loader.js";
7
+
8
+ const TRAINING_CASES = [
9
+ {
10
+ name: 'Dense (Linear)', iters: 5, inDim: 512, outDim: 512,
11
+ cfg: JSON.stringify({ depth: 1, rows: 1, cols: 1, layers_per_cell: 1, layers: [
12
+ { z: 0, y: 0, x: 0, l: 0, type: "Dense", input_height: 512, output_height: 512, activation: "Linear", dtype: "F32" }
13
+ ]})
14
+ },
15
+ {
16
+ name: 'RMSNorm', iters: 5, inDim: 512, outDim: 512,
17
+ cfg: JSON.stringify({ depth: 1, rows: 1, cols: 1, layers_per_cell: 1, layers: [
18
+ { z: 0, y: 0, x: 0, l: 0, type: "RMSNorm", input_height: 512, output_height: 512, dtype: "F32" }
19
+ ]})
20
+ },
21
+ {
22
+ name: 'SwiGLU (MLP)', iters: 5, inDim: 512, outDim: 1024,
23
+ cfg: JSON.stringify({ depth: 1, rows: 1, cols: 1, layers_per_cell: 1, layers: [
24
+ { z: 0, y: 0, x: 0, l: 0, type: "SwiGLU", input_height: 512, output_height: 1024, dtype: "F32" }
25
+ ]})
26
+ },
27
+ {
28
+ name: 'Embedding', iters: 5, inDim: 16, outDim: 2048, isEmbedding: true,
29
+ cfg: JSON.stringify({ depth: 1, rows: 1, cols: 1, layers_per_cell: 1, layers: [
30
+ { z: 0, y: 0, x: 0, l: 0, type: "Embedding", vocab_size: 1024, embedding_dim: 128, dtype: "F32" }
31
+ ]})
32
+ },
33
+ {
34
+ name: 'Residual Add', iters: 5, inDim: 512, outDim: 512,
35
+ cfg: JSON.stringify({ depth: 1, rows: 1, cols: 1, layers_per_cell: 1, layers: [
36
+ { z: 0, y: 0, x: 0, l: 0, type: "Residual", input_height: 512, output_height: 512, dtype: "F32" }
37
+ ]})
38
+ },
39
+ {
40
+ name: 'MHA (Fused)', iters: 5, inDim: 128, outDim: 128,
41
+ cfg: JSON.stringify({ depth: 1, rows: 1, cols: 1, layers_per_cell: 1, layers: [
42
+ { z: 0, y: 0, x: 0, l: 0, type: "MHA", input_height: 128, output_height: 128, num_heads: 4, d_model: 128, dtype: "F32" }
43
+ ]})
44
+ }
45
+ ];
46
+
47
+ function makeTrainBatches(inDim: number, outDim: number, nBatches: number, batchSize: number, isEmbedding?: boolean) {
48
+ const batches: any[] = [];
49
+ for (let b = 0; b < nBatches; b++) {
50
+ const inp = new Float32Array(batchSize * inDim);
51
+ const tgt = new Float32Array(batchSize * outDim);
52
+ if (isEmbedding) {
53
+ for (let i = 0; i < inp.length; i++) inp[i] = i % 1024;
54
+ } else {
55
+ for (let i = 0; i < inp.length; i++) inp[i] = (Math.random() * 2 - 1) * 0.5;
56
+ }
57
+ for (let i = 0; i < tgt.length; i++) tgt[i] = Math.random() * 0.1;
58
+ batches.push({
59
+ input: { shape: [batchSize, inDim], data: Array.from(inp) },
60
+ target: { shape: [batchSize, outDim], data: Array.from(tgt) }
61
+ });
62
+ }
63
+ return batches;
64
+ }
65
+
66
+ async function runCase(tc: any) {
67
+ // @ts-ignore
68
+ const net = globalThis.createLoomNetwork(tc.cfg);
69
+ const batchSize = 4;
70
+ const nBatches = 4;
71
+ const epochs = 3;
72
+
73
+ const batches = makeTrainBatches(tc.inDim, tc.outDim, nBatches, batchSize, tc.isEmbedding);
74
+ const batchesJSON = JSON.stringify(batches);
75
+
76
+ const input = new Float32Array(tc.inDim);
77
+ input.fill(0.5);
78
+ if (tc.isEmbedding) for (let i = 0; i < input.length; i++) input[i] = i % 1024;
79
+
80
+ // warm-up
81
+ net.sequentialForward(input);
82
+
83
+ const t0 = performance.now();
84
+ let lastOut: any;
85
+ for (let i = 0; i < tc.iters; i++) {
86
+ lastOut = net.sequentialForward(input);
87
+ }
88
+ const fwdMs = (performance.now() - t0) / tc.iters;
89
+
90
+ let trainMs = -1;
91
+ let initialLoss: number | null = null, finalLoss: number | null = null;
92
+ try {
93
+ const t1 = performance.now();
94
+ const trainResult = await net.train(batchesJSON, epochs, 0.001);
95
+ trainMs = performance.now() - t1;
96
+ if (typeof trainResult === 'string') {
97
+ try {
98
+ const r = JSON.parse(trainResult);
99
+ if (r.loss_history && r.loss_history.length > 0) {
100
+ initialLoss = r.loss_history[0];
101
+ finalLoss = r.loss_history[r.loss_history.length - 1];
102
+ }
103
+ } catch (e) {}
104
+ }
105
+ } catch (e) {
106
+ trainMs = -1;
107
+ }
108
+
109
+ const sample = lastOut ? [lastOut[0] || 0, lastOut[1] || 0, lastOut[2] || 0] : null;
110
+ const sanity = sample && sample.some((v: number) => Math.abs(v) > 1e-9);
111
+ net.free();
112
+ return { fwdMs, trainMs, sample, sanity, initialLoss, finalLoss };
113
+ }
114
+
115
+ export async function runBenchmark() {
116
+ console.log("=== M-POLY-VTD Training Showdown Benchmark ===");
117
+
118
+ // Decide which loader to use
119
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
120
+ const { loadLoomWASM } = await import("../src/loader.js");
121
+ await loadLoomWASM();
122
+ } else {
123
+ // @ts-ignore
124
+ const { loadLoomWASMBrowser } = await import("../src/loader.browser.js");
125
+ await loadLoomWASMBrowser();
126
+ }
127
+
128
+ console.log("Layer".padEnd(15) + " | " + "Fwd ms/it".padEnd(11) + " | " + "Train ms".padEnd(10) +
129
+ " | " + "Init Loss".padEnd(11) + " | " + "Final Loss".padEnd(11) + " | Sanity");
130
+ console.log("-".repeat(85));
131
+
132
+ for (const tc of TRAINING_CASES) {
133
+ const res = await runCase(tc);
134
+
135
+ const fwdStr = res.fwdMs >= 0 ? res.fwdMs.toFixed(3).padEnd(10) : 'N/A'.padEnd(10);
136
+ const trainStr = res.trainMs >= 0 ? res.trainMs.toFixed(1).padEnd(9) : 'N/A'.padEnd(9);
137
+ const iLoss = res.initialLoss != null ? res.initialLoss.toFixed(4).padEnd(10) : 'N/A'.padEnd(10);
138
+ const fLoss = res.finalLoss != null ? res.finalLoss.toFixed(4).padEnd(10) : 'N/A'.padEnd(10);
139
+ const sanStr = res.sanity ? 'REAL' : 'ZERO';
140
+
141
+ console.log(`${tc.name.padEnd(15)} | ${fwdStr} | ${trainStr} | ${iLoss} | ${fLoss} | ${sanStr}`);
142
+ }
143
+ }
144
+
145
+ // Auto-run if executed directly via Node.js/tsx
146
+ if (typeof process !== "undefined" && import.meta.url.includes(process.argv[1].replace(/\\/g, '/'))) {
147
+ runBenchmark();
148
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * cabi_verify.ts
3
+ * TypeScript port of cabi_verify.html
4
+ */
5
+ export declare function runVerify(): Promise<void>;
@@ -0,0 +1,181 @@
1
+ /**
2
+ * cabi_verify.ts
3
+ * TypeScript port of cabi_verify.html
4
+ */
5
+ const EXPECTED_SYMBOLS = [
6
+ 'createLoomNetwork', 'loadLoomNetwork',
7
+ 'compareLoomDNA',
8
+ 'getDefaultTargetPropConfig', 'defaultSpliceConfig', 'defaultNEATConfig',
9
+ 'createLoomNEATPopulation',
10
+ 'setupWebGPU',
11
+ ];
12
+ const EXPECTED_NET_METHODS = [
13
+ 'sequentialForward', 'extractDNA', 'extractBlueprint', 'getLayerCount',
14
+ 'getLayerSpec', 'morphLayer', 'spliceDNA', 'neatMutate',
15
+ 'createSystolicState', 'createTargetPropState', 'initGPU', 'syncToGPU',
16
+ 'syncToCPU', 'train', 'free', '_id',
17
+ ];
18
+ const EXPECTED_POP_METHODS = [
19
+ '_id', 'size', 'getNetwork', 'evolveWithFitnesses',
20
+ 'best', 'bestFitness', 'summary', 'free',
21
+ ];
22
+ const DENSE_3L = JSON.stringify({
23
+ depth: 3, rows: 1, cols: 1, layers_per_cell: 1,
24
+ layers: [
25
+ { z: 0, y: 0, x: 0, l: 0, type: "Dense", input_height: 16, output_height: 16, activation: "ReLU", dtype: "F32" },
26
+ { z: 1, y: 0, x: 0, l: 0, type: "Dense", input_height: 16, output_height: 16, activation: "ReLU", dtype: "F32" },
27
+ { z: 2, y: 0, x: 0, l: 0, type: "Dense", input_height: 16, output_height: 4, activation: "Linear", dtype: "F32" },
28
+ ]
29
+ });
30
+ const SWIGLU_NET = JSON.stringify({
31
+ depth: 2, rows: 1, cols: 1, layers_per_cell: 1,
32
+ layers: [
33
+ { z: 0, y: 0, x: 0, l: 0, type: "SwiGLU", input_height: 16, output_height: 32, dtype: "F32" },
34
+ { z: 1, y: 0, x: 0, l: 0, type: "Dense", input_height: 32, output_height: 4, activation: "Linear", dtype: "F32" },
35
+ ]
36
+ });
37
+ export async function runVerify() {
38
+ console.log("=== Loom WASM C-ABI Diagnostic Report ===");
39
+ // Decide which loader to use
40
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
41
+ const { loadLoomWASM } = await import("../src/loader.js");
42
+ await loadLoomWASM();
43
+ }
44
+ else {
45
+ // @ts-ignore
46
+ const { loadLoomWASMBrowser } = await import("../src/loader.browser.js");
47
+ await loadLoomWASMBrowser();
48
+ }
49
+ let totalPass = 0;
50
+ let totalFail = 0;
51
+ // 1. Global symbol check
52
+ console.log("\n[1] Checking global WASM exports...");
53
+ for (const sym of EXPECTED_SYMBOLS) {
54
+ // @ts-ignore
55
+ if (typeof globalThis[sym] === 'function') {
56
+ console.log(` [PASS] ${sym}`);
57
+ totalPass++;
58
+ }
59
+ else {
60
+ console.error(` [FAIL] ${sym} (missing)`);
61
+ totalFail++;
62
+ }
63
+ }
64
+ // 2. Network method check
65
+ console.log("\n[2] Checking network wrapper methods...");
66
+ let net = null;
67
+ try {
68
+ // @ts-ignore
69
+ net = globalThis.createLoomNetwork(DENSE_3L);
70
+ if (net) {
71
+ for (const m of EXPECTED_NET_METHODS) {
72
+ if (net[m] !== undefined) {
73
+ console.log(` [PASS] ${m}`);
74
+ totalPass++;
75
+ }
76
+ else {
77
+ console.error(` [FAIL] ${m} (missing)`);
78
+ totalFail++;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ catch (e) {
84
+ console.error(" [FAIL] createLoomNetwork failed:", e);
85
+ totalFail++;
86
+ }
87
+ // 3. Population method check
88
+ if (net) {
89
+ console.log("\n[3] Checking NEAT population wrapper methods...");
90
+ try {
91
+ // @ts-ignore
92
+ const cfg = globalThis.defaultNEATConfig(16);
93
+ // @ts-ignore
94
+ const pop = globalThis.createLoomNEATPopulation(net._id, 4, cfg);
95
+ if (pop) {
96
+ for (const m of EXPECTED_POP_METHODS) {
97
+ if (pop[m] !== undefined) {
98
+ console.log(` [PASS] ${m}`);
99
+ totalPass++;
100
+ }
101
+ else {
102
+ console.error(` [FAIL] ${m} (missing)`);
103
+ totalFail++;
104
+ }
105
+ }
106
+ pop.free();
107
+ }
108
+ }
109
+ catch (e) {
110
+ console.error(" [FAIL] Population creation failed:", e);
111
+ totalFail++;
112
+ }
113
+ }
114
+ // 4. Functional smoke tests
115
+ console.log("\n[4] Running functional smoke tests...");
116
+ const smokeTest = (name, fn) => {
117
+ try {
118
+ const result = fn();
119
+ console.log(` [PASS] ${name}${result ? " → " + result : ""}`);
120
+ totalPass++;
121
+ }
122
+ catch (e) {
123
+ console.error(` [FAIL] ${name} → ${e.message}`);
124
+ totalFail++;
125
+ }
126
+ };
127
+ smokeTest("sequentialForward", () => {
128
+ // @ts-ignore
129
+ const n = globalThis.createLoomNetwork(DENSE_3L);
130
+ const input = new Float32Array(16).fill(0.5);
131
+ const out = n.sequentialForward(input);
132
+ n.free();
133
+ if (!out || out.length === 0)
134
+ throw new Error("empty output");
135
+ return "out[0]=" + out[0].toFixed(4);
136
+ });
137
+ smokeTest("extractDNA", () => {
138
+ // @ts-ignore
139
+ const n = globalThis.createLoomNetwork(DENSE_3L);
140
+ const dna = n.extractDNA();
141
+ n.free();
142
+ const parsed = JSON.parse(dna);
143
+ return "sigs=" + parsed.length;
144
+ });
145
+ smokeTest("compareLoomDNA", () => {
146
+ // @ts-ignore
147
+ const n1 = globalThis.createLoomNetwork(DENSE_3L);
148
+ // @ts-ignore
149
+ const n2 = globalThis.createLoomNetwork(DENSE_3L);
150
+ const dna1 = n1.extractDNA();
151
+ const dna2 = n2.extractDNA();
152
+ // @ts-ignore
153
+ const result = JSON.parse(globalThis.compareLoomDNA(dna1, dna2));
154
+ n1.free();
155
+ n2.free();
156
+ return "overlap=" + (result.overall_overlap || result.OverallOverlap || "?");
157
+ });
158
+ smokeTest("createLoomNetwork (SwiGLU)", () => {
159
+ // @ts-ignore
160
+ const n = globalThis.createLoomNetwork(SWIGLU_NET);
161
+ const c = n.getLayerCount();
162
+ n.free();
163
+ return "layers=" + c;
164
+ });
165
+ console.log("\n[5] Final Summary");
166
+ console.log("================================");
167
+ if (totalFail === 0) {
168
+ console.log(`SUCCESS: All ${totalPass} checks passed.`);
169
+ }
170
+ else {
171
+ console.warn(`PARTIAL: ${totalPass} passed, ${totalFail} FAILED.`);
172
+ process.exit(1);
173
+ }
174
+ console.log("================================");
175
+ if (net)
176
+ net.free();
177
+ }
178
+ // Auto-run if executed directly via Node.js/tsx
179
+ if (typeof process !== "undefined" && import.meta.url.includes(process.argv[1].replace(/\\/g, '/'))) {
180
+ runVerify();
181
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * cabi_verify.ts
3
+ * TypeScript port of cabi_verify.html
4
+ */
5
+
6
+ import { loadLoomWASM } from "../src/loader.js";
7
+
8
+ const EXPECTED_SYMBOLS = [
9
+ 'createLoomNetwork', 'loadLoomNetwork',
10
+ 'compareLoomDNA',
11
+ 'getDefaultTargetPropConfig', 'defaultSpliceConfig', 'defaultNEATConfig',
12
+ 'createLoomNEATPopulation',
13
+ 'setupWebGPU',
14
+ ];
15
+
16
+ const EXPECTED_NET_METHODS = [
17
+ 'sequentialForward', 'extractDNA', 'extractBlueprint', 'getLayerCount',
18
+ 'getLayerSpec', 'morphLayer', 'spliceDNA', 'neatMutate',
19
+ 'createSystolicState', 'createTargetPropState', 'initGPU', 'syncToGPU',
20
+ 'syncToCPU', 'train', 'free', '_id',
21
+ ];
22
+
23
+ const EXPECTED_POP_METHODS = [
24
+ '_id', 'size', 'getNetwork', 'evolveWithFitnesses',
25
+ 'best', 'bestFitness', 'summary', 'free',
26
+ ];
27
+
28
+ const DENSE_3L = JSON.stringify({
29
+ depth: 3, rows: 1, cols: 1, layers_per_cell: 1,
30
+ layers: [
31
+ { z: 0, y: 0, x: 0, l: 0, type: "Dense", input_height: 16, output_height: 16, activation: "ReLU", dtype: "F32" },
32
+ { z: 1, y: 0, x: 0, l: 0, type: "Dense", input_height: 16, output_height: 16, activation: "ReLU", dtype: "F32" },
33
+ { z: 2, y: 0, x: 0, l: 0, type: "Dense", input_height: 16, output_height: 4, activation: "Linear", dtype: "F32" },
34
+ ]
35
+ });
36
+
37
+ const SWIGLU_NET = JSON.stringify({
38
+ depth: 2, rows: 1, cols: 1, layers_per_cell: 1,
39
+ layers: [
40
+ { z: 0, y: 0, x: 0, l: 0, type: "SwiGLU", input_height: 16, output_height: 32, dtype: "F32" },
41
+ { z: 1, y: 0, x: 0, l: 0, type: "Dense", input_height: 32, output_height: 4, activation: "Linear", dtype: "F32" },
42
+ ]
43
+ });
44
+
45
+ export async function runVerify() {
46
+ console.log("=== Loom WASM C-ABI Diagnostic Report ===");
47
+
48
+ // Decide which loader to use
49
+ if (typeof process !== "undefined" && process.versions && process.versions.node) {
50
+ const { loadLoomWASM } = await import("../src/loader.js");
51
+ await loadLoomWASM();
52
+ } else {
53
+ // @ts-ignore
54
+ const { loadLoomWASMBrowser } = await import("../src/loader.browser.js");
55
+ await loadLoomWASMBrowser();
56
+ }
57
+
58
+ let totalPass = 0;
59
+ let totalFail = 0;
60
+
61
+ // 1. Global symbol check
62
+ console.log("\n[1] Checking global WASM exports...");
63
+ for (const sym of EXPECTED_SYMBOLS) {
64
+ // @ts-ignore
65
+ if (typeof globalThis[sym] === 'function') {
66
+ console.log(` [PASS] ${sym}`);
67
+ totalPass++;
68
+ } else {
69
+ console.error(` [FAIL] ${sym} (missing)`);
70
+ totalFail++;
71
+ }
72
+ }
73
+
74
+ // 2. Network method check
75
+ console.log("\n[2] Checking network wrapper methods...");
76
+ let net: any = null;
77
+ try {
78
+ // @ts-ignore
79
+ net = globalThis.createLoomNetwork(DENSE_3L);
80
+ if (net) {
81
+ for (const m of EXPECTED_NET_METHODS) {
82
+ if (net[m] !== undefined) {
83
+ console.log(` [PASS] ${m}`);
84
+ totalPass++;
85
+ } else {
86
+ console.error(` [FAIL] ${m} (missing)`);
87
+ totalFail++;
88
+ }
89
+ }
90
+ }
91
+ } catch (e) {
92
+ console.error(" [FAIL] createLoomNetwork failed:", e);
93
+ totalFail++;
94
+ }
95
+
96
+ // 3. Population method check
97
+ if (net) {
98
+ console.log("\n[3] Checking NEAT population wrapper methods...");
99
+ try {
100
+ // @ts-ignore
101
+ const cfg = globalThis.defaultNEATConfig(16);
102
+ // @ts-ignore
103
+ const pop = globalThis.createLoomNEATPopulation(net._id, 4, cfg);
104
+ if (pop) {
105
+ for (const m of EXPECTED_POP_METHODS) {
106
+ if ((pop as any)[m] !== undefined) {
107
+ console.log(` [PASS] ${m}`);
108
+ totalPass++;
109
+ } else {
110
+ console.error(` [FAIL] ${m} (missing)`);
111
+ totalFail++;
112
+ }
113
+ }
114
+ pop.free();
115
+ }
116
+ } catch (e) {
117
+ console.error(" [FAIL] Population creation failed:", e);
118
+ totalFail++;
119
+ }
120
+ }
121
+
122
+ // 4. Functional smoke tests
123
+ console.log("\n[4] Running functional smoke tests...");
124
+
125
+ const smokeTest = (name: string, fn: () => any) => {
126
+ try {
127
+ const result = fn();
128
+ console.log(` [PASS] ${name}${result ? " → " + result : ""}`);
129
+ totalPass++;
130
+ } catch (e: any) {
131
+ console.error(` [FAIL] ${name} → ${e.message}`);
132
+ totalFail++;
133
+ }
134
+ };
135
+
136
+ smokeTest("sequentialForward", () => {
137
+ // @ts-ignore
138
+ const n = globalThis.createLoomNetwork(DENSE_3L);
139
+ const input = new Float32Array(16).fill(0.5);
140
+ const out = n.sequentialForward(input);
141
+ n.free();
142
+ if (!out || out.length === 0) throw new Error("empty output");
143
+ return "out[0]=" + out[0].toFixed(4);
144
+ });
145
+
146
+ smokeTest("extractDNA", () => {
147
+ // @ts-ignore
148
+ const n = globalThis.createLoomNetwork(DENSE_3L);
149
+ const dna = n.extractDNA();
150
+ n.free();
151
+ const parsed = JSON.parse(dna);
152
+ return "sigs=" + parsed.length;
153
+ });
154
+
155
+ smokeTest("compareLoomDNA", () => {
156
+ // @ts-ignore
157
+ const n1 = globalThis.createLoomNetwork(DENSE_3L);
158
+ // @ts-ignore
159
+ const n2 = globalThis.createLoomNetwork(DENSE_3L);
160
+ const dna1 = n1.extractDNA();
161
+ const dna2 = n2.extractDNA();
162
+ // @ts-ignore
163
+ const result = JSON.parse(globalThis.compareLoomDNA(dna1, dna2));
164
+ n1.free(); n2.free();
165
+ return "overlap=" + (result.overall_overlap || result.OverallOverlap || "?");
166
+ });
167
+
168
+ smokeTest("createLoomNetwork (SwiGLU)", () => {
169
+ // @ts-ignore
170
+ const n = globalThis.createLoomNetwork(SWIGLU_NET);
171
+ const c = n.getLayerCount();
172
+ n.free();
173
+ return "layers=" + c;
174
+ });
175
+
176
+ console.log("\n[5] Final Summary");
177
+ console.log("================================");
178
+ if (totalFail === 0) {
179
+ console.log(`SUCCESS: All ${totalPass} checks passed.`);
180
+ } else {
181
+ console.warn(`PARTIAL: ${totalPass} passed, ${totalFail} FAILED.`);
182
+ process.exit(1);
183
+ }
184
+ console.log("================================");
185
+
186
+ if (net) net.free();
187
+ }
188
+
189
+ // Auto-run if executed directly via Node.js/tsx
190
+ if (typeof process !== "undefined" && import.meta.url.includes(process.argv[1].replace(/\\/g, '/'))) {
191
+ runVerify();
192
+ }