@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.
Files changed (269) hide show
  1. package/README.md +344 -23
  2. package/dist/browser.d.ts +1 -0
  3. package/dist/browser.js +32 -0
  4. package/dist/browser.js.map +1 -0
  5. package/dist/chunks/context-E6iKaeuJ.js +3136 -0
  6. package/dist/chunks/context-E6iKaeuJ.js.map +1 -0
  7. package/dist/node.d.ts +1 -0
  8. package/dist/node.js +131 -0
  9. package/dist/node.js.map +1 -0
  10. package/dist/src/accelerator.d.ts +26 -0
  11. package/dist/src/accelerator.d.ts.map +1 -0
  12. package/dist/src/accelerator.js +101 -0
  13. package/dist/src/accelerator.js.map +1 -0
  14. package/dist/src/algorithms/degree.d.ts +35 -0
  15. package/dist/src/algorithms/degree.d.ts.map +1 -0
  16. package/dist/src/algorithms/degree.js +119 -0
  17. package/dist/src/algorithms/degree.js.map +1 -0
  18. package/dist/src/browser/index.d.ts +23 -0
  19. package/dist/src/browser/index.d.ts.map +1 -0
  20. package/dist/src/browser/index.js +48 -0
  21. package/dist/src/browser/index.js.map +1 -0
  22. package/dist/src/constants.d.ts +92 -0
  23. package/dist/src/constants.d.ts.map +1 -0
  24. package/dist/src/constants.js +92 -0
  25. package/dist/src/constants.js.map +1 -0
  26. package/dist/src/context.d.ts +84 -0
  27. package/dist/src/context.d.ts.map +1 -0
  28. package/dist/src/context.js +304 -0
  29. package/dist/src/context.js.map +1 -0
  30. package/dist/src/device/acquire.d.ts +57 -0
  31. package/dist/src/device/acquire.d.ts.map +1 -0
  32. package/dist/src/device/acquire.js +232 -0
  33. package/dist/src/device/acquire.js.map +1 -0
  34. package/dist/src/device/caps.d.ts +43 -0
  35. package/dist/src/device/caps.d.ts.map +1 -0
  36. package/dist/src/device/caps.js +104 -0
  37. package/dist/src/device/caps.js.map +1 -0
  38. package/dist/src/device/error-scope.d.ts +75 -0
  39. package/dist/src/device/error-scope.d.ts.map +1 -0
  40. package/dist/src/device/error-scope.js +152 -0
  41. package/dist/src/device/error-scope.js.map +1 -0
  42. package/dist/src/device/lost.d.ts +51 -0
  43. package/dist/src/device/lost.d.ts.map +1 -0
  44. package/dist/src/device/lost.js +130 -0
  45. package/dist/src/device/lost.js.map +1 -0
  46. package/dist/src/device/webgpu-constants.d.ts +31 -0
  47. package/dist/src/device/webgpu-constants.d.ts.map +1 -0
  48. package/dist/src/device/webgpu-constants.js +31 -0
  49. package/dist/src/device/webgpu-constants.js.map +1 -0
  50. package/dist/src/errors.d.ts +56 -0
  51. package/dist/src/errors.d.ts.map +1 -0
  52. package/dist/src/errors.js +57 -0
  53. package/dist/src/errors.js.map +1 -0
  54. package/dist/src/index.d.ts +29 -0
  55. package/dist/src/index.d.ts.map +1 -0
  56. package/dist/src/index.js +27 -0
  57. package/dist/src/index.js.map +1 -0
  58. package/dist/src/kernel/batch.d.ts +116 -0
  59. package/dist/src/kernel/batch.d.ts.map +1 -0
  60. package/dist/src/kernel/batch.js +335 -0
  61. package/dist/src/kernel/batch.js.map +1 -0
  62. package/dist/src/kernel/dispatch.d.ts +59 -0
  63. package/dist/src/kernel/dispatch.d.ts.map +1 -0
  64. package/dist/src/kernel/dispatch.js +139 -0
  65. package/dist/src/kernel/dispatch.js.map +1 -0
  66. package/dist/src/kernel/kernel.d.ts +84 -0
  67. package/dist/src/kernel/kernel.d.ts.map +1 -0
  68. package/dist/src/kernel/kernel.js +239 -0
  69. package/dist/src/kernel/kernel.js.map +1 -0
  70. package/dist/src/kernel/pipeline-cache.d.ts +90 -0
  71. package/dist/src/kernel/pipeline-cache.d.ts.map +1 -0
  72. package/dist/src/kernel/pipeline-cache.js +251 -0
  73. package/dist/src/kernel/pipeline-cache.js.map +1 -0
  74. package/dist/src/kernel/prelude.d.ts +35 -0
  75. package/dist/src/kernel/prelude.d.ts.map +1 -0
  76. package/dist/src/kernel/prelude.js +211 -0
  77. package/dist/src/kernel/prelude.js.map +1 -0
  78. package/dist/src/kernel/profiler.d.ts +64 -0
  79. package/dist/src/kernel/profiler.d.ts.map +1 -0
  80. package/dist/src/kernel/profiler.js +120 -0
  81. package/dist/src/kernel/profiler.js.map +1 -0
  82. package/dist/src/kernel/struct-block.d.ts +122 -0
  83. package/dist/src/kernel/struct-block.d.ts.map +1 -0
  84. package/dist/src/kernel/struct-block.js +353 -0
  85. package/dist/src/kernel/struct-block.js.map +1 -0
  86. package/dist/src/kernel/uniform-ring.d.ts +70 -0
  87. package/dist/src/kernel/uniform-ring.d.ts.map +1 -0
  88. package/dist/src/kernel/uniform-ring.js +146 -0
  89. package/dist/src/kernel/uniform-ring.js.map +1 -0
  90. package/dist/src/kernel/wgsl.d.ts +88 -0
  91. package/dist/src/kernel/wgsl.d.ts.map +1 -0
  92. package/dist/src/kernel/wgsl.js +390 -0
  93. package/dist/src/kernel/wgsl.js.map +1 -0
  94. package/dist/src/kernels.d.ts +81 -0
  95. package/dist/src/kernels.d.ts.map +1 -0
  96. package/dist/src/kernels.js +417 -0
  97. package/dist/src/kernels.js.map +1 -0
  98. package/dist/src/layouts/force-simulation.d.ts +498 -0
  99. package/dist/src/layouts/force-simulation.d.ts.map +1 -0
  100. package/dist/src/layouts/force-simulation.js +1650 -0
  101. package/dist/src/layouts/force-simulation.js.map +1 -0
  102. package/dist/src/layouts/forceatlas2.d.ts +210 -0
  103. package/dist/src/layouts/forceatlas2.d.ts.map +1 -0
  104. package/dist/src/layouts/forceatlas2.js +759 -0
  105. package/dist/src/layouts/forceatlas2.js.map +1 -0
  106. package/dist/src/layouts/inputs.d.ts +40 -0
  107. package/dist/src/layouts/inputs.d.ts.map +1 -0
  108. package/dist/src/layouts/inputs.js +185 -0
  109. package/dist/src/layouts/inputs.js.map +1 -0
  110. package/dist/src/layouts/repulsion-exact.d.ts +85 -0
  111. package/dist/src/layouts/repulsion-exact.d.ts.map +1 -0
  112. package/dist/src/layouts/repulsion-exact.js +134 -0
  113. package/dist/src/layouts/repulsion-exact.js.map +1 -0
  114. package/dist/src/layouts/seed.d.ts +56 -0
  115. package/dist/src/layouts/seed.d.ts.map +1 -0
  116. package/dist/src/layouts/seed.js +173 -0
  117. package/dist/src/layouts/seed.js.map +1 -0
  118. package/dist/src/memory/buffer-pool.d.ts +73 -0
  119. package/dist/src/memory/buffer-pool.d.ts.map +1 -0
  120. package/dist/src/memory/buffer-pool.js +170 -0
  121. package/dist/src/memory/buffer-pool.js.map +1 -0
  122. package/dist/src/memory/lease.d.ts +53 -0
  123. package/dist/src/memory/lease.d.ts.map +1 -0
  124. package/dist/src/memory/lease.js +85 -0
  125. package/dist/src/memory/lease.js.map +1 -0
  126. package/dist/src/memory/readback.d.ts +143 -0
  127. package/dist/src/memory/readback.d.ts.map +1 -0
  128. package/dist/src/memory/readback.js +375 -0
  129. package/dist/src/memory/readback.js.map +1 -0
  130. package/dist/src/memory/residency.d.ts +83 -0
  131. package/dist/src/memory/residency.d.ts.map +1 -0
  132. package/dist/src/memory/residency.js +573 -0
  133. package/dist/src/memory/residency.js.map +1 -0
  134. package/dist/src/memory/upload-plan.d.ts +101 -0
  135. package/dist/src/memory/upload-plan.d.ts.map +1 -0
  136. package/dist/src/memory/upload-plan.js +265 -0
  137. package/dist/src/memory/upload-plan.js.map +1 -0
  138. package/dist/src/node/index.d.ts +64 -0
  139. package/dist/src/node/index.d.ts.map +1 -0
  140. package/dist/src/node/index.js +183 -0
  141. package/dist/src/node/index.js.map +1 -0
  142. package/dist/src/primitives/reduce.d.ts +57 -0
  143. package/dist/src/primitives/reduce.d.ts.map +1 -0
  144. package/dist/src/primitives/reduce.js +161 -0
  145. package/dist/src/primitives/reduce.js.map +1 -0
  146. package/dist/src/primitives/segmented-reduce.d.ts +38 -0
  147. package/dist/src/primitives/segmented-reduce.d.ts.map +1 -0
  148. package/dist/src/primitives/segmented-reduce.js +211 -0
  149. package/dist/src/primitives/segmented-reduce.js.map +1 -0
  150. package/dist/src/types/accelerator.d.ts +209 -0
  151. package/dist/src/types/accelerator.d.ts.map +1 -0
  152. package/dist/src/types/accelerator.js +8 -0
  153. package/dist/src/types/accelerator.js.map +1 -0
  154. package/dist/src/types/context.d.ts +114 -0
  155. package/dist/src/types/context.d.ts.map +1 -0
  156. package/dist/src/types/context.js +7 -0
  157. package/dist/src/types/context.js.map +1 -0
  158. package/dist/src/types/layout.d.ts +95 -0
  159. package/dist/src/types/layout.d.ts.map +1 -0
  160. package/dist/src/types/layout.js +6 -0
  161. package/dist/src/types/layout.js.map +1 -0
  162. package/dist/src/types/memory.d.ts +22 -0
  163. package/dist/src/types/memory.d.ts.map +1 -0
  164. package/dist/src/types/memory.js +7 -0
  165. package/dist/src/types/memory.js.map +1 -0
  166. package/dist/src/types/options.d.ts +78 -0
  167. package/dist/src/types/options.d.ts.map +1 -0
  168. package/dist/src/types/options.js +7 -0
  169. package/dist/src/types/options.js.map +1 -0
  170. package/dist/src/types/run.d.ts +13 -0
  171. package/dist/src/types/run.d.ts.map +1 -0
  172. package/dist/src/types/run.js +6 -0
  173. package/dist/src/types/run.js.map +1 -0
  174. package/dist/src/wgsl/degree.wgsl.d.ts +10 -0
  175. package/dist/src/wgsl/degree.wgsl.d.ts.map +1 -0
  176. package/dist/src/wgsl/degree.wgsl.js +25 -0
  177. package/dist/src/wgsl/degree.wgsl.js.map +1 -0
  178. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts +12 -0
  179. package/dist/src/wgsl/fa2-attraction.wgsl.d.ts.map +1 -0
  180. package/dist/src/wgsl/fa2-attraction.wgsl.js +37 -0
  181. package/dist/src/wgsl/fa2-attraction.wgsl.js.map +1 -0
  182. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts +13 -0
  183. package/dist/src/wgsl/fa2-integrate.wgsl.d.ts.map +1 -0
  184. package/dist/src/wgsl/fa2-integrate.wgsl.js +69 -0
  185. package/dist/src/wgsl/fa2-integrate.wgsl.js.map +1 -0
  186. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts +12 -0
  187. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.d.ts.map +1 -0
  188. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js +79 -0
  189. package/dist/src/wgsl/fa2-repulsion-exact.wgsl.js.map +1 -0
  190. package/dist/src/wgsl/fa2-speed-finalize.wgsl.d.ts +15 -0
  191. package/dist/src/wgsl/fa2-speed-finalize.wgsl.d.ts.map +1 -0
  192. package/dist/src/wgsl/fa2-speed-finalize.wgsl.js +54 -0
  193. package/dist/src/wgsl/fa2-speed-finalize.wgsl.js.map +1 -0
  194. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts +14 -0
  195. package/dist/src/wgsl/fa2-stats-finalize.wgsl.d.ts.map +1 -0
  196. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js +57 -0
  197. package/dist/src/wgsl/fa2-stats-finalize.wgsl.js.map +1 -0
  198. package/dist/src/wgsl/fa2-to-scene.wgsl.d.ts +11 -0
  199. package/dist/src/wgsl/fa2-to-scene.wgsl.d.ts.map +1 -0
  200. package/dist/src/wgsl/fa2-to-scene.wgsl.js +19 -0
  201. package/dist/src/wgsl/fa2-to-scene.wgsl.js.map +1 -0
  202. package/dist/src/wgsl/fill.wgsl.d.ts +7 -0
  203. package/dist/src/wgsl/fill.wgsl.d.ts.map +1 -0
  204. package/dist/src/wgsl/fill.wgsl.js +14 -0
  205. package/dist/src/wgsl/fill.wgsl.js.map +1 -0
  206. package/dist/src/wgsl/reduce.wgsl.d.ts +10 -0
  207. package/dist/src/wgsl/reduce.wgsl.d.ts.map +1 -0
  208. package/dist/src/wgsl/reduce.wgsl.js +63 -0
  209. package/dist/src/wgsl/reduce.wgsl.js.map +1 -0
  210. package/dist/src/wgsl/segmented-reduce.wgsl.d.ts +13 -0
  211. package/dist/src/wgsl/segmented-reduce.wgsl.d.ts.map +1 -0
  212. package/dist/src/wgsl/segmented-reduce.wgsl.js +35 -0
  213. package/dist/src/wgsl/segmented-reduce.wgsl.js.map +1 -0
  214. package/dist/tsconfig.build.tsbuildinfo +1 -0
  215. package/dist/webgpu-graph-algorithms.d.ts +1 -0
  216. package/dist/webgpu-graph-algorithms.js +4454 -0
  217. package/dist/webgpu-graph-algorithms.js.map +1 -0
  218. package/package.json +108 -17
  219. package/src/accelerator.ts +117 -0
  220. package/src/algorithms/degree.ts +142 -0
  221. package/src/browser/index.ts +57 -0
  222. package/src/constants.ts +116 -0
  223. package/src/context.ts +399 -0
  224. package/src/device/acquire.ts +256 -0
  225. package/src/device/caps.ts +122 -0
  226. package/src/device/error-scope.ts +171 -0
  227. package/src/device/lost.ts +142 -0
  228. package/src/device/webgpu-constants.ts +44 -0
  229. package/src/errors.ts +94 -0
  230. package/src/index.ts +102 -0
  231. package/src/kernel/batch.ts +427 -0
  232. package/src/kernel/dispatch.ts +162 -0
  233. package/src/kernel/kernel.ts +311 -0
  234. package/src/kernel/pipeline-cache.ts +288 -0
  235. package/src/kernel/prelude.ts +229 -0
  236. package/src/kernel/profiler.ts +148 -0
  237. package/src/kernel/struct-block.ts +439 -0
  238. package/src/kernel/uniform-ring.ts +184 -0
  239. package/src/kernel/wgsl.ts +490 -0
  240. package/src/kernels.ts +511 -0
  241. package/src/layouts/force-simulation.ts +2111 -0
  242. package/src/layouts/forceatlas2.ts +942 -0
  243. package/src/layouts/inputs.ts +252 -0
  244. package/src/layouts/repulsion-exact.ts +183 -0
  245. package/src/layouts/seed.ts +198 -0
  246. package/src/memory/buffer-pool.ts +204 -0
  247. package/src/memory/lease.ts +93 -0
  248. package/src/memory/readback.ts +429 -0
  249. package/src/memory/residency.ts +753 -0
  250. package/src/memory/upload-plan.ts +350 -0
  251. package/src/node/index.ts +230 -0
  252. package/src/primitives/reduce.ts +233 -0
  253. package/src/primitives/segmented-reduce.ts +270 -0
  254. package/src/types/accelerator.ts +236 -0
  255. package/src/types/context.ts +135 -0
  256. package/src/types/layout.ts +103 -0
  257. package/src/types/memory.ts +23 -0
  258. package/src/types/options.ts +84 -0
  259. package/src/types/run.ts +13 -0
  260. package/src/wgsl/degree.wgsl.ts +24 -0
  261. package/src/wgsl/fa2-attraction.wgsl.ts +37 -0
  262. package/src/wgsl/fa2-integrate.wgsl.ts +69 -0
  263. package/src/wgsl/fa2-repulsion-exact.wgsl.ts +78 -0
  264. package/src/wgsl/fa2-speed-finalize.wgsl.ts +53 -0
  265. package/src/wgsl/fa2-stats-finalize.wgsl.ts +57 -0
  266. package/src/wgsl/fa2-to-scene.wgsl.ts +19 -0
  267. package/src/wgsl/fill.wgsl.ts +13 -0
  268. package/src/wgsl/reduce.wgsl.ts +62 -0
  269. package/src/wgsl/segmented-reduce.wgsl.ts +35 -0
