oidn-web 0.3.4 → 0.4.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 (122) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +140 -4
  3. package/benchmarks/compare.mjs +651 -0
  4. package/benchmarks/leak.mjs +255 -0
  5. package/benchmarks/results/before-spatial.json +391 -0
  6. package/benchmarks/results/before-spatial.md +47 -0
  7. package/benchmarks/results/int8-scan.json +2007 -0
  8. package/benchmarks/results/int8-scan.md +160 -0
  9. package/benchmarks/results/int8-w8a8-scan.json +2007 -0
  10. package/benchmarks/results/int8-w8a8-scan.md +160 -0
  11. package/benchmarks/results/int8-weight-channel.json +1413 -0
  12. package/benchmarks/results/int8-weight-channel.md +118 -0
  13. package/benchmarks/results/int8-weight-only.json +1437 -0
  14. package/benchmarks/results/int8-weight-only.md +118 -0
  15. package/benchmarks/results/kernel-webnn-final.json +1115 -0
  16. package/benchmarks/results/kernel-webnn-final.md +104 -0
  17. package/benchmarks/results/latest-optimized.json +375 -0
  18. package/benchmarks/results/latest-optimized.md +47 -0
  19. package/benchmarks/results/latest.json +391 -0
  20. package/benchmarks/results/latest.md +47 -0
  21. package/benchmarks/results/profile-baseline.json +331 -0
  22. package/benchmarks/results/profile-baseline.md +12 -0
  23. package/benchmarks/results/profile-conv2x.json +331 -0
  24. package/benchmarks/results/profile-conv2x.md +12 -0
  25. package/benchmarks/results/profile-fast-init.json +385 -0
  26. package/benchmarks/results/profile-fast-init.md +47 -0
  27. package/benchmarks/results/profile-fp16-fma.json +369 -0
  28. package/benchmarks/results/profile-fp16-fma.md +47 -0
  29. package/benchmarks/results/profile-fp16-tiled-decoder.json +369 -0
  30. package/benchmarks/results/profile-fp16-tiled-decoder.md +47 -0
  31. package/benchmarks/results/profile-fp16-tiled-encoder.json +369 -0
  32. package/benchmarks/results/profile-fp16-tiled-encoder.md +47 -0
  33. package/benchmarks/results/profile-fp16-unfused-pool.json +385 -0
  34. package/benchmarks/results/profile-fp16-unfused-pool.md +47 -0
  35. package/benchmarks/results/profile-input-major.json +347 -0
  36. package/benchmarks/results/profile-input-major.md +12 -0
  37. package/benchmarks/results/profile-k16.json +347 -0
  38. package/benchmarks/results/profile-k16.md +12 -0
  39. package/benchmarks/results/profile-k4.json +347 -0
  40. package/benchmarks/results/profile-k4.md +12 -0
  41. package/benchmarks/results/profile-pool-reuse.json +331 -0
  42. package/benchmarks/results/profile-pool-reuse.md +12 -0
  43. package/benchmarks/results/profile-precompiled.json +385 -0
  44. package/benchmarks/results/profile-precompiled.md +47 -0
  45. package/benchmarks/results/profile-static-channels.json +385 -0
  46. package/benchmarks/results/profile-static-channels.md +47 -0
  47. package/benchmarks/results/profile-static-io.json +385 -0
  48. package/benchmarks/results/profile-static-io.md +47 -0
  49. package/benchmarks/results/profile-tiled-conv.json +331 -0
  50. package/benchmarks/results/profile-tiled-conv.md +12 -0
  51. package/benchmarks/results/profile-tiled-decoder.json +347 -0
  52. package/benchmarks/results/profile-tiled-decoder.md +12 -0
  53. package/benchmarks/results/profile-tiled-matmul.json +331 -0
  54. package/benchmarks/results/profile-tiled-matmul.md +12 -0
  55. package/benchmarks/results/profile-unfused-decoder.json +379 -0
  56. package/benchmarks/results/profile-unfused-decoder.md +12 -0
  57. package/benchmarks/results/profile-unfused-pool.json +347 -0
  58. package/benchmarks/results/profile-unfused-pool.md +12 -0
  59. package/benchmarks/results/spatial-auto.json +575 -0
  60. package/benchmarks/results/spatial-auto.md +61 -0
  61. package/benchmarks/results/subgroup-smoke.json +1094 -0
  62. package/benchmarks/results/subgroup-smoke.md +104 -0
  63. package/benchmarks/results/webnn-smoke.json +739 -0
  64. package/benchmarks/results/webnn-smoke.md +76 -0
  65. package/dist/oidn.js +4189 -22603
  66. package/dist/oidn.umd.cjs +784 -5807
  67. package/lib/UNet.d.ts +66 -15
  68. package/lib/UNet.js +162 -257
  69. package/lib/UNet.js.map +1 -1
  70. package/lib/WGPUComputePass.d.ts +1 -1
  71. package/lib/WGPUComputePass.js +6 -4
  72. package/lib/WGPUComputePass.js.map +1 -1
  73. package/lib/backend.d.ts +8 -4
  74. package/lib/backend.js +36 -44
  75. package/lib/backend.js.map +1 -1
  76. package/lib/graphOptimizer.d.ts +54 -0
  77. package/lib/graphOptimizer.js +216 -0
  78. package/lib/graphOptimizer.js.map +1 -0
  79. package/lib/main.d.ts +33 -10
  80. package/lib/main.js +5 -0
  81. package/lib/main.js.map +1 -1
  82. package/lib/modelSpec.d.ts +80 -0
  83. package/lib/modelSpec.js +270 -0
  84. package/lib/modelSpec.js.map +1 -0
  85. package/lib/nativeUNet.d.ts +67 -0
  86. package/lib/nativeUNet.js +1735 -0
  87. package/lib/nativeUNet.js.map +1 -0
  88. package/lib/process.js +38 -35
  89. package/lib/process.js.map +1 -1
  90. package/lib/resourceTracker.d.ts +26 -0
  91. package/lib/resourceTracker.js +65 -0
  92. package/lib/resourceTracker.js.map +1 -0
  93. package/lib/tileScheduler.d.ts +33 -0
  94. package/lib/tileScheduler.js +86 -0
  95. package/lib/tileScheduler.js.map +1 -0
  96. package/lib/webnnUNet.d.ts +52 -0
  97. package/lib/webnnUNet.js +535 -0
  98. package/lib/webnnUNet.js.map +1 -0
  99. package/package.json +9 -5
  100. package/scripts/inspect-model.mjs +64 -0
  101. package/src/UNet.ts +236 -339
  102. package/src/WGPUComputePass.ts +6 -4
  103. package/src/backend.ts +42 -55
  104. package/src/graphOptimizer.ts +301 -0
  105. package/src/main.ts +71 -11
  106. package/src/modelSpec.ts +414 -0
  107. package/src/nativeUNet.ts +2256 -0
  108. package/src/process.ts +38 -36
  109. package/src/resourceTracker.ts +94 -0
  110. package/src/tileScheduler.ts +138 -0
  111. package/src/webnnUNet.ts +812 -0
  112. package/tests/modelSpec.test.mjs +128 -0
  113. package/tests/resourceLifecycle.test.mjs +383 -0
  114. package/tests/tileScheduler.test.mjs +90 -0
  115. package/lib/helper.d.ts +0 -4
  116. package/lib/helper.js +0 -33
  117. package/lib/helper.js.map +0 -1
  118. package/lib/kernels.d.ts +0 -1
  119. package/lib/kernels.js +0 -26
  120. package/lib/kernels.js.map +0 -1
  121. package/src/helper.ts +0 -43
  122. package/src/kernels.ts +0 -31
