@graphty/webgpu-graph-algorithms 0.6.6 → 0.6.7

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.
@@ -12,6 +12,17 @@ import { GpuContext } from "../context.js";
12
12
  import { WebGpuGraphError } from "../errors.js";
13
13
  /** The install hint of E_NO_WEBGPU (spec 2.5 item 4); P-ENV re-pins the version together with the devDependency. */
14
14
  const INSTALL_HINT = "install the optional peer dependency webgpu@0.4.0";
15
+ /**
16
+ * Every GPU object `dawn.create()` returned, per module and flag list, kept for the life of the process.
17
+ * webgpu@0.4.0's adapters, devices and queues run their promises through an AsyncRunner that polls the Dawn
18
+ * instance by RAW pointer, and only the GPU object owns that instance: once the GPU object is collected, the
19
+ * next promise on any adapter or device it produced (a requestDevice on a probed adapter, a queue call or a
20
+ * late map / lost callback of a destroyed device) polls freed memory -- SIGSEGV in
21
+ * dawn::native::InstanceBase::ProcessEvents, on Metal and lavapipe alike (issue #30). dawn-node signals no
22
+ * point at which the instance has drained, so no GPU object is ever released; sharing one per flag list
23
+ * bounds what that keeps to one instance per configuration.
24
+ */
25
+ const instances = new Map();
15
26
  /**
16
27
  * Whether a loaded module is usable as Dawn.
17
28
  * @param loaded - the module namespace
@@ -79,9 +90,11 @@ export function dawnFlags(options) {
79
90
  return flags;
80
91
  }
81
92
  /**
82
- * import("webgpu"), install dawn.globals unless installGlobals === false, dawn.create(flags) (spec 2.3).
93
+ * import("webgpu"), install dawn.globals unless installGlobals === false, dawn.create(flags) (spec 2.3). The GPU
94
+ * object is created once per flag list and reused by every later call with the same flags; it is never released,
95
+ * because Dawn keeps polling its instance for the adapters and devices it produced (issue #30).
83
96
  * @param options - adapter / backend / dawnFeatures / software / installGlobals (and the test seam)
84
- * @returns the handle; `dispose()` drops the GPU reference so the process can exit
97
+ * @returns the handle; `dispose()` drops the handle's reference, never the shared instance
85
98
  * @throws WebGpuGraphError E_NO_WEBGPU { reason, hint } when the module does not load (missing, or its glibc is too old), has no create(), or create(flags) throws
86
99
  */