@@ -0,0 +1,143 @@
1
+ /**
2
+ * The staging ring of spec 4.4: a ring of MAP_READ | COPY_DST buffers (default DEFAULT_STAGING_SLOTS slots of 4 MiB,
3
+ * PLAN DECISION 15) through which every readback of the package flows. `read()` copies with its own encoder and
4
+ * submit, awaits mapAsync, copies out of the mapped range BEFORE unmap (the range is detached at unmap, design 10.7)
5
+ * and never polls onSubmittedWorkDone; requests above the slot size are chunked. Ownership is one-directional: the
6
+ * ring owns its buffers; a CommandBatch (P2) BORROWS one slot through borrowSlot, maps it through mapSlot and always
7
+ * returns it through returnSlot, which unmaps it. Slots at or above OOM_SCOPE_THRESHOLD_BYTES are created through the
8
+ * AllocationTracker (the out-of-memory scope of spec 5.7), the default-size ones directly on the device, so the
9
+ * allocator counts residency and pool buffers only. A mapAsync rejection is E_DEVICE_LOST (or E_DISPOSED after
10
+ * destroyAll).
11
+ *
12
+ * The one invariant every path keeps: a staging buffer whose mapAsync is PENDING is never unmapped and never
13
+ * destroyed. dawn-node 0.4.0 settles the pending promise synchronously on unmap() / destroy() and settles it a
14
+ * second time when Dawn's map callback arrives (a SIGSEGV in AsyncRunner::Reject); on the Vulkan backends the
15
+ * callback has already run inside device.destroy(), on Dawn's Metal backend it arrives after the device-lost
16
+ * fan-out, which is where the macOS host lane lost its vitest worker (CLAUDE.md "Verified Platform Facts"). The
17
+ * ring therefore tracks every map on its slots (mapPending) and defers an unmap, a return or a destroy that
18
+ * arrives during one to the moment the map settles.
19
+ */
20
+ import { type AllocationTracker } from "../device/error-scope.js";
21
+ /**
22
+ * One MAP_READ | COPY_DST staging buffer of the ring. Exported for the borrowers of borrowSlot / returnSlot
23
+ * (contract 3.8): P2-T1's CommandBatch imports it as a type; nothing at P1 imports it by name.
24
+ * @public
25
+ */
26
+ export interface StagingSlot {
27
+ readonly index: number;
28
+ readonly buffer: GPUBuffer;
29
+ readonly capacity: number;
30
+ }
31
+ /** The staging ring (spec 4.4): default 3 slots; grows when every slot is busy; always unmaps and destroys its own buffers. */
32
+ export declare class Readback {
33
+ private readonly device;
34
+ private readonly allocator;
35
+ private readonly slotBytes;
36
+ private readonly ring;
37
+ private disposed;
38
+ /**
39
+ * Creates the ring with `slots` slots of `slotBytes` each.
40
+ * @param device - the device the copies run on
41
+ * @param allocator - the context's OOM-scoped allocator (used for slots at or above OOM_SCOPE_THRESHOLD_BYTES)
42
+ * @param options - ring options
43
+ * @param options.slots - slots created up front; default DEFAULT_STAGING_SLOTS
44
+ * @param options.slotBytes - capacity of each slot and the chunk size of read(); default 4 MiB; a positive multiple of 4
45
+ */
46
+ constructor(device: GPUDevice, allocator: AllocationTracker, options?: {
47
+ readonly slots?: number | undefined;
48
+ readonly slotBytes?: number | undefined;
49
+ });
50
+ /**
51
+ * Copies `byteLength` bytes from `src` at `srcOffset` (own encoder, own submit), maps, copies out BEFORE unmap;
52
+ * resolves the bytes (a fresh ArrayBuffer, or `dest.buffer` after `dest.set` when given). Requests above the slot
53
+ * size are chunked.
54
+ * @param src - a COPY_SRC buffer
55
+ * @param byteLength - bytes to read (a positive multiple of 4, within src)
56
+ * @param dest - an optional destination view of at least byteLength bytes over a plain ArrayBuffer
57
+ * @param srcOffset - the byte offset in src (default 0; a multiple of 4)
58
+ * @returns the bytes read
59
+ */
60
+ read(src: GPUBuffer, byteLength: number, dest?: ArrayBufferView, srcOffset?: number): Promise<ArrayBuffer>;
61
+ /**
62
+ * Reads one u32 counter through the same ring.
63
+ * @param src - a COPY_SRC buffer
64
+ * @param byteOffset - the counter's byte offset (a multiple of 4)
65
+ * @returns the counter value
66
+ */
67
+ readU32(src: GPUBuffer, byteOffset: number): Promise<number>;
68
+ /**
69
+ * Borrows an unmapped slot of at least byteLength (grows the ring when none is free); the borrower ALWAYS
70
+ * returns it (spec 4.4).
71
+ * @param byteLength - the bytes the borrower will copy into the slot
72
+ * @returns the slot
73
+ */
74
+ borrowSlot(byteLength: number): StagingSlot;
75
+ /**
76
+ * mapAsync(READ) on a borrowed slot, tracked by the ring: the slot counts as borrowed, and is neither unmapped
77
+ * nor destroyed, until the map settles (see the file comment). Returns the runtime's own promise, untranslated:
78
+ * the borrower classifies a rejection (a CommandBatch races it against device loss, spec 5.7).
79
+ * @param slot - a slot borrowed from this ring and not yet returned
80
+ * @param byteLength - the bytes to map from offset 0
81
+ * @returns the mapAsync promise
82
+ */
83
+ mapSlot(slot: StagingSlot, byteLength: number): Promise<void>;
84
+ /**
85
+ * Returns a borrowed slot (unmapping it if mapped). A slot whose map through the ring is still pending stays
86
+ * borrowed until the map settles, when the ring unmaps and returns it; a borrower that maps a slot itself must
87
+ * unmap it before returning it (spec 4.4; `mapState` decides when the runtime exposes it, otherwise the ring's
88
+ * own record does). A no-op after destroyAll() (the ring is gone; a borrower's finally must never mask the
89
+ * E_DISPOSED / E_DEVICE_LOST of the read it was serving).
90
+ * @param slot - a slot borrowed from this ring and not yet returned
91
+ */
92
+ returnSlot(slot: StagingSlot): void;
93
+ /**
94
+ * The entry of a slot borrowed from this ring and not yet returned.
95
+ * @param slot - the slot
96
+ * @returns its entry
97
+ */
98
+ private borrowedEntry;
99
+ /**
100
+ * Unmaps a returned slot when it is mapped and frees it.
101
+ * @param entry - the slot's entry (no map pending)
102
+ */
103
+ private finishReturn;
104
+ /**
105
+ * Tracks one mapAsync on a slot: mapPending until it settles, then the deferred work -- the destruction
106
+ * destroyAll() left to the settle, or the return returnSlot() left to it. The handler is attached before the
107
+ * promise is handed out, so it runs before any borrower's continuation.
108
+ * @param entry - the slot's entry
109
+ * @param pending - the runtime's mapAsync promise
110
+ * @returns the same promise
111
+ */
112
+ private track;
113
+ /**
114
+ * Number of slots (grows).
115
+ * @returns the slot count
116
+ */
117
+ get slots(): number;
118
+ /**
119
+ * Slots currently borrowed.
120
+ * @returns the borrowed count
121
+ */
122
+ get borrowed(): number;
123
+ /**
124
+ * Destroys one slot's buffer through the allocator when it was created there.
125
+ * @param entry - the slot
126
+ */
127
+ private destroySlot;
128
+ /**
129
+ * Creates one slot at the end of the ring.
130
+ * @param capacity - the slot's byte capacity
131
+ * @returns the new entry
132
+ */
133
+ private addSlot;
134
+ /**
135
+ * mapAsync(READ) on a slot for read(); a rejection becomes E_DISPOSED (after destroyAll) or E_DEVICE_LOST.
136
+ * @param entry - the ring entry of the borrowed slot
137
+ * @param byteLength - the bytes to map
138
+ */
139
+ private map;
140
+ /** Throws E_DISPOSED after destroyAll(). */
141
+ private assertLive;
142
+ }
143
+ //# sourceMappingURL=readback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readback.d.ts","sourceRoot":"","sources":["../../../src/memory/readback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAalE;;;;GAIG;AACH,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC7B;AAwCD,+HAA+H;AAC/H,qBAAa,QAAQ;IACjB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAY;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoB;IAC9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAmB;IACxC,OAAO,CAAC,QAAQ,CAAS;IAEzB;;;;;;;OAOG;gBAEC,MAAM,EAAE,SAAS,EACjB,SAAS,EAAE,iBAAiB,EAC5B,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;KAAE;IAkB9F;;;;;;;;;OASG;IACG,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,eAAe,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAiDhH;;;;;OAKG;IACG,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKlE;;;;;OAKG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,WAAW;IAkB3C;;;;;;;OAOG;IACH,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAS7D;;;;;;;OAOG;IACH,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IAYnC;;;;OAIG;IACH,OAAO,CAAC,aAAa;IAQrB;;;OAGG;IACH,OAAO,CAAC,YAAY;IAWpB;;;;;;;OAOG;IACH,OAAO,CAAC,KAAK;IA4Bb;;;OAGG;IACH,IAAI,KAAK,IAAI,MAAM,CAElB;IAED;;;OAGG;IACH,IAAI,QAAQ,IAAI,MAAM,CAQrB;IAoBD;;;OAGG;IACH,OAAO,CAAC,WAAW;IAQnB;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAqBf;;;;OAIG;YACW,GAAG;IAwBjB,4CAA4C;IAC5C,OAAO,CAAC,UAAU;CAKrB"}
@@ -0,0 +1,375 @@
1
+ /**
2
+ * The staging ring of spec 4.4: a ring of MAP_READ | COPY_DST buffers (default DEFAULT_STAGING_SLOTS slots of 4 MiB,
3
+ * PLAN DECISION 15) through which every readback of the package flows. `read()` copies with its own encoder and
4
+ * submit, awaits mapAsync, copies out of the mapped range BEFORE unmap (the range is detached at unmap, design 10.7)
5
+ * and never polls onSubmittedWorkDone; requests above the slot size are chunked. Ownership is one-directional: the
6
+ * ring owns its buffers; a CommandBatch (P2) BORROWS one slot through borrowSlot, maps it through mapSlot and always
7
+ * returns it through returnSlot, which unmaps it. Slots at or above OOM_SCOPE_THRESHOLD_BYTES are created through the
8
+ * AllocationTracker (the out-of-memory scope of spec 5.7), the default-size ones directly on the device, so the
9
+ * allocator counts residency and pool buffers only. A mapAsync rejection is E_DEVICE_LOST (or E_DISPOSED after
10
+ * destroyAll).
11
+ *
12
+ * The one invariant every path keeps: a staging buffer whose mapAsync is PENDING is never unmapped and never
13
+ * destroyed. dawn-node 0.4.0 settles the pending promise synchronously on unmap() / destroy() and settles it a
14
+ * second time when Dawn's map callback arrives (a SIGSEGV in AsyncRunner::Reject); on the Vulkan backends the
15
+ * callback has already run inside device.destroy(), on Dawn's Metal backend it arrives after the device-lost
16
+ * fan-out, which is where the macOS host lane lost its vitest worker (CLAUDE.md "Verified Platform Facts"). The
17
+ * ring therefore tracks every map on its slots (mapPending) and defers an unmap, a return or a destroy that
18
+ * arrives during one to the moment the map settles.
19
+ */
20
+ import { DEFAULT_STAGING_SLOTS, OOM_SCOPE_THRESHOLD_BYTES } from "../constants.js";
21
+ import { BufferUsage, MapMode } from "../device/webgpu-constants.js";
22
+ import { WebGpuGraphError } from "../errors.js";
23
+ /** Default capacity of one staging slot (PLAN DECISION 15). */
24
+ const DEFAULT_SLOT_BYTES = 4 * 1024 * 1024;
25
+ /** Every staging buffer is MAP_READ | COPY_DST. */
26
+ const STAGING_USAGE = BufferUsage.MAP_READ | BufferUsage.COPY_DST;
27
+ /** Grown slots are sized in 256-byte steps. */
28
+ const SLOT_GRANULE = 256;
29
+ /**
30
+ * Whether an ArrayBuffer-like is a SharedArrayBuffer (checked by tag so the global need not exist).
31
+ * @param buffer - the buffer to test
32
+ * @returns true for a SharedArrayBuffer
33
+ */
34
+ function isSharedBuffer(buffer) {
35
+ return Object.prototype.toString.call(buffer) === "[object SharedArrayBuffer]";
36
+ }
37
+ /**
38
+ * The E_INVALID_ARGUMENT error of a bad readback argument.
39
+ * @param argument - the argument name
40
+ * @param value - the value given
41
+ * @param expected - what was expected
42
+ * @returns the error to throw
43
+ */
44
+ function invalid(argument, value, expected) {
45
+ return new WebGpuGraphError("E_INVALID_ARGUMENT", `${argument}: expected ${expected}`, {
46
+ argument,
47
+ value,
48
+ expected,
49
+ });
50
+ }
51
+ /** The staging ring (spec 4.4): default 3 slots; grows when every slot is busy; always unmaps and destroys its own buffers. */
52
+ export class Readback {
53
+ /**
54
+ * Creates the ring with `slots` slots of `slotBytes` each.
55
+ * @param device - the device the copies run on
56
+ * @param allocator - the context's OOM-scoped allocator (used for slots at or above OOM_SCOPE_THRESHOLD_BYTES)
57
+ * @param options - ring options
58
+ * @param options.slots - slots created up front; default DEFAULT_STAGING_SLOTS
59
+ * @param options.slotBytes - capacity of each slot and the chunk size of read(); default 4 MiB; a positive multiple of 4
60
+ */
61
+ constructor(device, allocator, options) {
62
+ this.ring = [];
63
+ this.disposed = false;
64
+ const slotBytes = options?.slotBytes ?? DEFAULT_SLOT_BYTES;
65
+ if (!Number.isInteger(slotBytes) || slotBytes <= 0 || slotBytes % 4 !== 0) {
66
+ throw invalid("slotBytes", slotBytes, "a positive multiple of 4");
67
+ }
68
+ const slots = options?.slots ?? DEFAULT_STAGING_SLOTS;
69
+ if (!Number.isInteger(slots) || slots < 0) {
70
+ throw invalid("slots", slots, "a non-negative integer");
71
+ }
72
+ this.device = device;
73
+ this.allocator = allocator;
74
+ this.slotBytes = slotBytes;
75
+ for (let i = 0; i < slots; i++) {
76
+ this.addSlot(slotBytes);
77
+ }
78
+ }
79
+ /**
80
+ * Copies `byteLength` bytes from `src` at `srcOffset` (own encoder, own submit), maps, copies out BEFORE unmap;
81
+ * resolves the bytes (a fresh ArrayBuffer, or `dest.buffer` after `dest.set` when given). Requests above the slot
82
+ * size are chunked.
83
+ * @param src - a COPY_SRC buffer
84
+ * @param byteLength - bytes to read (a positive multiple of 4, within src)
85
+ * @param dest - an optional destination view of at least byteLength bytes over a plain ArrayBuffer
86
+ * @param srcOffset - the byte offset in src (default 0; a multiple of 4)
87
+ * @returns the bytes read
88
+ */
89
+ async read(src, byteLength, dest, srcOffset) {
90
+ this.assertLive();
91
+ const offset = srcOffset ?? 0;
92
+ if (!Number.isInteger(byteLength) || byteLength <= 0 || byteLength % 4 !== 0) {
93
+ throw invalid("byteLength", byteLength, "a positive multiple of 4");
94
+ }
95
+ if (!Number.isInteger(offset) || offset < 0 || offset % 4 !== 0) {
96
+ throw invalid("srcOffset", offset, "a non-negative multiple of 4");
97
+ }
98
+ if (offset + byteLength > src.size) {
99
+ throw invalid("byteLength", byteLength, `srcOffset + byteLength <= src.size (${src.size})`);
100
+ }
101
+ if ((src.usage & BufferUsage.COPY_SRC) === 0) {
102
+ throw invalid("src", src.label, "a buffer with COPY_SRC usage");
103
+ }
104
+ let out;
105
+ let outBytes;
106
+ if (dest === undefined) {
107
+ out = new ArrayBuffer(byteLength);
108
+ outBytes = new Uint8Array(out);
109
+ }
110
+ else {
111
+ if (isSharedBuffer(dest.buffer)) {
112
+ throw invalid("dest", "SharedArrayBuffer", "a view over a plain ArrayBuffer");
113
+ }
114
+ if (dest.byteLength < byteLength) {
115
+ throw invalid("dest", dest.byteLength, `at least ${byteLength} bytes`);
116
+ }
117
+ out = dest.buffer;
118
+ outBytes = new Uint8Array(out, dest.byteOffset, byteLength);
119
+ }
120
+ let done = 0;
121
+ while (done < byteLength) {
122
+ const chunk = Math.min(this.slotBytes, byteLength - done);
123
+ const slot = this.borrowSlot(chunk);
124
+ const entry = this.ring[slot.index];
125
+ try {
126
+ const encoder = this.device.createCommandEncoder({ label: "readback" });
127
+ encoder.copyBufferToBuffer(src, offset + done, slot.buffer, 0, chunk);
128
+ this.device.queue.submit([encoder.finish()]);
129
+ await this.map(entry, chunk);
130
+ outBytes.set(new Uint8Array(slot.buffer.getMappedRange(0, chunk)), done);
131
+ }
132
+ finally {
133
+ this.returnSlot(slot);
134
+ }
135
+ done += chunk;
136
+ }
137
+ return out;
138
+ }
139
+ /**
140
+ * Reads one u32 counter through the same ring.
141
+ * @param src - a COPY_SRC buffer
142
+ * @param byteOffset - the counter's byte offset (a multiple of 4)
143
+ * @returns the counter value
144
+ */
145
+ async readU32(src, byteOffset) {
146
+ const bytes = await this.read(src, 4, undefined, byteOffset);
147
+ return new Uint32Array(bytes)[0];
148
+ }
149
+ /**
150
+ * Borrows an unmapped slot of at least byteLength (grows the ring when none is free); the borrower ALWAYS
151
+ * returns it (spec 4.4).
152
+ * @param byteLength - the bytes the borrower will copy into the slot
153
+ * @returns the slot
154
+ */
155
+ borrowSlot(byteLength) {
156
+ this.assertLive();
157
+ if (!Number.isInteger(byteLength) || byteLength <= 0) {
158
+ throw invalid("byteLength", byteLength, "a positive integer");
159
+ }
160
+ // a free slot is unmapped by construction: returnSlot unmaps, and only a borrower maps
161
+ for (const entry of this.ring) {
162
+ if (!entry.borrowed && entry.slot.capacity >= byteLength) {
163
+ entry.borrowed = true;
164
+ return entry.slot;
165
+ }
166
+ }
167
+ const capacity = Math.max(this.slotBytes, Math.ceil(byteLength / SLOT_GRANULE) * SLOT_GRANULE);
168
+ const entry = this.addSlot(capacity);
169
+ entry.borrowed = true;
170
+ return entry.slot;
171
+ }
172
+ /**
173
+ * mapAsync(READ) on a borrowed slot, tracked by the ring: the slot counts as borrowed, and is neither unmapped
174
+ * nor destroyed, until the map settles (see the file comment). Returns the runtime's own promise, untranslated:
175
+ * the borrower classifies a rejection (a CommandBatch races it against device loss, spec 5.7).
176
+ * @param slot - a slot borrowed from this ring and not yet returned
177
+ * @param byteLength - the bytes to map from offset 0
178
+ * @returns the mapAsync promise
179
+ */
180
+ mapSlot(slot, byteLength) {
181
+ this.assertLive();
182
+ const entry = this.borrowedEntry(slot);
183
+ if (entry.mapPending || entry.mapped) {
184
+ throw invalid("slot", slot.index, "a borrowed slot that is not mapped and has no map pending");
185
+ }
186
+ return this.track(entry, slot.buffer.mapAsync(MapMode.READ, 0, byteLength));
187
+ }
188
+ /**
189
+ * Returns a borrowed slot (unmapping it if mapped). A slot whose map through the ring is still pending stays
190
+ * borrowed until the map settles, when the ring unmaps and returns it; a borrower that maps a slot itself must
191
+ * unmap it before returning it (spec 4.4; `mapState` decides when the runtime exposes it, otherwise the ring's
192
+ * own record does). A no-op after destroyAll() (the ring is gone; a borrower's finally must never mask the
193
+ * E_DISPOSED / E_DEVICE_LOST of the read it was serving).
194
+ * @param slot - a slot borrowed from this ring and not yet returned
195
+ */
196
+ returnSlot(slot) {
197
+ if (this.disposed) {
198
+ return;
199
+ }
200
+ const entry = this.borrowedEntry(slot);
201
+ if (entry.mapPending) {
202
+ entry.returnRequested = true;
203
+ return;
204
+ }
205
+ this.finishReturn(entry);
206
+ }
207
+ /**
208
+ * The entry of a slot borrowed from this ring and not yet returned.
209
+ * @param slot - the slot
210
+ * @returns its entry
211
+ */
212
+ borrowedEntry(slot) {
213
+ const entry = this.ring[slot.index];
214
+ if (entry === undefined || entry.slot !== slot || !entry.borrowed) {
215
+ throw invalid("slot", slot.index, "a slot borrowed from this ring and not yet returned");
216
+ }
217
+ return entry;
218
+ }
219
+ /**
220
+ * Unmaps a returned slot when it is mapped and frees it.
221
+ * @param entry - the slot's entry (no map pending)
222
+ */
223
+ finishReturn(entry) {
224
+ const state = entry.slot.buffer.mapState;
225
+ const mapped = state === undefined ? entry.mapped : state !== "unmapped";
226
+ if (mapped) {
227
+ entry.slot.buffer.unmap();
228
+ }
229
+ entry.mapped = false;
230
+ entry.borrowed = false;
231
+ entry.returnRequested = false;
232
+ }
233
+ /**
234
+ * Tracks one mapAsync on a slot: mapPending until it settles, then the deferred work -- the destruction
235
+ * destroyAll() left to the settle, or the return returnSlot() left to it. The handler is attached before the
236
+ * promise is handed out, so it runs before any borrower's continuation.
237
+ * @param entry - the slot's entry
238
+ * @param pending - the runtime's mapAsync promise
239
+ * @returns the same promise
240
+ */
241
+ track(entry, pending) {
242
+ entry.mapPending = true;
243
+ const settle = (mapped) => {
244
+ entry.mapPending = false;
245
+ entry.mapped = mapped;
246
+ if (this.disposed) {
247
+ if (mapped) {
248
+ entry.slot.buffer.unmap();
249
+ }
250
+ this.destroySlot(entry);
251
+ entry.mapped = false;
252
+ return;
253
+ }
254
+ if (entry.returnRequested) {
255
+ this.finishReturn(entry);
256
+ }
257
+ };
258
+ void pending.then(() => {
259
+ settle(true);
260
+ }, () => {
261
+ settle(false);
262
+ });
263
+ return pending;
264
+ }
265
+ /**
266
+ * Number of slots (grows).
267
+ * @returns the slot count
268
+ */
269
+ get slots() {
270
+ return this.ring.length;
271
+ }
272
+ /**
273
+ * Slots currently borrowed.
274
+ * @returns the borrowed count
275
+ */
276
+ get borrowed() {
277
+ let count = 0;
278
+ for (const entry of this.ring) {
279
+ if (entry.borrowed) {
280
+ count++;
281
+ }
282
+ }
283
+ return count;
284
+ }
285
+ /**
286
+ * Destroys every staging buffer (ctx.dispose()); idempotent. A slot whose mapAsync is still pending is NOT
287
+ * destroyed here (the file comment: dawn-node 0.4.0 settles the promise twice); its destruction is deferred to
288
+ * the moment the map settles (track()), where a pending read() still rejects with E_DISPOSED as the contract
289
+ * promises.
290
+ * @internal
291
+ */
292
+ destroyAll() {
293
+ for (const entry of this.ring) {
294
+ if (entry.mapPending) {
295
+ continue;
296
+ }
297
+ this.destroySlot(entry);
298
+ }
299
+ this.ring.length = 0;
300
+ this.disposed = true;
301
+ }
302
+ /**
303
+ * Destroys one slot's buffer through the allocator when it was created there.
304
+ * @param entry - the slot
305
+ */
306
+ destroySlot(entry) {
307
+ if (entry.tracked) {
308
+ this.allocator.destroy(entry.slot.buffer);
309
+ }
310
+ else {
311
+ entry.slot.buffer.destroy();
312
+ }
313
+ }
314
+ /**
315
+ * Creates one slot at the end of the ring.
316
+ * @param capacity - the slot's byte capacity
317
+ * @returns the new entry
318
+ */
319
+ addSlot(capacity) {
320
+ const index = this.ring.length;
321
+ const descriptor = {
322
+ label: `readback:slot:${index}`,
323
+ size: capacity,
324
+ usage: STAGING_USAGE,
325
+ };
326
+ const tracked = capacity >= OOM_SCOPE_THRESHOLD_BYTES;
327
+ const buffer = tracked ? this.allocator.createBuffer(descriptor) : this.device.createBuffer(descriptor);
328
+ const entry = {
329
+ slot: Object.freeze({ index, buffer, capacity }),
330
+ borrowed: false,
331
+ mapped: false,
332
+ mapPending: false,
333
+ returnRequested: false,
334
+ tracked,
335
+ };
336
+ this.ring.push(entry);
337
+ return entry;
338
+ }
339
+ /**
340
+ * mapAsync(READ) on a slot for read(); a rejection becomes E_DISPOSED (after destroyAll) or E_DEVICE_LOST.
341
+ * @param entry - the ring entry of the borrowed slot
342
+ * @param byteLength - the bytes to map
343
+ */
344
+ async map(entry, byteLength) {
345
+ let mapped = false;
346
+ let failure = null;
347
+ try {
348
+ await this.track(entry, entry.slot.buffer.mapAsync(MapMode.READ, 0, byteLength));
349
+ mapped = true;
350
+ }
351
+ catch (err) {
352
+ failure = err;
353
+ }
354
+ if (this.disposed) {
355
+ // destroyAll() ran while the map was pending: track() finished the deferred destruction just before this
356
+ throw new WebGpuGraphError("E_DISPOSED", "the readback ring was disposed while a read was pending", {
357
+ label: "readback",
358
+ });
359
+ }
360
+ if (!mapped) {
361
+ const message = failure instanceof Error ? failure.message : String(failure);
362
+ throw new WebGpuGraphError("E_DEVICE_LOST", `mapAsync rejected: ${message}`, {
363
+ reason: "mapAsync",
364
+ message,
365
+ });
366
+ }
367
+ }
368
+ /** Throws E_DISPOSED after destroyAll(). */
369
+ assertLive() {
370
+ if (this.disposed) {
371
+ throw new WebGpuGraphError("E_DISPOSED", "the readback ring was disposed", { label: "readback" });
372
+ }
373
+ }
374
+ }
375
+ //# sourceMappingURL=readback.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readback.js","sourceRoot":"","sources":["../../../src/memory/readback.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The upload cache of spec 4.1 / 4.3 / 4.5: every core array, view array, column and ad hoc array a kernel binds
3
+ * lives on the device exactly once per snapshot core, keyed on the typed-array object (or the Column object for
4
+ * columns, PLAN DECISION 8), recorded per serial so `release(snapshot)` destroys every buffer of a snapshot and its
5
+ * withColumns() siblings, and tombstoned so a live user learns of the release through `isReleased` (spec 4.5).
6
+ * Uploads follow the pure planner of ./upload-plan.ts: the arena path writes ONE buffer with ONE writeBuffer of the
7
+ * hot prefix (or the full arena when a cold segment is needed and fits) and binds segments at
8
+ * `segment.byteOffset - arena.byteOffset`; the perArray path writes one buffer per array; a windowed plan is
9
+ * E_TOO_LARGE until P4 executes windows (PLAN DECISION 2). Identity permutations are never materialised: presence is
10
+ * decided from counts and flags, and the arcToEdge / edgeToArc getters are read only when a segment exists. Nothing
11
+ * is freed by garbage collection; the once-only warning above warnUnreleasedSnapshots names the missing release.
12
+ */
13
+ import { type Column, type GpuEligibility, type GraphSnapshot } from "@graphty/graph-format";
14
+ import { type ArcWindow, type Binding } from "../types/memory.js";
15
+ /**
16
+ * The core arrays of a snapshot on the device (spec 4.1); a null member is absent (zero-length, unweighted or an
17
+ * identity permutation) and is bound as a dummy by the kernel layer (3.9). `Binding` itself is declared in
18
+ * src/types/memory.ts (3.3). Exported by contract 3.8: P1-T4's graphBindings / graphOverrides and every later
19
+ * kernel driver take it; nothing at P1-T2 imports it by name.
20
+ * @public
21
+ */
22
+ export interface CoreBinding {
23
+ readonly serial: number;
24
+ readonly plan: "arena" | "perArray" | "windowed";
25
+ readonly rowPtr: Binding;
26
+ readonly colIdx: Binding | null;
27
+ readonly weights: Binding | null;
28
+ readonly arcToEdge: Binding | null;
29
+ readonly edgeToArc: Binding | null;
30
+ readonly windows: readonly ArcWindow[] | null;
31
+ readonly hasWeights: boolean;
32
+ }
33
+ /**
34
+ * A view's arrays on the device plus the CPU-side scalars (degreeOrder's segmentOffsets) (spec 4.3). Exported by
35
+ * contract 3.8: the degreeOrder permutation of P4's kernels is a ViewBinding; nothing at P1-T2 imports it by name.
36
+ * @public
37
+ */
38
+ export interface ViewBinding {
39
+ readonly view: "reverse" | "coo" | "edgeList" | "outDegree" | "inDegree" | "degreeOrder" | "reverseDegreeOrder" | "mate";
40
+ readonly bindings: Readonly<Record<string, Binding>>;
41
+ readonly scalars: Readonly<Record<string, readonly number[]>>;
42
+ }
43
+ /**
44
+ * A column's gpuView() on the device (spec 4.3). Exported by contract 3.8: P3's layout inputs register columns
45
+ * through it; nothing at P1-T2 imports it by name.
46
+ * @public
47
+ */
48
+ export interface ColumnBinding {
49
+ readonly binding: Binding;
50
+ readonly column: Column;
51
+ readonly version: number;
52
+ readonly eligibility: GpuEligibility;
53
+ readonly components: number;
54
+ }
55
+ /**
56
+ * An ad hoc array on the device (spec 4.1 last row); `destroy()` is the caller's when no owner was given. Exported
57
+ * by contract 3.8: P3's model resolves column inputs to a registered ArrayBinding; nothing at P1-T2 imports it by
58
+ * name.
59
+ * @public
60
+ */
61
+ export interface ArrayBinding {
62
+ readonly binding: Binding;
63
+ readonly byteLength: number;
64
+ readonly owner: GraphSnapshot | null;
65
+ destroy(): void;
66
+ }
67
+ /**
68
+ * stats() shape (spec 4.1). Exported by contract 3.8 for the callers of ctx.residency.stats(); nothing at P1-T2
69
+ * imports it by name.
70
+ * @public
71
+ */
72
+ export interface ResidencyStats {
73
+ readonly buffers: number;
74
+ readonly bytes: number;
75
+ readonly snapshots: number;
76
+ readonly perSnapshot: readonly {
77
+ readonly serial: number;
78
+ readonly label: string | null;
79
+ readonly bytes: number;
80
+ readonly buffers: number;
81
+ }[];
82
+ }
83
+ //# sourceMappingURL=residency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"residency.d.ts","sourceRoot":"","sources":["../../../src/memory/residency.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAEH,KAAK,MAAM,EAEX,KAAK,cAAc,EACnB,KAAK,aAAa,EAErB,MAAM,uBAAuB,CAAC;AAM/B,OAAO,EAAE,KAAK,SAAS,EAAE,KAAK,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAYlE;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACjC,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,SAAS,EAAE,OAAO,GAAG,IAAI,CAAC;IACnC,QAAQ,CAAC,OAAO,EAAE,SAAS,SAAS,EAAE,GAAG,IAAI,CAAC;IAC9C,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;CAChC;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IACxB,QAAQ,CAAC,IAAI,EACT,SAAS,GAAG,KAAK,GAAG,UAAU,GAAG,WAAW,GAAG,UAAU,GAAG,aAAa,GAAG,oBAAoB,GAAG,MAAM,CAAC;IAC9G,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACrD,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAAC,CAAC;CACjE;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC1B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IACzB,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,OAAO,IAAI,IAAI,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC3B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,EAAE,SAAS;QAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC5B,EAAE,CAAC;CACP"}