@fraczak/k 7.0.1 → 7.1.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.
- package/CHANGELOG.md +78 -0
- package/DOCS/BIG_PICTURE.md +5 -5
- package/DOCS/FILE_FORMATS.md +241 -18
- package/DOCS/OBJECT_FILE_AND_PATTERN.md +9 -9
- package/DOCS/PATTERNS.md +3 -3
- package/DOCS/POLYMORPHIC_IR.md +104 -0
- package/DOCS/PROFILING_AND_TRACING.md +60 -72
- package/DOCS/REPL.md +3 -3
- package/DOCS/book/03-types-as-finite-automata.md +4 -4
- package/DOCS/book/06-values-in-memory.md +9 -9
- package/DOCS/book/08-operational-semantics-and-execution.md +1 -1
- package/DOCS/book/09-compiler-architecture.md +2 -2
- package/DOCS/book/10-from-ast-to-intermediate-representation.md +2 -2
- package/DOCS/book/14-canonical-serialization.md +1 -1
- package/Examples/arithmetics.k +2 -2
- package/Examples/bnat.k +1 -1
- package/Examples/karatsuba-mult.k +2 -2
- package/JOURNAL.md +288 -0
- package/README.md +13 -10
- package/access-table.mjs +343 -0
- package/backend-api.mjs +18 -0
- package/backends/llvm/README.md +20 -21
- package/backends/llvm/bin/k-llvm-build.mjs +105 -32
- package/backends/llvm/bin/k-llvm-compile.mjs +63 -24
- package/backends/llvm/bin/k-llvm.mjs +292 -0
- package/backends/llvm/runtime/krt.c +41 -0
- package/backends/llvm/runtime/krt.h +2 -0
- package/backends/llvm/src/cli.mjs +95 -17
- package/backends/llvm/src/executable.mjs +132 -15
- package/backends/llvm/src/kvm2llvm.mjs +50 -23
- package/backends/llvm/src/llvm.mjs +133 -20
- package/backends/llvm/tests/integration.sh +11 -11
- package/backends/llvm/{bin → tests}/k-llvm-run.mjs +48 -22
- package/backends/llvm/tests/perf-support.mjs +25 -58
- package/backends/llvm/tests/test-llvm.mjs +25 -4
- package/backends/wasm/bin/k-wasm-compile.mjs +46 -20
- package/backends/wasm/bin/k-wasm-run.mjs +61 -20
- package/backends/wasm/bin/k-wasm.mjs +47 -13
- package/backends/wasm/src/cli.mjs +141 -19
- package/backends/wasm/src/wasm.mjs +132 -24
- package/backends/wasm/tests/test-wasm.mjs +5 -5
- package/browser/repl-browser.mjs +16 -5
- package/browser/vfs-data.mjs +5 -5
- package/codecs/k-parse.mjs +29 -8
- package/codecs/k-print.mjs +22 -6
- package/codecs/runtime/codec-sdk.mjs +8 -4
- package/codecs/show.mjs +20 -6
- package/core.k +8 -8
- package/harness/format.mjs +2 -2
- package/harness/registry.mjs +0 -2
- package/k.mjs +56 -16
- package/kir.mjs +200 -75
- package/kvm.mjs +49 -12
- package/objects/compile.mjs +37 -23
- package/objects/decompile.mjs +40 -10
- package/objects/extract-aliases.mjs +44 -14
- package/objects/inspect.mjs +19 -14
- package/objects/validate.mjs +18 -11
- package/package.json +10 -7
- package/pkir.mjs +772 -0
- package/repl.mjs +36 -18
- package/scripts/benchmark-idempotency.mjs +12 -8
- package/scripts/benchmark.mjs +5 -9
- package/scripts/build-repl-html.mjs +16 -4
- package/scripts/perf-ieee.mjs +253 -103
- package/scripts/perf-int.mjs +585 -297
- package/scripts/perf-multiplication.mjs +66 -25
- package/scripts/perf-poly.mjs +292 -164
- package/scripts/run-tests.mjs +3 -0
- package/tests/code-derivation/pattern-envelope.mjs +4 -4
- package/tests/test-access-table.mjs +213 -0
- package/tests/test-kvm-polymorphic.mjs +2 -2
- package/tests/test-pkir.mjs +530 -0
- package/tests/test-polymorphic-tdd.mjs +196 -0
- package/tests/test-repl-html.mjs +15 -2
- package/tests/test-repl.mjs +30 -1
- package/backends/arm64/README.md +0 -103
- package/backends/arm64/bin/k-arm64-compile.mjs +0 -93
- package/backends/arm64/bin/k-arm64-run.mjs +0 -58
- package/backends/arm64/bin/k-arm64.mjs +0 -88
- package/backends/arm64/scripts/run-tests.mjs +0 -57
- package/backends/arm64/src/arm64.mjs +0 -229
- package/backends/arm64/src/cli.mjs +0 -155
- package/backends/arm64/src/kvm2arm64.mjs +0 -906
- package/backends/arm64/src/runtime.c +0 -744
- package/backends/arm64/tests/integration.sh +0 -112
- package/backends/arm64/tests/test-arm64.mjs +0 -240
- package/backends/llvm/bin/k-llvm-jit.mjs +0 -160
- package/harness/adapters/arm64.mjs +0 -105
package/scripts/perf-ieee.mjs
CHANGED
|
@@ -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
|
|
57
|
+
Native JS, kVM interpreter, LLVM, Wasm, and PKIR backends.
|
|
61
58
|
|
|
62
59
|
Options:
|
|
63
60
|
--opt=<levels>, --opts=<levels>
|
|
@@ -68,18 +65,20 @@ Options:
|
|
|
68
65
|
Run full LLVM optimization sweep (-O0, -O1, -O2).
|
|
69
66
|
--wasm-in-process
|
|
70
67
|
Run WebAssembly in-process instead of persistent subprocess runner.
|
|
68
|
+
--pkir-only
|
|
69
|
+
Run only PKIR backend.
|
|
71
70
|
-h, --help
|
|
72
71
|
Show this help message and exit.
|
|
73
72
|
|
|
74
73
|
Environment Variables:
|
|
75
74
|
BACKENDS
|
|
76
|
-
Target backend to run: 'llvm', 'wasm', or '
|
|
75
|
+
Target backend to run: 'llvm', 'wasm', or 'pkir'.
|
|
77
76
|
LLVM_ONLY
|
|
78
77
|
Run only LLVM backend ('1' to enable).
|
|
79
78
|
WASM_ONLY
|
|
80
79
|
Run only WebAssembly backend ('1' to enable).
|
|
81
|
-
|
|
82
|
-
Run only
|
|
80
|
+
PKIR_ONLY
|
|
81
|
+
Run only PKIR backend ('1' to enable).
|
|
83
82
|
BACKENDS_ONLY
|
|
84
83
|
Skip JS and kVM interpreter baselines ('1' to enable).
|
|
85
84
|
VALUES
|
|
@@ -87,14 +86,6 @@ Environment Variables:
|
|
|
87
86
|
(default: 0.5,-4,0,Infinity,-Infinity,NaN).
|
|
88
87
|
ITERATIONS
|
|
89
88
|
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
89
|
LLVM_WARMUP_ITERATIONS
|
|
99
90
|
Warmup iterations for LLVM backend (default: 1).
|
|
100
91
|
LLVM_SPAWN_PER_CALL
|
|
@@ -129,24 +120,57 @@ if (process.argv.includes("-h") || process.argv.includes("--help")) {
|
|
|
129
120
|
|
|
130
121
|
// Backend selection
|
|
131
122
|
const backendsEnv = process.env.BACKENDS?.toLowerCase();
|
|
132
|
-
const
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
const
|
|
140
|
-
|
|
123
|
+
const backendsList = backendsEnv
|
|
124
|
+
? backendsEnv.split(",").map(s => s.trim())
|
|
125
|
+
: null;
|
|
126
|
+
const llvmPkirOnly = process.env.LLVM_PKIR_ONLY === "1"
|
|
127
|
+
|| (backendsList && backendsList.length === 1 &&
|
|
128
|
+
backendsList[0] === "llvm-pkir")
|
|
129
|
+
|| process.argv.includes("--llvm-pkir-only");
|
|
130
|
+
const pkirOnly = !llvmPkirOnly && (
|
|
131
|
+
process.env.PKIR_ONLY === "1"
|
|
132
|
+
|| (backendsList && backendsList.length === 1 &&
|
|
133
|
+
backendsList[0] === "pkir")
|
|
134
|
+
|| process.argv.includes("--pkir-only")
|
|
135
|
+
);
|
|
136
|
+
const llvmOnly = !pkirOnly && !llvmPkirOnly && (
|
|
137
|
+
process.env.LLVM_ONLY === "1"
|
|
138
|
+
|| (backendsList && backendsList.length === 1 &&
|
|
139
|
+
backendsList[0] === "llvm")
|
|
140
|
+
);
|
|
141
|
+
const wasmOnly = !pkirOnly && !llvmPkirOnly && !llvmOnly && (
|
|
142
|
+
process.env.WASM_ONLY === "1"
|
|
143
|
+
|| (backendsList && backendsList.length === 1 &&
|
|
144
|
+
backendsList[0] === "wasm")
|
|
145
|
+
);
|
|
146
|
+
const runLLVM = backendsList
|
|
147
|
+
? backendsList.includes("llvm")
|
|
148
|
+
: !wasmOnly && !pkirOnly && !llvmPkirOnly;
|
|
149
|
+
const runLLVMPKIR = backendsList
|
|
150
|
+
? backendsList.includes("llvm-pkir")
|
|
151
|
+
: !wasmOnly && !pkirOnly && !llvmOnly;
|
|
152
|
+
const runWasm = backendsList
|
|
153
|
+
? backendsList.includes("wasm")
|
|
154
|
+
: !llvmOnly && !pkirOnly && !llvmPkirOnly;
|
|
155
|
+
const runPKIR = backendsList
|
|
156
|
+
? backendsList.includes("pkir")
|
|
157
|
+
: !llvmOnly && !wasmOnly && !llvmPkirOnly;
|
|
158
|
+
const runBaselines = !process.env.BACKENDS_ONLY
|
|
159
|
+
&& (backendsList == null || backendsList.includes("kvm") ||
|
|
160
|
+
backendsList.includes("js"))
|
|
161
|
+
&& !llvmOnly && !wasmOnly && !pkirOnly && !llvmPkirOnly;
|
|
162
|
+
|
|
163
|
+
function llvmLaneNameStr() {
|
|
164
|
+
return llvmLaneName();
|
|
165
|
+
}
|
|
166
|
+
function llvmPkirLaneNameStr() {
|
|
167
|
+
return llvmLaneName().replace("LLVM", "LLVM-PKIR");
|
|
168
|
+
}
|
|
141
169
|
|
|
142
170
|
const ops = ["add", "sub", "mul", "div"];
|
|
143
171
|
const values = csvEnv("VALUES", "0.5,-4,0,Infinity,-Infinity,NaN");
|
|
144
172
|
const iterations = parsePositiveIntEnv("ITERATIONS", 3);
|
|
145
173
|
|
|
146
|
-
// ARM64 options
|
|
147
|
-
const arm64WarmupIterations = parseNonNegativeIntEnv("ARM64_WARMUP_ITERATIONS", 1);
|
|
148
|
-
const arm64OptLevel = process.env.ARM64_OPT || "-O2";
|
|
149
|
-
|
|
150
174
|
// LLVM options
|
|
151
175
|
const llvmWarmupIterations = parseNonNegativeIntEnv("LLVM_WARMUP_ITERATIONS", 1);
|
|
152
176
|
const llvmRuntimeMode = process.env.K_LLVM_IEEE_RUNTIME_MODE || "fast";
|
|
@@ -193,6 +217,9 @@ function wasmLaneName() {
|
|
|
193
217
|
const mode = wasmPipe ? "persistent" : "in-process";
|
|
194
218
|
return `WebAssembly (${mode})`;
|
|
195
219
|
}
|
|
220
|
+
function pkirLaneName() {
|
|
221
|
+
return "PKIR (Wasm persistent)";
|
|
222
|
+
}
|
|
196
223
|
|
|
197
224
|
console.log("==> Initializing state and loading @fraczak/k/Examples/ieee.k");
|
|
198
225
|
const state = createState();
|
|
@@ -200,10 +227,7 @@ const ieeePath = fileURLToPath(import.meta.resolve("@fraczak/k/Examples/ieee.k")
|
|
|
200
227
|
await evaluateInput(`:load ${ieeePath}`, state);
|
|
201
228
|
|
|
202
229
|
function generatePerfK(values) {
|
|
203
|
-
const
|
|
204
|
-
const lines = [
|
|
205
|
-
`$params = {\n${paramFields}\n};`
|
|
206
|
-
];
|
|
230
|
+
const lines = [];
|
|
207
231
|
for (const op of ops) {
|
|
208
232
|
lines.push(`perf_${op} =`);
|
|
209
233
|
lines.push(" {");
|
|
@@ -216,7 +240,7 @@ function generatePerfK(values) {
|
|
|
216
240
|
lines.push(cases.join(",\n"));
|
|
217
241
|
lines.push(" };");
|
|
218
242
|
}
|
|
219
|
-
lines.push("perf_ieee =
|
|
243
|
+
lines.push("perf_ieee =");
|
|
220
244
|
lines.push(" {");
|
|
221
245
|
lines.push(" perf_add add,");
|
|
222
246
|
lines.push(" perf_sub sub,");
|
|
@@ -230,7 +254,8 @@ const perfKSource = generatePerfK(values);
|
|
|
230
254
|
await evaluateInput(perfKSource, state);
|
|
231
255
|
|
|
232
256
|
const ieeeRaw = fs.readFileSync(ieeePath, "utf8");
|
|
233
|
-
// Exclude trailing unassigned expression and comment block to ensure
|
|
257
|
+
// Exclude trailing unassigned expression and comment block to ensure
|
|
258
|
+
// clean parse.
|
|
234
259
|
const endIdx = ieeeRaw.indexOf("\n()\n");
|
|
235
260
|
const ieeeBase = endIdx !== -1 ? ieeeRaw.slice(0, endIdx) : ieeeRaw;
|
|
236
261
|
const fullSource = `${ieeeBase}\n${perfKSource}\nperf_ieee`;
|
|
@@ -242,18 +267,16 @@ const relation = prepareRelation(state, "perf_ieee", {
|
|
|
242
267
|
});
|
|
243
268
|
codes.load(state.codes);
|
|
244
269
|
|
|
245
|
-
const float64Hash = state.typeAliases.float64;
|
|
246
|
-
function float64(text) {
|
|
247
|
-
return valueForCode(parseFloat64(text), float64Hash, codes.find);
|
|
248
|
-
}
|
|
249
|
-
|
|
250
270
|
const paramsObj = {};
|
|
251
271
|
for (let i = 0; i < values.length; i++) {
|
|
252
|
-
paramsObj[`p${i}`] =
|
|
272
|
+
paramsObj[`p${i}`] = parseFloatValue(values[i]);
|
|
253
273
|
}
|
|
254
|
-
const
|
|
255
|
-
const
|
|
256
|
-
|
|
274
|
+
const inputVal = Value.product(paramsObj);
|
|
275
|
+
const inferredPattern = inputPatternForObjectRelation(
|
|
276
|
+
relation.object,
|
|
277
|
+
relation.relationName
|
|
278
|
+
);
|
|
279
|
+
const { inputWire, inputPattern } = wireInput(inputVal, inferredPattern);
|
|
257
280
|
|
|
258
281
|
console.log("==> Computing expected results via Native JS");
|
|
259
282
|
run_converged.defs = state;
|
|
@@ -275,7 +298,8 @@ if (runLLVM) {
|
|
|
275
298
|
cacheDir,
|
|
276
299
|
sourceLabel: "@fraczak/k/Examples/ieee.k#perf_ieee",
|
|
277
300
|
runtimeMode: llvmRuntimeMode,
|
|
278
|
-
clangOpt: opt
|
|
301
|
+
clangOpt: opt,
|
|
302
|
+
usePKIR: false
|
|
279
303
|
});
|
|
280
304
|
const singleCase = [{
|
|
281
305
|
op: "perf_ieee",
|
|
@@ -292,6 +316,37 @@ if (runLLVM) {
|
|
|
292
316
|
codes.load(state.codes);
|
|
293
317
|
}
|
|
294
318
|
|
|
319
|
+
// Setup LLVM-PKIR
|
|
320
|
+
const llvmPkirCasesByOpt = new Map();
|
|
321
|
+
if (runLLVMPKIR) {
|
|
322
|
+
for (const opt of llvmOptLevels) {
|
|
323
|
+
console.log(`==> Compiling LLVM-PKIR executable (${opt})...`);
|
|
324
|
+
const llvm = tryCompileCase({
|
|
325
|
+
object: relation.object,
|
|
326
|
+
relationName: relation.relationName,
|
|
327
|
+
relHash: relation.relHash,
|
|
328
|
+
inputPattern,
|
|
329
|
+
cacheDir,
|
|
330
|
+
sourceLabel: "@fraczak/k/Examples/ieee.k#perf_ieee",
|
|
331
|
+
runtimeMode: llvmRuntimeMode,
|
|
332
|
+
clangOpt: opt,
|
|
333
|
+
usePKIR: true
|
|
334
|
+
});
|
|
335
|
+
const singleCase = [{
|
|
336
|
+
op: "perf_ieee",
|
|
337
|
+
label: "params",
|
|
338
|
+
inputVal,
|
|
339
|
+
inputWire,
|
|
340
|
+
inputPattern,
|
|
341
|
+
expected,
|
|
342
|
+
llvm
|
|
343
|
+
}];
|
|
344
|
+
llvmPkirCasesByOpt.set(opt, singleCase);
|
|
345
|
+
printCompileFailures(singleCase);
|
|
346
|
+
}
|
|
347
|
+
codes.load(state.codes);
|
|
348
|
+
}
|
|
349
|
+
|
|
295
350
|
// Setup Wasm
|
|
296
351
|
let wasmExports = null;
|
|
297
352
|
let wasmPtrIn = null;
|
|
@@ -327,36 +382,34 @@ if (runWasm) {
|
|
|
327
382
|
const relDef = relation.relDef;
|
|
328
383
|
const graph = relDef.typePatternGraph;
|
|
329
384
|
|
|
330
|
-
const inputPatternNodeId = graph.find(relDef.def.patterns[0]);
|
|
331
|
-
const inputPat = propertyListToPattern(patternToPropertyList(exportPatternGraph(graph, inputPatternNodeId)));
|
|
332
|
-
|
|
333
385
|
const outputPatternNodeId = graph.find(relDef.def.patterns[1]);
|
|
334
386
|
wasmOutputPatternPropertyList = patternToPropertyList(exportPatternGraph(graph, outputPatternNodeId));
|
|
335
387
|
wasmOutputPattern = propertyListToPattern(wasmOutputPatternPropertyList);
|
|
336
388
|
|
|
337
|
-
wasmPtrIn = writeValueToArena(wasmExports, inputVal,
|
|
389
|
+
wasmPtrIn = writeValueToArena(wasmExports, inputVal, propertyListToPattern(inputPattern), 0);
|
|
338
390
|
wasmFuncName = cleanName(state.relAliases.perf_ieee);
|
|
339
391
|
}
|
|
340
392
|
}
|
|
341
393
|
|
|
342
|
-
// Setup
|
|
343
|
-
let
|
|
344
|
-
let
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
console.log(`==> Compiling Linux ARM64 executable (${arm64OptLevel})...`);
|
|
394
|
+
// Setup PKIR
|
|
395
|
+
let pkirExePath = null;
|
|
396
|
+
let pkirCompileError = null;
|
|
397
|
+
if (runPKIR) {
|
|
398
|
+
console.log("==> Compiling PKIR executable (persistent runner)...");
|
|
348
399
|
try {
|
|
349
|
-
|
|
350
|
-
|
|
400
|
+
const pkirPath = path.join(cacheDir, "perf_ieee_pkir.wasm");
|
|
401
|
+
pkirExePath = path.join(cacheDir, "perf_ieee_pkir.exe");
|
|
402
|
+
const wasmBuf = await compileWasmArtifactFromObject(relation.object, {
|
|
351
403
|
entry: "__main__",
|
|
352
|
-
|
|
353
|
-
outputPath: arm64ExePath,
|
|
354
|
-
optLevel: arm64OptLevel
|
|
404
|
+
usePKIR: true
|
|
355
405
|
});
|
|
406
|
+
fs.writeFileSync(pkirPath, wasmBuf);
|
|
407
|
+
const runBin = fileURLToPath(import.meta.resolve("../backends/wasm/bin/k-wasm-run.mjs"));
|
|
408
|
+
fs.writeFileSync(pkirExePath, `#!/bin/sh\nexec node "${runBin}" "${pkirPath}" "$@"\n`, { mode: 0o755 });
|
|
356
409
|
} catch (error) {
|
|
357
|
-
|
|
358
|
-
console.log("
|
|
359
|
-
console.log(
|
|
410
|
+
pkirCompileError = error.stack || error.message || String(error);
|
|
411
|
+
console.log("PKIR compilation failed:");
|
|
412
|
+
console.log(pkirCompileError.split("\n").slice(0, 8).join("\n"));
|
|
360
413
|
}
|
|
361
414
|
}
|
|
362
415
|
|
|
@@ -369,12 +422,28 @@ function printBenchmarkDescription() {
|
|
|
369
422
|
}
|
|
370
423
|
if (runLLVM) {
|
|
371
424
|
for (const opt of llvmOptLevels) {
|
|
372
|
-
const mode = llvmLaneName()
|
|
373
|
-
|
|
425
|
+
const mode = llvmLaneName()
|
|
426
|
+
.replace(/^LLVM Executable\s*\((.*)\)$/, "$1");
|
|
427
|
+
lanes.push(
|
|
428
|
+
llvmOptLevels.length > 1
|
|
429
|
+
? `LLVM ${opt} (${mode})`
|
|
430
|
+
: llvmLaneName()
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (runLLVMPKIR) {
|
|
435
|
+
for (const opt of llvmOptLevels) {
|
|
436
|
+
const mode = llvmLaneName()
|
|
437
|
+
.replace(/^LLVM Executable\s*\((.*)\)$/, "$1");
|
|
438
|
+
lanes.push(
|
|
439
|
+
llvmOptLevels.length > 1
|
|
440
|
+
? `LLVM-PKIR ${opt} (${mode})`
|
|
441
|
+
: llvmLaneName().replace("LLVM", "LLVM-PKIR")
|
|
442
|
+
);
|
|
374
443
|
}
|
|
375
444
|
}
|
|
376
445
|
if (runWasm) lanes.push(wasmLaneName());
|
|
377
|
-
if (
|
|
446
|
+
if (runPKIR) lanes.push(pkirLaneName());
|
|
378
447
|
|
|
379
448
|
console.log("==> Benchmark description");
|
|
380
449
|
console.log(" source: @fraczak/k/Examples/ieee.k#perf_ieee (single program)");
|
|
@@ -387,6 +456,11 @@ function printBenchmarkDescription() {
|
|
|
387
456
|
console.log(` llvm clang opts: ${llvmOptLevels.join(", ")}`);
|
|
388
457
|
console.log(` llvm cache dir: ${cacheDir}`);
|
|
389
458
|
}
|
|
459
|
+
if (runLLVMPKIR) {
|
|
460
|
+
console.log(` llvm-pkir warmup iterations: ${llvmWarmupIterations}`);
|
|
461
|
+
console.log(` llvm-pkir runtime mode: ${llvmRuntimeMode}`);
|
|
462
|
+
console.log(` llvm-pkir clang opts: ${llvmOptLevels.join(", ")}`);
|
|
463
|
+
}
|
|
390
464
|
if (runWasm) {
|
|
391
465
|
console.log(` wasm runner mode: ${wasmPipe ? "persistent pipe" : "in-process"}`);
|
|
392
466
|
console.log(` wasm warmup iterations: ${wasmWarmupIterations}`);
|
|
@@ -394,10 +468,8 @@ function printBenchmarkDescription() {
|
|
|
394
468
|
console.log(` wasm arena reset: ${wasmReset ? "yes" : "no"}`);
|
|
395
469
|
}
|
|
396
470
|
}
|
|
397
|
-
if (
|
|
398
|
-
console.log(`
|
|
399
|
-
console.log(` arm64 opt level: ${arm64OptLevel}`);
|
|
400
|
-
console.log(` arm64 runner mode: ${process.env.ARM64_SPAWN_PER_CALL === "1" ? "spawn per call" : "persistent"}`);
|
|
471
|
+
if (runPKIR) {
|
|
472
|
+
console.log(` pkir warmup iterations: ${wasmWarmupIterations}`);
|
|
401
473
|
}
|
|
402
474
|
console.log(` iterations: ${iterations}`);
|
|
403
475
|
console.log(` benchmark lanes: ${lanes.join("; ")}`);
|
|
@@ -459,6 +531,28 @@ if (runLLVM) {
|
|
|
459
531
|
}
|
|
460
532
|
}
|
|
461
533
|
|
|
534
|
+
// 2b. LLVM-PKIR lanes
|
|
535
|
+
const llvmPkirResults = new Map();
|
|
536
|
+
if (runLLVMPKIR) {
|
|
537
|
+
for (const opt of llvmOptLevels) {
|
|
538
|
+
const casesForOpt = llvmPkirCasesByOpt.get(opt);
|
|
539
|
+
const llvmRunner = createLLVMRunner(casesForOpt);
|
|
540
|
+
try {
|
|
541
|
+
if (llvmWarmupIterations > 0) {
|
|
542
|
+
console.log(`==> Warming LLVM-PKIR (${opt}) executable (${llvmWarmupIterations} iterations)...`);
|
|
543
|
+
await llvmRunner.run(llvmWarmupIterations);
|
|
544
|
+
}
|
|
545
|
+
console.log(`==> Running LLVM-PKIR (${opt}) (${iterations} iterations)...`);
|
|
546
|
+
const result = await llvmRunner.run(iterations);
|
|
547
|
+
llvmPkirResults.set(opt, result);
|
|
548
|
+
} catch (err) {
|
|
549
|
+
console.log(`==> LLVM-PKIR (${opt}) execution failed: ${err.message?.split("\n")[0]}`);
|
|
550
|
+
} finally {
|
|
551
|
+
llvmRunner.close();
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
|
|
462
556
|
// 3. Wasm lane
|
|
463
557
|
let wasmResult = null;
|
|
464
558
|
if (runWasm) {
|
|
@@ -501,24 +595,25 @@ if (runWasm) {
|
|
|
501
595
|
}
|
|
502
596
|
}
|
|
503
597
|
|
|
504
|
-
// 4.
|
|
505
|
-
let
|
|
506
|
-
if (
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
598
|
+
// 4. PKIR lane
|
|
599
|
+
let pkirResult = null;
|
|
600
|
+
if (runPKIR) {
|
|
601
|
+
if (pkirExePath) {
|
|
602
|
+
const server = new PersistentExecutable(pkirExePath);
|
|
603
|
+
try {
|
|
604
|
+
if (wasmWarmupIterations > 0) {
|
|
605
|
+
console.log(`==> Warming PKIR (${wasmWarmupIterations} iterations)...`);
|
|
606
|
+
for (let i = 0; i < wasmWarmupIterations; i++) {
|
|
607
|
+
await server.request(inputWire);
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
console.log(`==> Running PKIR (${iterations} iterations)...`);
|
|
611
|
+
pkirResult = await runTimedIterationsAsync(iterations, async () => {
|
|
612
|
+
await server.request(inputWire);
|
|
613
|
+
});
|
|
614
|
+
} finally {
|
|
615
|
+
server.close();
|
|
516
616
|
}
|
|
517
|
-
|
|
518
|
-
console.log(`==> Running Linux ARM64 (${iterations} iterations)...`);
|
|
519
|
-
arm64Result = await arm64Runner.run(iterations);
|
|
520
|
-
} finally {
|
|
521
|
-
arm64Runner.close();
|
|
522
617
|
}
|
|
523
618
|
}
|
|
524
619
|
|
|
@@ -534,19 +629,37 @@ if (runBaselines) {
|
|
|
534
629
|
}
|
|
535
630
|
if (runLLVM) {
|
|
536
631
|
for (const opt of llvmOptLevels) {
|
|
632
|
+
const mode = llvmLaneName()
|
|
633
|
+
.replace(/^LLVM Executable\s*\((.*)\)$/, "$1");
|
|
537
634
|
const title = llvmOptLevels.length > 1
|
|
538
|
-
? `LLVM ${opt} (${
|
|
635
|
+
? `LLVM ${opt} (${mode})`
|
|
539
636
|
: llvmLaneName();
|
|
540
|
-
console.log(
|
|
637
|
+
console.log(
|
|
638
|
+
`${laneIndex++}. ${title.padEnd(29)} ` +
|
|
639
|
+
`${formatTiming(llvmResults.get(opt))}`
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
if (runLLVMPKIR) {
|
|
644
|
+
for (const opt of llvmOptLevels) {
|
|
645
|
+
const mode = llvmLaneName()
|
|
646
|
+
.replace(/^LLVM Executable\s*\((.*)\)$/, "$1");
|
|
647
|
+
const title = llvmOptLevels.length > 1
|
|
648
|
+
? `LLVM-PKIR ${opt} (${mode})`
|
|
649
|
+
: llvmLaneName().replace("LLVM", "LLVM-PKIR");
|
|
650
|
+
console.log(
|
|
651
|
+
`${laneIndex++}. ${title.padEnd(29)} ` +
|
|
652
|
+
`${formatTiming(llvmPkirResults.get(opt))}`
|
|
653
|
+
);
|
|
541
654
|
}
|
|
542
655
|
}
|
|
543
656
|
if (runWasm) {
|
|
544
657
|
const timingStr = wasmResult ? formatTiming(wasmResult) : "compile failed";
|
|
545
658
|
console.log(`${laneIndex++}. ${wasmLaneName().padEnd(29)} ${timingStr}`);
|
|
546
659
|
}
|
|
547
|
-
if (
|
|
548
|
-
const timingStr =
|
|
549
|
-
console.log(`${laneIndex++}. ${
|
|
660
|
+
if (runPKIR) {
|
|
661
|
+
const timingStr = pkirResult ? formatTiming(pkirResult) : "compile failed";
|
|
662
|
+
console.log(`${laneIndex++}. ${pkirLaneName().padEnd(29)} ${timingStr}`);
|
|
550
663
|
}
|
|
551
664
|
console.log("==============================================================\n");
|
|
552
665
|
|
|
@@ -585,6 +698,28 @@ if (runLLVM) {
|
|
|
585
698
|
}
|
|
586
699
|
}
|
|
587
700
|
|
|
701
|
+
if (runLLVMPKIR) {
|
|
702
|
+
for (const opt of llvmOptLevels) {
|
|
703
|
+
const casesForOpt = llvmPkirCasesByOpt.get(opt);
|
|
704
|
+
const tc = casesForOpt[0];
|
|
705
|
+
if (tc.llvm.status !== "ok") {
|
|
706
|
+
tc.llvmConformance = "compile-failed";
|
|
707
|
+
} else {
|
|
708
|
+
try {
|
|
709
|
+
const outputWire = await runExecutable(tc.llvm.exePath, tc.inputWire);
|
|
710
|
+
const actual = decodeWire(outputWire).value;
|
|
711
|
+
assert.deepEqual(toPlainObject(actual), toPlainObject(expected));
|
|
712
|
+
tc.llvmConformance = "ok";
|
|
713
|
+
} catch (error) {
|
|
714
|
+
tc.llvmConformance = "failed";
|
|
715
|
+
tc.llvm.error = error.stack || error.message || String(error);
|
|
716
|
+
console.log(`LLVM-PKIR (${opt}) conformance failure:`);
|
|
717
|
+
console.log(tc.llvm.error.split("\n").slice(0, 8).join("\n"));
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
588
723
|
let wasmOk = false;
|
|
589
724
|
if (runWasm) {
|
|
590
725
|
if (wasmPipe) {
|
|
@@ -621,18 +756,18 @@ if (runWasm) {
|
|
|
621
756
|
}
|
|
622
757
|
}
|
|
623
758
|
|
|
624
|
-
let
|
|
625
|
-
if (
|
|
626
|
-
if (!
|
|
627
|
-
console.log("
|
|
759
|
+
let pkirOk = false;
|
|
760
|
+
if (runPKIR) {
|
|
761
|
+
if (!pkirExePath) {
|
|
762
|
+
console.log("PKIR conformance failure: executable was not compiled");
|
|
628
763
|
} else {
|
|
629
764
|
try {
|
|
630
|
-
const outputWire = await runExecutable(
|
|
765
|
+
const outputWire = await runExecutable(pkirExePath, inputWire);
|
|
631
766
|
const actual = decodeWire(outputWire).value;
|
|
632
767
|
assert.deepEqual(toPlainObject(actual), toPlainObject(expected));
|
|
633
|
-
|
|
768
|
+
pkirOk = true;
|
|
634
769
|
} catch (error) {
|
|
635
|
-
console.log("
|
|
770
|
+
console.log("PKIR conformance failure:", error.message || error);
|
|
636
771
|
}
|
|
637
772
|
}
|
|
638
773
|
}
|
|
@@ -646,11 +781,20 @@ if (runLLVM) {
|
|
|
646
781
|
validationSummary.push(`LLVM ${opt} (${tc.llvmConformance === "ok" ? `all ${totalOps} ops` : tc.llvmConformance})`);
|
|
647
782
|
}
|
|
648
783
|
}
|
|
784
|
+
if (runLLVMPKIR) {
|
|
785
|
+
for (const opt of llvmOptLevels) {
|
|
786
|
+
const casesForOpt = llvmPkirCasesByOpt.get(opt);
|
|
787
|
+
const tc = casesForOpt[0];
|
|
788
|
+
validationSummary.push(
|
|
789
|
+
`LLVM-PKIR ${opt} (${tc.llvmConformance === "ok" ? `all ${totalOps} ops` : tc.llvmConformance})`
|
|
790
|
+
);
|
|
791
|
+
}
|
|
792
|
+
}
|
|
649
793
|
if (runWasm) {
|
|
650
794
|
validationSummary.push(`Wasm (${wasmOk ? `all ${totalOps} ops` : "failed"})`);
|
|
651
795
|
}
|
|
652
|
-
if (
|
|
653
|
-
validationSummary.push(`
|
|
796
|
+
if (runPKIR) {
|
|
797
|
+
validationSummary.push(`PKIR (${pkirOk ? `all ${totalOps} ops` : "failed"})`);
|
|
654
798
|
}
|
|
655
799
|
|
|
656
800
|
console.log(`Conformance validation: ${validationSummary.join(", ")} match expected values.`);
|
|
@@ -660,5 +804,11 @@ if (runLLVM) {
|
|
|
660
804
|
if (shouldStrictFail(casesForOpt)) process.exitCode = 1;
|
|
661
805
|
}
|
|
662
806
|
}
|
|
807
|
+
if (runLLVMPKIR) {
|
|
808
|
+
for (const opt of llvmOptLevels) {
|
|
809
|
+
const casesForOpt = llvmPkirCasesByOpt.get(opt);
|
|
810
|
+
if (shouldStrictFail(casesForOpt)) process.exitCode = 1;
|
|
811
|
+
}
|
|
812
|
+
}
|
|
663
813
|
if (runWasm && !wasmOk) process.exitCode = 1;
|
|
664
|
-
if (
|
|
814
|
+
if (runPKIR && !pkirOk) process.exitCode = 1;
|