87
100
  export async function createNodeGpu(options) {
@@ -101,13 +114,23 @@ export async function createNodeGpu(options) {
101
114
  if (options?.installGlobals !== false && typeof loaded.globals === "object" && loaded.globals !== null) {
102
115
  Object.assign(globalThis, loaded.globals);
103
116
  }
104
- let gpu;
105
- try {
106
- gpu = loaded.create(dawnFlags(options));
107
- }
108
- catch (err) {
109
- const reason = `dawn.create() threw: ${messageOf(err)}`;
110
- throw new WebGpuGraphError("E_NO_WEBGPU", `${reason}; ${INSTALL_HINT}`, { reason, hint: INSTALL_HINT });
117
+ const flags = dawnFlags(options);
118
+ const key = flags.join("\n");
119
+ let byFlags = instances.get(loaded);
120
+ if (byFlags === undefined) {
121
+ byFlags = new Map();
122
+ instances.set(loaded, byFlags);
123
+ }
124
+ let gpu = byFlags.get(key);
125
+ if (gpu === undefined) {
126
+ try {
127
+ gpu = loaded.create(flags);
128
+ }
129
+ catch (err) {
130
+ const reason = `dawn.create() threw: ${messageOf(err)}`;
131
+ throw new WebGpuGraphError("E_NO_WEBGPU", `${reason}; ${INSTALL_HINT}`, { reason, hint: INSTALL_HINT });
132
+ }
133
+ byFlags.set(key, gpu);
111
134
  }
112
135
  return new DawnHandle(gpu);
113
136
  }
@@ -131,10 +154,9 @@ function contextOptionsOf(options) {
131
154
  }
132
155
  /**
133
156
  * createNodeGpu + GpuContext.create({ gpu, runtime: "node", ...options }); ctx.dispose() also disposes the
134
- * handle, and a create() failure disposes it before rethrowing. The handle is dropped once `ctx.lost` has
135
- * settled, never before: under webgpu@0.4.0 a GPU object collected while the device it created is still
136
- * tearing down (its lost / work-done callbacks in flight) crashes or deadlocks the process (PLAN DECISION,
137
- * P1-T1; measured with tmp/p1t1/gc-race2.mjs), and device.destroy() reports the loss right away.
157
+ * handle, and a create() failure disposes it before rethrowing. Disposing is safe at any moment: the Dawn
158
+ * instance itself stays alive for the process (createNodeGpu), so a callback of the destroyed device that
159
+ * arrives late, or a call on `ctx.device` after dispose(), never reaches a freed instance.
138
160
  * @param options - the Node options
139
161
  * @returns the context
140
162
  */
@@ -148,11 +170,8 @@ export async function createNodeGpuContext(options) {
148
170
  handle.dispose();
149
171
  throw err;
150
172
  }
151
- const { lost } = ctx;
152
173
  ctx.attachDisposer(() => {
153
- void lost.then(() => {
154
- handle.dispose();
155
- });
174
+ handle.dispose();
156
175
  });
157
176
  return ctx;
158
177
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/node/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/node/index.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { W as WebGpuGraphError, U as UNIFORM_SLOT_BYTES, B as BufferUsage, M as MAX_WORKGROUPS_PER_DIM, a as WGSL_RESERVED_WORDS, S as STATE_HEADER_BYTES, d as deviceLostError, i as isWebGpuGraphError, b as U32_MAX$2, c as MAX_LEVELS_PER_SUBMIT, R as RADIX_BINS, F as FUSED_FRONTIER_MAX, e as BEAMER_BETA, f as SSSP_DELTA_FACTOR, g as F32_INF_BITS, h as GRID_COARSEST_SIDE, j as GRID_MIN_SIDE, k as GRID_SORT_BITS, l as FA2_DEFAULTS, m as MAX_ITERATIONS_PER_STEP, n as MAX_1D_ITEMS, o as hasErrorCode, p as FA2_FLAG_FIRST, P as PARTIAL_BYTES, E as EXACT_TILES_PER_PASS, I as INDIRECT_ARGS_STRIDE, q as GRID_HUB_CELL, L as LAYOUT_TUNING_DEFAULTS, r as EXACT_MAX_NODES, s as SETTLE_FLOOR_UNBOUNDED, T as TRACE_RECORD_BYTES, t as GRID_BBOX_MARGIN, u as GRID_EXTENT_FLOOR, v as FR_ADAPTIVE_MAX_ITERATIONS, w as FR_START_TEMPERATURE, x as FA2_FLAG_ADAPTIVE, y as SETTLE_FLOOR_FRACTION, z as FR_REHEAT_FRACTION, A as FR_DEFAULTS, C as SE_DEFAULTS, D as SETTLE_FLOOR_REFERENCE_NODES, H as SE_SCALE_REFERENCE_NODES } from "./chunks/context-DiSr6eiz.js";
2
- import { J, G, K, N, O, Q } from "./chunks/context-DiSr6eiz.js";
1
+ import { W as WebGpuGraphError, U as UNIFORM_SLOT_BYTES, B as BufferUsage, M as MAX_WORKGROUPS_PER_DIM, a as WGSL_RESERVED_WORDS, S as STATE_HEADER_BYTES, d as deviceLostError, i as isWebGpuGraphError, b as U32_MAX$2, c as MAX_LEVELS_PER_SUBMIT, R as RADIX_BINS, F as FUSED_FRONTIER_MAX, e as BEAMER_BETA, f as SSSP_DELTA_FACTOR, g as F32_INF_BITS, h as GRID_COARSEST_SIDE, j as GRID_MIN_SIDE, k as GRID_SORT_BITS, l as FA2_DEFAULTS, m as MAX_ITERATIONS_PER_STEP, n as MAX_1D_ITEMS, o as hasErrorCode, p as FA2_FLAG_FIRST, P as PARTIAL_BYTES, E as EXACT_TILES_PER_PASS, I as INDIRECT_ARGS_STRIDE, q as GRID_HUB_CELL, L as LAYOUT_TUNING_DEFAULTS, r as EXACT_MAX_NODES, s as SETTLE_FLOOR_UNBOUNDED, T as TRACE_RECORD_BYTES, t as GRID_BBOX_MARGIN, u as GRID_EXTENT_FLOOR, v as FR_ADAPTIVE_MAX_ITERATIONS, w as FR_START_TEMPERATURE, x as FA2_FLAG_ADAPTIVE, y as SETTLE_FLOOR_FRACTION, z as FR_REHEAT_FRACTION, A as FR_DEFAULTS, C as SE_DEFAULTS, D as SETTLE_FLOOR_REFERENCE_NODES, H as SE_SCALE_REFERENCE_NODES } from "./chunks/context-Cezi7qpi.js";
2
+ import { J, G, K, N, O, Q } from "./chunks/context-Cezi7qpi.js";
3
3
  import { renumberPartition, INVALID_INDEX, makeMask, maskTest, expandEdges, fromEdgeArrays } from "@graphty/graph-format";
4
4
  class UniformRing {
5
5
  /**
@@ -5098,7 +5098,7 @@ async function prepareSpmvPull(scope, rev, options) {
5098
5098
  return new SpmvPullPlannerImpl(scope, compiled, perm, options.weights);
5099
5099
  }
5100
5100
  const PR_BATCH = 8;
5101
- const RING_SLOTS$4 = 2 * PR_BATCH + 1;
5101
+ const RING_SLOTS$4 = 2 * PR_BATCH + 2;
5102
5102
  function checkDest$3(dest, n, algorithm) {
5103
5103
  if (dest === void 0) {
5104
5104
  return null;
@@ -5188,6 +5188,7 @@ async function run(ctx, s, personalization, options, algorithm) {
5188
5188
  const groups = groupsOf(scalePlan);
5189
5189
  const partialsBytes = PR_PARTIAL.byteLength * (1 + groups);
5190
5190
  const partials = scope.scratch(partialsBytes, "partials");
5191
+ const lastHeader = scope.scratch(PR_PARTIAL.byteLength, "lastHeader");
5191
5192
  if (personalization !== null) {
5192
5193
  uploaded = ctx.residency.array(personalization, `${algorithm}/personalization`);
5193
5194
  }
@@ -5216,17 +5217,19 @@ async function run(ctx, s, personalization, options, algorithm) {
5216
5217
  const xNormBinding = bindingOf$2(xNorm, bytes);
5217
5218
  const outWeightSumBinding = bindingOf$2(outWeightSum, bytes);
5218
5219
  const partialsBinding = bindingOf$2(partials, partialsBytes);
5220
+ const lastHeaderBinding = bindingOf$2(lastHeader, PR_PARTIAL.byteLength);
5219
5221
  const coefficients = { alpha, beta: 1 - alpha, uniformP: 1 / n };
5220
5222
  let cur = 0;
5221
5223
  let iterationsRun = 0;
5222
5224
  for (; ; ) {
5223
5225
  const k = Math.min(PR_BATCH, maxIterations - iterationsRun);
5224
5226
  const batch = new CommandBatch(ctx, algorithm);
5225
- const pass = batch.pass("iterations");
5227
+ let pass = batch.pass("iterations");
5226
5228
  if (iterationsRun === 0) {
5227
5229
  normaliser.record(pass, weightedCore, outWeightSumBinding);
5228
5230
  }
5229
- for (let i = 0; i < k; i++) {
5231
+ const last = iterationsRun + k === maxIterations;
5232
+ for (let i = 0; i < k + (last ? 1 : 0); i++) {
5230
5233
  const params = scope.params(PR_PARAMS, {
5231
5234
  n,
5232
5235
  groups,
@@ -5235,6 +5238,10 @@ async function run(ctx, s, personalization, options, algorithm) {
5235
5238
  convergeThreshold: tolerance * n
5236
5239
  });
5237
5240
  const other = 1 - cur;
5241
+ if (i === k) {
5242
+ batch.copy(partialsBinding, lastHeaderBinding, PR_PARTIAL.byteLength);
5243
+ pass = batch.pass("convergence");
5244
+ }
5238
5245
  const scaleBound = scale.bind({
5239
5246
  rankIn: rank[cur],
5240
5247
  rankPrev: rank[other],
@@ -5246,6 +5253,9 @@ async function run(ctx, s, personalization, options, algorithm) {
5246
5253
  scale.dispatch(pass, scaleBound, scalePlan, [params.offset]);
5247
5254
  const finalizeBound = finalize.bind({ partials: partialsBinding, P: params.binding });
5248
5255
  finalize.dispatch(pass, finalizeBound, finalizePlan, [params.offset]);
5256
+ if (i === k) {
5257
+ break;
5258
+ }
5249
5259
  pull.record(
5250
5260
  pass,
5251
5261
  weightedRev,
@@ -5261,6 +5271,7 @@ async function run(ctx, s, personalization, options, algorithm) {
5261
5271
  }
5262
5272
  batch.endPass();
5263
5273
  const headerRequest = batch.readback(partials, 0, PR_PARTIAL.byteLength);
5274
+ const lastHeaderRequest = last ? batch.readback(lastHeader, 0, PR_PARTIAL.byteLength) : headerRequest;
5264
5275
  const scoresRequest = batch.readback(rank[cur].buffer, 0, bytes);
5265
5276
  scope.flush();
5266
5277
  const submitted = batch.submit();
@@ -5284,7 +5295,7 @@ async function run(ctx, s, personalization, options, algorithm) {
5284
5295
  scores,
5285
5296
  iterations: converged ? firstConverged : iterationsRun,
5286
5297
  converged,
5287
- danglingMass: folded.danglingMass,
5298
+ danglingMass: PR_PARTIAL.read(new DataView(back), lastHeaderRequest.offset).danglingMass,
5288
5299
  precision: "f32"
5289
5300
  };
5290
5301
  }
@@ -5403,7 +5414,8 @@ async function runPowerIteration(ctx, n, config) {
5403
5414
  const k = Math.min(BATCH, config.maxIterations - iterationsRun);
5404
5415
  const batch = new CommandBatch(ctx, config.label);
5405
5416
  const pass = batch.pass("iterations");
5406
- for (let i = 0; i < k; i++) {
5417
+ const last = iterationsRun + k === config.maxIterations;
5418
+ for (let i = 0; i < k + (last ? 1 : 0); i++) {
5407
5419
  const iteration = iterationsRun + i + 1;
5408
5420
  const params = scope.params(PR_PARAMS, {
5409
5421
  n,
@@ -5425,6 +5437,9 @@ async function runPowerIteration(ctx, n, config) {
5425
5437
  };
5426
5438
  scaleNorm.dispatch(pass, scaleNorm.bind(scaleBindings), scalePlan, [params.offset]);
5427
5439
  finalize.dispatch(pass, finalize.bind({ partials, P: params.binding }), finalizePlan, [params.offset]);
5440
+ if (i === k) {
5441
+ break;
5442
+ }
5428
5443
  if (scaleApply !== null) {
5429
5444
  scaleApply.dispatch(pass, scaleApply.bind(scaleBindings), scalePlan, [params.offset]);
5430
5445
  }