@fraczak/k 7.0.1 → 7.0.2

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.
Files changed (53) hide show
  1. package/CHANGELOG.md +36 -0
  2. package/DOCS/BIG_PICTURE.md +5 -5
  3. package/DOCS/FILE_FORMATS.md +5 -5
  4. package/DOCS/OBJECT_FILE_AND_PATTERN.md +9 -9
  5. package/DOCS/PATTERNS.md +3 -3
  6. package/DOCS/PROFILING_AND_TRACING.md +60 -72
  7. package/DOCS/REPL.md +3 -3
  8. package/DOCS/book/03-types-as-finite-automata.md +4 -4
  9. package/DOCS/book/06-values-in-memory.md +9 -9
  10. package/DOCS/book/08-operational-semantics-and-execution.md +1 -1
  11. package/DOCS/book/09-compiler-architecture.md +2 -2
  12. package/DOCS/book/10-from-ast-to-intermediate-representation.md +2 -2
  13. package/DOCS/book/14-canonical-serialization.md +1 -1
  14. package/Examples/arithmetics.k +2 -2
  15. package/Examples/bnat.k +1 -1
  16. package/Examples/karatsuba-mult.k +2 -2
  17. package/README.md +3 -8
  18. package/backends/llvm/runtime/krt.c +33 -0
  19. package/backends/llvm/runtime/krt.h +1 -0
  20. package/backends/llvm/src/executable.mjs +4 -4
  21. package/backends/llvm/src/kvm2llvm.mjs +40 -18
  22. package/backends/llvm/src/llvm.mjs +12 -11
  23. package/backends/llvm/tests/perf-support.mjs +1 -55
  24. package/backends/llvm/tests/test-llvm.mjs +3 -3
  25. package/backends/wasm/src/wasm.mjs +2 -1
  26. package/backends/wasm/tests/test-wasm.mjs +5 -5
  27. package/browser/vfs-data.mjs +5 -5
  28. package/core.k +8 -8
  29. package/harness/format.mjs +2 -2
  30. package/harness/registry.mjs +0 -2
  31. package/kir.mjs +142 -56
  32. package/package.json +1 -5
  33. package/scripts/benchmark-idempotency.mjs +12 -8
  34. package/scripts/benchmark.mjs +5 -9
  35. package/scripts/build-repl-html.mjs +2 -2
  36. package/scripts/perf-ieee.mjs +17 -118
  37. package/scripts/perf-int.mjs +313 -318
  38. package/scripts/perf-multiplication.mjs +10 -20
  39. package/scripts/perf-poly.mjs +29 -183
  40. package/tests/code-derivation/pattern-envelope.mjs +4 -4
  41. package/tests/test-kvm-polymorphic.mjs +2 -2
  42. package/backends/arm64/README.md +0 -103
  43. package/backends/arm64/bin/k-arm64-compile.mjs +0 -93
  44. package/backends/arm64/bin/k-arm64-run.mjs +0 -58
  45. package/backends/arm64/bin/k-arm64.mjs +0 -88
  46. package/backends/arm64/scripts/run-tests.mjs +0 -57
  47. package/backends/arm64/src/arm64.mjs +0 -229
  48. package/backends/arm64/src/cli.mjs +0 -155
  49. package/backends/arm64/src/kvm2arm64.mjs +0 -906
  50. package/backends/arm64/src/runtime.c +0 -744
  51. package/backends/arm64/tests/integration.sh +0 -112
  52. package/backends/arm64/tests/test-arm64.mjs +0 -240
  53. package/harness/adapters/arm64.mjs +0 -105
@@ -11,21 +11,19 @@ import {
11
11
  evaluateInput,
12
12
  executeKVM,
13
13
  exportPatternGraph,
14
- parseFloat64,
15
14
  patternToPropertyList,
16
15
  propertyListToPattern,
17
16
  run,
18
17
  run_converged,
19
- valueForCode,
20
18
  Value
21
19
  } from "@fraczak/k/backend-api.mjs";
20
+ import { parse as parseFloatValue } from "@fraczak/k/codecs/ieee.mjs";
21
+ import { inputPatternForObjectRelation } from "../backends/llvm/src/executable.mjs";
22
22
 
