@graphty/webgpu-graph-algorithms 0.0.0 → 0.2.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/README.md +344 -23
- package/dist/browser.d.ts +1 -0
- package/dist/browser.js +32 -0
- package/dist/browser.js.map +1 -0
- package/dist/chunks/context-E6iKaeuJ.js +3136 -0
- package/dist/chunks/context-E6iKaeuJ.js.map +1 -0
- package/dist/node.d.ts +1 -0
- package/dist/node.js +131 -0
- package/dist/node.js.map +1 -0
- package/dist/src/accelerator.d.ts +26 -0
- package/dist/src/accelerator.d.ts.map +1 -0
- package/dist/src/accelerator.js +101 -0
- package/dist/src/accelerator.js.map +1 -0
- package/dist/src/algorithms/degree.d.ts +35 -0
- package/dist/src/algorithms/degree.d.ts.map +1 -0
- package/dist/src/algorithms/degree.js +119 -0
- package/dist/src/algorithms/degree.js.map +1 -0
- package/dist/src/browser/index.d.ts +23 -0
- package/dist/src/browser/index.d.ts.map +1 -0
- package/dist/src/browser/index.js +48 -0
- package/dist/src/browser/index.js.map +1 -0
- package/dist/src/constants.d.ts +92 -0
- package/dist/src/constants.d.ts.map +1 -0
- package/dist/src/constants.js +92 -0
- package/dist/src/constants.js.map +1 -0
- package/dist/src/context.d.ts +84 -0
- package/dist/src/context.d.ts.map +1 -0
- package/dist/src/context.js +304 -0
- package/dist/src/context.js.map +1 -0
- package/dist/src/device/acquire.d.ts +57 -0
- package/dist/src/device/acquire.d.ts.map +1 -0
- package/dist/src/device/acquire.js +232 -0
- package/dist/src/device/acquire.js.map +1 -0
- package/dist/src/device/caps.d.ts +43 -0
- package/dist/src/device/caps.d.ts.map +1 -0
- package/dist/src/device/caps.js +104 -0
- package/dist/src/device/caps.js.map +1 -0
- package/dist/src/device/error-scope.d.ts +75 -0
- package/dist/src/device/error-scope.d.ts.map +1 -0
- package/dist/src/device/error-scope.js +152 -0
- package/dist/src/device/error-scope.js.map +1 -0
- package/dist/src/device/lost.d.ts +51 -0
- package/dist/src/device/lost.d.ts.map +1 -0
- package/dist/src/device/lost.js +130 -0
- package/dist/src/device/lost.js.map +1 -0
- package/dist/src/device/webgpu-constants.d.ts +31 -0
- package/dist/src/device/webgpu-constants.d.ts.map +1 -0
- package/dist/src/device/webgpu-constants.js +31 -0
- package/dist/src/device/webgpu-constants.js.map +1 -0
- package/dist/src/errors.d.ts +56 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +57 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +27 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/kernel/batch.d.ts +116 -0
- package/dist/src/kernel/batch.d.ts.map +1 -0
- package/dist/src/kernel/batch.js +335 -0
- package/dist/src/kernel/batch.js.map +1 -0
- package/dist/src/kernel/dispatch.d.ts +59 -0
- package/dist/src/kernel/dispatch.d.ts.map +1 -0
- package/dist/src/kernel/dispatch.js +139 -0
- package/dist/src/kernel/dispatch.js.map +1 -0
- package/dist/src/kernel/kernel.d.ts +84 -0
- package/dist/src/kernel/kernel.d.ts.map +1 -0
- package/dist/src/kernel/kernel.js +239 -0
- package/dist/src/kernel/kernel.js.map +1 -0
- package/dist/src/kernel/pipeline-cache.d.ts +90 -0
- package/dist/src/kernel/pipeline-cache.d.ts.map +1 -0
- package/dist/src/kernel/pipeline-cache.js +251 -0
- package/dist/src/kernel/pipeline-cache.js.map +1 -0
- package/dist/src/kernel/prelude.d.ts +35 -0
- package/dist/src/kernel/prelude.d.ts.map +1 -0
- package/dist/src/kernel/prelude.js +211 -0
- package/dist/src/kernel/prelude.js.map +1 -0
- package/dist/src/kernel/profiler.d.ts +64 -0
- package/dist/src/kernel/profiler.d.ts.map +1 -0
- package/dist/src/kernel/profiler.js +120 -0
- package/dist/src/kernel/profiler.js.map +1 -0
- package/dist/src/kernel/struct-block.d.ts +122 -0
- package/dist/src/kernel/struct-block.d.ts.map +1 -0
- package/dist/src/kernel/struct-block.js +353 -0
- package/dist/src/kernel/struct-block.js.map +1 -0
- package/dist/src/kernel/uniform-ring.d.ts +70 -0
- package/dist/src/kernel/uniform-ring.d.ts.map +1 -0
- package/dist/src/kernel/uniform-ring.js +146 -0
- package/dist/src/kernel/uniform-ring.js.map +1 -0
- package/dist/src/kernel/wgsl.d.ts +88 -0
- package/dist/src/kernel/wgsl.d.ts.map +1 -0
- package/dist/src/kernel/wgsl.js +390 -0
- package/dist/src/kernel/wgsl.js.map +1 -0
- package/dist/src/kernels.d.ts +81 -0
- package/dist/src/kernels.d.ts.map +1 -0
- package/dist/src/kernels.js +417 -0
- package/dist/src/kernels.js.map +1 -0
- package/dist/src/layouts/force-simulation.d.ts +498 -0
- package/dist/src/layouts/force-simulation.d.ts.map +1 -0
- package/dist/src/layouts/force-simulation.js +1650 -0
- package/dist/src/layouts/force-simulation.js.map +1 -0
- package/dist/src/layouts/forceatlas2.d.ts +210 -0
- package/dist/src/layouts/forceatlas2.d.ts.map +1 -0
- package/dist/src/layouts/forceatlas2.js +759 -0
- package/dist/src/layouts/forceatlas2.js.map +1 -0
- package/dist/src/layouts/inputs.d.ts +40 -0
- package/dist/src/layouts/inputs.d.ts.map +1 -0
- package/dist/src/layouts/inputs.js +185 -0
- package/dist/src/layouts/inputs.js.map +1 -0
- package/dist/src/layouts/repulsion-exact.d.ts +85 -0
- package/dist/src/layouts/repulsion-exact.d.ts.map +1 -0
- package/dist/src/layouts/repulsion-exact.js +134 -0
- package/dist/src/layouts/repulsion-exact.js.map +1 -0
- package/dist/src/layouts/seed.d.ts +56 -0
- package/dist/src/layouts/seed.d.ts.map +1 -0
- package/dist/src/layouts/seed.js +173 -0
- package/dist/src/layouts/seed.js.map +1 -0
- package/dist/src/memory/buffer-pool.d.ts +73 -0
- package/dist/src/memory/buffer-pool.d.ts.map +1 -0
- package/dist/src/memory/buffer-pool.js +170 -0
- package/dist/src/memory/buffer-pool.js.map +1 -0
- package/dist/src/memory/lease.d.ts +53 -0
- package/dist/src/memory/lease.d.ts.map +1 -0
- package/dist/src/memory/lease.js +85 -0
- package/dist/src/memory/lease.js.map +1 -0
- package/dist/src/memory/readback.d.ts +143 -0
- package/dist/src/memory/readback.d.ts.map +1 -0
- package/dist/src/memory/readback.js +375 -0
- package/dist/src/memory/readback.js.map +1 -0
- package/dist/src/memory/residency.d.ts +83 -0
- package/dist/src/memory/residency.d.ts.map +1 -0
- package/dist/src/memory/residency.js +573 -0
- package/dist/src/memory/residency.js.map +1 -0
- package/dist/src/memory/upload-plan.d.ts +101 -0
- package/dist/src/memory/upload-plan.d.ts.map +1 -0
- package/dist/src/memory/upload-plan.js +265 -0
- package/dist/src/memory/upload-plan.js.map +1 -0
- package/dist/src/node/index.d.ts +64 -0
- package/dist/src/node/index.d.ts.map +1 -0
- package/dist/src/node/index.js +183 -0
- package/dist/src/node/index.js.map +1 -0
- package/dist/src/primitives/reduce.d.ts +57 -0
- package/dist/src/primitives/reduce.d.ts.map +1 -0
- package/dist/src/primitives/reduce.js +161 -0
- package/dist/src/primitives/reduce.js.map +1 -0
- package/dist/src/primitives/segmented-reduce.d.ts +38 -0
- package/dist/src/primitives/segmented-reduce.d.ts.map +1 -0
- package/dist/src/primitives/segmented-reduce.js +211 -0
- package/dist/src/primitives/segmented-reduce.js.map +1 -0
- package/dist/src/types/accelerator.d.ts +209 -0
- package/dist/src/types/accelerator.d.ts.map +1 -0
- package/dist/src/types/accelerator.js +8 -0
- package/dist/src/types/accelerator.js.map +1 -0
- package/dist/src/types/context.d.ts +114 -0
- package/dist/src/types/context.d.ts.map +1 -0
- package/dist/src/types/context.js +7 -0
- package/dist/src/types/context.js.map +1 -0
- package/dist/src/types/layout.d.ts +95 -0
- package/dist/src/types/layout.d.ts.map +1 -0
- package/dist/src/types/layout.js +6 -0
- package/dist/src/types/layout.js.map +1 -0
- package/dist/src/types/memory.d.ts +22 -0
- package/dist/src/types/memory.d.ts.map +1 -0
- package/dist/src/types/memory.js +7 -0
- package/dist/src/types/memory.js.map +1 -0
- package/dist/src/types/options.d.ts +78 -0
- package/dist/src/types/options.d.ts.map +1 -0
- package/dist/src/types/options.js +7 -0
- package/dist/src/types/options.js.map +1 -0
- package/dist/src/types/run.d.ts +13 -0
- package/dist/src/types/run.d.ts.map +1 -0
- package/dist/src/types/run.js +6 -0
- package/dist/src/types/run.js.map +1 -0
- package/dist/src/wgsl/degree.wgsl.d.ts +10 -0
- package/dist/src/wgsl/degree.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/degree.wgsl.js +25 -0
- package/dist/src/wgsl/degree.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-attraction.wgsl.d.ts +12 -0
- package/dist/src/wgsl/fa2-attraction.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fa2-attraction.wgsl.js +37 -0
- package/dist/src/wgsl/fa2-attraction.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-integrate.wgsl.d.ts +13 -0
- package/dist/src/wgsl/fa2-integrate.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fa2-integrate.wgsl.js +69 -0
- package/dist/src/wgsl/fa2-integrate.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts +12 -0
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js +79 -0
- package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-speed-finalize.wgsl.d.ts +15 -0
- package/dist/src/wgsl/fa2-speed-finalize.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fa2-speed-finalize.wgsl.js +54 -0
- package/dist/src/wgsl/fa2-speed-finalize.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts +14 -0
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.js +57 -0
- package/dist/src/wgsl/fa2-stats-finalize.wgsl.js.map +1 -0
- package/dist/src/wgsl/fa2-to-scene.wgsl.d.ts +11 -0
- package/dist/src/wgsl/fa2-to-scene.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fa2-to-scene.wgsl.js +19 -0
- package/dist/src/wgsl/fa2-to-scene.wgsl.js.map +1 -0
- package/dist/src/wgsl/fill.wgsl.d.ts +7 -0
- package/dist/src/wgsl/fill.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/fill.wgsl.js +14 -0
- package/dist/src/wgsl/fill.wgsl.js.map +1 -0
- package/dist/src/wgsl/reduce.wgsl.d.ts +10 -0
- package/dist/src/wgsl/reduce.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/reduce.wgsl.js +63 -0
- package/dist/src/wgsl/reduce.wgsl.js.map +1 -0
- package/dist/src/wgsl/segmented-reduce.wgsl.d.ts +13 -0
- package/dist/src/wgsl/segmented-reduce.wgsl.d.ts.map +1 -0
- package/dist/src/wgsl/segmented-reduce.wgsl.js +35 -0
- package/dist/src/wgsl/segmented-reduce.wgsl.js.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/webgpu-graph-algorithms.d.ts +1 -0
- package/dist/webgpu-graph-algorithms.js +4454 -0
- package/dist/webgpu-graph-algorithms.js.map +1 -0
- package/package.json +108 -17
- package/src/accelerator.ts +117 -0
- package/src/algorithms/degree.ts +142 -0
- package/src/browser/index.ts +57 -0
- package/src/constants.ts +116 -0
- package/src/context.ts +399 -0
- package/src/device/acquire.ts +256 -0
- package/src/device/caps.ts +122 -0
- package/src/device/error-scope.ts +171 -0
- package/src/device/lost.ts +142 -0
- package/src/device/webgpu-constants.ts +44 -0
- package/src/errors.ts +94 -0
- package/src/index.ts +102 -0
- package/src/kernel/batch.ts +427 -0
- package/src/kernel/dispatch.ts +162 -0
- package/src/kernel/kernel.ts +311 -0
- package/src/kernel/pipeline-cache.ts +288 -0
- package/src/kernel/prelude.ts +229 -0
- package/src/kernel/profiler.ts +148 -0
- package/src/kernel/struct-block.ts +439 -0
- package/src/kernel/uniform-ring.ts +184 -0
- package/src/kernel/wgsl.ts +490 -0
- package/src/kernels.ts +511 -0
- package/src/layouts/force-simulation.ts +2111 -0
- package/src/layouts/forceatlas2.ts +942 -0
- package/src/layouts/inputs.ts +252 -0
- package/src/layouts/repulsion-exact.ts +183 -0
- package/src/layouts/seed.ts +198 -0
- package/src/memory/buffer-pool.ts +204 -0
- package/src/memory/lease.ts +93 -0
- package/src/memory/readback.ts +429 -0
- package/src/memory/residency.ts +753 -0
- package/src/memory/upload-plan.ts +350 -0
- package/src/node/index.ts +230 -0
- package/src/primitives/reduce.ts +233 -0
- package/src/primitives/segmented-reduce.ts +270 -0
- package/src/types/accelerator.ts +236 -0
- package/src/types/context.ts +135 -0
- package/src/types/layout.ts +103 -0
- package/src/types/memory.ts +23 -0
- package/src/types/options.ts +84 -0
- package/src/types/run.ts +13 -0
- package/src/wgsl/degree.wgsl.ts +24 -0
- package/src/wgsl/fa2-attraction.wgsl.ts +37 -0
- package/src/wgsl/fa2-integrate.wgsl.ts +69 -0
- package/src/wgsl/fa2-repulsion-exact.wgsl.ts +78 -0
- package/src/wgsl/fa2-speed-finalize.wgsl.ts +53 -0
- package/src/wgsl/fa2-stats-finalize.wgsl.ts +57 -0
- package/src/wgsl/fa2-to-scene.wgsl.ts +19 -0
- package/src/wgsl/fill.wgsl.ts +13 -0
- package/src/wgsl/reduce.wgsl.ts +62 -0
- package/src/wgsl/segmented-reduce.wgsl.ts +35 -0
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CPU port's random number generator, bit for bit, and the NaN-row seeding both paths share (spec 7.2 "Initial
|
|
3
|
+
* positions", 9.3 seedPositions, 7.14 `pos`, 7.19 topology change): a seed gives the same start on the CPU and the
|
|
4
|
+
* GPU because both write the same f32 values in index order. The package carries its own copy of the LCG for its
|
|
5
|
+
* whole life (D27: it cannot import @graphty/layout); W1 cross-tests it against the real RandomNumberGenerator.
|
|
6
|
+
*/
|
|
7
|
+
import { WebGpuGraphError } from "../errors.js";
|
|
8
|
+
/** The CPU port's LCG constants (layout/src/utils/random.ts): m = 2^35 - 31, a = 185852, c = 1. */
|
|
9
|
+
export const LCG_M = 34359738337;
|
|
10
|
+
/** The multiplier a of the port's LCG. */
|
|
11
|
+
export const LCG_A = 185852;
|
|
12
|
+
/** The increment c of the port's LCG. */
|
|
13
|
+
export const LCG_C = 1;
|
|
14
|
+
/**
|
|
15
|
+
* The port's RandomNumberGenerator, bit for bit: `seed || Math.floor(Math.random() * 1000000)` (seed 0 / null =
|
|
16
|
+
* unseeded, the quirk preserved), state = seed % m, next = (a * state + c) % m, value = state / m. The product
|
|
17
|
+
* a * state stays below 2^53 (a < 2^18, state < 2^35), so every step is exact in f64, as it is in the port.
|
|
18
|
+
*/
|
|
19
|
+
export class Lcg {
|
|
20
|
+
/**
|
|
21
|
+
* Creates the generator; a seed of 0, -0, NaN or null means unseeded (the port's `seed || random` quirk).
|
|
22
|
+
* @param seed - the seed, or null for a random seed
|
|
23
|
+
*/
|
|
24
|
+
constructor(seed) {
|
|
25
|
+
this.seed = seed === null || seed === 0 || Number.isNaN(seed) ? Math.floor(Math.random() * 1000000) : seed;
|
|
26
|
+
this.state = this.seed % LCG_M;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Next value in [0, 1).
|
|
30
|
+
* @returns state / m after one LCG step
|
|
31
|
+
*/
|
|
32
|
+
next() {
|
|
33
|
+
this.state = (LCG_A * this.state + LCG_C) % LCG_M;
|
|
34
|
+
return this.state / LCG_M;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The three center components of a CommonLayoutOptions.center (missing components are 0).
|
|
39
|
+
* @param center - the caller's center, or null
|
|
40
|
+
* @returns [x, y, z]; E_INVALID_ARGUMENT when a component is not finite
|
|
41
|
+
*/
|
|
42
|
+
function resolveCenter(center) {
|
|
43
|
+
const out = [0, 0, 0];
|
|
44
|
+
if (center === null) {
|
|
45
|
+
return out;
|
|
46
|
+
}
|
|
47
|
+
for (let axis = 0; axis < 3 && axis < center.length; axis++) {
|
|
48
|
+
const v = center[axis];
|
|
49
|
+
if (!Number.isFinite(v)) {
|
|
50
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", `center[${axis}] is not finite`, {
|
|
51
|
+
argument: "center",
|
|
52
|
+
value: v,
|
|
53
|
+
expected: "finite components",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
out[axis] = v;
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Seeds the unseeded rows of the owner's stride-3 SCENE array in index order (spec 9.3 seedPositions, 7.14 `pos`,
|
|
62
|
+
* 7.19 topology change): a row is unseeded when any of its `dim` components is not finite; every such component
|
|
63
|
+
* draws one LCG value; when NO row is fully finite the draw is uniform in [-1, 1) layout units per axis (`range:
|
|
64
|
+
* "fa2"`; `"fr"` is [0, 1)), otherwise uniform inside the [min, max] box of the finite components per axis,
|
|
65
|
+
* converted to layout units (an axis with no finite value falls back to the range box); the value is written as
|
|
66
|
+
* `v * scale + center[axis]`, which for scale 1 / center 0 is bit-identical to the port's `u * 2 - 1` (resp. `u`);
|
|
67
|
+
* in 2D the third component of a seeded row is written as center[2]. Finite components are never changed and a
|
|
68
|
+
* fully finite row is never touched. No random number is drawn when nothing needs seeding.
|
|
69
|
+
* PLAN DECISION 12 (P3-T1): the box is taken over every finite COMPONENT (the port's rule), not over the fully
|
|
70
|
+
* finite ROWS only; the two differ only when a partially finite row's finite axis lies outside the fully finite
|
|
71
|
+
* rows' box (pinned by test/layouts/seed.test.ts). PLAN DECISION 13: a 2D row whose x and y are finite is seeded
|
|
72
|
+
* whatever its z holds.
|
|
73
|
+
* @param s - the snapshot (nodeCount rows)
|
|
74
|
+
* @param positions - the owner's stride-3 scene-unit array, length 3 * nodeCount, modified in place
|
|
75
|
+
* @param seed - the LCG seed (0 / null = unseeded, the port's quirk)
|
|
76
|
+
* @param dim - 2 or 3
|
|
77
|
+
* @param scale - the scene scale (> 0)
|
|
78
|
+
* @param center - the scene center, or null for the origin
|
|
79
|
+
* @param range - "fa2" for [-1, 1), "fr" for [0, 1)
|
|
80
|
+
*/
|
|
81
|
+
export function seedPositions(s, positions, seed, dim, scale, center, range) {
|
|
82
|
+
const n = s.nodeCount;
|
|
83
|
+
if (dim !== 2 && dim !== 3) {
|
|
84
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", `dim must be 2 or 3, got ${String(dim)}`, {
|
|
85
|
+
argument: "dim",
|
|
86
|
+
value: dim,
|
|
87
|
+
expected: "2 or 3",
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (positions.length !== 3 * n) {
|
|
91
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", `positions has ${positions.length} entries, expected ${3 * n}`, {
|
|
92
|
+
argument: "positions",
|
|
93
|
+
value: positions.length,
|
|
94
|
+
expected: 3 * n,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
if (!Number.isFinite(scale) || scale <= 0) {
|
|
98
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", `scale must be a finite number > 0, got ${scale}`, {
|
|
99
|
+
argument: "scale",
|
|
100
|
+
value: scale,
|
|
101
|
+
expected: "a finite number > 0",
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
const c = resolveCenter(center);
|
|
105
|
+
// classify the rows and collect the per-axis box of the finite components (scene units)
|
|
106
|
+
const lo = [Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY];
|
|
107
|
+
const hi = [Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY];
|
|
108
|
+
let finiteRows = 0;
|
|
109
|
+
let unseededRows = 0;
|
|
110
|
+
for (let i = 0; i < n; i++) {
|
|
111
|
+
let finite = true;
|
|
112
|
+
for (let axis = 0; axis < dim; axis++) {
|
|
113
|
+
const v = positions[3 * i + axis];
|
|
114
|
+
if (Number.isFinite(v)) {
|
|
115
|
+
if (v < lo[axis]) {
|
|
116
|
+
lo[axis] = v;
|
|
117
|
+
}
|
|
118
|
+
if (v > hi[axis]) {
|
|
119
|
+
hi[axis] = v;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
finite = false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (finite) {
|
|
127
|
+
finiteRows++;
|
|
128
|
+
}
|
|
129
|
+
else {
|
|
130
|
+
unseededRows++;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
if (unseededRows === 0) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// the per-axis draw box in layout units
|
|
137
|
+
const rangeLo = range === "fr" ? 0 : -1;
|
|
138
|
+
const rangeHi = 1;
|
|
139
|
+
const boxLo = [rangeLo, rangeLo, rangeLo];
|
|
140
|
+
const boxHi = [rangeHi, rangeHi, rangeHi];
|
|
141
|
+
if (finiteRows > 0) {
|
|
142
|
+
for (let axis = 0; axis < dim; axis++) {
|
|
143
|
+
if (Number.isFinite(lo[axis]) && Number.isFinite(hi[axis])) {
|
|
144
|
+
boxLo[axis] = (lo[axis] - c[axis]) / scale;
|
|
145
|
+
boxHi[axis] = (hi[axis] - c[axis]) / scale;
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const rng = new Lcg(seed);
|
|
150
|
+
for (let i = 0; i < n; i++) {
|
|
151
|
+
let unseeded = false;
|
|
152
|
+
for (let axis = 0; axis < dim; axis++) {
|
|
153
|
+
if (!Number.isFinite(positions[3 * i + axis])) {
|
|
154
|
+
unseeded = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!unseeded) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
for (let axis = 0; axis < dim; axis++) {
|
|
161
|
+
const at = 3 * i + axis;
|
|
162
|
+
if (!Number.isFinite(positions[at])) {
|
|
163
|
+
const u = rng.next();
|
|
164
|
+
const v = boxLo[axis] + u * (boxHi[axis] - boxLo[axis]);
|
|
165
|
+
positions[at] = v * scale + c[axis];
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (dim === 2) {
|
|
169
|
+
positions[3 * i + 2] = c[2];
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
//# sourceMappingURL=seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../../src/layouts/seed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size-class pool of GPUBuffers by usage (spec 4.4): a request rounds up to a class (powers of two from 4 KiB to
|
|
3
|
+
* 64 MiB, then 16 MiB steps), an idle buffer of that (class, usage) is reused, otherwise one is created through the
|
|
4
|
+
* context's AllocationTracker (so the OOM scope of spec 5.7 and the resident accounting are shared with the
|
|
5
|
+
* residency); `release` keeps at most maxIdlePerClass idle buffers per (class, usage); `trim` destroys the idle
|
|
6
|
+
* ones (ctx.release and layouts on dispose); `destroyAll` everything (ctx.dispose). The Lease scope object arrives
|
|
7
|
+
* with P2-T1 (`lease()`, PLAN DECISION 1). Classes above maxBufferSize are never created: a request that fits the
|
|
8
|
+
* device but whose class overshoots gets the capped class (PLAN DECISION 14).
|
|
9
|
+
*/
|
|
10
|
+
import { type AllocationTracker } from "../device/error-scope.js";
|
|
11
|
+
import { Lease } from "./lease.js";
|
|
12
|
+
/** Size-class pool of GPUBuffers by usage (spec 4.4). */
|
|
13
|
+
export declare class BufferPool {
|
|
14
|
+
private readonly allocator;
|
|
15
|
+
private readonly maxBufferSize;
|
|
16
|
+
private readonly maxIdlePerClass;
|
|
17
|
+
private readonly idle;
|
|
18
|
+
private readonly live;
|
|
19
|
+
private liveBytesValue;
|
|
20
|
+
private idleBytesValue;
|
|
21
|
+
private disposed;
|
|
22
|
+
/**
|
|
23
|
+
* Creates an empty pool.
|
|
24
|
+
* @param _device - the device (buffers are created through the allocator, which owns it; the parameter keeps
|
|
25
|
+
* the contract's constructor shape)
|
|
26
|
+
* @param allocator - the context's OOM-scoped allocator
|
|
27
|
+
* @param maxBufferSize - the device's maxBufferSize (classes above it are never created)
|
|
28
|
+
* @param options - pool options
|
|
29
|
+
* @param options.maxIdlePerClass - idle buffers kept per (class, usage); default POOL_MAX_IDLE_PER_CLASS
|
|
30
|
+
*/
|
|
31
|
+
constructor(_device: GPUDevice, allocator: AllocationTracker, maxBufferSize: number, options?: {
|
|
32
|
+
readonly maxIdlePerClass?: number | undefined;
|
|
33
|
+
});
|
|
34
|
+
/**
|
|
35
|
+
* The size class a byte length rounds up to: powers of two from 4 KiB to 64 MiB, then 16 MiB steps (pure).
|
|
36
|
+
* @param byteLength - a positive integer
|
|
37
|
+
* @returns the class in bytes
|
|
38
|
+
*/
|
|
39
|
+
static sizeClass(byteLength: number): number;
|
|
40
|
+
/**
|
|
41
|
+
* Acquires a buffer of at least byteLength (an idle one of the class and usage, else a new one through the
|
|
42
|
+
* allocator); E_TOO_LARGE above maxBufferSize.
|
|
43
|
+
* @param byteLength - the bytes needed
|
|
44
|
+
* @param usage - the GPUBufferUsage flags
|
|
45
|
+
* @param label - the buffer label (a reused buffer is relabelled)
|
|
46
|
+
* @returns a buffer of the class size
|
|
47
|
+
*/
|
|
48
|
+
acquire(byteLength: number, usage: number, label: string): GPUBuffer;
|
|
49
|
+
/**
|
|
50
|
+
* Returns a buffer to its class; destroys it when the class already holds maxIdlePerClass idle buffers. A no-op
|
|
51
|
+
* after destroyAll() (so a `finally` never masks the original error).
|
|
52
|
+
* @param buffer - a buffer acquired from this pool and not yet released
|
|
53
|
+
*/
|
|
54
|
+
release(buffer: GPUBuffer): void;
|
|
55
|
+
/** Destroys every idle buffer. */
|
|
56
|
+
trim(): void;
|
|
57
|
+
/**
|
|
58
|
+
* A scope object that releases everything acquired through it (spec 4.4, P2).
|
|
59
|
+
* @returns a fresh lease over this pool
|
|
60
|
+
*/
|
|
61
|
+
lease(): Lease;
|
|
62
|
+
/**
|
|
63
|
+
* Bytes of buffers acquired and not yet released (class sizes).
|
|
64
|
+
* @returns the live byte count
|
|
65
|
+
*/
|
|
66
|
+
get liveBytes(): number;
|
|
67
|
+
/**
|
|
68
|
+
* Bytes of idle buffers (class sizes).
|
|
69
|
+
* @returns the idle byte count
|
|
70
|
+
*/
|
|
71
|
+
get idleBytes(): number;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=buffer-pool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer-pool.d.ts","sourceRoot":"","sources":["../../../src/memory/buffer-pool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAQH,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAElE,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAkBnC,yDAAyD;AACzD,qBAAa,UAAU;IACnB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAS;IACzC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAkC;IACvD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmC;IACxD,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;;OAQG;gBAEC,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,iBAAiB,EAC5B,aAAa,EAAE,MAAM,EACrB,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAO/D;;;;OAIG;IACH,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM;IAkB5C;;;;;;;OAOG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IA2BpE;;;;OAIG;IACH,OAAO,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI;IA4BhC,kCAAkC;IAClC,IAAI,IAAI,IAAI;IAqBZ;;;OAGG;IACH,KAAK,IAAI,KAAK;IAId;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED;;;OAGG;IACH,IAAI,SAAS,IAAI,MAAM,CAEtB;CACJ"}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Size-class pool of GPUBuffers by usage (spec 4.4): a request rounds up to a class (powers of two from 4 KiB to
|
|
3
|
+
* 64 MiB, then 16 MiB steps), an idle buffer of that (class, usage) is reused, otherwise one is created through the
|
|
4
|
+
* context's AllocationTracker (so the OOM scope of spec 5.7 and the resident accounting are shared with the
|
|
5
|
+
* residency); `release` keeps at most maxIdlePerClass idle buffers per (class, usage); `trim` destroys the idle
|
|
6
|
+
* ones (ctx.release and layouts on dispose); `destroyAll` everything (ctx.dispose). The Lease scope object arrives
|
|
7
|
+
* with P2-T1 (`lease()`, PLAN DECISION 1). Classes above maxBufferSize are never created: a request that fits the
|
|
8
|
+
* device but whose class overshoots gets the capped class (PLAN DECISION 14).
|
|
9
|
+
*/
|
|
10
|
+
import { POOL_LINEAR_STEP_BYTES, POOL_MAX_IDLE_PER_CLASS, POOL_MAX_POW2_CLASS_BYTES, POOL_MIN_CLASS_BYTES, } from "../constants.js";
|
|
11
|
+
import { WebGpuGraphError } from "../errors.js";
|
|
12
|
+
import { Lease } from "./lease.js";
|
|
13
|
+
/**
|
|
14
|
+
* The idle-list key of a (class, usage) pair.
|
|
15
|
+
* @param sizeClass - the class in bytes
|
|
16
|
+
* @param usage - the GPUBufferUsage flags
|
|
17
|
+
* @returns the map key
|
|
18
|
+
*/
|
|
19
|
+
function classKey(sizeClass, usage) {
|
|
20
|
+
return `${sizeClass}:${usage}`;
|
|
21
|
+
}
|
|
22
|
+
/** Size-class pool of GPUBuffers by usage (spec 4.4). */
|
|
23
|
+
export class BufferPool {
|
|
24
|
+
/**
|
|
25
|
+
* Creates an empty pool.
|
|
26
|
+
* @param _device - the device (buffers are created through the allocator, which owns it; the parameter keeps
|
|
27
|
+
* the contract's constructor shape)
|
|
28
|
+
* @param allocator - the context's OOM-scoped allocator
|
|
29
|
+
* @param maxBufferSize - the device's maxBufferSize (classes above it are never created)
|
|
30
|
+
* @param options - pool options
|
|
31
|
+
* @param options.maxIdlePerClass - idle buffers kept per (class, usage); default POOL_MAX_IDLE_PER_CLASS
|
|
32
|
+
*/
|
|
33
|
+
constructor(_device, allocator, maxBufferSize, options) {
|
|
34
|
+
this.idle = new Map();
|
|
35
|
+
this.live = new Map();
|
|
36
|
+
this.liveBytesValue = 0;
|
|
37
|
+
this.idleBytesValue = 0;
|
|
38
|
+
this.disposed = false;
|
|
39
|
+
this.allocator = allocator;
|
|
40
|
+
this.maxBufferSize = maxBufferSize - (maxBufferSize % 4);
|
|
41
|
+
this.maxIdlePerClass = options?.maxIdlePerClass ?? POOL_MAX_IDLE_PER_CLASS;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The size class a byte length rounds up to: powers of two from 4 KiB to 64 MiB, then 16 MiB steps (pure).
|
|
45
|
+
* @param byteLength - a positive integer
|
|
46
|
+
* @returns the class in bytes
|
|
47
|
+
*/
|
|
48
|
+
static sizeClass(byteLength) {
|
|
49
|
+
if (!Number.isInteger(byteLength) || byteLength <= 0) {
|
|
50
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", "byteLength: expected a positive integer", {
|
|
51
|
+
argument: "byteLength",
|
|
52
|
+
value: byteLength,
|
|
53
|
+
expected: "a positive integer",
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
if (byteLength > POOL_MAX_POW2_CLASS_BYTES) {
|
|
57
|
+
return Math.ceil(byteLength / POOL_LINEAR_STEP_BYTES) * POOL_LINEAR_STEP_BYTES;
|
|
58
|
+
}
|
|
59
|
+
let sizeClass = POOL_MIN_CLASS_BYTES;
|
|
60
|
+
while (sizeClass < byteLength) {
|
|
61
|
+
sizeClass *= 2;
|
|
62
|
+
}
|
|
63
|
+
return sizeClass;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Acquires a buffer of at least byteLength (an idle one of the class and usage, else a new one through the
|
|
67
|
+
* allocator); E_TOO_LARGE above maxBufferSize.
|
|
68
|
+
* @param byteLength - the bytes needed
|
|
69
|
+
* @param usage - the GPUBufferUsage flags
|
|
70
|
+
* @param label - the buffer label (a reused buffer is relabelled)
|
|
71
|
+
* @returns a buffer of the class size
|
|
72
|
+
*/
|
|
73
|
+
acquire(byteLength, usage, label) {
|
|
74
|
+
if (this.disposed) {
|
|
75
|
+
throw new WebGpuGraphError("E_DISPOSED", "the buffer pool was disposed", { label: "pool" });
|
|
76
|
+
}
|
|
77
|
+
const rounded = BufferPool.sizeClass(byteLength);
|
|
78
|
+
if (byteLength > this.maxBufferSize) {
|
|
79
|
+
throw new WebGpuGraphError("E_TOO_LARGE", `pool: ${byteLength} bytes exceed the device maxBufferSize of ${this.maxBufferSize} bytes`, { needed: byteLength, limit: this.maxBufferSize, path: "pool", algorithm: null });
|
|
80
|
+
}
|
|
81
|
+
const sizeClass = Math.min(rounded, this.maxBufferSize);
|
|
82
|
+
const key = classKey(sizeClass, usage);
|
|
83
|
+
const idle = this.idle.get(key);
|
|
84
|
+
let buffer = idle?.pop();
|
|
85
|
+
if (buffer === undefined) {
|
|
86
|
+
buffer = this.allocator.createBuffer({ label, size: sizeClass, usage });
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
this.idleBytesValue -= sizeClass;
|
|
90
|
+
buffer.label = label;
|
|
91
|
+
}
|
|
92
|
+
this.live.set(buffer, { sizeClass, usage });
|
|
93
|
+
this.liveBytesValue += sizeClass;
|
|
94
|
+
return buffer;
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Returns a buffer to its class; destroys it when the class already holds maxIdlePerClass idle buffers. A no-op
|
|
98
|
+
* after destroyAll() (so a `finally` never masks the original error).
|
|
99
|
+
* @param buffer - a buffer acquired from this pool and not yet released
|
|
100
|
+
*/
|
|
101
|
+
release(buffer) {
|
|
102
|
+
if (this.disposed) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const entry = this.live.get(buffer);
|
|
106
|
+
if (entry === undefined) {
|
|
107
|
+
throw new WebGpuGraphError("E_INVALID_ARGUMENT", "buffer: not a live buffer of this pool", {
|
|
108
|
+
argument: "buffer",
|
|
109
|
+
value: buffer.label,
|
|
110
|
+
expected: "a buffer acquired from this pool and not yet released",
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
this.live.delete(buffer);
|
|
114
|
+
this.liveBytesValue -= entry.sizeClass;
|
|
115
|
+
const key = classKey(entry.sizeClass, entry.usage);
|
|
116
|
+
let idle = this.idle.get(key);
|
|
117
|
+
if (idle === undefined) {
|
|
118
|
+
idle = [];
|
|
119
|
+
this.idle.set(key, idle);
|
|
120
|
+
}
|
|
121
|
+
if (idle.length >= this.maxIdlePerClass) {
|
|
122
|
+
this.allocator.destroy(buffer);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
idle.push(buffer);
|
|
126
|
+
this.idleBytesValue += entry.sizeClass;
|
|
127
|
+
}
|
|
128
|
+
/** Destroys every idle buffer. */
|
|
129
|
+
trim() {
|
|
130
|
+
for (const buffers of this.idle.values()) {
|
|
131
|
+
for (const buffer of buffers) {
|
|
132
|
+
this.allocator.destroy(buffer);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
this.idle.clear();
|
|
136
|
+
this.idleBytesValue = 0;
|
|
137
|
+
}
|
|
138
|
+
/** Destroys everything, idle and live (ctx.dispose()); idempotent. @internal */
|
|
139
|
+
destroyAll() {
|
|
140
|
+
this.trim();
|
|
141
|
+
for (const buffer of this.live.keys()) {
|
|
142
|
+
this.allocator.destroy(buffer);
|
|
143
|
+
}
|
|
144
|
+
this.live.clear();
|
|
145
|
+
this.liveBytesValue = 0;
|
|
146
|
+
this.disposed = true;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* A scope object that releases everything acquired through it (spec 4.4, P2).
|
|
150
|
+
* @returns a fresh lease over this pool
|
|
151
|
+
*/
|
|
152
|
+
lease() {
|
|
153
|
+
return new Lease(this);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Bytes of buffers acquired and not yet released (class sizes).
|
|
157
|
+
* @returns the live byte count
|
|
158
|
+
*/
|
|
159
|
+
get liveBytes() {
|
|
160
|
+
return this.liveBytesValue;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Bytes of idle buffers (class sizes).
|
|
164
|
+
* @returns the idle byte count
|
|
165
|
+
*/
|
|
166
|
+
get idleBytes() {
|
|
167
|
+
return this.idleBytesValue;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=buffer-pool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"buffer-pool.js","sourceRoot":"","sources":["../../../src/memory/buffer-pool.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Lease scope object of spec 4.4: every buffer an algorithm acquires through it goes back to the
|
|
3
|
+
* BufferPool in ONE `release()` call placed in the algorithm's `finally` block, so scratch never
|
|
4
|
+
* outlives the call that took it (a `try / finally`, not `Symbol.dispose`, until the monorepo's
|
|
5
|
+
* TypeScript target supports `using`). Persistent buffers (layout state) are owned by the simulation
|
|
6
|
+
* object instead and freed by its `dispose()`.
|
|
7
|
+
*/
|
|
8
|
+
import type { BufferPool } from "./buffer-pool.js";
|
|
9
|
+
/** Scope object algorithms use: every buffer acquired through it is released by `release()` in a finally block (spec 4.4). */
|
|
10
|
+
export declare class Lease {
|
|
11
|
+
private readonly pool;
|
|
12
|
+
private readonly buffers;
|
|
13
|
+
private released;
|
|
14
|
+
/**
|
|
15
|
+
* Creates a lease over a pool; `pool.lease()` is the usual way to get one.
|
|
16
|
+
* @param pool - the pool every acquisition of this lease goes through
|
|
17
|
+
*/
|
|
18
|
+
constructor(pool: BufferPool);
|
|
19
|
+
/**
|
|
20
|
+
* pool.acquire(byteLength, STORAGE | COPY_SRC | COPY_DST, label).
|
|
21
|
+
* @param byteLength - bytes needed; the pool rounds up to its size class
|
|
22
|
+
* @param label - the buffer label
|
|
23
|
+
* @returns the buffer, returned to the pool by `release()`
|
|
24
|
+
*/
|
|
25
|
+
storage(byteLength: number, label: string): GPUBuffer;
|
|
26
|
+
/**
|
|
27
|
+
* pool.acquire(byteLength, UNIFORM | COPY_DST, label).
|
|
28
|
+
* @param byteLength - bytes needed; the pool rounds up to its size class
|
|
29
|
+
* @param label - the buffer label
|
|
30
|
+
* @returns the buffer, returned to the pool by `release()`
|
|
31
|
+
*/
|
|
32
|
+
uniform(byteLength: number, label: string): GPUBuffer;
|
|
33
|
+
/**
|
|
34
|
+
* pool.acquire with explicit usage.
|
|
35
|
+
* @param byteLength - bytes needed; the pool rounds up to its size class
|
|
36
|
+
* @param usage - the GPUBufferUsage bits
|
|
37
|
+
* @param label - the buffer label
|
|
38
|
+
* @returns the buffer, returned to the pool by `release()`
|
|
39
|
+
*/
|
|
40
|
+
acquire(byteLength: number, usage: number, label: string): GPUBuffer;
|
|
41
|
+
/**
|
|
42
|
+
* Releases every buffer acquired through this lease; idempotent. A pool that `ctx.dispose()` already
|
|
43
|
+
* destroyed has nothing left to take back, so its E_DISPOSED is swallowed here: the lease sits in a
|
|
44
|
+
* `finally` block and must never mask the error that unwound the algorithm.
|
|
45
|
+
*/
|
|
46
|
+
release(): void;
|
|
47
|
+
/**
|
|
48
|
+
* Live buffers of this lease.
|
|
49
|
+
* @returns the number of buffers acquired through the lease and not yet released
|
|
50
|
+
*/
|
|
51
|
+
get count(): number;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=lease.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease.d.ts","sourceRoot":"","sources":["../../../src/memory/lease.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,8HAA8H;AAC9H,qBAAa,KAAK;IACd,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;OAGG;gBACS,IAAI,EAAE,UAAU;IAI5B;;;;;OAKG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IAIrD;;;;;OAKG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IAIrD;;;;;;OAMG;IACH,OAAO,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,SAAS;IASpE;;;;OAIG;IACH,OAAO,IAAI,IAAI;IAkBf;;;OAGG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;CACJ"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Lease scope object of spec 4.4: every buffer an algorithm acquires through it goes back to the
|
|
3
|
+
* BufferPool in ONE `release()` call placed in the algorithm's `finally` block, so scratch never
|
|
4
|
+
* outlives the call that took it (a `try / finally`, not `Symbol.dispose`, until the monorepo's
|
|
5
|
+
* TypeScript target supports `using`). Persistent buffers (layout state) are owned by the simulation
|
|
6
|
+
* object instead and freed by its `dispose()`.
|
|
7
|
+
*/
|
|
8
|
+
import { BufferUsage } from "../device/webgpu-constants.js";
|
|
9
|
+
import { hasErrorCode, WebGpuGraphError } from "../errors.js";
|
|
10
|
+
/** Scope object algorithms use: every buffer acquired through it is released by `release()` in a finally block (spec 4.4). */
|
|
11
|
+
export class Lease {
|
|
12
|
+
/**
|
|
13
|
+
* Creates a lease over a pool; `pool.lease()` is the usual way to get one.
|
|
14
|
+
* @param pool - the pool every acquisition of this lease goes through
|
|
15
|
+
*/
|
|
16
|
+
constructor(pool) {
|
|
17
|
+
this.buffers = new Set();
|
|
18
|
+
this.released = false;
|
|
19
|
+
this.pool = pool;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* pool.acquire(byteLength, STORAGE | COPY_SRC | COPY_DST, label).
|
|
23
|
+
* @param byteLength - bytes needed; the pool rounds up to its size class
|
|
24
|
+
* @param label - the buffer label
|
|
25
|
+
* @returns the buffer, returned to the pool by `release()`
|
|
26
|
+
*/
|
|
27
|
+
storage(byteLength, label) {
|
|
28
|
+
return this.acquire(byteLength, BufferUsage.STORAGE | BufferUsage.COPY_SRC | BufferUsage.COPY_DST, label);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* pool.acquire(byteLength, UNIFORM | COPY_DST, label).
|
|
32
|
+
* @param byteLength - bytes needed; the pool rounds up to its size class
|
|
33
|
+
* @param label - the buffer label
|
|
34
|
+
* @returns the buffer, returned to the pool by `release()`
|
|
35
|
+
*/
|
|
36
|
+
uniform(byteLength, label) {
|
|
37
|
+
return this.acquire(byteLength, BufferUsage.UNIFORM | BufferUsage.COPY_DST, label);
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* pool.acquire with explicit usage.
|
|
41
|
+
* @param byteLength - bytes needed; the pool rounds up to its size class
|
|
42
|
+
* @param usage - the GPUBufferUsage bits
|
|
43
|
+
* @param label - the buffer label
|
|
44
|
+
* @returns the buffer, returned to the pool by `release()`
|
|
45
|
+
*/
|
|
46
|
+
acquire(byteLength, usage, label) {
|
|
47
|
+
if (this.released) {
|
|
48
|
+
throw new WebGpuGraphError("E_DISPOSED", `lease already released: cannot acquire "${label}"`, { label });
|
|
49
|
+
}
|
|
50
|
+
const buffer = this.pool.acquire(byteLength, usage, label);
|
|
51
|
+
this.buffers.add(buffer);
|
|
52
|
+
return buffer;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Releases every buffer acquired through this lease; idempotent. A pool that `ctx.dispose()` already
|
|
56
|
+
* destroyed has nothing left to take back, so its E_DISPOSED is swallowed here: the lease sits in a
|
|
57
|
+
* `finally` block and must never mask the error that unwound the algorithm.
|
|
58
|
+
*/
|
|
59
|
+
release() {
|
|
60
|
+
if (this.released) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
this.released = true;
|
|
64
|
+
const owned = [...this.buffers];
|
|
65
|
+
this.buffers.clear();
|
|
66
|
+
for (const buffer of owned) {
|
|
67
|
+
try {
|
|
68
|
+
this.pool.release(buffer);
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
if (!hasErrorCode(error, "E_DISPOSED")) {
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Live buffers of this lease.
|
|
79
|
+
* @returns the number of buffers acquired through the lease and not yet released
|
|
80
|
+
*/
|
|
81
|
+
get count() {
|
|
82
|
+
return this.buffers.size;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=lease.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lease.js","sourceRoot":"","sources":["../../../src/memory/lease.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAG9D,8HAA8H;AAC9H,MAAM,OAAO,KAAK;IAKd;;;OAGG;IACH,YAAY,IAAgB;QAPX,YAAO,GAAG,IAAI,GAAG,EAAa,CAAC;QACxC,aAAQ,GAAG,KAAK,CAAC;QAOrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,UAAkB,EAAE,KAAa;QACrC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC9G,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,UAAkB,EAAE,KAAa;QACrC,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IACvF,CAAC;IAED;;;;;;OAMG;IACH,OAAO,CAAC,UAAkB,EAAE,KAAa,EAAE,KAAa;QACpD,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,MAAM,IAAI,gBAAgB,CAAC,YAAY,EAAE,2CAA2C,KAAK,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC7G,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC3D,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACzB,OAAO,MAAM,CAAC;IAClB,CAAC;IAED;;;;OAIG;IACH,OAAO;QACH,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChB,OAAO;QACX,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QACrB,KAAK,MAAM,MAAM,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC9B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,YAAY,CAAC,EAAE,CAAC;oBACrC,MAAM,KAAK,CAAC;gBAChB,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,IAAI,KAAK;QACL,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC7B,CAAC;CACJ"}
|