@graphty/webgpu-graph-algorithms 0.0.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/README.md +378 -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
package/dist/node.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from "./src/node/index.js";
package/dist/node.js ADDED
@@ -0,0 +1,131 @@
1
+ import { W as WebGpuGraphError, G as GpuContext } from "./chunks/context-E6iKaeuJ.js";
2
+ const INSTALL_HINT = "install the optional peer dependency webgpu@0.4.0";
3
+ function isDawnModule(loaded) {
4
+ return typeof loaded === "object" && loaded !== null && typeof loaded.create === "function";
5
+ }
6
+ function messageOf(err) {
7
+ return err instanceof Error ? err.message : String(err);
8
+ }
9
+ class DawnHandle {
10
+ /**
11
+ * Wraps a GPU object.
12
+ * @param gpu - the object dawn.create() returned
13
+ */
14
+ constructor(gpu) {
15
+ this.ref = gpu;
16
+ }
17
+ /**
18
+ * The GPU object; E_DISPOSED after dispose().
19
+ * @returns the GPU object
20
+ */
21
+ get gpu() {
22
+ if (this.ref === null) {
23
+ throw new WebGpuGraphError("E_DISPOSED", "the Dawn GPU handle was disposed", { label: "NodeGpuHandle" });
24
+ }
25
+ return this.ref;
26
+ }
27
+ /** Drops the reference; idempotent. */
28
+ dispose() {
29
+ this.ref = null;
30
+ }
31
+ }
32
+ function dawnFlags(options) {
33
+ const flags = [];
34
+ if (options === void 0) {
35
+ return flags;
36
+ }
37
+ if (options.adapter !== void 0 && options.adapter !== "") {
38
+ flags.push(`adapter=${options.adapter}`);
39
+ } else if (options.software === true) {
40
+ flags.push("adapter=llvmpipe");
41
+ }
42
+ if (options.backend !== void 0) {
43
+ flags.push(`backend=${options.backend}`);
44
+ }
45
+ if (options.dawnFeatures !== void 0 && options.dawnFeatures.length > 0) {
46
+ flags.push(`enable-dawn-features=${options.dawnFeatures.join(",")}`);
47
+ }
48
+ return flags;
49
+ }
50
+ async function createNodeGpu(options) {
51
+ const load = options?.loadModule ?? (() => import("webgpu"));
52
+ let loaded;
53
+ try {
54
+ loaded = await load();
55
+ } catch (err) {
56
+ const reason = messageOf(err);
57
+ throw new WebGpuGraphError(
58
+ "E_NO_WEBGPU",
59
+ `the webgpu (Dawn) native module did not load: ${reason}; ${INSTALL_HINT}`,
60
+ { reason, hint: INSTALL_HINT }
61
+ );
62
+ }
63
+ if (!isDawnModule(loaded)) {
64
+ const reason = "the webgpu module exports no create() function";
65
+ throw new WebGpuGraphError("E_NO_WEBGPU", `${reason}; ${INSTALL_HINT}`, { reason, hint: INSTALL_HINT });
66
+ }
67
+ if (options?.installGlobals !== false && typeof loaded.globals === "object" && loaded.globals !== null) {
68
+ Object.assign(globalThis, loaded.globals);
69
+ }
70
+ let gpu;
71
+ try {
72
+ gpu = loaded.create(dawnFlags(options));
73
+ } catch (err) {
74
+ const reason = `dawn.create() threw: ${messageOf(err)}`;
75
+ throw new WebGpuGraphError("E_NO_WEBGPU", `${reason}; ${INSTALL_HINT}`, { reason, hint: INSTALL_HINT });
76
+ }
77
+ return new DawnHandle(gpu);
78
+ }
79
+ function contextOptionsOf(options) {
80
+ return {
81
+ powerPreference: options.powerPreference,
82
+ rejectSoftware: options.rejectSoftware,
83
+ limits: options.limits,
84
+ optionalFeatures: options.optionalFeatures,
85
+ requiredFeatures: options.requiredFeatures,
86
+ label: options.label,
87
+ onError: options.onError,
88
+ warnUnreleasedSnapshots: options.warnUnreleasedSnapshots
89
+ };
90
+ }
91
+ async function createNodeGpuContext(options) {
92
+ const handle = await createNodeGpu(options);
93
+ let ctx;
94
+ try {
95
+ ctx = await GpuContext.create({ ...contextOptionsOf(options ?? {}), gpu: handle.gpu, runtime: "node" });
96
+ } catch (err) {
97
+ handle.dispose();
98
+ throw err;
99
+ }
100
+ const { lost } = ctx;
101
+ ctx.attachDisposer(() => {
102
+ void lost.then(() => {
103
+ handle.dispose();
104
+ });
105
+ });
106
+ return ctx;
107
+ }
108
+ async function probeNodeWebGpu(options) {
109
+ let handle;
110
+ try {
111
+ handle = await createNodeGpu(options);
112
+ } catch (err) {
113
+ return { ok: false, code: "E_NO_WEBGPU", reason: messageOf(err), adapter: null, summary: null };
114
+ }
115
+ try {
116
+ return await GpuContext.probe({
117
+ gpu: handle.gpu,
118
+ powerPreference: options?.powerPreference ?? "high-performance",
119
+ rejectSoftware: options?.rejectSoftware
120
+ });
121
+ } finally {
122
+ handle.dispose();
123
+ }
124
+ }
125
+ export {
126
+ createNodeGpu,
127
+ createNodeGpuContext,
128
+ dawnFlags,
129
+ probeNodeWebGpu
130
+ };
131
+ //# sourceMappingURL=node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.js","sources":["../src/node/index.ts"],"sourcesContent":["/// <reference types=\"@webgpu/types\" preserve=\"true\" />\n/**\n * The ./node entry (spec 2.1, 2.3, 3.4; contract 3.7): Dawn through the optional peer dependency `webgpu`. The\n * ONLY file of the package that names the \"webgpu\" module, and only inside `await import(\"webgpu\")` in a\n * function body, so the root and browser bundles never carry the specifier (spec 2.5; test/build-output.test.ts,\n * test/layers.test.ts). P0-T3 wrote createNodeGpu, dawnFlags and their types; P1-T1 adds createNodeGpuContext,\n * probeNodeWebGpu and the `extends Omit<GpuContextOptions, ...>` clause of NodeGpuOptions.\n *\n * Rule of spec 2.5 item 5 (also in CLAUDE.md): \"./node\" is imported only by Node entry points and tests.\n */\n\nimport { GpuContext } from \"../context.js\";\nimport { WebGpuGraphError } from \"../errors.js\";\nimport type { GpuContextOptions, ProbeResult } from \"../types/context.js\";\n\n/** Options of the Node helpers (spec 3.4). */\nexport interface NodeGpuOptions extends Omit<GpuContextOptions, \"gpu\" | \"adapter\" | \"device\" | \"runtime\"> {\n /** Dawn `adapter=<substring>`: a substring of the adapter name (`llvmpipe`, `4070`); an empty string is ignored; wins over `software`. */\n readonly adapter?: string | undefined;\n /** Dawn `backend=<name>`; `null` compiles pipelines and runs nothing (spec 5.1; the compile tests use it). */\n readonly backend?: \"vulkan\" | \"d3d12\" | \"d3d11\" | \"metal\" | \"opengl\" | \"opengles\" | \"null\" | undefined;\n /** Dawn toggles, emitted as `enable-dawn-features=a,b`. */\n readonly dawnFeatures?: readonly string[] | undefined;\n /** Shorthand for `adapter=llvmpipe` (Linux / Mesa specific, spec 2.3); ignored when `adapter` is given. */\n readonly software?: boolean | undefined;\n /** Install dawn.globals on globalThis (default true; spec 2.1 rule 2) so user code sees GPUBufferUsage and friends. */\n readonly installGlobals?: boolean | undefined;\n /**\n * Test seam: replaces `() => import(\"webgpu\")` so a missing / broken module can be simulated.\n * @internal\n */\n readonly loadModule?: (() => Promise<unknown>) | undefined;\n}\n\n/** The Dawn GPU handle (spec 2.3): dispose() drops the reference so the process can exit. */\nexport interface NodeGpuHandle {\n /** The GPU of `dawn.create(flags)`; reading it after dispose() throws E_DISPOSED. */\n readonly gpu: GPU;\n /** Drops the GPU reference; idempotent. */\n dispose(): void;\n}\n\n/** The install hint of E_NO_WEBGPU (spec 2.5 item 4); P-ENV re-pins the version together with the devDependency. */\nconst INSTALL_HINT = \"install the optional peer dependency webgpu@0.4.0\";\n\n/** The shape of the `webgpu` module (its types.d.ts: create(options: string[]): GPU; globals: Object). */\ninterface DawnModule {\n create(options: string[]): GPU;\n globals?: unknown;\n}\n\n/**\n * Whether a loaded module is usable as Dawn.\n * @param loaded - the module namespace\n * @returns true when it has a create() function\n */\nfunction isDawnModule(loaded: unknown): loaded is DawnModule {\n return (\n typeof loaded === \"object\" && loaded !== null && typeof (loaded as { create?: unknown }).create === \"function\"\n );\n}\n\n/**\n * The message of a thrown value.\n * @param err - what was caught\n * @returns the Error message, or the value as a string\n */\nfunction messageOf(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n\n/** The handle returned by createNodeGpu(): `gpu` is a getter so dispose() can drop the reference. */\nclass DawnHandle implements NodeGpuHandle {\n private ref: GPU | null;\n\n /**\n * Wraps a GPU object.\n * @param gpu - the object dawn.create() returned\n */\n constructor(gpu: GPU) {\n this.ref = gpu;\n }\n\n /**\n * The GPU object; E_DISPOSED after dispose().\n * @returns the GPU object\n */\n get gpu(): GPU {\n if (this.ref === null) {\n throw new WebGpuGraphError(\"E_DISPOSED\", \"the Dawn GPU handle was disposed\", { label: \"NodeGpuHandle\" });\n }\n return this.ref;\n }\n\n /** Drops the reference; idempotent. */\n dispose(): void {\n this.ref = null;\n }\n}\n\n/**\n * The Dawn flag list a NodeGpuOptions maps to (exported for the tests and scripts/gpu-report.js):\n * adapter=<s>, backend=<s>, enable-dawn-features=a,b, and software -> adapter=llvmpipe; an explicit non-empty\n * `adapter` wins over `software`; an empty feature list emits nothing.\n * @param options - the Node options, or undefined for no flags\n * @returns the strings for dawn.create(), in the order adapter, backend, features\n */\nexport function dawnFlags(options: NodeGpuOptions | undefined): string[] {\n const flags: string[] = [];\n if (options === undefined) {\n return flags;\n }\n if (options.adapter !== undefined && options.adapter !== \"\") {\n flags.push(`adapter=${options.adapter}`);\n } else if (options.software === true) {\n flags.push(\"adapter=llvmpipe\");\n }\n if (options.backend !== undefined) {\n flags.push(`backend=${options.backend}`);\n }\n if (options.dawnFeatures !== undefined && options.dawnFeatures.length > 0) {\n flags.push(`enable-dawn-features=${options.dawnFeatures.join(\",\")}`);\n }\n return flags;\n}\n\n/**\n * import(\"webgpu\"), install dawn.globals unless installGlobals === false, dawn.create(flags) (spec 2.3).\n * @param options - adapter / backend / dawnFeatures / software / installGlobals (and the test seam)\n * @returns the handle; `dispose()` drops the GPU reference so the process can exit\n * @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\n */\nexport async function createNodeGpu(options?: NodeGpuOptions): Promise<NodeGpuHandle> {\n const load = options?.loadModule ?? ((): Promise<unknown> => import(\"webgpu\"));\n let loaded: unknown;\n try {\n loaded = await load();\n } catch (err) {\n const reason = messageOf(err);\n throw new WebGpuGraphError(\n \"E_NO_WEBGPU\",\n `the webgpu (Dawn) native module did not load: ${reason}; ${INSTALL_HINT}`,\n { reason, hint: INSTALL_HINT },\n );\n }\n if (!isDawnModule(loaded)) {\n const reason = \"the webgpu module exports no create() function\";\n throw new WebGpuGraphError(\"E_NO_WEBGPU\", `${reason}; ${INSTALL_HINT}`, { reason, hint: INSTALL_HINT });\n }\n if (options?.installGlobals !== false && typeof loaded.globals === \"object\" && loaded.globals !== null) {\n Object.assign(globalThis, loaded.globals);\n }\n let gpu: GPU;\n try {\n gpu = loaded.create(dawnFlags(options));\n } catch (err) {\n const reason = `dawn.create() threw: ${messageOf(err)}`;\n throw new WebGpuGraphError(\"E_NO_WEBGPU\", `${reason}; ${INSTALL_HINT}`, { reason, hint: INSTALL_HINT });\n }\n return new DawnHandle(gpu);\n}\n\n/**\n * The GpuContextOptions part of a NodeGpuOptions, copied key by key so the Node-only `adapter` string never\n * reaches GpuContext.create as a GPUAdapter.\n * @param options - the Node options\n * @returns the context options without gpu / adapter / device / runtime\n */\nfunction contextOptionsOf(options: NodeGpuOptions): Omit<GpuContextOptions, \"gpu\" | \"adapter\" | \"device\" | \"runtime\"> {\n return {\n powerPreference: options.powerPreference,\n rejectSoftware: options.rejectSoftware,\n limits: options.limits,\n optionalFeatures: options.optionalFeatures,\n requiredFeatures: options.requiredFeatures,\n label: options.label,\n onError: options.onError,\n warnUnreleasedSnapshots: options.warnUnreleasedSnapshots,\n };\n}\n\n/**\n * createNodeGpu + GpuContext.create({ gpu, runtime: \"node\", ...options }); ctx.dispose() also disposes the\n * handle, and a create() failure disposes it before rethrowing. The handle is dropped once `ctx.lost` has\n * settled, never before: under webgpu@0.4.0 a GPU object collected while the device it created is still\n * tearing down (its lost / work-done callbacks in flight) crashes or deadlocks the process (PLAN DECISION,\n * P1-T1; measured with tmp/p1t1/gc-race2.mjs), and device.destroy() reports the loss right away.\n * @param options - the Node options\n * @returns the context\n */\nexport async function createNodeGpuContext(options?: NodeGpuOptions): Promise<GpuContext> {\n const handle = await createNodeGpu(options);\n let ctx: GpuContext;\n try {\n ctx = await GpuContext.create({ ...contextOptionsOf(options ?? {}), gpu: handle.gpu, runtime: \"node\" });\n } catch (err) {\n handle.dispose();\n throw err;\n }\n const { lost } = ctx;\n ctx.attachDisposer(() => {\n void lost.then(() => {\n handle.dispose();\n });\n });\n return ctx;\n}\n\n/**\n * createNodeGpu + GpuContext.probe + dispose; never throws (a load failure is { code: \"E_NO_WEBGPU\" }).\n * @param options - the Node options\n * @returns the probe result\n */\nexport async function probeNodeWebGpu(options?: NodeGpuOptions): Promise<ProbeResult> {\n let handle: NodeGpuHandle;\n try {\n handle = await createNodeGpu(options);\n } catch (err) {\n return { ok: false, code: \"E_NO_WEBGPU\", reason: messageOf(err), adapter: null, summary: null };\n }\n try {\n return await GpuContext.probe({\n gpu: handle.gpu,\n powerPreference: options?.powerPreference ?? \"high-performance\",\n rejectSoftware: options?.rejectSoftware,\n });\n } finally {\n handle.dispose();\n }\n}\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * createAccelerator (spec 3.3, 9; contract 3.14): the injectable object that satisfies the CPU packages'
3
+ * AlgorithmAccelerator and LayoutAccelerator interfaces STRUCTURALLY (spec 9.2, 9.3; the mirrors of
4
+ * src/types/accelerator.ts until W1, D27). At P3 it carries `forceAtlas2`, `release` and `dispose` and nothing
5
+ * else: the CPU-side dispatchers (`accelerated()`, `createSimulation()`) test `acc.pageRank !== undefined` and
6
+ * route to the CPU when the member is absent (spec 2.4 row "method missing"), so a method the GPU does not
7
+ * implement must not exist here -- never a throwing stub. The algorithm members arrive one per shipped algorithm
8
+ * from P7; `fruchtermanReingold` / `springElectrical` with P5.
9
+ */
10
+ import { type GpuContext } from "./context.js";
11
+ import { type AcceleratorOptions, type GpuAccelerator } from "./types/accelerator.js";
12
+ /**
13
+ * Spec 3.3 createAccelerator, verbatim: the object implementing AlgorithmAccelerator & LayoutAccelerator
14
+ * structurally; at P3 it carries forceAtlas2, release and dispose. One per call (the app creates one and injects
15
+ * it, spec 2.4); `kind` is "webgpu"; `options` is a frozen deep copy; `forceAtlas2(o)` is
16
+ * `createForceAtlas2(ctx, { ...o, ...options.layout })`, so the GPU tuning given here wins over anything the
17
+ * CPU-typed option object carries (spec 3.3: tuning never comes from the caller of the accelerator method);
18
+ * `release(s)` is `ctx.release(s)`; `dispose()` is `ctx.dispose()`.
19
+ * @param ctx - the context every simulation the accelerator creates runs on
20
+ * @param options - GPU-only defaults inherited by every simulation (`layout`) and, from P9, the algorithm defaults
21
+ * @returns the injectable accelerator
22
+ * @throws E_DISPOSED / E_DEVICE_LOST from `ctx.assertReady()` (here and inside `forceAtlas2()`); `forceAtlas2()`
23
+ * also throws what createForceAtlas2 throws (E_UNSUPPORTED for `nodeSize`, E_INVALID_ARGUMENT for a bad range)
24
+ */
25
+ export declare function createAccelerator(ctx: GpuContext, options?: AcceleratorOptions): GpuAccelerator;
26
+ //# sourceMappingURL=accelerator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accelerator.d.ts","sourceRoot":"","sources":["../../src/accelerator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,OAAO,EAAE,KAAK,kBAAkB,EAAE,KAAK,cAAc,EAAE,MAAM,wBAAwB,CAAC;AA2DtF;;;;;;;;;;;;GAYG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,cAAc,CA8B/F"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * createAccelerator (spec 3.3, 9; contract 3.14): the injectable object that satisfies the CPU packages'
3
+ * AlgorithmAccelerator and LayoutAccelerator interfaces STRUCTURALLY (spec 9.2, 9.3; the mirrors of
4
+ * src/types/accelerator.ts until W1, D27). At P3 it carries `forceAtlas2`, `release` and `dispose` and nothing
5
+ * else: the CPU-side dispatchers (`accelerated()`, `createSimulation()`) test `acc.pageRank !== undefined` and
6
+ * route to the CPU when the member is absent (spec 2.4 row "method missing"), so a method the GPU does not
7
+ * implement must not exist here -- never a throwing stub. The algorithm members arrive one per shipped algorithm
8
+ * from P7; `fruchtermanReingold` / `springElectrical` with P5.
9
+ */
10
+ import { createForceAtlas2 } from "./layouts/forceatlas2.js";
11
+ /**
12
+ * Frozen copy of the betweenness defaults; `sources` is copied into a fresh frozen array so a later mutation of
13
+ * the caller's list is never seen by the accelerator.
14
+ * @param defaults - the caller's record
15
+ * @returns the frozen copy
16
+ */
17
+ function copyBetweenness(defaults) {
18
+ const copy = { ...defaults };
19
+ if (defaults.sources !== undefined) {
20
+ copy.sources = Object.freeze([...defaults.sources]);
21
+ }
22
+ return Object.freeze(copy);
23
+ }
24
+ /**
25
+ * Frozen copy of the algorithms record, one level deeper for `betweenness`.
26
+ * @param algorithms - the caller's record
27
+ * @returns the frozen copy
28
+ */
29
+ function copyAlgorithms(algorithms) {
30
+ const copy = { ...algorithms };
31
+ if (algorithms.betweenness !== undefined) {
32
+ copy.betweenness = copyBetweenness(algorithms.betweenness);
33
+ }
34
+ return Object.freeze(copy);
35
+ }
36
+ /**
37
+ * The frozen deep copy of the accelerator options (spec 3.3 GpuAccelerator.options: "the tuning defaults given
38
+ * to createAccelerator; frozen"; contract 3.14): the record, its `layout` tuning, its `algorithms` record, the
39
+ * `betweenness` record and the `sources` list are each fresh frozen objects, so neither the caller's later edits
40
+ * nor a consumer's writes can change what the accelerator's simulations inherit.
41
+ * @param options - the caller's options, or undefined
42
+ * @returns the frozen copy (an empty frozen record when nothing was given)
43
+ */
44
+ function freezeOptions(options) {
45
+ if (options === undefined) {
46
+ return Object.freeze({});
47
+ }
48
+ const copy = { ...options };
49
+ if (options.layout !== undefined) {
50
+ copy.layout = Object.freeze({ ...options.layout });
51
+ }
52
+ if (options.algorithms !== undefined) {
53
+ copy.algorithms = copyAlgorithms(options.algorithms);
54
+ }
55
+ return Object.freeze(copy);
56
+ }
57
+ /**
58
+ * Spec 3.3 createAccelerator, verbatim: the object implementing AlgorithmAccelerator & LayoutAccelerator
59
+ * structurally; at P3 it carries forceAtlas2, release and dispose. One per call (the app creates one and injects
60
+ * it, spec 2.4); `kind` is "webgpu"; `options` is a frozen deep copy; `forceAtlas2(o)` is
61
+ * `createForceAtlas2(ctx, { ...o, ...options.layout })`, so the GPU tuning given here wins over anything the
62
+ * CPU-typed option object carries (spec 3.3: tuning never comes from the caller of the accelerator method);
63
+ * `release(s)` is `ctx.release(s)`; `dispose()` is `ctx.dispose()`.
64
+ * @param ctx - the context every simulation the accelerator creates runs on
65
+ * @param options - GPU-only defaults inherited by every simulation (`layout`) and, from P9, the algorithm defaults
66
+ * @returns the injectable accelerator
67
+ * @throws E_DISPOSED / E_DEVICE_LOST from `ctx.assertReady()` (here and inside `forceAtlas2()`); `forceAtlas2()`
68
+ * also throws what createForceAtlas2 throws (E_UNSUPPORTED for `nodeSize`, E_INVALID_ARGUMENT for a bad range)
69
+ */
70
+ export function createAccelerator(ctx, options) {
71
+ ctx.assertReady();
72
+ const frozen = freezeOptions(options);
73
+ return {
74
+ kind: "webgpu",
75
+ ctx,
76
+ options: frozen,
77
+ /**
78
+ * The ForceAtlas2 simulation with this accelerator's layout tuning (spec 3.3; contract 3.14).
79
+ * @param o - the CPU option type (spec 9.3 ForceAtlas2Options); GPU tuning keys come from `options.layout`
80
+ * @returns a fresh simulation in state "created"
81
+ */
82
+ forceAtlas2(o) {
83
+ ctx.assertReady();
84
+ return createForceAtlas2(ctx, { ...o, ...frozen.layout });
85
+ },
86
+ /**
87
+ * Destroys every device buffer recorded for the snapshot (spec 4.5); delegates to ctx.release.
88
+ * @param s - the snapshot the app is done with
89
+ */
90
+ release(s) {
91
+ ctx.release(s);
92
+ },
93
+ /**
94
+ * Disposes the context (spec 2.8); delegates to ctx.dispose, idempotent.
95
+ */
96
+ dispose() {
97
+ ctx.dispose();
98
+ },
99
+ };
100
+ }
101
+ //# sourceMappingURL=accelerator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"accelerator.js","sourceRoot":"","sources":["../../src/accelerator.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAKH,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAW7D;;;;;GAKG;AACH,SAAS,eAAe,CAAC,QAA6B;IAClD,MAAM,IAAI,GAAwE,EAAE,GAAG,QAAQ,EAAE,CAAC;IAClG,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,SAAS,cAAc,CAAC,UAA6B;IACjD,MAAM,IAAI,GAAsD,EAAE,GAAG,UAAU,EAAE,CAAC;IAClF,IAAI,UAAU,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAC/D,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,aAAa,CAAC,OAAuC;IAC1D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC7B,CAAC;IACD,MAAM,IAAI,GAAyF,EAAE,GAAG,OAAO,EAAE,CAAC;IAClH,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC/B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvD,CAAC;IACD,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAe,EAAE,OAA4B;IAC3E,GAAG,CAAC,WAAW,EAAE,CAAC;IAClB,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO;QACH,IAAI,EAAE,QAAQ;QACd,GAAG;QACH,OAAO,EAAE,MAAM;QACf;;;;WAIG;QACH,WAAW,CAAC,CAAsB;YAC9B,GAAG,CAAC,WAAW,EAAE,CAAC;YAClB,OAAO,iBAAiB,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD;;;WAGG;QACH,OAAO,CAAC,CAAgB;YACpB,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;QACD;;WAEG;QACH,OAAO;YACH,GAAG,CAAC,OAAO,EAAE,CAAC;QAClB,CAAC;KACJ,CAAC;AACN,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * `degree(ctx, s)` -- the walking-skeleton algorithm, kept public as a diagnostic (spec 3.3, 11.5): the out-degree of
3
+ * every node computed on the device by the row-walking `degree` kernel (4.5) over the resident core of the snapshot,
4
+ * with the group-0 dummy-binding pattern of spec 3.5 (`colIdx` in the `weights` slot when the snapshot is unweighted,
5
+ * `rowPtr` in the `perm` slot because P1-P3 pass no row permutation, so `USE_PERM` is false). The result equals
6
+ * `snapshot.outDegree()`; the point of the kernel is to prove the upload, bind, dispatch and readback path end to end
7
+ * on every adapter (bitwise identical across adapters, spec 11.5), not to be faster than the CPU (the README says
8
+ * so).
9
+ *
10
+ * Contract (3.12): `ctx.assertReady()` first; `nodeCount === 0` returns an empty `Uint32Array` (or `dest`) with no
11
+ * GPU work (spec 5.6: there is no work, which is not a fallback); an already-aborted `signal` is `E_ABORTED` before
12
+ * any work; `dest` must be a `Uint32Array` of length n over an `ArrayBuffer`; a windowed core is `E_TOO_LARGE
13
+ * { path: "windowed", algorithm: "degree" }` until P4 executes windows -- `residency.core()` (3.8) throws that error
14
+ * itself with `algorithm: null` before it would ever return a windowed `CoreBinding`, so `degree` catches it and
15
+ * re-throws the same error with `algorithm: "degree"` (the 3.12 detail) instead of testing `core.plan`, which never
16
+ * observes "windowed" in P1-P3; `arcCount === 0` skips the dispatch (only `rowPtr` is resident)
17
+ * and the result is zeros; otherwise ONE dispatch over rows [0, n) with `accumulate = 0` (every row is written, so no
18
+ * fill precedes it), a readback into the result, `onProgress(1, 1)`, and the scratch returned in a finally. Two runs
19
+ * are bitwise identical (spec 11.9 item 4).
20
+ */
21
+ import { type GraphSnapshot, type U32 } from "@graphty/graph-format";
22
+ import { type GpuContext } from "../context.js";
23
+ import { type GpuRunOptions } from "../types/run.js";
24
+ /**
25
+ * The walking-skeleton kernel, kept public as a diagnostic (spec 3.3): out-degree per node through the row-walking
26
+ * gather with the USE_PERM dummy pattern; equals snapshot.outDegree().
27
+ * @param ctx - the context whose device runs the kernel
28
+ * @param s - the snapshot (uploaded through ctx.residency, or found there)
29
+ * @param options - dest / signal / onProgress (spec 3.3). PLAN DECISION: spelled `?: GpuRunOptions` rather than the
30
+ * contract's `?: GpuRunOptions | undefined` because the root ESLint rule no-duplicate-type-constituents rejects the
31
+ * explicit undefined on an optional parameter (the call signature is identical; P1-T3 made the same choice).
32
+ * @returns the out-degree of every node, index-aligned (`dest` itself when given)
33
+ */
34
+ export declare function degree(ctx: GpuContext, s: GraphSnapshot, options?: GpuRunOptions): Promise<U32>;
35
+ //# sourceMappingURL=degree.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"degree.d.ts","sourceRoot":"","sources":["../../../src/algorithms/degree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAOhD,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAiDrD;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAAC,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,CAoDrG"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * `degree(ctx, s)` -- the walking-skeleton algorithm, kept public as a diagnostic (spec 3.3, 11.5): the out-degree of
3
+ * every node computed on the device by the row-walking `degree` kernel (4.5) over the resident core of the snapshot,
4
+ * with the group-0 dummy-binding pattern of spec 3.5 (`colIdx` in the `weights` slot when the snapshot is unweighted,
5
+ * `rowPtr` in the `perm` slot because P1-P3 pass no row permutation, so `USE_PERM` is false). The result equals
6
+ * `snapshot.outDegree()`; the point of the kernel is to prove the upload, bind, dispatch and readback path end to end
7
+ * on every adapter (bitwise identical across adapters, spec 11.5), not to be faster than the CPU (the README says
8
+ * so).
9
+ *
10
+ * Contract (3.12): `ctx.assertReady()` first; `nodeCount === 0` returns an empty `Uint32Array` (or `dest`) with no
11
+ * GPU work (spec 5.6: there is no work, which is not a fallback); an already-aborted `signal` is `E_ABORTED` before
12
+ * any work; `dest` must be a `Uint32Array` of length n over an `ArrayBuffer`; a windowed core is `E_TOO_LARGE
13
+ * { path: "windowed", algorithm: "degree" }` until P4 executes windows -- `residency.core()` (3.8) throws that error
14
+ * itself with `algorithm: null` before it would ever return a windowed `CoreBinding`, so `degree` catches it and
15
+ * re-throws the same error with `algorithm: "degree"` (the 3.12 detail) instead of testing `core.plan`, which never
16
+ * observes "windowed" in P1-P3; `arcCount === 0` skips the dispatch (only `rowPtr` is resident)
17
+ * and the result is zeros; otherwise ONE dispatch over rows [0, n) with `accumulate = 0` (every row is written, so no
18
+ * fill precedes it), a readback into the result, `onProgress(1, 1)`, and the scratch returned in a finally. Two runs
19
+ * are bitwise identical (spec 11.9 item 4).
20
+ */
21
+ import { BufferUsage } from "../device/webgpu-constants.js";
22
+ import { isWebGpuGraphError, WebGpuGraphError } from "../errors.js";
23
+ import { plan1d } from "../kernel/dispatch.js";
24
+ import { graphBindings, graphOverrides, kernelSpec, RANGE_PARAMS } from "../kernels.js";
25
+ /**
26
+ * Validates `options.dest` for a result of `n` elements.
27
+ * @param dest - the caller's destination array, if any
28
+ * @param n - the node count
29
+ * @returns the destination as a U32, or null when none was given
30
+ */
31
+ function checkDest(dest, n) {
32
+ if (dest === undefined) {
33
+ return null;
34
+ }
35
+ if (dest instanceof Uint32Array && dest.length === n && dest.buffer instanceof ArrayBuffer) {
36
+ return dest;
37
+ }
38
+ throw new WebGpuGraphError("E_INVALID_ARGUMENT", `degree: dest must be a Uint32Array of length ${n} over an ArrayBuffer`, {
39
+ argument: "dest",
40
+ value: `${dest.constructor.name}(${dest.length})`,
41
+ expected: `Uint32Array(${n}) over an ArrayBuffer`,
42
+ });
43
+ }
44
+ /**
45
+ * Uploads (or finds) the core through the residency; a windowed plan, which the residency reports as `E_TOO_LARGE
46
+ * { path: "windowed", algorithm: null }` (3.8), is re-thrown with `algorithm: "degree"` (3.12) and its other details
47
+ * (`needed`, `limit`, `path`) kept. Every other error passes through untouched.
48
+ * @param ctx - the context whose residency holds the core
49
+ * @param s - the snapshot
50
+ * @returns the resident core binding (arena or perArray)
51
+ */
52
+ function coreOf(ctx, s) {
53
+ try {
54
+ return ctx.residency.core(s);
55
+ }
56
+ catch (error) {
57
+ if (isWebGpuGraphError(error) && error.code === "E_TOO_LARGE" && error.details.path === "windowed") {
58
+ throw new WebGpuGraphError("E_TOO_LARGE", "degree: the arc arrays need a windowed upload, which P1-P3 plan but do not execute", { ...error.details, algorithm: "degree" });
59
+ }
60
+ throw error;
61
+ }
62
+ }
63
+ /**
64
+ * The walking-skeleton kernel, kept public as a diagnostic (spec 3.3): out-degree per node through the row-walking
65
+ * gather with the USE_PERM dummy pattern; equals snapshot.outDegree().
66
+ * @param ctx - the context whose device runs the kernel
67
+ * @param s - the snapshot (uploaded through ctx.residency, or found there)
68
+ * @param options - dest / signal / onProgress (spec 3.3). PLAN DECISION: spelled `?: GpuRunOptions` rather than the
69
+ * contract's `?: GpuRunOptions | undefined` because the root ESLint rule no-duplicate-type-constituents rejects the
70
+ * explicit undefined on an optional parameter (the call signature is identical; P1-T3 made the same choice).
71
+ * @returns the out-degree of every node, index-aligned (`dest` itself when given)
72
+ */
73
+ export async function degree(ctx, s, options) {
74
+ ctx.assertReady();
75
+ const n = s.nodeCount;
76
+ const dest = checkDest(options?.dest, n);
77
+ if (options?.signal?.aborted) {
78
+ throw new WebGpuGraphError("E_ABORTED", "degree: the signal was aborted before any work started", {});
79
+ }
80
+ if (n === 0) {
81
+ options?.onProgress?.(1, 1);
82
+ return dest ?? new Uint32Array(0);
83
+ }
84
+ const core = coreOf(ctx, s);
85
+ if (s.arcCount === 0) {
86
+ const zeros = dest ?? new Uint32Array(n);
87
+ zeros.fill(0);
88
+ options?.onProgress?.(1, 1);
89
+ return zeros;
90
+ }
91
+ const byteLength = n * 4;
92
+ const out = ctx.pool.acquire(byteLength, BufferUsage.STORAGE | BufferUsage.COPY_SRC | BufferUsage.COPY_DST, "degree/out");
93
+ const params = ctx.pool.acquire(RANGE_PARAMS.byteLength, BufferUsage.UNIFORM | BufferUsage.COPY_DST, "degree/params");
94
+ try {
95
+ await ctx.allocator.check();
96
+ const kernel = await ctx.pipelines.kernel(kernelSpec("degree", graphOverrides(core, null)));
97
+ const bytes = new ArrayBuffer(RANGE_PARAMS.byteLength);
98
+ RANGE_PARAMS.write(new DataView(bytes), { start: 0, end: n, arcBase: 0, arcEnd: s.arcCount, accumulate: 0, n });
99
+ ctx.device.queue.writeBuffer(params, 0, bytes);
100
+ const outBinding = { buffer: out, offset: 0, size: byteLength, window: null };
101
+ const paramsBinding = { buffer: params, offset: 0, size: RANGE_PARAMS.byteLength, window: null };
102
+ const bound = kernel.bind({ ...graphBindings(core, null), out: outBinding, P: paramsBinding });
103
+ const encoder = ctx.device.createCommandEncoder({ label: "degree" });
104
+ const pass = encoder.beginComputePass({ label: "degree" });
105
+ kernel.dispatch(pass, bound, plan1d(n, ctx.workgroupSize, ctx.caps), [0]);
106
+ pass.end();
107
+ ctx.device.queue.submit([encoder.finish()]);
108
+ ctx.assertReady();
109
+ const result = await ctx.readback.read(out, byteLength, dest ?? undefined);
110
+ ctx.assertReady();
111
+ options?.onProgress?.(1, 1);
112
+ return dest ?? new Uint32Array(result);
113
+ }
114
+ finally {
115
+ ctx.pool.release(params);
116
+ ctx.pool.release(out);
117
+ }
118
+ }
119
+ //# sourceMappingURL=degree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"degree.js","sourceRoot":"","sources":["../../../src/algorithms/degree.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAKH,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAKxF;;;;;GAKG;AACH,SAAS,SAAS,CAAC,IAA4C,EAAE,CAAS;IACtE,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACrB,OAAO,IAAI,CAAC;IAChB,CAAC;IACD,IAAI,IAAI,YAAY,WAAW,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,YAAY,WAAW,EAAE,CAAC;QACzF,OAAO,IAAW,CAAC;IACvB,CAAC;IACD,MAAM,IAAI,gBAAgB,CACtB,oBAAoB,EACpB,gDAAgD,CAAC,sBAAsB,EACvE;QACI,QAAQ,EAAE,MAAM;QAChB,KAAK,EAAE,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,GAAG;QACjD,QAAQ,EAAE,eAAe,CAAC,uBAAuB;KACpD,CACJ,CAAC;AACN,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,MAAM,CAAC,GAAe,EAAE,CAAgB;IAC7C,IAAI,CAAC;QACD,OAAO,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACtB,IAAI,kBAAkB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;YACjG,MAAM,IAAI,gBAAgB,CACtB,aAAa,EACb,oFAAoF,EACpF,EAAE,GAAG,KAAK,CAAC,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,CAC5C,CAAC;QACN,CAAC;QACD,MAAM,KAAK,CAAC;IAChB,CAAC;AACL,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,GAAe,EAAE,CAAgB,EAAE,OAAuB;IACnF,GAAG,CAAC,WAAW,EAAE,CAAC;IAClB,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,CAAC;IACtB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IACzC,IAAI,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;QAC3B,MAAM,IAAI,gBAAgB,CAAC,WAAW,EAAE,wDAAwD,EAAE,EAAE,CAAC,CAAC;IAC1G,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACV,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,IAAI,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;IACtC,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;QACnB,MAAM,KAAK,GAAG,IAAI,IAAI,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACd,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC;IACzB,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CACxB,UAAU,EACV,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,GAAG,WAAW,CAAC,QAAQ,EACjE,YAAY,CACf,CAAC;IACF,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,CAC3B,YAAY,CAAC,UAAU,EACvB,WAAW,CAAC,OAAO,GAAG,WAAW,CAAC,QAAQ,EAC1C,eAAe,CAClB,CAAC;IACF,IAAI,CAAC;QACD,MAAM,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,QAAQ,EAAE,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAC5F,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;QACvD,YAAY,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAChH,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACvF,MAAM,aAAa,GAAY,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QAC1G,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,CAAC;QAC/F,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,OAAO,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC3D,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,IAAI,CAAC,GAAG,EAAE,CAAC;QACX,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5C,GAAG,CAAC,WAAW,EAAE,CAAC;QAClB,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,IAAI,SAAS,CAAC,CAAC;QAC3E,GAAG,CAAC,WAAW,EAAE,CAAC;QAClB,OAAO,EAAE,UAAU,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5B,OAAO,IAAI,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;YAAS,CAAC;QACP,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;AACL,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * The ./browser entry (spec 2.1, 2.3, 3.4; contract 3.6): the only directory of the package allowed to read
3
+ * navigator.gpu. probeBrowserWebGpu never throws; requestGpuContext tags the context runtime "browser".
4
+ */
5
+ /// <reference types="@webgpu/types" preserve="true" />
6
+ import { GpuContext } from "../context.js";
7
+ import type { GpuContextOptions, ProbeResult } from "../types/context.js";
8
+ /** Options of the browser helpers (spec 3.4); a type alias, not an empty `extends` interface, which strictTypeChecked's no-empty-object-type (allowInterfaces "never") reports. */
9
+ export type BrowserGpuOptions = Omit<GpuContextOptions, "gpu" | "device" | "runtime">;
10
+ /**
11
+ * navigator.gpu absent -> { ok: false, code: "E_NO_WEBGPU" }; else GpuContext.probe. Never throws.
12
+ * @param options - the power preference and the software policy
13
+ * @returns the probe result
14
+ */
15
+ export declare function probeBrowserWebGpu(options?: BrowserGpuOptions): Promise<ProbeResult>;
16
+ /**
17
+ * GpuContext.create({ gpu: navigator.gpu, powerPreference: "high-performance", runtime: "browser", ...options });
18
+ * pass `{ adapter: probe.adapter }` to reuse the probed adapter; create() honours rejectSoftware.
19
+ * @param options - see BrowserGpuOptions
20
+ * @returns the context
21
+ */
22
+ export declare function requestGpuContext(options?: BrowserGpuOptions): Promise<GpuContext>;
23
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AACA;;;GAGG;;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAE1E,mLAAmL;AACnL,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,iBAAiB,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;AAetF;;;;GAIG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,WAAW,CAAC,CAMpF;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,UAAU,CAAC,CAWlF"}
@@ -0,0 +1,48 @@
1
+ /// <reference types="@webgpu/types" preserve="true" />
2
+ /**
3
+ * The ./browser entry (spec 2.1, 2.3, 3.4; contract 3.6): the only directory of the package allowed to read
4
+ * navigator.gpu. probeBrowserWebGpu never throws; requestGpuContext tags the context runtime "browser".
5
+ */
6
+ import { GpuContext } from "../context.js";
7
+ import { WebGpuGraphError } from "../errors.js";
8
+ /**
9
+ * navigator.gpu, or undefined when the runtime has no navigator or no WebGPU (Node 22 has a navigator
10
+ * without gpu; browsers without WebGPU have navigator.gpu undefined).
11
+ * @returns the GPU object or undefined
12
+ */
13
+ function navigatorGpu() {
14
+ if (typeof navigator === "undefined") {
15
+ return undefined;
16
+ }
17
+ const candidate = navigator;
18
+ return candidate.gpu;
19
+ }
20
+ /**
21
+ * navigator.gpu absent -> { ok: false, code: "E_NO_WEBGPU" }; else GpuContext.probe. Never throws.
22
+ * @param options - the power preference and the software policy
23
+ * @returns the probe result
24
+ */
25
+ export function probeBrowserWebGpu(options) {
26
+ return GpuContext.probe({
27
+ gpu: navigatorGpu(),
28
+ powerPreference: options?.powerPreference ?? "high-performance",
29
+ rejectSoftware: options?.rejectSoftware,
30
+ });
31
+ }
32
+ /**
33
+ * GpuContext.create({ gpu: navigator.gpu, powerPreference: "high-performance", runtime: "browser", ...options });
34
+ * pass `{ adapter: probe.adapter }` to reuse the probed adapter; create() honours rejectSoftware.
35
+ * @param options - see BrowserGpuOptions
36
+ * @returns the context
37
+ */
38
+ export function requestGpuContext(options) {
39
+ const gpu = navigatorGpu();
40
+ if (gpu === undefined && options?.adapter === undefined) {
41
+ return Promise.reject(new WebGpuGraphError("E_NO_WEBGPU", "navigator.gpu is undefined: this browser or context has no WebGPU", {
42
+ reason: "navigator.gpu is undefined",
43
+ hint: "WebGPU needs a supporting browser and a secure context (https or localhost)",
44
+ }));
45
+ }
46
+ return GpuContext.create({ powerPreference: "high-performance", ...options, gpu, runtime: "browser" });
47
+ }
48
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/browser/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD;;;GAGG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAMhD;;;;GAIG;AACH,SAAS,YAAY;IACjB,IAAI,OAAO,SAAS,KAAK,WAAW,EAAE,CAAC;QACnC,OAAO,SAAS,CAAC;IACrB,CAAC;IACD,MAAM,SAAS,GAAuC,SAAS,CAAC;IAChE,OAAO,SAAS,CAAC,GAAG,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAA2B;IAC1D,OAAO,UAAU,CAAC,KAAK,CAAC;QACpB,GAAG,EAAE,YAAY,EAAE;QACnB,eAAe,EAAE,OAAO,EAAE,eAAe,IAAI,kBAAkB;QAC/D,cAAc,EAAE,OAAO,EAAE,cAAc;KAC1C,CAAC,CAAC;AACP,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IACzD,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,IAAI,GAAG,KAAK,SAAS,IAAI,OAAO,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;QACtD,OAAO,OAAO,CAAC,MAAM,CACjB,IAAI,gBAAgB,CAAC,aAAa,EAAE,mEAAmE,EAAE;YACrG,MAAM,EAAE,4BAA4B;YACpC,IAAI,EAAE,6EAA6E;SACtF,CAAC,CACL,CAAC;IACN,CAAC;IACD,OAAO,UAAU,CAAC,MAAM,CAAC,EAAE,eAAe,EAAE,kBAAkB,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;AAC3G,CAAC"}