23
23
  import {
24
24
  csvEnv,
25
25
  formatTiming,
26
26
  createLLVMRunner,
27
- createARM64Runner,
28
- arm64LaneName,
29
27
  llvmLaneName,
30
28
  makeCacheDir,
31
29
  parseNonNegativeIntEnv,
@@ -50,14 +48,13 @@ import {
50
48
  } from "../backends/wasm/tests/perf-support.mjs";
51
49
 
52
50
  import { compileWasmArtifactFromObject } from "../backends/wasm/src/wasm.mjs";
53
- import { compileARM64ArtifactFromObject } from "../backends/arm64/src/arm64.mjs";
54
51
 
55
52
  function printHelp() {
56
53
  console.log(`Usage: node scripts/perf-ieee.mjs [options]
57
54
 
58
55
  IEEE 754 Floating-Point Arithmetic Benchmark Harness.
59
56
  Benchmarks add, sub, mul, and div on Examples/ieee.k across
60
- Native JS, kVM interpreter, LLVM, Wasm, and ARM64 backends.
57
+ Native JS, kVM interpreter, LLVM, and Wasm backends.
61
58
 
62
59
  Options:
63
60
  --opt=<levels>, --opts=<levels>
@@ -73,13 +70,11 @@ Options:
73
70
 
74
71
  Environment Variables:
75
72
  BACKENDS
76
- Target backend to run: 'llvm', 'wasm', or 'arm64'.
73
+ Target backend to run: 'llvm' or 'wasm'.
77
74
  LLVM_ONLY
78
75
  Run only LLVM backend ('1' to enable).
79
76
  WASM_ONLY
80
77
  Run only WebAssembly backend ('1' to enable).
81
- ARM64_ONLY
82
- Run only ARM64 backend ('1' to enable).
83
78
  BACKENDS_ONLY
84
79
  Skip JS and kVM interpreter baselines ('1' to enable).
85
80
  VALUES
@@ -87,14 +82,6 @@ Environment Variables:
87
82
  (default: 0.5,-4,0,Infinity,-Infinity,NaN).
88
83
  ITERATIONS
89
84
  Measured iterations per benchmark (default: 3).
90
- ARM64_WARMUP_ITERATIONS
91
- Warmup iterations for ARM64 backend (default: 1).
92
- ARM64_OPT
93
- ARM64 backend optimization flags (default: -O2).
94
- ARM64_SPAWN_PER_CALL
95
- Spawn process per ARM64 call instead of persistent ('1' or '0').
96
- ARM64_PIPELINE
97
- Use persistent pipelined runner for ARM64 ('1' or '0').
98
85
  LLVM_WARMUP_ITERATIONS
99
86
  Warmup iterations for LLVM backend (default: 1).
100
87
  LLVM_SPAWN_PER_CALL
@@ -131,22 +118,14 @@ if (process.argv.includes("-h") || process.argv.includes("--help")) {
131
118
  const backendsEnv = process.env.BACKENDS?.toLowerCase();
132
119
  const llvmOnly = process.env.LLVM_ONLY === "1" || backendsEnv === "llvm";
133
120
  const wasmOnly = process.env.WASM_ONLY === "1" || backendsEnv === "wasm";
134
- const arm64Only = process.env.ARM64_ONLY === "1" || backendsEnv === "arm64";
135
-
136
- const isArm64Host = process.arch === "arm64" && process.platform === "linux";
137
- const runARM64 = !wasmOnly && !llvmOnly && (isArm64Host || arm64Only);
138
- const runLLVM = !wasmOnly && !arm64Only;
139
- const runWasm = !llvmOnly && !arm64Only;
140
- const runBaselines = !process.env.BACKENDS_ONLY && (process.env.LLVM_ONLY !== "1") && (process.env.WASM_ONLY !== "1") && (process.env.ARM64_ONLY !== "1");
121
+ const runLLVM = !wasmOnly;
122
+ const runWasm = !llvmOnly;
123
+ const runBaselines = !process.env.BACKENDS_ONLY && (process.env.LLVM_ONLY !== "1") && (process.env.WASM_ONLY !== "1");
141
124
 
142
125
  const ops = ["add", "sub", "mul", "div"];
143
126
  const values = csvEnv("VALUES", "0.5,-4,0,Infinity,-Infinity,NaN");
144
127
  const iterations = parsePositiveIntEnv("ITERATIONS", 3);
145
128
 
146
- // ARM64 options
147
- const arm64WarmupIterations = parseNonNegativeIntEnv("ARM64_WARMUP_ITERATIONS", 1);
148
- const arm64OptLevel = process.env.ARM64_OPT || "-O2";
149
-
150
129
  // LLVM options
151
130
  const llvmWarmupIterations = parseNonNegativeIntEnv("LLVM_WARMUP_ITERATIONS", 1);
152
131
  const llvmRuntimeMode = process.env.K_LLVM_IEEE_RUNTIME_MODE || "fast";
@@ -200,10 +179,7 @@ const ieeePath = fileURLToPath(import.meta.resolve("@fraczak/k/Examples/ieee.k")
200
179
  await evaluateInput(`:load ${ieeePath}`, state);
201
180
 
202
181
  function generatePerfK(values) {
203
- const paramFields = values.map((_, i) => ` float64 p${i}`).join(",\n");
204
- const lines = [
205
- `$params = {\n${paramFields}\n};`
206
- ];
182
+ const lines = [];
207
183
  for (const op of ops) {
208
184
  lines.push(`perf_${op} =`);
209
185
  lines.push(" {");
@@ -216,7 +192,7 @@ function generatePerfK(values) {
216
192
  lines.push(cases.join(",\n"));
217
193
  lines.push(" };");
218
194
  }
219
- lines.push("perf_ieee = ?params");
195
+ lines.push("perf_ieee =");
220
196
  lines.push(" {");
221
197
  lines.push(" perf_add add,");
222
198
  lines.push(" perf_sub sub,");
@@ -242,18 +218,16 @@ const relation = prepareRelation(state, "perf_ieee", {
242
218
  });
243
219
  codes.load(state.codes);
244
220
 
245
- const float64Hash = state.typeAliases.float64;
246
- function float64(text) {
247
- return valueForCode(parseFloat64(text), float64Hash, codes.find);
248
- }
249
-
250
221
  const paramsObj = {};
251
222
  for (let i = 0; i < values.length; i++) {
252
- paramsObj[`p${i}`] = float64(values[i]);
223
+ paramsObj[`p${i}`] = parseFloatValue(values[i]);
253
224
  }
254
- const rawProduct = Value.product(paramsObj);
255
- const inputVal = valueForCode(rawProduct, state.typeAliases.params, codes.find);
256
- const { inputWire, inputPattern } = wireInput(inputVal);
225
+ const inputVal = Value.product(paramsObj);
226
+ const inferredPattern = inputPatternForObjectRelation(
227
+ relation.object,
228
+ relation.relationName
229
+ );
230
+ const { inputWire, inputPattern } = wireInput(inputVal, inferredPattern);
257
231
 
258
232
  console.log("==> Computing expected results via Native JS");
259
233
  run_converged.defs = state;
@@ -327,39 +301,15 @@ if (runWasm) {
327
301
  const relDef = relation.relDef;
328
302
  const graph = relDef.typePatternGraph;
329
303
 
330
- const inputPatternNodeId = graph.find(relDef.def.patterns[0]);
331
- const inputPat = propertyListToPattern(patternToPropertyList(exportPatternGraph(graph, inputPatternNodeId)));
332
-
333
304
  const outputPatternNodeId = graph.find(relDef.def.patterns[1]);
334
305
  wasmOutputPatternPropertyList = patternToPropertyList(exportPatternGraph(graph, outputPatternNodeId));
335
306
  wasmOutputPattern = propertyListToPattern(wasmOutputPatternPropertyList);
336
307
 
337
- wasmPtrIn = writeValueToArena(wasmExports, inputVal, inputPat, 0);
308
+ wasmPtrIn = writeValueToArena(wasmExports, inputVal, propertyListToPattern(inputPattern), 0);
338
309
  wasmFuncName = cleanName(state.relAliases.perf_ieee);
339
310
  }
340
311
  }
341
312
 
342
- // Setup ARM64
343
- let arm64ExePath = null;
344
- let arm64CompileError = null;
345
-
346
- if (runARM64) {
347
- console.log(`==> Compiling Linux ARM64 executable (${arm64OptLevel})...`);
348
- try {
349
- arm64ExePath = path.join(cacheDir, "perf_ieee_arm64");
350
- compileARM64ArtifactFromObject(relation.object, {
351
- entry: "__main__",
352
- inputPattern,
353
- outputPath: arm64ExePath,
354
- optLevel: arm64OptLevel
355
- });
356
- } catch (error) {
357
- arm64CompileError = error.stack || error.message || String(error);
358
- console.log("Linux ARM64 compilation failed:");
359
- console.log(arm64CompileError.split("\n").slice(0, 8).join("\n"));
360
- }
361
- }
362
-
363
313
  function printBenchmarkDescription() {
364
314
  const lanes = [];
365
315
  if (runBaselines) {
@@ -374,7 +324,6 @@ function printBenchmarkDescription() {
374
324
  }
375
325
  }
376
326
  if (runWasm) lanes.push(wasmLaneName());
377
- if (runARM64) lanes.push(arm64LaneName(arm64OptLevel));
378
327
 
379
328
  console.log("==> Benchmark description");
380
329
  console.log(" source: @fraczak/k/Examples/ieee.k#perf_ieee (single program)");
@@ -394,11 +343,6 @@ function printBenchmarkDescription() {
394
343
  console.log(` wasm arena reset: ${wasmReset ? "yes" : "no"}`);
395
344
  }
396
345
  }
397
- if (runARM64) {
398
- console.log(` arm64 warmup iterations: ${arm64WarmupIterations}`);
399
- console.log(` arm64 opt level: ${arm64OptLevel}`);
400
- console.log(` arm64 runner mode: ${process.env.ARM64_SPAWN_PER_CALL === "1" ? "spawn per call" : "persistent"}`);
401
- }
402
346
  console.log(` iterations: ${iterations}`);
403
347
  console.log(` benchmark lanes: ${lanes.join("; ")}`);
404
348
  console.log(" conformance: all outputs are compared to native expected values");
@@ -501,27 +445,6 @@ if (runWasm) {
501
445
  }
502
446
  }
503
447
 
504
- // 4. Linux ARM64 lane
505
- let arm64Result = null;
506
- if (runARM64 && arm64ExePath) {
507
- const arm64Runner = createARM64Runner([{
508
- op: "perf_ieee",
509
- inputWire,
510
- arm64: { status: "ok", exePath: arm64ExePath }
511
- }]);
512
- try {
513
- if (arm64WarmupIterations > 0) {
514
- console.log(`==> Warming Linux ARM64 (${arm64WarmupIterations} iterations)...`);
515
- await arm64Runner.run(arm64WarmupIterations);
516
- }
517
-
518
- console.log(`==> Running Linux ARM64 (${iterations} iterations)...`);
519
- arm64Result = await arm64Runner.run(iterations);
520
- } finally {
521
- arm64Runner.close();
522
- }
523
- }
524
-
525
448
  console.log("\n=================== IEEE BENCHMARK RESULTS ===================");
526
449
  console.log(`Program calls per iteration: 1 (${totalOps} IEEE operations evaluated inside)`);
527
450
  console.log(`Total requested program calls: ${iterations} (${iterations * totalOps} equivalent IEEE operations)`);
@@ -544,10 +467,6 @@ if (runWasm) {
544
467
  const timingStr = wasmResult ? formatTiming(wasmResult) : "compile failed";
545
468
  console.log(`${laneIndex++}. ${wasmLaneName().padEnd(29)} ${timingStr}`);
546
469
  }
547
- if (runARM64) {
548
- const timingStr = arm64Result ? formatTiming(arm64Result) : "compile failed";
549
- console.log(`${laneIndex++}. ${arm64LaneName(arm64OptLevel).padEnd(29)} ${timingStr}`);
550
- }
551
470
  console.log("==============================================================\n");
552
471
 
553
472
  // Conformance Validation
@@ -621,22 +540,6 @@ if (runWasm) {
621
540
  }
622
541
  }
623
542
 
624
- let arm64Ok = false;
625
- if (runARM64) {
626
- if (!arm64ExePath) {
627
- console.log("Linux ARM64 conformance failure: executable was not compiled");
628
- } else {
629
- try {
630
- const outputWire = await runExecutable(arm64ExePath, inputWire);
631
- const actual = decodeWire(outputWire).value;
632
- assert.deepEqual(toPlainObject(actual), toPlainObject(expected));
633
- arm64Ok = true;
634
- } catch (error) {
635
- console.log("Linux ARM64 conformance failure:", error.message || error);
636
- }
637
- }
638
- }
639
-
640
543
  const validationSummary = [];
641
544
  if (runBaselines && kvmOk) validationSummary.push(`kVM (all ${totalOps} ops)`);
642
545
  if (runLLVM) {
@@ -649,9 +552,6 @@ if (runLLVM) {
649
552
  if (runWasm) {
650
553
  validationSummary.push(`Wasm (${wasmOk ? `all ${totalOps} ops` : "failed"})`);
651
554
  }
652
- if (runARM64) {
653
- validationSummary.push(`Linux ARM64 (${arm64Ok ? `all ${totalOps} ops` : "failed"})`);
654
- }
655
555
 
656
556
  console.log(`Conformance validation: ${validationSummary.join(", ")} match expected values.`);
657
557
  if (runLLVM) {
@@ -661,4 +561,3 @@ if (runLLVM) {
661
561
  }
662
562
  }
663
563
  if (runWasm && !wasmOk) process.exitCode = 1;
664
- if (runARM64 && !arm64Ok) process.exitCode = 1;