package/lib/main.js CHANGED
@@ -2,12 +2,17 @@ import { parseTZA } from './tza';
2
2
  import UNet from './UNet';
3
3
  import { initWebGPUBackend, initWebGPUBackendWithDevice } from './backend';
4
4
  export { parseTZA, UNet };
5
+ export { detectUNetModelSpec, OIDN_UNET_LARGE_SPEC, OIDN_UNET_SMALL_SPEC, validateUNetModel } from './modelSpec';
6
+ export { optimizeModelGraph, planModelExecution } from './graphOptimizer';
7
+ export { NativeUNetExecutor, resolveNativeUNetPrecision } from './nativeUNet';
8
+ export { WebNNUNetExecutor } from './webnnUNet';
5
9
  export async function initUNetFromBuffer(tzaBuffer, backendParams, opts) {
6
10
  const backend = await (backendParams
7
11
  ? initWebGPUBackendWithDevice(backendParams.device, backendParams.adapterInfo)
8
12
  : initWebGPUBackend());
9
13
  const tensors = parseTZA(tzaBuffer);
10
14
  const unet = new UNet(tensors, backend, opts);
15
+ await unet.prepare();
11
16
  return unet;
12
17
  }
13
18
  export async function initUNetFromURL(modelPath, backendParams, opts) {
package/lib/main.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,IAAI,MAAM,QAAQ,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAE3E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAsB,EACtB,aAAkE,EAClE,IAIC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa;QAClC,CAAC,CAAC,2BAA2B,CACzB,aAAa,CAAC,MAAM,EACpB,aAAa,CAAC,WAAW,CAC1B;QACH,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,OAAQ,EAAE,IAAI,CAAC,CAAC;IAC/C,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,aAAkE,EAClE,IAIC;IAED,OAAO,KAAK,CAAC,SAAS,CAAC;SACpB,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;SAChC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;QACX,OAAO,kBAAkB,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjC,OAAO,IAAI,MAAM,QAAQ,CAAC;AAE1B,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,EAAE,MAAM,WAAW,CAAC;AAQ3E,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;AAE1B,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAOrB,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAQ1E,OAAO,EACL,kBAAkB,EAClB,0BAA0B,EAC3B,MAAM,cAAc,CAAC;AA6BtB,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQhD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,SAAsB,EACtB,aAAkE,EAClE,IAAkB;IAElB,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa;QAClC,CAAC,CAAC,2BAA2B,CACzB,aAAa,CAAC,MAAM,EACpB,aAAa,CAAC,WAAW,CAC1B;QACH,CAAC,CAAC,iBAAiB,EAAE,CAAC,CAAC;IACzB,MAAM,OAAO,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACrB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,SAAiB,EACjB,aAAkE,EAClE,IAAkB;IAElB,OAAO,KAAK,CAAC,SAAS,CAAC;SACpB,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;SAChC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE;QACX,OAAO,kBAAkB,CAAC,EAAE,EAAE,aAAa,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -0,0 +1,80 @@
1
+ import type { HostTensor } from './tza';
2
+ /**
3
+ * Versioned, runtime-independent description of an OIDN network.
4
+ *
5
+ * TZA contains named tensors but no executable graph. Keeping the graph in a
6
+ * small declarative descriptor makes model upgrades independent from the WGSL
7
+ * kernels: a new OIDN topology only needs a new descriptor and validation
8
+ * fixture unless it introduces a genuinely new operation.
9
+ */
10
+ export interface UNetModelSpec {
11
+ schemaVersion: 1;
12
+ id: string;
13
+ family: 'oidn-unet-small' | 'oidn-unet-large' | (string & {});
14
+ input: string;
15
+ output: string;
16
+ receptiveField: number;
17
+ nodes: readonly ModelNodeSpec[];
18
+ /** Reject unrecognised tensors so an upstream topology change is explicit. */
19
+ allowAdditionalTensors?: boolean;
20
+ }
21
+ export type ModelActivation = 'identity' | 'relu';
22
+ export interface Conv2DNodeSpec {
23
+ op: 'conv2d';
24
+ id: string;
25
+ input: string;
26
+ weight: string;
27
+ bias: string;
28
+ activation: ModelActivation;
29
+ padding: 'same';
30
+ }
31
+ export interface MaxPool2DNodeSpec {
32
+ op: 'maxPool2d';
33
+ id: string;
34
+ input: string;
35
+ size: 2;
36
+ stride: 2;
37
+ padding: 'same';
38
+ }
39
+ export interface Upsample2DNodeSpec {
40
+ op: 'upsample2d';
41
+ id: string;
42
+ input: string;
43
+ scale: 2;
44
+ mode: 'nearest';
45
+ }
46
+ export interface ConcatNodeSpec {
47
+ op: 'concat';
48
+ id: string;
49
+ inputs: readonly string[];
50
+ axis: 'channels';
51
+ }
52
+ export type ModelNodeSpec = Conv2DNodeSpec | MaxPool2DNodeSpec | Upsample2DNodeSpec | ConcatNodeSpec;
53
+ export interface ValidatedConvTensor {
54
+ weight: HostTensor;
55
+ bias: HostTensor;
56
+ inputChannels: number;
57
+ outputChannels: number;
58
+ kernelHeight: number;
59
+ kernelWidth: number;
60
+ }
61
+ export interface ModelConvChannels {
62
+ inputChannels: number;
63
+ outputChannels: number;
64
+ }
65
+ export interface UNetModelGraph {
66
+ spec: UNetModelSpec;
67
+ inputChannels: number;
68
+ outputChannels: number;
69
+ channelsByValue: ReadonlyMap<string, number>;
70
+ convChannels: ReadonlyMap<string, ModelConvChannels>;
71
+ }
72
+ export interface ValidatedUNetModel extends UNetModelGraph {
73
+ tensorDataType: HostTensor['desc']['dataType'];
74
+ convTensors: ReadonlyMap<string, ValidatedConvTensor>;
75
+ }
76
+ export declare const OIDN_UNET_SMALL_SPEC: UNetModelSpec;
77
+ export declare const OIDN_UNET_LARGE_SPEC: UNetModelSpec;
78
+ export declare function detectUNetModelSpec(tensors: ReadonlyMap<string, HostTensor>, specs?: readonly UNetModelSpec[]): UNetModelSpec;
79
+ /** Validate tensor layout, shapes, dtypes, graph order, and channel flow. */
80
+ export declare function validateUNetModel(tensors: ReadonlyMap<string, HostTensor>, spec?: UNetModelSpec): ValidatedUNetModel;
@@ -0,0 +1,270 @@
1
+ function conv(id, input) {
2
+ return {
3
+ op: 'conv2d',
4
+ id,
5
+ input,
6
+ weight: `${id}.weight`,
7
+ bias: `${id}.bias`,
8
+ activation: 'relu',
9
+ padding: 'same'
10
+ };
11
+ }
12
+ function pool(id, input) {
13
+ return {
14
+ op: 'maxPool2d',
15
+ id,
16
+ input,
17
+ size: 2,
18
+ stride: 2,
19
+ padding: 'same'
20
+ };
21
+ }
22
+ function upsample(id, input) {
23
+ return {
24
+ op: 'upsample2d',
25
+ id,
26
+ input,
27
+ scale: 2,
28
+ mode: 'nearest'
29
+ };
30
+ }
31
+ function concat(id, first, second) {
32
+ return {
33
+ op: 'concat',
34
+ id,
35
+ inputs: [first, second],
36
+ axis: 'channels'
37
+ };
38
+ }
39
+ export const OIDN_UNET_SMALL_SPEC = {
40
+ schemaVersion: 1,
41
+ id: 'oidn-unet-small-v1',
42
+ family: 'oidn-unet-small',
43
+ input: 'input',
44
+ output: 'dec_conv0',
45
+ receptiveField: 174,
46
+ nodes: [
47
+ conv('enc_conv0', 'input'),
48
+ conv('enc_conv1', 'enc_conv0'),
49
+ pool('pool1', 'enc_conv1'),
50
+ conv('enc_conv2', 'pool1'),
51
+ pool('pool2', 'enc_conv2'),
52
+ conv('enc_conv3', 'pool2'),
53
+ pool('pool3', 'enc_conv3'),
54
+ conv('enc_conv4', 'pool3'),
55
+ pool('pool4', 'enc_conv4'),
56
+ conv('enc_conv5a', 'pool4'),
57
+ conv('enc_conv5b', 'enc_conv5a'),
58
+ upsample('up4', 'enc_conv5b'),
59
+ concat('concat4', 'up4', 'pool3'),
60
+ conv('dec_conv4a', 'concat4'),
61
+ conv('dec_conv4b', 'dec_conv4a'),
62
+ upsample('up3', 'dec_conv4b'),
63
+ concat('concat3', 'up3', 'pool2'),
64
+ conv('dec_conv3a', 'concat3'),
65
+ conv('dec_conv3b', 'dec_conv3a'),
66
+ upsample('up2', 'dec_conv3b'),
67
+ concat('concat2', 'up2', 'pool1'),
68
+ conv('dec_conv2a', 'concat2'),
69
+ conv('dec_conv2b', 'dec_conv2a'),
70
+ upsample('up1', 'dec_conv2b'),
71
+ concat('concat1', 'up1', 'input'),
72
+ conv('dec_conv1a', 'concat1'),
73
+ conv('dec_conv1b', 'dec_conv1a'),
74
+ conv('dec_conv0', 'dec_conv1b')
75
+ ]
76
+ };
77
+ export const OIDN_UNET_LARGE_SPEC = {
78
+ schemaVersion: 1,
79
+ id: 'oidn-unet-large-v1',
80
+ family: 'oidn-unet-large',
81
+ input: 'input',
82
+ output: 'dec_conv1c',
83
+ receptiveField: 202,
84
+ nodes: [
85
+ conv('enc_conv1a', 'input'),
86
+ conv('enc_conv1b', 'enc_conv1a'),
87
+ pool('pool1', 'enc_conv1b'),
88
+ conv('enc_conv2a', 'pool1'),
89
+ conv('enc_conv2b', 'enc_conv2a'),
90
+ pool('pool2', 'enc_conv2b'),
91
+ conv('enc_conv3a', 'pool2'),
92
+ conv('enc_conv3b', 'enc_conv3a'),
93
+ pool('pool3', 'enc_conv3b'),
94
+ conv('enc_conv4a', 'pool3'),
95
+ conv('enc_conv4b', 'enc_conv4a'),
96
+ pool('pool4', 'enc_conv4b'),
97
+ conv('enc_conv5a', 'pool4'),
98
+ conv('enc_conv5b', 'enc_conv5a'),
99
+ upsample('up4', 'enc_conv5b'),
100
+ concat('concat4', 'up4', 'pool3'),
101
+ conv('dec_conv4a', 'concat4'),
102
+ conv('dec_conv4b', 'dec_conv4a'),
103
+ upsample('up3', 'dec_conv4b'),
104
+ concat('concat3', 'up3', 'pool2'),
105
+ conv('dec_conv3a', 'concat3'),
106
+ conv('dec_conv3b', 'dec_conv3a'),
107
+ upsample('up2', 'dec_conv3b'),
108
+ concat('concat2', 'up2', 'pool1'),
109
+ conv('dec_conv2a', 'concat2'),
110
+ conv('dec_conv2b', 'dec_conv2a'),
111
+ upsample('up1', 'dec_conv2b'),
112
+ concat('concat1', 'up1', 'input'),
113
+ conv('dec_conv1a', 'concat1'),
114
+ conv('dec_conv1b', 'dec_conv1a'),
115
+ conv('dec_conv1c', 'dec_conv1b')
116
+ ]
117
+ };
118
+ const BUILTIN_MODEL_SPECS = [
119
+ OIDN_UNET_SMALL_SPEC,
120
+ OIDN_UNET_LARGE_SPEC
121
+ ];
122
+ function expectedTensorNames(spec) {
123
+ const names = new Set();
124
+ for (const node of spec.nodes) {
125
+ if (node.op === 'conv2d') {
126
+ names.add(node.weight);
127
+ names.add(node.bias);
128
+ }
129
+ }
130
+ return names;
131
+ }
132
+ function tensorByteSize(tensor) {
133
+ return tensor.desc.getByteSize();
134
+ }
135
+ function describeNames(names) {
136
+ return [...names].sort().join(', ');
137
+ }
138
+ export function detectUNetModelSpec(tensors, specs = BUILTIN_MODEL_SPECS) {
139
+ const matches = specs.filter((spec) => {
140
+ const expected = expectedTensorNames(spec);
141
+ if ([...expected].some((name) => !tensors.has(name)))
142
+ return false;
143
+ return (spec.allowAdditionalTensors === true ||
144
+ [...tensors.keys()].every((name) => expected.has(name)));
145
+ });
146
+ if (matches.length === 1)
147
+ return matches[0];
148
+ if (matches.length > 1) {
149
+ throw new Error(`Ambiguous OIDN model topology: ${matches.map((spec) => spec.id).join(', ')}`);
150
+ }
151
+ throw new Error(`Unsupported OIDN model topology. TZA tensors: ${describeNames(tensors.keys())}`);
152
+ }
153
+ function requireTensor(tensors, name, modelId) {
154
+ const tensor = tensors.get(name);
155
+ if (!tensor) {
156
+ throw new Error(`Model ${modelId} is missing tensor ${name}`);
157
+ }
158
+ if (tensor.data.byteLength !== tensorByteSize(tensor)) {
159
+ throw new Error(`Tensor ${name} has ${tensor.data.byteLength} bytes, expected ${tensorByteSize(tensor)}`);
160
+ }
161
+ return tensor;
162
+ }
163
+ /** Validate tensor layout, shapes, dtypes, graph order, and channel flow. */
164
+ export function validateUNetModel(tensors, spec = detectUNetModelSpec(tensors)) {
165
+ if (spec.schemaVersion !== 1) {
166
+ throw new Error(`Unsupported model descriptor schema ${spec.schemaVersion}`);
167
+ }
168
+ const expected = expectedTensorNames(spec);
169
+ if (!spec.allowAdditionalTensors) {
170
+ const additional = [...tensors.keys()].filter((name) => !expected.has(name));
171
+ if (additional.length > 0) {
172
+ throw new Error(`Model ${spec.id} has unexpected tensors: ${describeNames(additional)}`);
173
+ }
174
+ }
175
+ const channelsByValue = new Map();
176
+ const convTensors = new Map();
177
+ const convChannels = new Map();
178
+ const producedValues = new Set([spec.input]);
179
+ let inputChannels;
180
+ let commonDataType;
181
+ const getChannels = (value, nodeId) => {
182
+ const channels = channelsByValue.get(value);
183
+ if (channels === undefined) {
184
+ throw new Error(`Model ${spec.id} node ${nodeId} reads unknown or forward value ${value}`);
185
+ }
186
+ return channels;
187
+ };
188
+ for (const node of spec.nodes) {
189
+ if (producedValues.has(node.id)) {
190
+ throw new Error(`Model ${spec.id} produces duplicate value ${node.id}`);
191
+ }
192
+ if (node.op === 'conv2d') {
193
+ const weight = requireTensor(tensors, node.weight, spec.id);
194
+ const bias = requireTensor(tensors, node.bias, spec.id);
195
+ const dims = weight.desc.dims;
196
+ if (weight.desc.layout !== 'oihw' || dims.length !== 4) {
197
+ throw new Error(`Tensor ${node.weight} must use OIHW layout`);
198
+ }
199
+ if (dims[2] !== 3 || dims[3] !== 3) {
200
+ throw new Error(`Tensor ${node.weight} must use a 3x3 kernel`);
201
+ }
202
+ if (bias.desc.layout !== 'x' || bias.desc.dims.length !== 1) {
203
+ throw new Error(`Tensor ${node.bias} must be a one-dimensional bias`);
204
+ }
205
+ if (bias.desc.dims[0] !== dims[0]) {
206
+ throw new Error(`Tensor ${node.bias} has ${bias.desc.dims[0]} channels, expected ${dims[0]}`);
207
+ }
208
+ if (weight.desc.dataType !== bias.desc.dataType) {
209
+ throw new Error(`Weight and bias dtype differ for ${node.id}`);
210
+ }
211
+ if (commonDataType && commonDataType !== weight.desc.dataType) {
212
+ throw new Error(`Mixed tensor dtypes are not supported by model ${spec.id}`);
213
+ }
214
+ commonDataType = weight.desc.dataType;
215
+ if (node.input === spec.input && inputChannels === undefined) {
216
+ inputChannels = dims[1];
217
+ channelsByValue.set(spec.input, inputChannels);
218
+ }
219
+ const actualInputChannels = getChannels(node.input, node.id);
220
+ if (actualInputChannels !== dims[1]) {
221
+ throw new Error(`Tensor ${node.weight} expects ${dims[1]} input channels, ` +
222
+ `but ${node.input} provides ${actualInputChannels}`);
223
+ }
224
+ channelsByValue.set(node.id, dims[0]);
225
+ convTensors.set(node.id, {
226
+ weight,
227
+ bias,
228
+ inputChannels: dims[1],
229
+ outputChannels: dims[0],
230
+ kernelHeight: dims[2],
231
+ kernelWidth: dims[3]
232
+ });
233
+ convChannels.set(node.id, {
234
+ inputChannels: dims[1],
235
+ outputChannels: dims[0]
236
+ });
237
+ }
238
+ else if (node.op === 'concat') {
239
+ if (node.inputs.length < 2) {
240
+ throw new Error(`Concat ${node.id} requires at least two inputs`);
241
+ }
242
+ const channels = node.inputs.reduce((sum, value) => sum + getChannels(value, node.id), 0);
243
+ channelsByValue.set(node.id, channels);
244
+ }
245
+ else {
246
+ channelsByValue.set(node.id, getChannels(node.input, node.id));
247
+ }
248
+ producedValues.add(node.id);
249
+ }
250
+ if (inputChannels === undefined || commonDataType === undefined) {
251
+ throw new Error(`Model ${spec.id} has no convolution reading its input`);
252
+ }
253
+ const outputChannels = channelsByValue.get(spec.output);
254
+ if (outputChannels === undefined) {
255
+ throw new Error(`Model ${spec.id} output ${spec.output} is not produced`);
256
+ }
257
+ if (outputChannels !== 3) {
258
+ throw new Error(`Model ${spec.id} must produce 3 channels, got ${outputChannels}`);
259
+ }
260
+ return {
261
+ spec,
262
+ inputChannels,
263
+ outputChannels,
264
+ tensorDataType: commonDataType,
265
+ channelsByValue,
266
+ convChannels,
267
+ convTensors
268
+ };
269
+ }
270
+ //# sourceMappingURL=modelSpec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modelSpec.js","sourceRoot":"","sources":["../src/modelSpec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,67 @@
1
+ import type { ValidatedUNetModel } from './modelSpec';
2
+ import { type OIDNResourceSnapshot } from './resourceTracker.js';
3
+ export type NativeUNetPrecision = 'fp32' | 'fp16';
4
+ export type NativeUNetPrecisionSetting = NativeUNetPrecision | 'auto';
5
+ export type NativeUNetKernel = 'direct' | 'implicit-gemm' | 'spatial' | 'subgroup';
6
+ export type NativeUNetKernelSetting = NativeUNetKernel | 'auto';
7
+ export interface NativeUNetOptions {
8
+ precision?: NativeUNetPrecisionSetting;
9
+ /**
10
+ * Convolution kernel selection. `auto` uses a model-independent capability
11
+ * heuristic and falls back to the direct kernel when a tile does not fit.
12
+ */
13
+ kernel?: NativeUNetKernelSetting;
14
+ /** Maximum number of shape-dependent activation plans retained. */
15
+ shapeCacheSize?: number;
16
+ }
17
+ export interface NativeUNetLayerTiming {
18
+ id: string;
19
+ durationMs: number;
20
+ }
21
+ export interface NativeUNetExecutionProfile {
22
+ totalMs: number;
23
+ layers: NativeUNetLayerTiming[];
24
+ }
25
+ export declare function resolveNativeUNetPrecision(device: GPUDevice, requested?: NativeUNetPrecisionSetting): NativeUNetPrecision;
26
+ /** Native, model-driven OIDN U-Net executor. */
27
+ export declare class NativeUNetExecutor {
28
+ private _device;
29
+ readonly precision: NativeUNetPrecision;
30
+ readonly kernelSetting: NativeUNetKernelSetting;
31
+ readonly maxSpatialInputBlocks: number;
32
+ readonly subgroupsAvailable: boolean;
33
+ private _model;
34
+ private _packedConvs;
35
+ private _pipelineCache;
36
+ private _pipelinePromises;
37
+ private _executionCache;
38
+ private _retiredExecutions;
39
+ private _clock;
40
+ private _shapeCacheSize;
41
+ private _profileNextExecution;
42
+ private _lastExecutionProfile?;
43
+ private _profileOperations;
44
+ private _resources;
45
+ private _disposed;
46
+ constructor(_device: GPUDevice, model: ValidatedUNetModel, options?: NativeUNetOptions);
47
+ private _pipeline;
48
+ private _pipelineAsync;
49
+ private _nodePipelineSpec;
50
+ private _selectConvKernel;
51
+ private _nodePipeline;
52
+ /** Compiles all shape-independent kernels before the model reports ready. */
53
+ prepare(): Promise<void>;
54
+ private _createExecution;
55
+ private _execution;
56
+ /** Captures per-pass GPU timestamps for the next execute call when supported. */
57
+ profileNextExecution(): boolean;
58
+ getLastExecutionProfile(): Promise<NativeUNetExecutionProfile> | undefined;
59
+ execute(inputBuffers: readonly GPUBuffer[], width: number, height: number): GPUBuffer;
60
+ /** Compatibility path for ImageData/HDR arrays without TensorFlow.js. */
61
+ executeCPU(interleavedInput: Float32Array, width: number, height: number): Promise<Float32Array>;
62
+ private _releaseBuffer;
63
+ private _releaseQuerySet;
64
+ private _destroyExecution;
65
+ getResourceInfo(): OIDNResourceSnapshot;
66
+ dispose(): void;
67
+ }