@aethervtt/shard-core 0.1.0 → 0.2.1
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/dist/scheduler/capture/capture.d.ts +192 -0
- package/dist/scheduler/capture/capture.js +410 -0
- package/dist/scheduler/capture/index.d.ts +3 -0
- package/dist/scheduler/capture/index.js +17 -0
- package/dist/scheduler/capture/recorder.d.ts +83 -0
- package/dist/scheduler/capture/recorder.js +224 -0
- package/dist/scheduler/capture/samples.d.ts +49 -0
- package/dist/scheduler/capture/samples.js +91 -0
- package/dist/scheduler/index.d.ts +3 -1
- package/dist/scheduler/index.js +29 -2
- package/dist/scheduler/profiler.d.ts +180 -5
- package/dist/scheduler/profiler.js +430 -17
- package/dist/scheduler/schedule.d.ts +5 -1
- package/dist/scheduler/schedule.js +33 -3
- package/dist/test-env.d.ts +95 -1
- package/dist/test-env.js +70 -2
- package/package.json +6 -2
package/dist/test-env.js
CHANGED
|
@@ -1,8 +1,73 @@
|
|
|
1
|
+
import { ShardError } from "./error.js";
|
|
1
2
|
const env = globalThis.process?.env ?? {};
|
|
2
3
|
const timingMode = env.SHARD_BENCH ? "bench" : env.SHARD_CI ? "ci" : "test";
|
|
3
4
|
const slack = timingMode === "bench" ? 1 : Number.POSITIVE_INFINITY;
|
|
4
|
-
function
|
|
5
|
-
return
|
|
5
|
+
function unknownBudget(key, detail = "") {
|
|
6
|
+
return new ShardError("perf/unknown-budget", `No budget "${key}"${detail} in budgets.json`, {
|
|
7
|
+
path: key,
|
|
8
|
+
hint: "Add it to bench/perf/budgets.json with a number for every machine and a note."
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
function resolveLimit(budgets2, key, opts = {}, enforce = true) {
|
|
12
|
+
if (!budgets2) {
|
|
13
|
+
if (enforce) {
|
|
14
|
+
throw new ShardError("perf/no-budgets", `No budgets to resolve "${key}" against`, {
|
|
15
|
+
hint: "pnpm bench passes them in SHARD_BUDGETS; run tests through it or through testFiles()."
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return { limit: Number.POSITIVE_INFINITY, reference: null, kind: "target" };
|
|
19
|
+
}
|
|
20
|
+
const on = enforce && budgets2.enforce;
|
|
21
|
+
const span = budgets2.spans[key];
|
|
22
|
+
if (span) {
|
|
23
|
+
let reference2 = span.value;
|
|
24
|
+
if (reference2 !== null && span.kind === "unit") reference2 *= opts.count ?? 1;
|
|
25
|
+
if (reference2 !== null && span.kind === "guard") reference2 *= 1 + (span.margin ?? 0);
|
|
26
|
+
const off = span.kind === "rate" ? 0 : Number.POSITIVE_INFINITY;
|
|
27
|
+
return { limit: on && reference2 !== null ? reference2 : off, reference: reference2, kind: span.kind };
|
|
28
|
+
}
|
|
29
|
+
const scenario = budgets2.scenarios[key];
|
|
30
|
+
if (!scenario) throw unknownBudget(key);
|
|
31
|
+
const track = opts.track ?? (opts.slice?.startsWith("gpu:") ? "gpu" : "cpu");
|
|
32
|
+
const slices = scenario.slices[track];
|
|
33
|
+
if (opts.slice !== void 0 && !(opts.slice in slices)) {
|
|
34
|
+
throw unknownBudget(key, ` slice "${opts.slice}" (${track})`);
|
|
35
|
+
}
|
|
36
|
+
const reference = opts.slice !== void 0 ? slices[opts.slice] : scenario.frame[track];
|
|
37
|
+
return {
|
|
38
|
+
limit: on && reference !== null ? reference : Number.POSITIVE_INFINITY,
|
|
39
|
+
reference,
|
|
40
|
+
kind: "slice"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
let resolved;
|
|
44
|
+
let parsed = false;
|
|
45
|
+
function budgets() {
|
|
46
|
+
if (!parsed) {
|
|
47
|
+
parsed = true;
|
|
48
|
+
if (env.SHARD_BUDGETS) resolved = JSON.parse(env.SHARD_BUDGETS);
|
|
49
|
+
}
|
|
50
|
+
return resolved;
|
|
51
|
+
}
|
|
52
|
+
function scenarioSlices(name) {
|
|
53
|
+
const scenario = budgets()?.scenarios[name];
|
|
54
|
+
if (!scenario) throw unknownBudget(name);
|
|
55
|
+
const keys = (track) => Object.keys(scenario.slices[track]).filter((k) => k !== "headroom");
|
|
56
|
+
return { gpu: keys("gpu"), cpu: keys("cpu") };
|
|
57
|
+
}
|
|
58
|
+
function passTiming() {
|
|
59
|
+
return timingMode === "bench" && budgets()?.passTiming === "ablation" ? "ablation" : "timestamps";
|
|
60
|
+
}
|
|
61
|
+
function budget(key, opts = {}) {
|
|
62
|
+
if (typeof key === "number") return key * slack;
|
|
63
|
+
const bench = timingMode === "bench";
|
|
64
|
+
const data = budgets();
|
|
65
|
+
const result = resolveLimit(data, key, opts, bench);
|
|
66
|
+
if (bench && env.SHARD_PERF_REPORT) {
|
|
67
|
+
const call = { key, opts, used: false, ...result };
|
|
68
|
+
globalThis.__shardBudget = call;
|
|
69
|
+
}
|
|
70
|
+
return result.limit;
|
|
6
71
|
}
|
|
7
72
|
function timeout(ms) {
|
|
8
73
|
return timingMode === "ci" ? ms * 5 : ms;
|
|
@@ -31,6 +96,9 @@ export {
|
|
|
31
96
|
allocationChecks,
|
|
32
97
|
budget,
|
|
33
98
|
gcWindow,
|
|
99
|
+
passTiming,
|
|
100
|
+
resolveLimit,
|
|
101
|
+
scenarioSlices,
|
|
34
102
|
slack,
|
|
35
103
|
timeout,
|
|
36
104
|
timingMode
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aethervtt/shard-core",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"types": "./dist/index.d.ts",
|
|
10
10
|
"default": "./dist/index.js"
|
|
11
11
|
},
|
|
12
|
+
"./capture": {
|
|
13
|
+
"types": "./dist/scheduler/capture/index.d.ts",
|
|
14
|
+
"default": "./dist/scheduler/capture/index.js"
|
|
15
|
+
},
|
|
12
16
|
"./math": {
|
|
13
17
|
"types": "./dist/math/index.d.ts",
|
|
14
18
|
"default": "./dist/math/index.js"
|
|
@@ -33,6 +37,6 @@
|
|
|
33
37
|
"provenance": true
|
|
34
38
|
},
|
|
35
39
|
"shard": {
|
|
36
|
-
"buildSha": "
|
|
40
|
+
"buildSha": "772eb0d2b8a5fc499105708f4ae92c58788cc9ea"
|
|
37
41
|
}
|
|
38
42
|
}
|