@photivra/engine 2.18.0 → 2.19.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +68 -1
- package/CITATION.cff +1 -1
- package/README.md +6 -6
- package/SECURITY.md +1 -1
- package/dist/capture/focus-control.js +2 -75
- package/dist/capture/focus-control.js.map +1 -1
- package/dist/capture/native-environment-lean.d.ts +1 -0
- package/dist/capture/native-environment-lean.js +1 -1
- package/dist/capture/native-environment-lean.js.map +1 -1
- package/dist/capture/native-environment-optical-stage.d.ts +1 -0
- package/dist/capture/native-environment-optical-stage.js +2 -5
- package/dist/capture/native-environment-optical-stage.js.map +1 -1
- package/dist/capture/native-environment-raw.js +1 -5
- package/dist/capture/native-environment-raw.js.map +1 -1
- package/dist/capture/release-sequence.js +2 -47
- package/dist/capture/release-sequence.js.map +1 -1
- package/dist/color/white-balance.d.ts +2 -0
- package/dist/color/white-balance.js +3 -56
- package/dist/color/white-balance.js.map +1 -1
- package/dist/composition/image-formation-plan.d.ts +1 -0
- package/dist/composition/image-formation-plan.js +3 -49
- package/dist/composition/image-formation-plan.js.map +1 -1
- package/dist/core/evidence-provenance.js +1 -16
- package/dist/core/evidence-provenance.js.map +1 -1
- package/dist/core/record-validation.d.ts +54 -0
- package/dist/core/record-validation.js +176 -0
- package/dist/core/record-validation.js.map +1 -1
- package/dist/core/scientific-assurance.js +1 -18
- package/dist/core/scientific-assurance.js.map +1 -1
- package/dist/core/shared-helpers.d.ts +33 -0
- package/dist/core/shared-helpers.js +34 -0
- package/dist/core/shared-helpers.js.map +1 -0
- package/dist/core/spectral-composition.js +1 -36
- package/dist/core/spectral-composition.js.map +1 -1
- package/dist/core/spectral.js +1 -19
- package/dist/core/spectral.js.map +1 -1
- package/dist/core/version.d.ts +1 -1
- package/dist/core/version.js +1 -1
- package/dist/core/version.js.map +1 -1
- package/dist/equipment/exposure-capabilities.d.ts +1 -0
- package/dist/equipment/exposure-capabilities.js +2 -36
- package/dist/equipment/exposure-capabilities.js.map +1 -1
- package/dist/equipment/iso-capabilities.js +2 -49
- package/dist/equipment/iso-capabilities.js.map +1 -1
- package/dist/equipment/metering-capabilities.js +1 -26
- package/dist/equipment/metering-capabilities.js.map +1 -1
- package/dist/equipment/release-capabilities.js +1 -53
- package/dist/equipment/release-capabilities.js.map +1 -1
- package/dist/exposure/auto-iso-slowest-shutter.js +1 -7
- package/dist/exposure/auto-iso-slowest-shutter.js.map +1 -1
- package/dist/exposure/exposure-duration-control.js +1 -16
- package/dist/exposure/exposure-duration-control.js.map +1 -1
- package/dist/exposure/exposure-mode-resolver.js +1 -17
- package/dist/exposure/exposure-mode-resolver.js.map +1 -1
- package/dist/exposure/filtered-exposure-time.d.ts +93 -0
- package/dist/exposure/filtered-exposure-time.js +129 -0
- package/dist/exposure/filtered-exposure-time.js.map +1 -0
- package/dist/exposure/flash-ttl.d.ts +1 -0
- package/dist/exposure/flash-ttl.js +1 -1
- package/dist/exposure/flash-ttl.js.map +1 -1
- package/dist/exposure/flash.js +1 -49
- package/dist/exposure/flash.js.map +1 -1
- package/dist/exposure/metering-scene-radiance.js +1 -25
- package/dist/exposure/metering-scene-radiance.js.map +1 -1
- package/dist/exposure/metering-target.js +1 -30
- package/dist/exposure/metering-target.js.map +1 -1
- package/dist/exposure/metering-temporal.js +1 -8
- package/dist/exposure/metering-temporal.js.map +1 -1
- package/dist/exposure/metering.js +1 -72
- package/dist/exposure/metering.js.map +1 -1
- package/dist/exposure/program-line.js +1 -45
- package/dist/exposure/program-line.js.map +1 -1
- package/dist/facade/develop-joined-parts.d.ts +29 -0
- package/dist/facade/develop-joined-parts.js +33 -0
- package/dist/facade/develop-joined-parts.js.map +1 -0
- package/dist/facade/generic-lens-capture.d.ts +4 -2
- package/dist/facade/generic-lens-capture.js +4 -2
- package/dist/facade/generic-lens-capture.js.map +1 -1
- package/dist/facade/simulate-capture.d.ts +37 -5
- package/dist/facade/simulate-capture.js +153 -96
- package/dist/facade/simulate-capture.js.map +1 -1
- package/dist/gpu/chart-composite-gpu.js +1 -3
- package/dist/gpu/chart-composite-gpu.js.map +1 -1
- package/dist/gpu/chart-radiance-gpu.js +1 -5
- package/dist/gpu/chart-radiance-gpu.js.map +1 -1
- package/dist/gpu/display-view-quality-gpu.d.ts +13 -1
- package/dist/gpu/display-view-quality-gpu.js +4 -8
- package/dist/gpu/display-view-quality-gpu.js.map +1 -1
- package/dist/gpu/display-view-speed-gpu.js +3 -25
- package/dist/gpu/display-view-speed-gpu.js.map +1 -1
- package/dist/gpu/sensor-stage-gpu.js +1 -5
- package/dist/gpu/sensor-stage-gpu.js.map +1 -1
- package/dist/gpu/webgpu-runtime.d.ts +2 -0
- package/dist/gpu/webgpu-runtime.js +3 -0
- package/dist/gpu/webgpu-runtime.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/motion/camera-rotation.js +1 -6
- package/dist/motion/camera-rotation.js.map +1 -1
- package/dist/motion/capture-rotation-inverse-mapping.d.ts +12 -0
- package/dist/motion/capture-rotation-inverse-mapping.js +2 -2
- package/dist/motion/capture-rotation-inverse-mapping.js.map +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.d.ts +1 -0
- package/dist/motion/capture-rotation-temporal-quadrature.js +1 -1
- package/dist/motion/capture-rotation-temporal-quadrature.js.map +1 -1
- package/dist/motion/capture-rotation-trajectory.js +2 -17
- package/dist/motion/capture-rotation-trajectory.js.map +1 -1
- package/dist/motion/capture-translation-parallax-temporal-quadrature.d.ts +1 -0
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js +3 -14
- package/dist/motion/capture-translation-parallax-temporal-quadrature.js.map +1 -1
- package/dist/motion/extended-object-projection.js +5 -40
- package/dist/motion/extended-object-projection.js.map +1 -1
- package/dist/optics/atmospheric-haze.js +1 -7
- package/dist/optics/atmospheric-haze.js.map +1 -1
- package/dist/optics/brown-conrady-distortion.js +1 -7
- package/dist/optics/brown-conrady-distortion.js.map +1 -1
- package/dist/optics/complex-pupil-psf.d.ts +1 -0
- package/dist/optics/complex-pupil-psf.js +2 -84
- package/dist/optics/complex-pupil-psf.js.map +1 -1
- package/dist/optics/focus-state.js +1 -11
- package/dist/optics/focus-state.js.map +1 -1
- package/dist/optics/front-of-lens-filter.d.ts +5 -0
- package/dist/optics/front-of-lens-filter.js +3 -65
- package/dist/optics/front-of-lens-filter.js.map +1 -1
- package/dist/optics/generic-nd-filter-presets.d.ts +12 -0
- package/dist/optics/generic-nd-filter-presets.js +48 -0
- package/dist/optics/generic-nd-filter-presets.js.map +1 -0
- package/dist/optics/illumination-vignetting.js +1 -6
- package/dist/optics/illumination-vignetting.js.map +1 -1
- package/dist/optics/lens-psf-profile.d.ts +4 -1
- package/dist/optics/lens-psf-profile.js +12 -111
- package/dist/optics/lens-psf-profile.js.map +1 -1
- package/dist/optics/longitudinal-chromatic-aberration.js +1 -7
- package/dist/optics/longitudinal-chromatic-aberration.js.map +1 -1
- package/dist/optics/pupil-vignetting.js +1 -7
- package/dist/optics/pupil-vignetting.js.map +1 -1
- package/dist/optics/radial-distortion.js +1 -6
- package/dist/optics/radial-distortion.js.map +1 -1
- package/dist/optics/scene-to-sensor-irradiance.js +4 -96
- package/dist/optics/scene-to-sensor-irradiance.js.map +1 -1
- package/dist/optics/stray-light.d.ts +1 -0
- package/dist/optics/stray-light.js +1 -1
- package/dist/optics/stray-light.js.map +1 -1
- package/dist/optics/zernike-wavefront.js +1 -7
- package/dist/optics/zernike-wavefront.js.map +1 -1
- package/dist/output/capture-geometry.js +1 -8
- package/dist/output/capture-geometry.js.map +1 -1
- package/dist/output/developed-lens-corrections.d.ts +62 -0
- package/dist/output/developed-lens-corrections.js +135 -0
- package/dist/output/developed-lens-corrections.js.map +1 -0
- package/dist/output/generic-lens-corrections.d.ts +2 -6
- package/dist/output/generic-lens-corrections.js +3 -6
- package/dist/output/generic-lens-corrections.js.map +1 -1
- package/dist/output/geometric-transforms.js +1 -4
- package/dist/output/geometric-transforms.js.map +1 -1
- package/dist/output/native-capture-sdr.d.ts +2 -2
- package/dist/output/native-capture-sdr.js +3 -2
- package/dist/output/native-capture-sdr.js.map +1 -1
- package/dist/processing/development-detail.d.ts +29 -0
- package/dist/processing/development-detail.js +128 -107
- package/dist/processing/development-detail.js.map +1 -1
- package/dist/schema/illumination-temporal.js +3 -72
- package/dist/schema/illumination-temporal.js.map +1 -1
- package/dist/schema/illumination.d.ts +1 -0
- package/dist/schema/illumination.js +2 -65
- package/dist/schema/illumination.js.map +1 -1
- package/dist/schema/scene-radiance-temporal.js +2 -14
- package/dist/schema/scene-radiance-temporal.js.map +1 -1
- package/dist/schema/scene-radiance.js +2 -60
- package/dist/schema/scene-radiance.js.map +1 -1
- package/dist/schema/validation.d.ts +2 -0
- package/dist/schema/validation.js +2 -17
- package/dist/schema/validation.js.map +1 -1
- package/dist/sensor/accumulated-charge.js +2 -59
- package/dist/sensor/accumulated-charge.js.map +1 -1
- package/dist/sensor/architecture.js +1 -16
- package/dist/sensor/architecture.js.map +1 -1
- package/dist/sensor/camera-saturation-capacity.d.ts +1 -0
- package/dist/sensor/camera-saturation-capacity.js +3 -55
- package/dist/sensor/camera-saturation-capacity.js.map +1 -1
- package/dist/sensor/capture-color-sampling-binding.js +1 -26
- package/dist/sensor/capture-color-sampling-binding.js.map +1 -1
- package/dist/sensor/capture-mode-timing.js +1 -39
- package/dist/sensor/capture-mode-timing.js.map +1 -1
- package/dist/sensor/capture-mode.js +1 -23
- package/dist/sensor/capture-mode.js.map +1 -1
- package/dist/sensor/color-sampling.js +1 -26
- package/dist/sensor/color-sampling.js.map +1 -1
- package/dist/sensor/constant-rate-temporal-integration.js +2 -46
- package/dist/sensor/constant-rate-temporal-integration.js.map +1 -1
- package/dist/sensor/dark-current.js +2 -45
- package/dist/sensor/dark-current.js.map +1 -1
- package/dist/sensor/eqe-electron-rate.js +2 -35
- package/dist/sensor/eqe-electron-rate.js.map +1 -1
- package/dist/sensor/exposure-window.d.ts +5 -0
- package/dist/sensor/exposure-window.js +7 -22
- package/dist/sensor/exposure-window.js.map +1 -1
- package/dist/sensor/iso-gain.js +1 -7
- package/dist/sensor/iso-gain.js.map +1 -1
- package/dist/sensor/iso-signal-chain.js +1 -43
- package/dist/sensor/iso-signal-chain.js.map +1 -1
- package/dist/sensor/optical-stack.js +1 -25
- package/dist/sensor/optical-stack.js.map +1 -1
- package/dist/sensor/photon-energy.js +1 -26
- package/dist/sensor/photon-energy.js.map +1 -1
- package/dist/sensor/physical-charge-capacity.js +3 -77
- package/dist/sensor/physical-charge-capacity.js.map +1 -1
- package/dist/sensor/radiometry-readiness.js +2 -23
- package/dist/sensor/radiometry-readiness.js.map +1 -1
- package/dist/sensor/raw-readout.d.ts +3 -0
- package/dist/sensor/raw-readout.js +4 -66
- package/dist/sensor/raw-readout.js.map +1 -1
- package/dist/sensor/raw-reconstruction.js +2 -64
- package/dist/sensor/raw-reconstruction.js.map +1 -1
- package/dist/sensor/readout-exposure-linkage.js +1 -9
- package/dist/sensor/readout-exposure-linkage.js.map +1 -1
- package/dist/sensor/readout-timing.js +3 -57
- package/dist/sensor/readout-timing.js.map +1 -1
- package/dist/sensor/response-application-compatibility.d.ts +2 -0
- package/dist/sensor/response-application-compatibility.js +3 -29
- package/dist/sensor/response-application-compatibility.js.map +1 -1
- package/dist/sensor/response-operating-range.d.ts +1 -0
- package/dist/sensor/response-operating-range.js +3 -79
- package/dist/sensor/response-operating-range.js.map +1 -1
- package/dist/sensor/responsivity-photocurrent.js +4 -108
- package/dist/sensor/responsivity-photocurrent.js.map +1 -1
- package/dist/sensor/sampling-aperture.js +1 -25
- package/dist/sensor/sampling-aperture.js.map +1 -1
- package/dist/sensor/spatial-sample-reduction.js +2 -19
- package/dist/sensor/spatial-sample-reduction.js.map +1 -1
- package/dist/sensor/spatial-sampling-quadrature.js +1 -3
- package/dist/sensor/spatial-sampling-quadrature.js.map +1 -1
- package/dist/sensor/spatio-spectral-reduction.js +1 -18
- package/dist/sensor/spatio-spectral-reduction.js.map +1 -1
- package/dist/sensor/spectral-coverage.d.ts +10 -1
- package/dist/sensor/spectral-coverage.js +1 -1
- package/dist/sensor/spectral-coverage.js.map +1 -1
- package/dist/sensor/spectral-quadrature.js +2 -35
- package/dist/sensor/spectral-quadrature.js.map +1 -1
- package/dist/sensor/spectral-response.js +1 -47
- package/dist/sensor/spectral-response.js.map +1 -1
- package/dist/stabilization/camera-shake.js +1 -6
- package/dist/stabilization/camera-shake.js.map +1 -1
- package/dist/stabilization/system.js +2 -80
- package/dist/stabilization/system.js.map +1 -1
- package/docs/AGENT_GUIDE.md +1 -0
- package/docs/API_REFERENCE.md +41 -2
- package/docs/QUICK_START.md +90 -8
- package/docs/USAGE.md +47 -2
- package/docs/api/core-version.md +1 -1
- package/docs/api/exports.json +53 -3
- package/docs/api/exposure-filtered-exposure-time.md +105 -0
- package/docs/api/facade-develop-joined-parts.md +32 -0
- package/docs/api/facade-simulate-capture.md +36 -5
- package/docs/api/optics-generic-nd-filter-presets.md +34 -0
- package/docs/api/optics-lens-psf-profile.md +3 -1
- package/docs/api/output-developed-lens-corrections.md +12 -0
- package/docs/api/output-generic-lens-corrections.md +0 -9
- package/llms.txt +1 -0
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sensor-stage-gpu.js","sourceRoot":"","sources":["../../src/gpu/sensor-stage-gpu.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Host side of the `webgpu-f32` sensor stage (#277): domain checks, frame constants, per-site mean\n * packing, banded dispatch and readback. The float64 reference is `simulatePackedSensorRaw`\n * (capture/packed-sensor-raw.ts). Internal; the public entry point is the image-kernel accelerator.\n */\nimport { createHostYieldGate } from \"../capture/host-yield-cadence.js\";\nimport { calculatePackedSensorRawPlan, createPackedFixedPattern, packedSensorDiagnostics, packedSensorExtras, simulatePackedSensorRows,\n type PackedSensorRawInput, type PackedSensorRawPlan } from \"../capture/packed-sensor-raw.js\";\nimport { adcTransfer, type SensorReadoutConversionRegime } from \"../sensor/raw-readout.js\";\nimport { ImageKernelExecutionError, webGpuExecution, type ImageKernelExecution } from \"./image-kernel-execution.js\";\nimport type { AcceleratedPackedSensorRawResult } from \"./image-kernel-accelerator.js\";\nimport { BUFFER_USAGE, GpuResourceScope, abortedError, linearDispatch, runComputePass, type WebGpuRuntime } from \"./webgpu-runtime.js\";\nimport { SENSOR_AUX, SENSOR_EXTRAS, SENSOR_MEAN_CATEGORY, SENSOR_OUTPUT, SENSOR_PIECE_WORDS, SENSOR_RAW_WGSL, SENSOR_ROUNDING, SENSOR_SITE_WORDS,\n SENSOR_WORKGROUP_SIZE } from \"./wgsl-sensor-kernel.js\";\n\ntype PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;\ntype YieldControl = ((signal: AbortSignal) => Promise<void>) | undefined;\n\n/** Largest physical capacity on the GPU: every realized count up to it is exact in float32. */\nexport const SENSOR_GPU_MAXIMUM_CAPACITY = 2 ** 24;\n/** Poisson means must stay below this on the GPU (30-bit integer part of a mean word). */\nexport const SENSOR_GPU_MAXIMUM_MEAN = 2 ** 30;\n/** Largest |fixed-pattern readout offset| on the GPU, in electrons and in codes. */\nexport const SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS = 2 ** 28;\nexport const SENSOR_GPU_MAXIMUM_OFFSET_CODES = 2 ** 20;\nconst CPU_RELATIVE = 2 ** -47;\n/** One WGSL rounding, either direction (2^-23). */\nconst E = SENSOR_ROUNDING;\nconst POISSON_NORMAL_MINIMUM_MEAN = 1e9;\n\nfunction checkAbort(signal: AbortSignal): void {\n if (signal.aborted) throw abortedError();\n}\n\n/** CPU reference with host yields and abort, row-chunked; codes equal `simulatePackedSensorRaw`. */\nexport async function simulateSensorRawOnCpu(input: PackedSensorRawInput, abort: AbortController, yieldControl: YieldControl,\n execution: ImageKernelExecution): Promise<AcceleratedPackedSensorRawResult> {\n const plan = calculatePackedSensorRawPlan(input);\n // Snapshot so a caller mutation during host yields cannot change the reference.\n const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice(), extras = packedSensorExtras(plan, input, true);\n const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];\n const rowsPerChunk = Math.max(1, Math.floor(65_536 / plan.region.width)), gate = createHostYieldGate();\n for (let row = 0; row < plan.region.height; row += rowsPerChunk) {\n checkAbort(abort.signal);\n simulatePackedSensorRows(plan, photo, dark, row, Math.min(plan.region.height, row + rowsPerChunk), codes, counts, extras);\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n checkAbort(abort.signal);\n return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: new Uint32Array(0) };\n}\n\n/**\n * Splits a positive value into four non-negative pieces with at most 12 significant bits each (by\n * truncation), so that the product of any integer below 2^12 and a piece is exact in float32. Returns\n * the pieces and the non-negative remainder (below 2^-44 of the value).\n * @internal\n */\nexport function twelveBitPieces(value: number): { pieces: number[]; residual: number } {\n const pieces: number[] = [];\n let rest = value;\n for (let j = 0; j < 4; j++) {\n if (!(rest > 0)) { pieces.push(0); continue; }\n let e = Math.floor(Math.log2(rest));\n if (rest / 2 ** e >= 2) e++;\n if (rest / 2 ** e < 1) e--;\n const scale = 2 ** (e - 11), piece = Math.floor(rest / scale) * scale;\n pieces.push(piece);\n rest -= piece;\n }\n return { pieces, residual: rest };\n}\n\n/**\n * A 12-bit piece as the kernel reads it: an integer mantissa m < 2^12, the exponent s and the exact scale 2^s,\n * with piece = m·2^s exactly. A zero piece is (0, 0, 1).\n * @internal\n */\nexport function pieceWords(piece: number): [mantissa: number, exponent: number, scale: number] {\n if (piece === 0) return [0, 0, 1];\n let e = Math.floor(Math.log2(piece));\n if (piece / 2 ** e >= 2) e++;\n if (piece / 2 ** e < 1) e--;\n const s = e - 11, m = piece / 2 ** s;\n if (!Number.isInteger(m) || m >= 4096 || s < -126 || s > 60) throw new ImageKernelExecutionError(\"unsupported-float32-domain\", \"A gain piece is outside the float32 sensor domain.\");\n return [m, s, 2 ** s];\n}\n\n/**\n * Writes the four pieces of a positive gain-like value into the auxiliary table.\n * @internal\n */\nexport function writePieces(aux: Float32Array, at: number, pieces: readonly number[]): void {\n pieces.forEach((piece, j) => aux.set(pieceWords(piece), at + SENSOR_PIECE_WORDS * j));\n}\n\n/**\n * `L(k) − S(k)` for k < 256, where L is the reference's log k! (the summed logarithms of\n * `samplePoisson`'s logFactorial) and S(k) = (k + ½) ln k − k + ½ ln 2π.\n * @internal\n */\nexport function stirlingRemainderTable(): Float64Array {\n const table = new Float64Array(256);\n let sum = 0;\n for (let k = 1; k < 256; k++) {\n if (k >= 2) sum += Math.log(k);\n table[k] = sum - ((k + 0.5) * Math.log(k) - k + 0.5 * Math.log(2 * Math.PI));\n }\n return table;\n}\n\nfunction unsupported(message: string): ImageKernelExecutionError {\n return new ImageKernelExecutionError(\"unsupported-float32-domain\", message);\n}\n\ninterface SensorConstants { aux: Float32Array<ArrayBuffer>; params: ArrayBuffer; siteWords: number; poissonComponents: number[];\n deterministicComponents: number[]; threshold: number; gain: number }\n\n/** Checks the float32 execution domain and builds the frame constants (see docs/WEBGPU.md). @internal */\nexport function sensorGpuConstants(plan: PackedSensorRawPlan): SensorConstants {\n const regime = plan.readout.regime, adc = regime.adc, capacity = plan.physicalChargeCapacityElectrons;\n const gain = regime.systemConversionGainElectronsPerCode.value, inverse = 1 / gain;\n const threshold = regime.preAdcSaturationElectronEquivalent.value;\n const sigmas = regime.readNoiseComponents.map(c => c.rmsElectrons.value);\n const sigmaSum = sigmas.reduce((s, v) => s + v, 0);\n if (capacity > SENSOR_GPU_MAXIMUM_CAPACITY) throw unsupported(\"Physical capacity above 2^24 electrons is outside the float32 sensor domain.\");\n // Fixed-pattern factors scale the means; those are checked per site while packing.\n if (!(plan.maximumPhotoElectrons < SENSOR_GPU_MAXIMUM_MEAN && plan.maximumDarkElectrons < SENSOR_GPU_MAXIMUM_MEAN) ||\n plan.additionalChargeComponents.some(c => !(c.maximumExpectedElectrons < SENSOR_GPU_MAXIMUM_MEAN))) {\n throw unsupported(\"Expected electrons of 2^30 and above are outside the float32 sensor domain.\");\n }\n if (adc.digitalGain !== undefined && !(adc.digitalGain >= 2 ** -60 && adc.digitalGain <= 2 ** 60)) {\n throw unsupported(\"Digital gain is outside the float32 sensor domain.\");\n }\n if (!(inverse >= 2 ** -60 && inverse <= 2 ** 60) || capacity * inverse > 2 ** 30 ||\n sigmas.some(s => s !== 0 && !(s >= 2 ** -100 && s <= 2 ** 100)) || 7 * sigmaSum > 2 ** 28 || 7 * sigmaSum * inverse > 2 ** 20) {\n throw unsupported(\"Conversion gain or read noise is outside the float32 sensor domain.\");\n }\n const knots = adc.integralNonLinearity?.knots ?? [];\n // Segment slopes in float64 on the host, so the kernel's INL offset needs no division. Codes, offsets, slopes.\n const slopes = knots.slice(1).map((k, i) => (k.offsetCodes - knots[i]!.offsetCodes) / (k.code - knots[i]!.code));\n const slope = slopes.reduce((m, v) => Math.max(m, Math.abs(v)), 0), offset = knots.reduce((m, k) => Math.max(m, Math.abs(k.offsetCodes)), 0);\n const knotMagnitude = knots.reduce((m, k) => Math.max(m, Math.abs(k.code)), 0);\n const aux = new Float32Array(SENSOR_AUX.knots + 3 * knots.length);\n aux.set(stirlingRemainderTable(), SENSOR_AUX.stirlingRemainder);\n aux.set(sigmas, SENSOR_AUX.sigma);\n const inversePieces = twelveBitPieces(inverse), digital = adc.digitalGain === undefined ? null : twelveBitPieces(adc.digitalGain);\n writePieces(aux, SENSOR_AUX.inversePieces, inversePieces.pieces);\n if (digital) writePieces(aux, SENSOR_AUX.digitalPieces, digital.pieces);\n knots.forEach((k, i) => { aux[SENSOR_AUX.knots + i] = k.code; aux[SENSOR_AUX.knots + knots.length + i] = k.offsetCodes; });\n slopes.forEach((v, i) => { aux[SENSOR_AUX.knots + 2 * knots.length + i] = v; });\n // Pre-ADC-saturated sites all have the same rounded ADC input; computed once with the reference, before digital gain.\n const { digitalGain: _omitted, ...withoutDigital } = adc;\n void _omitted;\n const saturated = adcTransfer({ ...regime, adc: withoutDigital } as SensorReadoutConversionRegime, plan.readout.adcMaximumCode, threshold).quantized;\n const params = new ArrayBuffer(128), words = new Uint32Array(params), ints = new Int32Array(params), floats = new Float32Array(params);\n const capacityFloor = Math.floor(capacity), thresholdFloor = Math.min(Math.floor(threshold), 2 ** 30);\n words[2] = plan.region.width; words[3] = plan.nativeWidth; words[4] = plan.region.x; words[5] = plan.region.y;\n // Mode bits: 1 digital gain; 2 the digital-gain product is exact on both sides (gain has ≤ 12 significant\n // bits); 4 the ADC input is exact on both sides (no read noise, power-of-two gain, integer capacity, no INL).\n // In an exact mode both evaluations give the same dyadic value, so a tie is decided identically and needs no flag.\n const digitalExact = digital !== null && digital.residual === 0 && digital.pieces.slice(1).every(p => p === 0);\n const poissonComponents: number[] = [], deterministicComponents: number[] = [];\n plan.additionalChargeComponents.forEach((c, k) => (c.model === \"poisson\" ? poissonComponents : deterministicComponents).push(k));\n const deterministic = deterministicComponents.length > 0, pattern = plan.fixedPatternNoise !== null;\n const idealExact = sigmas.every(s => s === 0) && Number.isInteger(Math.log2(gain)) && Number.isInteger(capacity) && knots.length === 0 &&\n !deterministic && !pattern;\n words[6] = plan.captureSeedUint32; words[7] = sigmas.length; words[8] = knots.length;\n words[9] = (digital ? 1 : 0) | (digitalExact ? 2 : 0) | (idealExact ? 4 : 0);\n words[10] = adc.digitalSaturationCode; words[11] = plan.readout.adcMaximumCode; words[12] = capacityFloor; words[13] = thresholdFloor;\n words[14] = adc.blackLevelCode; ints[15] = Math.max(-(2 ** 30), Math.min(2 ** 30, saturated));\n floats[16] = capacity - capacityFloor; floats[17] = threshold < 2 ** 30 ? threshold - thresholdFloor : 0;\n floats[18] = inverse; floats[19] = inversePieces.residual * (1 + 2 ** -20);\n floats[20] = adc.digitalGain ?? 1; floats[21] = digital ? digital.residual * (1 + 2 ** -20) : 0;\n floats[22] = slope * (1 + 2 ** -20); floats[23] = offset; floats[30] = knotMagnitude;\n const siteWords = SENSOR_SITE_WORDS + 2 * poissonComponents.length + (deterministic ? 2 : 0) + (pattern ? 4 : 0);\n words[24] = siteWords; words[25] = poissonComponents.length;\n words[26] = (deterministic ? SENSOR_EXTRAS.deterministic : 0) | (pattern ? SENSOR_EXTRAS.fixedPattern : 0);\n return { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain };\n}\n\n/** Writes the float64 slack terms of the fixed-pattern bounds, from the region's largest offsets. */\nfunction setFixedPatternSlack(params: ArrayBuffer, threshold: number, maximumOffset: number, maximumOffsetCodes: number): void {\n const floats = new Float32Array(params);\n // The reference adds the offset in float64 and the host forms threshold − offset and offset/gain in float64.\n floats[28] = CPU_RELATIVE * (maximumOffset + Math.min(threshold, 2 ** 30)) * (1 + 2 ** -20);\n // The offset fraction's float32 rounding (its place in the fraction sum is counted by the kernel) and offset/gain's float64 rounding.\n floats[29] = (E + CPU_RELATIVE * maximumOffsetCodes) * (1 + 2 ** -20);\n}\n\n/** Splits a value into a floor and its float32 fraction. */\nfunction packSplit(value: number, words: Int32Array, floats: Float32Array, at: number): void {\n const whole = Math.floor(value);\n words[at] = whole; floats[at + 1] = value - whole;\n}\n\n/** Packs one mean: category in bits 30–31 with the integer part, and the float32 fraction. */\nfunction packMean(mean: number, words: Uint32Array, floats: Float32Array, at: number): void {\n if (mean === 0) { words[at] = 0; floats[at + 1] = 0; return; }\n if (!(mean < SENSOR_GPU_MAXIMUM_MEAN)) throw unsupported(\"Expected electrons of 2^30 and above are outside the float32 sensor domain.\");\n const whole = Math.floor(mean);\n const category = mean < 30 ? SENSOR_MEAN_CATEGORY.multiplication : mean < POISSON_NORMAL_MINIMUM_MEAN ? SENSOR_MEAN_CATEGORY.transformedRejection\n : SENSOR_MEAN_CATEGORY.normal;\n words[at] = ((category << 30) | whole) >>> 0;\n floats[at + 1] = mean - whole;\n}\n\nexport async function simulateSensorRawOnGpu(runtime: WebGpuRuntime, bandBytes: number, input: PackedSensorRawInput, abort: AbortController,\n yieldControl: YieldControl, pipelines: PipelineSource): Promise<AcceleratedPackedSensorRawResult> {\n const plan = calculatePackedSensorRawPlan(input);\n const constants = sensorGpuConstants(plan), { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain } = constants;\n const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice();\n const additional = (input.additionalChargeComponents ?? []).map(c => c.expectedElectrons.slice());\n const width = plan.region.width, height = plan.region.height, siteBytes = siteWords * 4;\n const pattern = createPackedFixedPattern(plan);\n // Fixed-pattern values are evaluated once, in float64 (exactly the reference's values), before any dispatch.\n const patterns = pattern === null ? null : new Float64Array(plan.siteCount * 3);\n if (patterns !== null) {\n let maximumOffset = 0, maximumOffsetCodes = 0;\n for (let row = 0, i = 0; row < height; row++) for (let column = 0; column < width; column++, i++) {\n const p = pattern!(column, row), offsetCodes = p.readoutOffsetElectrons / gain;\n patterns[i * 3] = p.photoResponseGainFactor; patterns[i * 3 + 1] = p.darkCurrentFactor; patterns[i * 3 + 2] = p.readoutOffsetElectrons;\n maximumOffset = Math.max(maximumOffset, Math.abs(p.readoutOffsetElectrons)); maximumOffsetCodes = Math.max(maximumOffsetCodes, Math.abs(offsetCodes));\n }\n if (!(maximumOffset <= SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS && maximumOffsetCodes <= SENSOR_GPU_MAXIMUM_OFFSET_CODES)) {\n throw unsupported(\"Fixed-pattern readout offsets are outside the float32 sensor domain.\");\n }\n setFixedPatternSlack(params, threshold, maximumOffset, maximumOffsetCodes);\n }\n const rows = Math.max(1, Math.min(height, Math.floor(bandBytes / (width * siteBytes))));\n if (rows * width * siteBytes > runtime.maximumStorageBindingBytes) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"One sensor band exceeds the device's storage binding limit.\");\n }\n const pipeline = await pipelines(\"photivra-sensor-raw\", SENSOR_RAW_WGSL);\n const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];\n const packed = new ArrayBuffer(rows * width * siteBytes), packedWords = new Uint32Array(packed), packedFloats = new Float32Array(packed);\n const packedInts = new Int32Array(packed);\n const words = new Uint32Array(params);\n let flagged = 0;\n const flaggedIndices: number[] = [];\n const scope = new GpuResourceScope(runtime);\n try {\n const auxBuffer = scope.upload(\"photivra-sensor-aux\", aux, BUFFER_USAGE.STORAGE);\n const gate = createHostYieldGate();\n for (let row0 = 0; row0 < height; row0 += rows) {\n checkAbort(abort.signal);\n const row1 = Math.min(height, row0 + rows), count = (row1 - row0) * width, first = row0 * width;\n for (let i = 0; i < count; i++) {\n const site = first + i, at = i * siteWords;\n // The reference's own float64 products of the means and the fixed-pattern factors.\n packMean(patterns === null ? photo[site]! : photo[site]! * patterns[site * 3]!, packedWords, packedFloats, at);\n packMean(patterns === null ? dark[site]! : dark[site]! * patterns[site * 3 + 1]!, packedWords, packedFloats, at + 2);\n let cursor = at + 4;\n for (const k of poissonComponents) { packMean(additional[k]![site]!, packedWords, packedFloats, cursor); cursor += 2; }\n if (deterministicComponents.length > 0) {\n let sum = 0;\n for (const k of deterministicComponents) sum += additional[k]![site]!;\n if (!(sum < SENSOR_GPU_MAXIMUM_MEAN)) throw unsupported(\"Deterministic charge of 2^30 electrons and above is outside the float32 sensor domain.\");\n packSplit(sum, packedInts, packedFloats, cursor);\n cursor += 2;\n }\n if (patterns !== null) {\n const offset = patterns[site * 3 + 2]!, limit = threshold - offset;\n if (limit >= 2 ** 30) { packedInts[cursor] = 2 ** 30; packedFloats[cursor + 1] = 0; } else packSplit(limit, packedInts, packedFloats, cursor);\n packSplit(offset / gain, packedInts, packedFloats, cursor + 2);\n }\n }\n words[0] = count; words[1] = row0;\n const band = new GpuResourceScope(runtime);\n try {\n const means = band.upload(\"photivra-sensor-means\", new Uint32Array(packed, 0, count * siteWords), BUFFER_USAGE.STORAGE);\n const out = band.buffer(\"photivra-sensor-codes\", count * 4, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);\n const uniform = band.upload(\"photivra-sensor-params\", new Uint8Array(params), BUFFER_USAGE.UNIFORM);\n const bindGroup = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [\n { binding: 0, resource: { buffer: uniform } }, { binding: 1, resource: { buffer: means } },\n { binding: 2, resource: { buffer: auxBuffer } }, { binding: 3, resource: { buffer: out } }] });\n const [data] = await runComputePass(runtime, band, pipeline, bindGroup, linearDispatch(count, SENSOR_WORKGROUP_SIZE, runtime.maximumWorkgroupsPerDimension),\n [{ buffer: out, bytes: count * 4 }], abort.signal);\n const result = new Uint32Array(data!, 0, count);\n for (let i = 0; i < count; i++) {\n const word = result[i]!, flags = word >>> SENSOR_OUTPUT.flagShift;\n codes[first + i] = word & SENSOR_OUTPUT.codeMask;\n if (flags & 1) counts[0]!++;\n if (flags & 2) counts[1]!++;\n if (flags & 4) counts[2]!++;\n if (flags & 8) counts[3]!++;\n if (word & SENSOR_OUTPUT.uncertainBit) { flagged++; flaggedIndices.push(first + i); }\n }\n } finally {\n band.release();\n }\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n } catch (error) {\n codes.fill(0);\n throw error;\n } finally {\n scope.release();\n }\n checkAbort(abort.signal);\n const execution = webGpuExecution({ kind: \"exact-except-flagged-sites\", flaggedSiteCount: flagged, noiseModel: { ...plan.noiseModel },\n seedSchedule: plan.seedSchedule }, flagged);\n return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: Uint32Array.from(flaggedIndices) };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sensor-stage-gpu.js","sourceRoot":"","sources":["../../src/gpu/sensor-stage-gpu.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Host side of the `webgpu-f32` sensor stage (#277): domain checks, frame constants, per-site mean\n * packing, banded dispatch and readback. The float64 reference is `simulatePackedSensorRaw`\n * (capture/packed-sensor-raw.ts). Internal; the public entry point is the image-kernel accelerator.\n */\nimport { createHostYieldGate } from \"../capture/host-yield-cadence.js\";\nimport { calculatePackedSensorRawPlan, createPackedFixedPattern, packedSensorDiagnostics, packedSensorExtras, simulatePackedSensorRows,\n type PackedSensorRawInput, type PackedSensorRawPlan } from \"../capture/packed-sensor-raw.js\";\nimport { adcTransfer, type SensorReadoutConversionRegime } from \"../sensor/raw-readout.js\";\nimport { ImageKernelExecutionError, webGpuExecution, type ImageKernelExecution } from \"./image-kernel-execution.js\";\nimport type { AcceleratedPackedSensorRawResult } from \"./image-kernel-accelerator.js\";\nimport { BUFFER_USAGE, GpuResourceScope, linearDispatch, runComputePass, type WebGpuRuntime, throwIfAborted as checkAbort } from \"./webgpu-runtime.js\";\nimport { SENSOR_AUX, SENSOR_EXTRAS, SENSOR_MEAN_CATEGORY, SENSOR_OUTPUT, SENSOR_PIECE_WORDS, SENSOR_RAW_WGSL, SENSOR_ROUNDING, SENSOR_SITE_WORDS,\n SENSOR_WORKGROUP_SIZE } from \"./wgsl-sensor-kernel.js\";\n\ntype PipelineSource = (label: string, code: string) => Promise<GPUComputePipeline>;\ntype YieldControl = ((signal: AbortSignal) => Promise<void>) | undefined;\n\n/** Largest physical capacity on the GPU: every realized count up to it is exact in float32. */\nexport const SENSOR_GPU_MAXIMUM_CAPACITY = 2 ** 24;\n/** Poisson means must stay below this on the GPU (30-bit integer part of a mean word). */\nexport const SENSOR_GPU_MAXIMUM_MEAN = 2 ** 30;\n/** Largest |fixed-pattern readout offset| on the GPU, in electrons and in codes. */\nexport const SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS = 2 ** 28;\nexport const SENSOR_GPU_MAXIMUM_OFFSET_CODES = 2 ** 20;\nconst CPU_RELATIVE = 2 ** -47;\n/** One WGSL rounding, either direction (2^-23). */\nconst E = SENSOR_ROUNDING;\nconst POISSON_NORMAL_MINIMUM_MEAN = 1e9;\n\n/** CPU reference with host yields and abort, row-chunked; codes equal `simulatePackedSensorRaw`. */\nexport async function simulateSensorRawOnCpu(input: PackedSensorRawInput, abort: AbortController, yieldControl: YieldControl,\n execution: ImageKernelExecution): Promise<AcceleratedPackedSensorRawResult> {\n const plan = calculatePackedSensorRawPlan(input);\n // Snapshot so a caller mutation during host yields cannot change the reference.\n const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice(), extras = packedSensorExtras(plan, input, true);\n const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];\n const rowsPerChunk = Math.max(1, Math.floor(65_536 / plan.region.width)), gate = createHostYieldGate();\n for (let row = 0; row < plan.region.height; row += rowsPerChunk) {\n checkAbort(abort.signal);\n simulatePackedSensorRows(plan, photo, dark, row, Math.min(plan.region.height, row + rowsPerChunk), codes, counts, extras);\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n checkAbort(abort.signal);\n return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: new Uint32Array(0) };\n}\n\n/**\n * Splits a positive value into four non-negative pieces with at most 12 significant bits each (by\n * truncation), so that the product of any integer below 2^12 and a piece is exact in float32. Returns\n * the pieces and the non-negative remainder (below 2^-44 of the value).\n * @internal\n */\nexport function twelveBitPieces(value: number): { pieces: number[]; residual: number } {\n const pieces: number[] = [];\n let rest = value;\n for (let j = 0; j < 4; j++) {\n if (!(rest > 0)) { pieces.push(0); continue; }\n let e = Math.floor(Math.log2(rest));\n if (rest / 2 ** e >= 2) e++;\n if (rest / 2 ** e < 1) e--;\n const scale = 2 ** (e - 11), piece = Math.floor(rest / scale) * scale;\n pieces.push(piece);\n rest -= piece;\n }\n return { pieces, residual: rest };\n}\n\n/**\n * A 12-bit piece as the kernel reads it: an integer mantissa m < 2^12, the exponent s and the exact scale 2^s,\n * with piece = m·2^s exactly. A zero piece is (0, 0, 1).\n * @internal\n */\nexport function pieceWords(piece: number): [mantissa: number, exponent: number, scale: number] {\n if (piece === 0) return [0, 0, 1];\n let e = Math.floor(Math.log2(piece));\n if (piece / 2 ** e >= 2) e++;\n if (piece / 2 ** e < 1) e--;\n const s = e - 11, m = piece / 2 ** s;\n if (!Number.isInteger(m) || m >= 4096 || s < -126 || s > 60) throw new ImageKernelExecutionError(\"unsupported-float32-domain\", \"A gain piece is outside the float32 sensor domain.\");\n return [m, s, 2 ** s];\n}\n\n/**\n * Writes the four pieces of a positive gain-like value into the auxiliary table.\n * @internal\n */\nexport function writePieces(aux: Float32Array, at: number, pieces: readonly number[]): void {\n pieces.forEach((piece, j) => aux.set(pieceWords(piece), at + SENSOR_PIECE_WORDS * j));\n}\n\n/**\n * `L(k) − S(k)` for k < 256, where L is the reference's log k! (the summed logarithms of\n * `samplePoisson`'s logFactorial) and S(k) = (k + ½) ln k − k + ½ ln 2π.\n * @internal\n */\nexport function stirlingRemainderTable(): Float64Array {\n const table = new Float64Array(256);\n let sum = 0;\n for (let k = 1; k < 256; k++) {\n if (k >= 2) sum += Math.log(k);\n table[k] = sum - ((k + 0.5) * Math.log(k) - k + 0.5 * Math.log(2 * Math.PI));\n }\n return table;\n}\n\nfunction unsupported(message: string): ImageKernelExecutionError {\n return new ImageKernelExecutionError(\"unsupported-float32-domain\", message);\n}\n\ninterface SensorConstants { aux: Float32Array<ArrayBuffer>; params: ArrayBuffer; siteWords: number; poissonComponents: number[];\n deterministicComponents: number[]; threshold: number; gain: number }\n\n/** Checks the float32 execution domain and builds the frame constants (see docs/WEBGPU.md). @internal */\nexport function sensorGpuConstants(plan: PackedSensorRawPlan): SensorConstants {\n const regime = plan.readout.regime, adc = regime.adc, capacity = plan.physicalChargeCapacityElectrons;\n const gain = regime.systemConversionGainElectronsPerCode.value, inverse = 1 / gain;\n const threshold = regime.preAdcSaturationElectronEquivalent.value;\n const sigmas = regime.readNoiseComponents.map(c => c.rmsElectrons.value);\n const sigmaSum = sigmas.reduce((s, v) => s + v, 0);\n if (capacity > SENSOR_GPU_MAXIMUM_CAPACITY) throw unsupported(\"Physical capacity above 2^24 electrons is outside the float32 sensor domain.\");\n // Fixed-pattern factors scale the means; those are checked per site while packing.\n if (!(plan.maximumPhotoElectrons < SENSOR_GPU_MAXIMUM_MEAN && plan.maximumDarkElectrons < SENSOR_GPU_MAXIMUM_MEAN) ||\n plan.additionalChargeComponents.some(c => !(c.maximumExpectedElectrons < SENSOR_GPU_MAXIMUM_MEAN))) {\n throw unsupported(\"Expected electrons of 2^30 and above are outside the float32 sensor domain.\");\n }\n if (adc.digitalGain !== undefined && !(adc.digitalGain >= 2 ** -60 && adc.digitalGain <= 2 ** 60)) {\n throw unsupported(\"Digital gain is outside the float32 sensor domain.\");\n }\n if (!(inverse >= 2 ** -60 && inverse <= 2 ** 60) || capacity * inverse > 2 ** 30 ||\n sigmas.some(s => s !== 0 && !(s >= 2 ** -100 && s <= 2 ** 100)) || 7 * sigmaSum > 2 ** 28 || 7 * sigmaSum * inverse > 2 ** 20) {\n throw unsupported(\"Conversion gain or read noise is outside the float32 sensor domain.\");\n }\n const knots = adc.integralNonLinearity?.knots ?? [];\n // Segment slopes in float64 on the host, so the kernel's INL offset needs no division. Codes, offsets, slopes.\n const slopes = knots.slice(1).map((k, i) => (k.offsetCodes - knots[i]!.offsetCodes) / (k.code - knots[i]!.code));\n const slope = slopes.reduce((m, v) => Math.max(m, Math.abs(v)), 0), offset = knots.reduce((m, k) => Math.max(m, Math.abs(k.offsetCodes)), 0);\n const knotMagnitude = knots.reduce((m, k) => Math.max(m, Math.abs(k.code)), 0);\n const aux = new Float32Array(SENSOR_AUX.knots + 3 * knots.length);\n aux.set(stirlingRemainderTable(), SENSOR_AUX.stirlingRemainder);\n aux.set(sigmas, SENSOR_AUX.sigma);\n const inversePieces = twelveBitPieces(inverse), digital = adc.digitalGain === undefined ? null : twelveBitPieces(adc.digitalGain);\n writePieces(aux, SENSOR_AUX.inversePieces, inversePieces.pieces);\n if (digital) writePieces(aux, SENSOR_AUX.digitalPieces, digital.pieces);\n knots.forEach((k, i) => { aux[SENSOR_AUX.knots + i] = k.code; aux[SENSOR_AUX.knots + knots.length + i] = k.offsetCodes; });\n slopes.forEach((v, i) => { aux[SENSOR_AUX.knots + 2 * knots.length + i] = v; });\n // Pre-ADC-saturated sites all have the same rounded ADC input; computed once with the reference, before digital gain.\n const { digitalGain: _omitted, ...withoutDigital } = adc;\n void _omitted;\n const saturated = adcTransfer({ ...regime, adc: withoutDigital } as SensorReadoutConversionRegime, plan.readout.adcMaximumCode, threshold).quantized;\n const params = new ArrayBuffer(128), words = new Uint32Array(params), ints = new Int32Array(params), floats = new Float32Array(params);\n const capacityFloor = Math.floor(capacity), thresholdFloor = Math.min(Math.floor(threshold), 2 ** 30);\n words[2] = plan.region.width; words[3] = plan.nativeWidth; words[4] = plan.region.x; words[5] = plan.region.y;\n // Mode bits: 1 digital gain; 2 the digital-gain product is exact on both sides (gain has ≤ 12 significant\n // bits); 4 the ADC input is exact on both sides (no read noise, power-of-two gain, integer capacity, no INL).\n // In an exact mode both evaluations give the same dyadic value, so a tie is decided identically and needs no flag.\n const digitalExact = digital !== null && digital.residual === 0 && digital.pieces.slice(1).every(p => p === 0);\n const poissonComponents: number[] = [], deterministicComponents: number[] = [];\n plan.additionalChargeComponents.forEach((c, k) => (c.model === \"poisson\" ? poissonComponents : deterministicComponents).push(k));\n const deterministic = deterministicComponents.length > 0, pattern = plan.fixedPatternNoise !== null;\n const idealExact = sigmas.every(s => s === 0) && Number.isInteger(Math.log2(gain)) && Number.isInteger(capacity) && knots.length === 0 &&\n !deterministic && !pattern;\n words[6] = plan.captureSeedUint32; words[7] = sigmas.length; words[8] = knots.length;\n words[9] = (digital ? 1 : 0) | (digitalExact ? 2 : 0) | (idealExact ? 4 : 0);\n words[10] = adc.digitalSaturationCode; words[11] = plan.readout.adcMaximumCode; words[12] = capacityFloor; words[13] = thresholdFloor;\n words[14] = adc.blackLevelCode; ints[15] = Math.max(-(2 ** 30), Math.min(2 ** 30, saturated));\n floats[16] = capacity - capacityFloor; floats[17] = threshold < 2 ** 30 ? threshold - thresholdFloor : 0;\n floats[18] = inverse; floats[19] = inversePieces.residual * (1 + 2 ** -20);\n floats[20] = adc.digitalGain ?? 1; floats[21] = digital ? digital.residual * (1 + 2 ** -20) : 0;\n floats[22] = slope * (1 + 2 ** -20); floats[23] = offset; floats[30] = knotMagnitude;\n const siteWords = SENSOR_SITE_WORDS + 2 * poissonComponents.length + (deterministic ? 2 : 0) + (pattern ? 4 : 0);\n words[24] = siteWords; words[25] = poissonComponents.length;\n words[26] = (deterministic ? SENSOR_EXTRAS.deterministic : 0) | (pattern ? SENSOR_EXTRAS.fixedPattern : 0);\n return { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain };\n}\n\n/** Writes the float64 slack terms of the fixed-pattern bounds, from the region's largest offsets. */\nfunction setFixedPatternSlack(params: ArrayBuffer, threshold: number, maximumOffset: number, maximumOffsetCodes: number): void {\n const floats = new Float32Array(params);\n // The reference adds the offset in float64 and the host forms threshold − offset and offset/gain in float64.\n floats[28] = CPU_RELATIVE * (maximumOffset + Math.min(threshold, 2 ** 30)) * (1 + 2 ** -20);\n // The offset fraction's float32 rounding (its place in the fraction sum is counted by the kernel) and offset/gain's float64 rounding.\n floats[29] = (E + CPU_RELATIVE * maximumOffsetCodes) * (1 + 2 ** -20);\n}\n\n/** Splits a value into a floor and its float32 fraction. */\nfunction packSplit(value: number, words: Int32Array, floats: Float32Array, at: number): void {\n const whole = Math.floor(value);\n words[at] = whole; floats[at + 1] = value - whole;\n}\n\n/** Packs one mean: category in bits 30–31 with the integer part, and the float32 fraction. */\nfunction packMean(mean: number, words: Uint32Array, floats: Float32Array, at: number): void {\n if (mean === 0) { words[at] = 0; floats[at + 1] = 0; return; }\n if (!(mean < SENSOR_GPU_MAXIMUM_MEAN)) throw unsupported(\"Expected electrons of 2^30 and above are outside the float32 sensor domain.\");\n const whole = Math.floor(mean);\n const category = mean < 30 ? SENSOR_MEAN_CATEGORY.multiplication : mean < POISSON_NORMAL_MINIMUM_MEAN ? SENSOR_MEAN_CATEGORY.transformedRejection\n : SENSOR_MEAN_CATEGORY.normal;\n words[at] = ((category << 30) | whole) >>> 0;\n floats[at + 1] = mean - whole;\n}\n\nexport async function simulateSensorRawOnGpu(runtime: WebGpuRuntime, bandBytes: number, input: PackedSensorRawInput, abort: AbortController,\n yieldControl: YieldControl, pipelines: PipelineSource): Promise<AcceleratedPackedSensorRawResult> {\n const plan = calculatePackedSensorRawPlan(input);\n const constants = sensorGpuConstants(plan), { aux, params, siteWords, poissonComponents, deterministicComponents, threshold, gain } = constants;\n const photo = input.photoElectrons.slice(), dark = input.darkElectrons.slice();\n const additional = (input.additionalChargeComponents ?? []).map(c => c.expectedElectrons.slice());\n const width = plan.region.width, height = plan.region.height, siteBytes = siteWords * 4;\n const pattern = createPackedFixedPattern(plan);\n // Fixed-pattern values are evaluated once, in float64 (exactly the reference's values), before any dispatch.\n const patterns = pattern === null ? null : new Float64Array(plan.siteCount * 3);\n if (patterns !== null) {\n let maximumOffset = 0, maximumOffsetCodes = 0;\n for (let row = 0, i = 0; row < height; row++) for (let column = 0; column < width; column++, i++) {\n const p = pattern!(column, row), offsetCodes = p.readoutOffsetElectrons / gain;\n patterns[i * 3] = p.photoResponseGainFactor; patterns[i * 3 + 1] = p.darkCurrentFactor; patterns[i * 3 + 2] = p.readoutOffsetElectrons;\n maximumOffset = Math.max(maximumOffset, Math.abs(p.readoutOffsetElectrons)); maximumOffsetCodes = Math.max(maximumOffsetCodes, Math.abs(offsetCodes));\n }\n if (!(maximumOffset <= SENSOR_GPU_MAXIMUM_OFFSET_ELECTRONS && maximumOffsetCodes <= SENSOR_GPU_MAXIMUM_OFFSET_CODES)) {\n throw unsupported(\"Fixed-pattern readout offsets are outside the float32 sensor domain.\");\n }\n setFixedPatternSlack(params, threshold, maximumOffset, maximumOffsetCodes);\n }\n const rows = Math.max(1, Math.min(height, Math.floor(bandBytes / (width * siteBytes))));\n if (rows * width * siteBytes > runtime.maximumStorageBindingBytes) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"One sensor band exceeds the device's storage binding limit.\");\n }\n const pipeline = await pipelines(\"photivra-sensor-raw\", SENSOR_RAW_WGSL);\n const codes = new Uint16Array(plan.siteCount), counts = [0, 0, 0, 0];\n const packed = new ArrayBuffer(rows * width * siteBytes), packedWords = new Uint32Array(packed), packedFloats = new Float32Array(packed);\n const packedInts = new Int32Array(packed);\n const words = new Uint32Array(params);\n let flagged = 0;\n const flaggedIndices: number[] = [];\n const scope = new GpuResourceScope(runtime);\n try {\n const auxBuffer = scope.upload(\"photivra-sensor-aux\", aux, BUFFER_USAGE.STORAGE);\n const gate = createHostYieldGate();\n for (let row0 = 0; row0 < height; row0 += rows) {\n checkAbort(abort.signal);\n const row1 = Math.min(height, row0 + rows), count = (row1 - row0) * width, first = row0 * width;\n for (let i = 0; i < count; i++) {\n const site = first + i, at = i * siteWords;\n // The reference's own float64 products of the means and the fixed-pattern factors.\n packMean(patterns === null ? photo[site]! : photo[site]! * patterns[site * 3]!, packedWords, packedFloats, at);\n packMean(patterns === null ? dark[site]! : dark[site]! * patterns[site * 3 + 1]!, packedWords, packedFloats, at + 2);\n let cursor = at + 4;\n for (const k of poissonComponents) { packMean(additional[k]![site]!, packedWords, packedFloats, cursor); cursor += 2; }\n if (deterministicComponents.length > 0) {\n let sum = 0;\n for (const k of deterministicComponents) sum += additional[k]![site]!;\n if (!(sum < SENSOR_GPU_MAXIMUM_MEAN)) throw unsupported(\"Deterministic charge of 2^30 electrons and above is outside the float32 sensor domain.\");\n packSplit(sum, packedInts, packedFloats, cursor);\n cursor += 2;\n }\n if (patterns !== null) {\n const offset = patterns[site * 3 + 2]!, limit = threshold - offset;\n if (limit >= 2 ** 30) { packedInts[cursor] = 2 ** 30; packedFloats[cursor + 1] = 0; } else packSplit(limit, packedInts, packedFloats, cursor);\n packSplit(offset / gain, packedInts, packedFloats, cursor + 2);\n }\n }\n words[0] = count; words[1] = row0;\n const band = new GpuResourceScope(runtime);\n try {\n const means = band.upload(\"photivra-sensor-means\", new Uint32Array(packed, 0, count * siteWords), BUFFER_USAGE.STORAGE);\n const out = band.buffer(\"photivra-sensor-codes\", count * 4, BUFFER_USAGE.STORAGE | BUFFER_USAGE.COPY_SRC);\n const uniform = band.upload(\"photivra-sensor-params\", new Uint8Array(params), BUFFER_USAGE.UNIFORM);\n const bindGroup = runtime.device.createBindGroup({ layout: pipeline.getBindGroupLayout(0), entries: [\n { binding: 0, resource: { buffer: uniform } }, { binding: 1, resource: { buffer: means } },\n { binding: 2, resource: { buffer: auxBuffer } }, { binding: 3, resource: { buffer: out } }] });\n const [data] = await runComputePass(runtime, band, pipeline, bindGroup, linearDispatch(count, SENSOR_WORKGROUP_SIZE, runtime.maximumWorkgroupsPerDimension),\n [{ buffer: out, bytes: count * 4 }], abort.signal);\n const result = new Uint32Array(data!, 0, count);\n for (let i = 0; i < count; i++) {\n const word = result[i]!, flags = word >>> SENSOR_OUTPUT.flagShift;\n codes[first + i] = word & SENSOR_OUTPUT.codeMask;\n if (flags & 1) counts[0]!++;\n if (flags & 2) counts[1]!++;\n if (flags & 4) counts[2]!++;\n if (flags & 8) counts[3]!++;\n if (word & SENSOR_OUTPUT.uncertainBit) { flagged++; flaggedIndices.push(first + i); }\n }\n } finally {\n band.release();\n }\n if (yieldControl && gate.due()) { await yieldControl(abort.signal); gate.restart(); }\n }\n } catch (error) {\n codes.fill(0);\n throw error;\n } finally {\n scope.release();\n }\n checkAbort(abort.signal);\n const execution = webGpuExecution({ kind: \"exact-except-flagged-sites\", flaggedSiteCount: flagged, noiseModel: { ...plan.noiseModel },\n seedSchedule: plan.seedSchedule }, flagged);\n return { plan, codes, diagnostics: packedSensorDiagnostics(counts), execution, flaggedSiteIndices: Uint32Array.from(flaggedIndices) };\n}\n"]}
|
|
@@ -36,6 +36,8 @@ export type WebGpuAcquisition = {
|
|
|
36
36
|
message: string;
|
|
37
37
|
};
|
|
38
38
|
export declare function abortedError(): ImageKernelExecutionError;
|
|
39
|
+
/** Throws `abortedError()` when the signal has aborted. */
|
|
40
|
+
export declare function throwIfAborted(signal: AbortSignal): void;
|
|
39
41
|
/**
|
|
40
42
|
* Requests a device with high limits from `gpu` (normally `navigator.gpu`). It does not throw when
|
|
41
43
|
* WebGPU is unavailable; the caller decides whether to fall back to the CPU or fail. An abort during
|
|
@@ -19,6 +19,9 @@ function hostIsLittleEndian() {
|
|
|
19
19
|
export function abortedError() {
|
|
20
20
|
return new ImageKernelExecutionError("aborted", "Image-kernel execution was aborted; no output is available.");
|
|
21
21
|
}
|
|
22
|
+
/** Throws `abortedError()` when the signal has aborted. */
|
|
23
|
+
export function throwIfAborted(signal) { if (signal.aborted)
|
|
24
|
+
throw abortedError(); }
|
|
22
25
|
/** Rejects when the signal aborts; the returned cleanup removes the listener. */
|
|
23
26
|
function abortRace(signal) {
|
|
24
27
|
if (!signal)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"webgpu-runtime.js","sourceRoot":"","sources":["../../src/gpu/webgpu-runtime.ts"],"names":[],"mappings":"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","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Internal WebGPU device handling for the image-kernel accelerator: getting the adapter and device,\n * limits, tracking device loss, racing work against abort and loss, error scopes, banded buffers and\n * cleanup. Not exported from the package root. WebGPU types never appear in the published type\n * declarations, so consumers do not need WebGPU typings.\n */\nimport { ImageKernelExecutionError, type ImageKernelAdapterDescription, type ImageKernelFallbackReason } from \"./image-kernel-execution.js\";\n\n/** WebGPU spec constants (GPUBufferUsage, GPUMapMode), defined here so no global is needed at import time. */\nexport const BUFFER_USAGE = /* @__PURE__ */ Object.freeze({ MAP_READ: 0x0001, COPY_SRC: 0x0004, COPY_DST: 0x0008, UNIFORM: 0x0040, STORAGE: 0x0080 });\nconst MAP_MODE_READ = 0x0001;\n\n/** Minimum per-binding storage this backend requires (the WebGPU default is 128 MiB). */\nexport const WEBGPU_MINIMUM_STORAGE_BINDING_BYTES = 16 * 1024 * 1024;\n/** Upper limit requested from the adapter, so one band never asks for more than this per binding. */\nexport const WEBGPU_REQUESTED_STORAGE_BINDING_BYTES = 1024 * 1024 * 1024;\n\nexport interface WebGpuRuntime {\n readonly device: GPUDevice;\n /** #481: the adapter's `info`, or null when the implementation has none. */\n readonly adapter: ImageKernelAdapterDescription | null;\n readonly maximumStorageBindingBytes: number;\n readonly maximumWorkgroupsPerDimension: number;\n /** Set once `device.lost` settles; every later wait rejects with `device-lost`. */\n isLost(): boolean;\n /** Races a GPU promise with device loss and the operation's abort signal. */\n guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;\n destroy(): void;\n}\n\nexport type WebGpuAcquisition = { runtime: WebGpuRuntime } | { failure: ImageKernelFallbackReason; message: string };\n\nfunction hostIsLittleEndian(): boolean {\n return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n}\n\nexport function abortedError(): ImageKernelExecutionError {\n return new ImageKernelExecutionError(\"aborted\", \"Image-kernel execution was aborted; no output is available.\");\n}\n\n/** Rejects when the signal aborts; the returned cleanup removes the listener. */\nfunction abortRace(signal: AbortSignal | undefined): { promise: Promise<never>; cleanup: () => void } {\n if (!signal) return { promise: new Promise<never>(() => undefined), cleanup: () => undefined };\n let cleanup = (): void => undefined;\n const promise = new Promise<never>((_, reject) => {\n if (signal.aborted) { reject(abortedError()); return; }\n const listener = (): void => reject(abortedError());\n signal.addEventListener(\"abort\", listener, { once: true });\n cleanup = (): void => signal.removeEventListener(\"abort\", listener);\n });\n promise.catch(() => undefined);\n return { promise, cleanup };\n}\n\n/**\n * Requests a device with high limits from `gpu` (normally `navigator.gpu`). It does not throw when\n * WebGPU is unavailable; the caller decides whether to fall back to the CPU or fail. An abort during\n * acquisition does throw.\n */\nexport async function acquireWebGpuRuntime(gpu: unknown, powerPreference: \"low-power\" | \"high-performance\" | undefined,\n signal: AbortSignal | undefined): Promise<WebGpuAcquisition> {\n if (!hostIsLittleEndian()) return { failure: \"unsupported-platform-endianness\", message: \"WebGPU buffers require a little-endian host.\" };\n const api = gpu as Partial<GPU> | null | undefined;\n if (!api || typeof api !== \"object\" || typeof api.requestAdapter !== \"function\") {\n return { failure: \"webgpu-unavailable\", message: \"WebGPU is not available in this runtime.\" };\n }\n const abort = abortRace(signal);\n try {\n let adapter: GPUAdapter | null;\n try {\n adapter = await Promise.race([api.requestAdapter(powerPreference ? { powerPreference } : undefined), abort.promise]);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) throw error;\n adapter = null;\n }\n if (!adapter) return { failure: \"adapter-unavailable\", message: \"No WebGPU adapter is available.\" };\n const adapterStorage = adapter.limits.maxStorageBufferBindingSize, adapterBuffer = adapter.limits.maxBufferSize;\n if (!(adapterStorage >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES && adapterBuffer >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES)) {\n return { failure: \"insufficient-limits\", message: \"The WebGPU adapter's storage-buffer limits are below the backend minimum.\" };\n }\n const storage = Math.min(adapterStorage, adapterBuffer, WEBGPU_REQUESTED_STORAGE_BINDING_BYTES);\n let device: GPUDevice, pending: Promise<GPUDevice> | undefined;\n try {\n pending = adapter.requestDevice({ label: \"photivra-image-kernels\",\n requiredLimits: { maxStorageBufferBindingSize: storage, maxBufferSize: storage } });\n device = await Promise.race([pending, abort.promise]);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) {\n // The abort won the race. A device that still arrives later is destroyed, so it never leaks.\n if (pending) void Promise.resolve(pending).then(late => late.destroy(), () => undefined);\n throw error;\n }\n return { failure: \"device-request-failed\", message: \"The WebGPU device request failed.\" };\n }\n if (signal?.aborted) { device.destroy(); throw abortedError(); }\n return { runtime: createRuntime(device, storage, describeAdapter(adapter)) };\n } finally {\n abort.cleanup();\n }\n}\n\n/** `GPUAdapter.info` as plain strings (missing or non-string fields read as empty), or null when the adapter has no `info`. */\nfunction describeAdapter(adapter: GPUAdapter): ImageKernelAdapterDescription | null {\n const info = (adapter as { info?: Partial<Record<keyof ImageKernelAdapterDescription, unknown>> | null }).info;\n if (!info || typeof info !== \"object\") return null;\n const text = (value: unknown): string => (typeof value === \"string\" ? value : \"\");\n return { vendor: text(info.vendor), architecture: text(info.architecture), device: text(info.device), description: text(info.description) };\n}\n\nfunction createRuntime(device: GPUDevice, storage: number, adapter: ImageKernelAdapterDescription | null): WebGpuRuntime {\n let lost = false, destroyed = false;\n let rejectLost: (error: ImageKernelExecutionError) => void = () => undefined;\n const lostPromise = new Promise<never>((_, reject) => { rejectLost = reject; });\n lostPromise.catch(() => undefined);\n void device.lost.then(() => {\n lost = true;\n rejectLost(new ImageKernelExecutionError(\"device-lost\", \"The WebGPU device was lost; no output is available.\"));\n });\n // Errors are collected through error scopes; this only keeps uncaptured errors out of the console.\n device.onuncapturederror = (event: GPUUncapturedErrorEvent): void => { event.preventDefault(); };\n const maximumWorkgroupsPerDimension = device.limits.maxComputeWorkgroupsPerDimension;\n return {\n device, adapter,\n maximumStorageBindingBytes: Math.min(storage, device.limits.maxStorageBufferBindingSize, device.limits.maxBufferSize),\n maximumWorkgroupsPerDimension,\n isLost: (): boolean => lost,\n async guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n promise.catch(() => undefined);\n if (lost) throw new ImageKernelExecutionError(\"device-lost\", \"The WebGPU device was lost; no output is available.\");\n const abort = abortRace(signal);\n try { return await Promise.race([promise, lostPromise, abort.promise]); } finally { abort.cleanup(); }\n },\n destroy(): void { if (!destroyed) { destroyed = true; device.destroy(); } }\n };\n}\n\n/** Per-operation resource scope: every buffer is destroyed when the operation settles. */\nexport class GpuResourceScope {\n readonly #runtime: WebGpuRuntime;\n readonly #buffers: GPUBuffer[] = [];\n\n constructor(runtime: WebGpuRuntime) { this.#runtime = runtime; }\n\n buffer(label: string, size: number, usage: number): GPUBuffer {\n const buffer = this.#runtime.device.createBuffer({ label, size: Math.max(16, Math.ceil(size / 16) * 16), usage });\n this.#buffers.push(buffer);\n return buffer;\n }\n\n /** Storage buffer initialised from host data (padded to a 16-byte multiple). */\n upload(label: string, data: ArrayBufferView<ArrayBuffer>, usage: number): GPUBuffer {\n const buffer = this.buffer(label, data.byteLength, usage | BUFFER_USAGE.COPY_DST);\n if (data.byteLength > 0) this.#runtime.device.queue.writeBuffer(buffer, 0, data.buffer, data.byteOffset, data.byteLength);\n return buffer;\n }\n\n release(): void {\n for (const buffer of this.#buffers.splice(0)) buffer.destroy();\n }\n}\n\n/** Workgroup grid for a 1-D invocation count (2-D when it exceeds one dimension). */\nexport function linearDispatch(invocations: number, workgroupSize: number, maximumPerDimension: number): [number, number] {\n const groups = Math.max(1, Math.ceil(invocations / workgroupSize));\n const x = Math.min(groups, maximumPerDimension), y = Math.ceil(groups / x);\n if (y > maximumPerDimension) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"Band exceeds the adapter's dispatch limits.\");\n }\n return [x, y];\n}\n\n/**\n * Submits one compute pass and copies `outputs` into mappable staging buffers, then maps them. Validation\n * and out-of-memory errors are captured with error scopes and reported as domain errors.\n */\nexport async function runComputePass(runtime: WebGpuRuntime, scope: GpuResourceScope, pipeline: GPUComputePipeline,\n bindGroup: GPUBindGroup | readonly GPUBindGroup[], workgroups: readonly [number, number], outputs: readonly { buffer: GPUBuffer; bytes: number }[],\n signal: AbortSignal | undefined): Promise<ArrayBuffer[]> {\n const device = runtime.device;\n device.pushErrorScope(\"out-of-memory\");\n device.pushErrorScope(\"validation\");\n const staging = outputs.map(({ bytes }, i) =>\n scope.buffer(`photivra-readback-${i}`, bytes, BUFFER_USAGE.MAP_READ | BUFFER_USAGE.COPY_DST));\n const encoder = device.createCommandEncoder({ label: \"photivra-image-kernel\" });\n const pass = encoder.beginComputePass();\n pass.setPipeline(pipeline);\n // One bind group at index 0, or several at indices 0, 1, … (the display-view kernel binds its material module at 1).\n (Array.isArray(bindGroup) ? bindGroup as readonly GPUBindGroup[] : [bindGroup as GPUBindGroup]).forEach((group, index) => pass.setBindGroup(index, group));\n pass.dispatchWorkgroups(workgroups[0], workgroups[1]);\n pass.end();\n outputs.forEach(({ buffer }, i) => encoder.copyBufferToBuffer(buffer, 0, staging[i]!, 0, staging[i]!.size));\n device.queue.submit([encoder.finish()]);\n // Pop both scopes before any await so an abort or loss never leaves the device's scope stack unbalanced.\n const validationScope = device.popErrorScope(), memoryScope = device.popErrorScope();\n const validation = await runtime.guard(validationScope, signal);\n const memory = await runtime.guard(memoryScope, signal);\n if (memory) throw new ImageKernelExecutionError(\"out-of-memory\", \"The WebGPU device ran out of memory.\");\n if (validation) throw new ImageKernelExecutionError(\"gpu-validation\", \"WebGPU rejected an image-kernel command.\");\n const results: ArrayBuffer[] = [];\n for (let i = 0; i < staging.length; i++) {\n const buffer = staging[i]!;\n await runtime.guard(buffer.mapAsync(MAP_MODE_READ), signal);\n results.push(buffer.getMappedRange(0, Math.ceil(outputs[i]!.bytes / 4) * 4).slice(0));\n buffer.unmap();\n }\n return results;\n}\n\n/** Compiles a compute pipeline; compilation/validation failures are domain errors. */\nexport async function createComputePipeline(runtime: WebGpuRuntime, label: string, code: string,\n signal: AbortSignal | undefined): Promise<GPUComputePipeline> {\n const device = runtime.device;\n device.pushErrorScope(\"validation\");\n const module = device.createShaderModule({ label, code });\n const pending = device.createComputePipelineAsync({ label, layout: \"auto\", compute: { module, entryPoint: \"main\" } });\n const scope = device.popErrorScope();\n let pipeline: GPUComputePipeline;\n try {\n pipeline = await runtime.guard(pending, signal);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) throw error;\n throw new ImageKernelExecutionError(\"gpu-validation\", `WebGPU could not compile the ${label} kernel.`);\n }\n if (await runtime.guard(scope, signal)) {\n throw new ImageKernelExecutionError(\"gpu-validation\", `WebGPU could not compile the ${label} kernel.`);\n }\n return pipeline;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"webgpu-runtime.js","sourceRoot":"","sources":["../../src/gpu/webgpu-runtime.ts"],"names":[],"mappings":"AAAA,sCAAsC;AAEtC;;;;;GAKG;AACH,OAAO,EAAE,yBAAyB,EAAsE,MAAM,6BAA6B,CAAC;AAE5I,8GAA8G;AAC9G,MAAM,CAAC,MAAM,YAAY,GAAG,eAAe,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;AACtJ,MAAM,aAAa,GAAG,MAAM,CAAC;AAE7B,yFAAyF;AACzF,MAAM,CAAC,MAAM,oCAAoC,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AACrE,qGAAqG;AACrG,MAAM,CAAC,MAAM,sCAAsC,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAiBzE,SAAS,kBAAkB;IACzB,OAAO,IAAI,UAAU,CAAC,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,yBAAyB,CAAC,SAAS,EAAE,6DAA6D,CAAC,CAAC;AACjH,CAAC;AACD,2DAA2D;AAC3D,MAAM,UAAU,cAAc,CAAC,MAAmB,IAAU,IAAI,MAAM,CAAC,OAAO;IAAE,MAAM,YAAY,EAAE,CAAC,CAAC,CAAC;AAEvG,iFAAiF;AACjF,SAAS,SAAS,CAAC,MAA+B;IAChD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,CAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;IAC/F,IAAI,OAAO,GAAG,GAAS,EAAE,CAAC,SAAS,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE;QAC/C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;YAAC,OAAO;QAAC,CAAC;QACvD,MAAM,QAAQ,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;QACpD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IACtE,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC/B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC;AAC9B,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,GAAY,EAAE,eAA6D,EACpH,MAA+B;IAC/B,IAAI,CAAC,kBAAkB,EAAE;QAAE,OAAO,EAAE,OAAO,EAAE,iCAAiC,EAAE,OAAO,EAAE,8CAA8C,EAAE,CAAC;IAC1I,MAAM,GAAG,GAAG,GAAsC,CAAC;IACnD,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,OAAO,GAAG,CAAC,cAAc,KAAK,UAAU,EAAE,CAAC;QAChF,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,0CAA0C,EAAE,CAAC;IAChG,CAAC;IACD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,IAAI,OAA0B,CAAC;QAC/B,IAAI,CAAC;YACH,OAAO,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACvH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,yBAAyB;gBAAE,MAAM,KAAK,CAAC;YAC5D,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QACD,IAAI,CAAC,OAAO;YAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,iCAAiC,EAAE,CAAC;QACpG,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,2BAA2B,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,aAAa,CAAC;QAChH,IAAI,CAAC,CAAC,cAAc,IAAI,oCAAoC,IAAI,aAAa,IAAI,oCAAoC,CAAC,EAAE,CAAC;YACvH,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,OAAO,EAAE,2EAA2E,EAAE,CAAC;QAClI,CAAC;QACD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,aAAa,EAAE,sCAAsC,CAAC,CAAC;QAChG,IAAI,MAAiB,EAAE,OAAuC,CAAC;QAC/D,IAAI,CAAC;YACH,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,EAAE,KAAK,EAAE,wBAAwB;gBAC/D,cAAc,EAAE,EAAE,2BAA2B,EAAE,OAAO,EAAE,aAAa,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC;YACtF,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,yBAAyB,EAAE,CAAC;gBAC/C,6FAA6F;gBAC7F,IAAI,OAAO;oBAAE,KAAK,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;gBACzF,MAAM,KAAK,CAAC;YACd,CAAC;YACD,OAAO,EAAE,OAAO,EAAE,uBAAuB,EAAE,OAAO,EAAE,mCAAmC,EAAE,CAAC;QAC5F,CAAC;QACD,IAAI,MAAM,EAAE,OAAO,EAAE,CAAC;YAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YAAC,MAAM,YAAY,EAAE,CAAC;QAAC,CAAC;QAChE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC;IAC/E,CAAC;YAAS,CAAC;QACT,KAAK,CAAC,OAAO,EAAE,CAAC;IAClB,CAAC;AACH,CAAC;AAED,+HAA+H;AAC/H,SAAS,eAAe,CAAC,OAAmB;IAC1C,MAAM,IAAI,GAAI,OAA2F,CAAC,IAAI,CAAC;IAC/G,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACnD,MAAM,IAAI,GAAG,CAAC,KAAc,EAAU,EAAE,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAClF,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;AAC9I,CAAC;AAED,SAAS,aAAa,CAAC,MAAiB,EAAE,OAAe,EAAE,OAA6C;IACtG,IAAI,IAAI,GAAG,KAAK,EAAE,SAAS,GAAG,KAAK,CAAC;IACpC,IAAI,UAAU,GAA+C,GAAG,EAAE,CAAC,SAAS,CAAC;IAC7E,MAAM,WAAW,GAAG,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,GAAG,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChF,WAAW,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACnC,KAAK,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;QACzB,IAAI,GAAG,IAAI,CAAC;QACZ,UAAU,CAAC,IAAI,yBAAyB,CAAC,aAAa,EAAE,qDAAqD,CAAC,CAAC,CAAC;IAClH,CAAC,CAAC,CAAC;IACH,mGAAmG;IACnG,MAAM,CAAC,iBAAiB,GAAG,CAAC,KAA8B,EAAQ,EAAE,GAAG,KAAK,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,CAAC;IACjG,MAAM,6BAA6B,GAAG,MAAM,CAAC,MAAM,CAAC,gCAAgC,CAAC;IACrF,OAAO;QACL,MAAM,EAAE,OAAO;QACf,0BAA0B,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,2BAA2B,EAAE,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC;QACrH,6BAA6B;QAC7B,MAAM,EAAE,GAAY,EAAE,CAAC,IAAI;QAC3B,KAAK,CAAC,KAAK,CAAI,OAAmB,EAAE,MAA+B;YACjE,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;YAC/B,IAAI,IAAI;gBAAE,MAAM,IAAI,yBAAyB,CAAC,aAAa,EAAE,qDAAqD,CAAC,CAAC;YACpH,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;YAChC,IAAI,CAAC;gBAAC,OAAO,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAC,CAAC;oBAAS,CAAC;gBAAC,KAAK,CAAC,OAAO,EAAE,CAAC;YAAC,CAAC;QACxG,CAAC;QACD,OAAO,KAAW,IAAI,CAAC,SAAS,EAAE,CAAC;YAAC,SAAS,GAAG,IAAI,CAAC;YAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAAC,CAAC,CAAC,CAAC;KAC5E,CAAC;AACJ,CAAC;AAED,0FAA0F;AAC1F,MAAM,OAAO,gBAAgB;IAClB,QAAQ,CAAgB;IACxB,QAAQ,GAAgB,EAAE,CAAC;IAEpC,YAAY,OAAsB,IAAI,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC;IAEhE,MAAM,CAAC,KAAa,EAAE,IAAY,EAAE,KAAa;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;QAClH,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3B,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,gFAAgF;IAChF,MAAM,CAAC,KAAa,EAAE,IAAkC,EAAE,KAAa;QACrE,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC;QAClF,IAAI,IAAI,CAAC,UAAU,GAAG,CAAC;YAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC1H,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,OAAO;QACL,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;YAAE,MAAM,CAAC,OAAO,EAAE,CAAC;IACjE,CAAC;CACF;AAED,qFAAqF;AACrF,MAAM,UAAU,cAAc,CAAC,WAAmB,EAAE,aAAqB,EAAE,mBAA2B;IACpG,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC;IACnE,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC3E,IAAI,CAAC,GAAG,mBAAmB,EAAE,CAAC;QAC5B,MAAM,IAAI,yBAAyB,CAAC,qBAAqB,EAAE,6CAA6C,CAAC,CAAC;IAC5G,CAAC;IACD,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAsB,EAAE,KAAuB,EAAE,QAA4B,EAChH,SAAiD,EAAE,UAAqC,EAAE,OAAwD,EAClJ,MAA+B;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,CAAC,cAAc,CAAC,eAAe,CAAC,CAAC;IACvC,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,EAAE,CAC3C,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,EAAE,KAAK,EAAE,YAAY,CAAC,QAAQ,GAAG,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChG,MAAM,OAAO,GAAG,MAAM,CAAC,oBAAoB,CAAC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC,CAAC;IAChF,MAAM,IAAI,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IACxC,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IAC3B,qHAAqH;IACrH,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAoC,CAAC,CAAC,CAAC,CAAC,SAAyB,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;IAC3J,IAAI,CAAC,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;IACtD,IAAI,CAAC,GAAG,EAAE,CAAC;IACX,OAAO,CAAC,OAAO,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,kBAAkB,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAE,EAAE,CAAC,EAAE,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAC5G,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;IACxC,yGAAyG;IACzG,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,EAAE,EAAE,WAAW,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IACrF,MAAM,UAAU,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;IACxD,IAAI,MAAM;QAAE,MAAM,IAAI,yBAAyB,CAAC,eAAe,EAAE,sCAAsC,CAAC,CAAC;IACzG,IAAI,UAAU;QAAE,MAAM,IAAI,yBAAyB,CAAC,gBAAgB,EAAE,0CAA0C,CAAC,CAAC;IAClH,MAAM,OAAO,GAAkB,EAAE,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;QAC3B,MAAM,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,CAAC,KAAK,EAAE,CAAC;IACjB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,sFAAsF;AACtF,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,OAAsB,EAAE,KAAa,EAAE,IAAY,EAC7F,MAA+B;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,MAAM,CAAC,0BAA0B,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,CAAC,CAAC;IACtH,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IACrC,IAAI,QAA4B,CAAC;IACjC,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,OAAO,CAAC,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,yBAAyB;YAAE,MAAM,KAAK,CAAC;QAC5D,MAAM,IAAI,yBAAyB,CAAC,gBAAgB,EAAE,gCAAgC,KAAK,UAAU,CAAC,CAAC;IACzG,CAAC;IACD,IAAI,MAAM,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;QACvC,MAAM,IAAI,yBAAyB,CAAC,gBAAgB,EAAE,gCAAgC,KAAK,UAAU,CAAC,CAAC;IACzG,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC","sourcesContent":["// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Internal WebGPU device handling for the image-kernel accelerator: getting the adapter and device,\n * limits, tracking device loss, racing work against abort and loss, error scopes, banded buffers and\n * cleanup. Not exported from the package root. WebGPU types never appear in the published type\n * declarations, so consumers do not need WebGPU typings.\n */\nimport { ImageKernelExecutionError, type ImageKernelAdapterDescription, type ImageKernelFallbackReason } from \"./image-kernel-execution.js\";\n\n/** WebGPU spec constants (GPUBufferUsage, GPUMapMode), defined here so no global is needed at import time. */\nexport const BUFFER_USAGE = /* @__PURE__ */ Object.freeze({ MAP_READ: 0x0001, COPY_SRC: 0x0004, COPY_DST: 0x0008, UNIFORM: 0x0040, STORAGE: 0x0080 });\nconst MAP_MODE_READ = 0x0001;\n\n/** Minimum per-binding storage this backend requires (the WebGPU default is 128 MiB). */\nexport const WEBGPU_MINIMUM_STORAGE_BINDING_BYTES = 16 * 1024 * 1024;\n/** Upper limit requested from the adapter, so one band never asks for more than this per binding. */\nexport const WEBGPU_REQUESTED_STORAGE_BINDING_BYTES = 1024 * 1024 * 1024;\n\nexport interface WebGpuRuntime {\n readonly device: GPUDevice;\n /** #481: the adapter's `info`, or null when the implementation has none. */\n readonly adapter: ImageKernelAdapterDescription | null;\n readonly maximumStorageBindingBytes: number;\n readonly maximumWorkgroupsPerDimension: number;\n /** Set once `device.lost` settles; every later wait rejects with `device-lost`. */\n isLost(): boolean;\n /** Races a GPU promise with device loss and the operation's abort signal. */\n guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;\n destroy(): void;\n}\n\nexport type WebGpuAcquisition = { runtime: WebGpuRuntime } | { failure: ImageKernelFallbackReason; message: string };\n\nfunction hostIsLittleEndian(): boolean {\n return new Uint8Array(new Uint16Array([1]).buffer)[0] === 1;\n}\n\nexport function abortedError(): ImageKernelExecutionError {\n return new ImageKernelExecutionError(\"aborted\", \"Image-kernel execution was aborted; no output is available.\");\n}\n/** Throws `abortedError()` when the signal has aborted. */\nexport function throwIfAborted(signal: AbortSignal): void { if (signal.aborted) throw abortedError(); }\n\n/** Rejects when the signal aborts; the returned cleanup removes the listener. */\nfunction abortRace(signal: AbortSignal | undefined): { promise: Promise<never>; cleanup: () => void } {\n if (!signal) return { promise: new Promise<never>(() => undefined), cleanup: () => undefined };\n let cleanup = (): void => undefined;\n const promise = new Promise<never>((_, reject) => {\n if (signal.aborted) { reject(abortedError()); return; }\n const listener = (): void => reject(abortedError());\n signal.addEventListener(\"abort\", listener, { once: true });\n cleanup = (): void => signal.removeEventListener(\"abort\", listener);\n });\n promise.catch(() => undefined);\n return { promise, cleanup };\n}\n\n/**\n * Requests a device with high limits from `gpu` (normally `navigator.gpu`). It does not throw when\n * WebGPU is unavailable; the caller decides whether to fall back to the CPU or fail. An abort during\n * acquisition does throw.\n */\nexport async function acquireWebGpuRuntime(gpu: unknown, powerPreference: \"low-power\" | \"high-performance\" | undefined,\n signal: AbortSignal | undefined): Promise<WebGpuAcquisition> {\n if (!hostIsLittleEndian()) return { failure: \"unsupported-platform-endianness\", message: \"WebGPU buffers require a little-endian host.\" };\n const api = gpu as Partial<GPU> | null | undefined;\n if (!api || typeof api !== \"object\" || typeof api.requestAdapter !== \"function\") {\n return { failure: \"webgpu-unavailable\", message: \"WebGPU is not available in this runtime.\" };\n }\n const abort = abortRace(signal);\n try {\n let adapter: GPUAdapter | null;\n try {\n adapter = await Promise.race([api.requestAdapter(powerPreference ? { powerPreference } : undefined), abort.promise]);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) throw error;\n adapter = null;\n }\n if (!adapter) return { failure: \"adapter-unavailable\", message: \"No WebGPU adapter is available.\" };\n const adapterStorage = adapter.limits.maxStorageBufferBindingSize, adapterBuffer = adapter.limits.maxBufferSize;\n if (!(adapterStorage >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES && adapterBuffer >= WEBGPU_MINIMUM_STORAGE_BINDING_BYTES)) {\n return { failure: \"insufficient-limits\", message: \"The WebGPU adapter's storage-buffer limits are below the backend minimum.\" };\n }\n const storage = Math.min(adapterStorage, adapterBuffer, WEBGPU_REQUESTED_STORAGE_BINDING_BYTES);\n let device: GPUDevice, pending: Promise<GPUDevice> | undefined;\n try {\n pending = adapter.requestDevice({ label: \"photivra-image-kernels\",\n requiredLimits: { maxStorageBufferBindingSize: storage, maxBufferSize: storage } });\n device = await Promise.race([pending, abort.promise]);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) {\n // The abort won the race. A device that still arrives later is destroyed, so it never leaks.\n if (pending) void Promise.resolve(pending).then(late => late.destroy(), () => undefined);\n throw error;\n }\n return { failure: \"device-request-failed\", message: \"The WebGPU device request failed.\" };\n }\n if (signal?.aborted) { device.destroy(); throw abortedError(); }\n return { runtime: createRuntime(device, storage, describeAdapter(adapter)) };\n } finally {\n abort.cleanup();\n }\n}\n\n/** `GPUAdapter.info` as plain strings (missing or non-string fields read as empty), or null when the adapter has no `info`. */\nfunction describeAdapter(adapter: GPUAdapter): ImageKernelAdapterDescription | null {\n const info = (adapter as { info?: Partial<Record<keyof ImageKernelAdapterDescription, unknown>> | null }).info;\n if (!info || typeof info !== \"object\") return null;\n const text = (value: unknown): string => (typeof value === \"string\" ? value : \"\");\n return { vendor: text(info.vendor), architecture: text(info.architecture), device: text(info.device), description: text(info.description) };\n}\n\nfunction createRuntime(device: GPUDevice, storage: number, adapter: ImageKernelAdapterDescription | null): WebGpuRuntime {\n let lost = false, destroyed = false;\n let rejectLost: (error: ImageKernelExecutionError) => void = () => undefined;\n const lostPromise = new Promise<never>((_, reject) => { rejectLost = reject; });\n lostPromise.catch(() => undefined);\n void device.lost.then(() => {\n lost = true;\n rejectLost(new ImageKernelExecutionError(\"device-lost\", \"The WebGPU device was lost; no output is available.\"));\n });\n // Errors are collected through error scopes; this only keeps uncaptured errors out of the console.\n device.onuncapturederror = (event: GPUUncapturedErrorEvent): void => { event.preventDefault(); };\n const maximumWorkgroupsPerDimension = device.limits.maxComputeWorkgroupsPerDimension;\n return {\n device, adapter,\n maximumStorageBindingBytes: Math.min(storage, device.limits.maxStorageBufferBindingSize, device.limits.maxBufferSize),\n maximumWorkgroupsPerDimension,\n isLost: (): boolean => lost,\n async guard<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n promise.catch(() => undefined);\n if (lost) throw new ImageKernelExecutionError(\"device-lost\", \"The WebGPU device was lost; no output is available.\");\n const abort = abortRace(signal);\n try { return await Promise.race([promise, lostPromise, abort.promise]); } finally { abort.cleanup(); }\n },\n destroy(): void { if (!destroyed) { destroyed = true; device.destroy(); } }\n };\n}\n\n/** Per-operation resource scope: every buffer is destroyed when the operation settles. */\nexport class GpuResourceScope {\n readonly #runtime: WebGpuRuntime;\n readonly #buffers: GPUBuffer[] = [];\n\n constructor(runtime: WebGpuRuntime) { this.#runtime = runtime; }\n\n buffer(label: string, size: number, usage: number): GPUBuffer {\n const buffer = this.#runtime.device.createBuffer({ label, size: Math.max(16, Math.ceil(size / 16) * 16), usage });\n this.#buffers.push(buffer);\n return buffer;\n }\n\n /** Storage buffer initialised from host data (padded to a 16-byte multiple). */\n upload(label: string, data: ArrayBufferView<ArrayBuffer>, usage: number): GPUBuffer {\n const buffer = this.buffer(label, data.byteLength, usage | BUFFER_USAGE.COPY_DST);\n if (data.byteLength > 0) this.#runtime.device.queue.writeBuffer(buffer, 0, data.buffer, data.byteOffset, data.byteLength);\n return buffer;\n }\n\n release(): void {\n for (const buffer of this.#buffers.splice(0)) buffer.destroy();\n }\n}\n\n/** Workgroup grid for a 1-D invocation count (2-D when it exceeds one dimension). */\nexport function linearDispatch(invocations: number, workgroupSize: number, maximumPerDimension: number): [number, number] {\n const groups = Math.max(1, Math.ceil(invocations / workgroupSize));\n const x = Math.min(groups, maximumPerDimension), y = Math.ceil(groups / x);\n if (y > maximumPerDimension) {\n throw new ImageKernelExecutionError(\"insufficient-limits\", \"Band exceeds the adapter's dispatch limits.\");\n }\n return [x, y];\n}\n\n/**\n * Submits one compute pass and copies `outputs` into mappable staging buffers, then maps them. Validation\n * and out-of-memory errors are captured with error scopes and reported as domain errors.\n */\nexport async function runComputePass(runtime: WebGpuRuntime, scope: GpuResourceScope, pipeline: GPUComputePipeline,\n bindGroup: GPUBindGroup | readonly GPUBindGroup[], workgroups: readonly [number, number], outputs: readonly { buffer: GPUBuffer; bytes: number }[],\n signal: AbortSignal | undefined): Promise<ArrayBuffer[]> {\n const device = runtime.device;\n device.pushErrorScope(\"out-of-memory\");\n device.pushErrorScope(\"validation\");\n const staging = outputs.map(({ bytes }, i) =>\n scope.buffer(`photivra-readback-${i}`, bytes, BUFFER_USAGE.MAP_READ | BUFFER_USAGE.COPY_DST));\n const encoder = device.createCommandEncoder({ label: \"photivra-image-kernel\" });\n const pass = encoder.beginComputePass();\n pass.setPipeline(pipeline);\n // One bind group at index 0, or several at indices 0, 1, … (the display-view kernel binds its material module at 1).\n (Array.isArray(bindGroup) ? bindGroup as readonly GPUBindGroup[] : [bindGroup as GPUBindGroup]).forEach((group, index) => pass.setBindGroup(index, group));\n pass.dispatchWorkgroups(workgroups[0], workgroups[1]);\n pass.end();\n outputs.forEach(({ buffer }, i) => encoder.copyBufferToBuffer(buffer, 0, staging[i]!, 0, staging[i]!.size));\n device.queue.submit([encoder.finish()]);\n // Pop both scopes before any await so an abort or loss never leaves the device's scope stack unbalanced.\n const validationScope = device.popErrorScope(), memoryScope = device.popErrorScope();\n const validation = await runtime.guard(validationScope, signal);\n const memory = await runtime.guard(memoryScope, signal);\n if (memory) throw new ImageKernelExecutionError(\"out-of-memory\", \"The WebGPU device ran out of memory.\");\n if (validation) throw new ImageKernelExecutionError(\"gpu-validation\", \"WebGPU rejected an image-kernel command.\");\n const results: ArrayBuffer[] = [];\n for (let i = 0; i < staging.length; i++) {\n const buffer = staging[i]!;\n await runtime.guard(buffer.mapAsync(MAP_MODE_READ), signal);\n results.push(buffer.getMappedRange(0, Math.ceil(outputs[i]!.bytes / 4) * 4).slice(0));\n buffer.unmap();\n }\n return results;\n}\n\n/** Compiles a compute pipeline; compilation/validation failures are domain errors. */\nexport async function createComputePipeline(runtime: WebGpuRuntime, label: string, code: string,\n signal: AbortSignal | undefined): Promise<GPUComputePipeline> {\n const device = runtime.device;\n device.pushErrorScope(\"validation\");\n const module = device.createShaderModule({ label, code });\n const pending = device.createComputePipelineAsync({ label, layout: \"auto\", compute: { module, entryPoint: \"main\" } });\n const scope = device.popErrorScope();\n let pipeline: GPUComputePipeline;\n try {\n pipeline = await runtime.guard(pending, signal);\n } catch (error) {\n if (error instanceof ImageKernelExecutionError) throw error;\n throw new ImageKernelExecutionError(\"gpu-validation\", `WebGPU could not compile the ${label} kernel.`);\n }\n if (await runtime.guard(scope, signal)) {\n throw new ImageKernelExecutionError(\"gpu-validation\", `WebGPU could not compile the ${label} kernel.`);\n }\n return pipeline;\n}\n"]}
|
package/dist/index.d.ts
CHANGED
|
@@ -103,6 +103,8 @@ export { calculateInverseRadialDistortionMapping, calculateInverseRadialDistorti
|
|
|
103
103
|
export { calculateBrownConradyDistortionMapping, calculateInverseBrownConradyDistortionMapping, type BrownConradyDistortionCoefficients, type BrownConradyDistortionMapping, type BrownConradyDistortionProfile, type CalculateBrownConradyDistortionMappingInput, type CalculateInverseBrownConradyDistortionMappingInput, type InverseBrownConradyDistortionMapping } from "./optics/brown-conrady-distortion.js";
|
|
104
104
|
export { calculateInverseLateralChromaticAberrationMapping, calculateInverseLateralChromaticAberrationMappings, calculateLateralChromaticAberrationMapping, type CalculateInverseLateralChromaticAberrationMappingInput, type CalculateInverseLateralChromaticAberrationMappingsInput, type CalculateLateralChromaticAberrationMappingInput, type ChannelSeparationVectorMm, type InverseLateralChromaticAberrationChannelMapping, type InverseLateralChromaticAberrationMapping, type InverseLateralChromaticAberrationMappings, type LateralChromaticAberrationChannel, type LateralChromaticAberrationChannelMapping, type LateralChromaticAberrationMapping, type LateralChromaticAberrationProfile, type LateralChromaticAberrationSeparation } from "./optics/lateral-chromatic-aberration.js";
|
|
105
105
|
export { FRONT_OF_LENS_FILTER_PROFILE_SCHEMA_VERSION, FRONT_OF_LENS_POLARIZER_PROFILE_SCHEMA_VERSION, composeFrontOfLensFilterTransmission, parseFrontOfLensFilterProfile, resolveFrontOfLensFilterTransmission, type ComposeFrontOfLensFilterTransmissionInput, type ComposedFrontOfLensFilterTransmission, type FrontOfLensFilterProfile, type FrontOfLensFilterProfileSchemaVersion, type FrontOfLensFilterScientificStatus, type FrontOfLensFilterSpectralSample, type FrontOfLensFilterTransmissionModel, type FrontOfLensFilterUncertainty, type LinearPolarizationState, type ResolveFrontOfLensFilterTransmissionInput, type ResolvedFrontOfLensFilterTransmission } from "./optics/front-of-lens-filter.js";
|
|
106
|
+
export { GENERIC_ND_FILTER_PROFILES, GENERIC_ND_FILTER_STOPS, type GenericNdFilterStops } from "./optics/generic-nd-filter-presets.js";
|
|
107
|
+
export { FILTERED_EXPOSURE_DEFAULT_WAVELENGTH_NANOMETERS, calculateFilteredExposureTime, type CalculateFilteredExposureTimeInput, type FilteredExposureDialSetting, type FilteredExposureTime } from "./exposure/filtered-exposure-time.js";
|
|
106
108
|
export { calculateIlluminationVignetting, type CalculateIlluminationVignettingInput, type IlluminationVignetting, type IlluminationVignettingCoefficients, type IlluminationVignettingProfile } from "./optics/illumination-vignetting.js";
|
|
107
109
|
export { SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION, calculateSceneRadianceToSensorIrradiance, parseSceneToSensorIrradianceProfile, type CalculateSceneRadianceToSensorIrradianceInput, type NumericRange, type OpticalBridgeFieldThroughput, type OpticalBridgeFocusApplicability, type OpticalBridgeFocusContext, type OpticalBridgeScientificStatus, type OpticalBridgeUncertainty, type OpticalTransmissionModel, type SceneToSensorIrradianceProfile, type SceneToSensorIrradianceResult, type SpectralTransmissionSample } from "./optics/scene-to-sensor-irradiance.js";
|
|
108
110
|
export { LENS_SAMPLED_PSF_PROFILE_SCHEMA_VERSION, LENS_MTF_DIAGNOSTIC_PROFILE_SCHEMA_VERSION, assessMtfOnlyPsfRenderability, parseLensMtfDiagnosticProfile, parseLensSampledPsfProfile, resolveLensSampledPsf, type LensMtfDiagnosticProfile, type LensMtfDiagnosticSample, type LensPsfGridAxes, type LensPsfKernel, type LensPsfScientificStatus, type LensPsfUncertainty, type LensSampledPsfGridCoordinate, type LensSampledPsfGridNode, type LensSampledPsfInterpolation, type LensSampledPsfProfile, type MtfOnlyPsfRenderabilityAssessment, type ResolveLensSampledPsfInput, type ResolvedLensSampledPsf } from "./optics/lens-psf-profile.js";
|
|
@@ -203,7 +205,8 @@ export { createFocusStackTask, type FocusStackInput, type FocusStackOutput } fro
|
|
|
203
205
|
export { createPanoramaTask, type PanoramaFrame, type PanoramaCanvas, type PanoramaInput, type PanoramaOutput } from "./processing/panorama.js";
|
|
204
206
|
export { SYNTHETIC_FILM_GRAIN_STREAM_ID, createBilateralFilterTask, createNonLocalMeansTask, createUnsharpMaskTask, createSyntheticFilmGrainTask, type ProcessedRgbImage, type BilateralFilterInput, type NonLocalMeansInput, type UnsharpMaskInput, type SyntheticFilmGrainInput, type SyntheticFilmGrainOutput } from "./processing/denoise.js";
|
|
205
207
|
export { calculateSensorApertureRays, type CalculateSensorApertureRaysInput, type IdealCircularPupil, type SensorApertureRay, type SensorApertureRays } from "./optics/sensor-aperture-rays.js";
|
|
206
|
-
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, SIMULATE_CAPTURE_METERING_MODES, simulateCapture, type SimulateCaptureOptions, type SimulateCaptureResult, type SimulateCaptureAssumption, type SimulateCaptureProgress, type SimulateCaptureExposureMode, type SimulateCaptureMetering, type SimulateCaptureAutoIsoAfterMaximum, type SimulateCaptureAutoIsoReport, type SimulateCaptureAutomaticSlowestShutterOptions, type SimulateCaptureAutomaticSlowestShutterReport, type SimulateCaptureOutputFormat, type SimulateCaptureWhiteBalance, type SimulateCaptureColorEncoding, type SimulateCaptureDemosaic, type SimulateCaptureBorderHandling, type SimulateCaptureLensDistortion, type SimulateCaptureMotion, type SimulateCaptureSensorAntiAliasing, type SimulateCaptureCostOption, type SimulateCapturePixelAperture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, SIMULATE_CAPTURE_FAST_OPTIONS, type SimulateCaptureFastOption, type SimulateCaptureFastReport, type SimulateCaptureDemosaicRecord, type SimulateCaptureLensCatalogueRecord, type SimulateCaptureSharpening, type SimulateCaptureDiffractionCorrection, type SimulateCaptureDetailDiagnostics, simulateIdealReference, type IdealReferenceResult, serializeSimulatedCaptureDngFromParts, type SimulateCaptureDngPart, type SimulateDisplayViewOptions, type DisplayViewResult, type DisplayViewHighlightDiagnostics, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
208
|
+
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, SIMULATE_CAPTURE_METERING_MODES, simulateCapture, type SimulateCaptureOptions, type SimulateCaptureResult, type SimulateCaptureAssumption, type SimulateCaptureProgress, type SimulateCaptureExposureMode, type SimulateCaptureMetering, type SimulateCaptureAutoIsoAfterMaximum, type SimulateCaptureAutoIsoReport, type SimulateCaptureAutomaticSlowestShutterOptions, type SimulateCaptureAutomaticSlowestShutterReport, type SimulateCaptureOutputFormat, type SimulateCaptureWhiteBalance, type SimulateCaptureColorEncoding, type SimulateCaptureDemosaic, type SimulateCaptureBorderHandling, type SimulateCaptureLensDistortion, type SimulateCaptureMotion, type SimulateCaptureSensorAntiAliasing, type SimulateCaptureCostOption, type SimulateCapturePixelAperture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, SIMULATE_CAPTURE_FAST_OPTIONS, type SimulateCaptureFastOption, type SimulateCaptureFastReport, type SimulateCaptureDemosaicRecord, type SimulateCaptureLensCatalogueRecord, type SimulateCaptureSharpening, type SimulateCaptureDiffractionCorrection, type SimulateCaptureLensCorrections, type SimulateCaptureDetailDiagnostics, simulateIdealReference, type IdealReferenceResult, serializeSimulatedCaptureDngFromParts, type SimulateCaptureDngPart, type SimulateDisplayViewOptions, type DisplayViewResult, type DisplayViewHighlightDiagnostics, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
209
|
+
export { simulateCaptureFromParts } from "./facade/develop-joined-parts.js";
|
|
207
210
|
export { simulateDisplayView, prepareDisplayView, type PreparedDisplayView, type PreparedDisplayViewRenderOptions, serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates, type DisplayViewCorrectionStateKeys, type DisplayViewCorrectionStateSet } from "./facade/simulate-display-view.js";
|
|
208
211
|
export type { DisplayViewGpuMode, PrepareDisplayViewOptions, DisplayViewGpuFallbackReason, DisplayViewGpuConformance, DisplayViewExecution, DisplayViewFastReport } from "./facade/display-view-gpu.js";
|
|
209
212
|
export { type OutputTextMetadata, addJpegTextMetadata, addPngTextMetadata } from "./output/text-metadata.js";
|
package/dist/index.js
CHANGED
|
@@ -102,6 +102,8 @@ export { calculateInverseRadialDistortionMapping, calculateInverseRadialDistorti
|
|
|
102
102
|
export { calculateBrownConradyDistortionMapping, calculateInverseBrownConradyDistortionMapping } from "./optics/brown-conrady-distortion.js";
|
|
103
103
|
export { calculateInverseLateralChromaticAberrationMapping, calculateInverseLateralChromaticAberrationMappings, calculateLateralChromaticAberrationMapping } from "./optics/lateral-chromatic-aberration.js";
|
|
104
104
|
export { FRONT_OF_LENS_FILTER_PROFILE_SCHEMA_VERSION, FRONT_OF_LENS_POLARIZER_PROFILE_SCHEMA_VERSION, composeFrontOfLensFilterTransmission, parseFrontOfLensFilterProfile, resolveFrontOfLensFilterTransmission } from "./optics/front-of-lens-filter.js";
|
|
105
|
+
export { GENERIC_ND_FILTER_PROFILES, GENERIC_ND_FILTER_STOPS } from "./optics/generic-nd-filter-presets.js";
|
|
106
|
+
export { FILTERED_EXPOSURE_DEFAULT_WAVELENGTH_NANOMETERS, calculateFilteredExposureTime } from "./exposure/filtered-exposure-time.js";
|
|
105
107
|
export { calculateIlluminationVignetting } from "./optics/illumination-vignetting.js";
|
|
106
108
|
export { SCENE_TO_SENSOR_IRRADIANCE_PROFILE_SCHEMA_VERSION, calculateSceneRadianceToSensorIrradiance, parseSceneToSensorIrradianceProfile } from "./optics/scene-to-sensor-irradiance.js";
|
|
107
109
|
export { LENS_SAMPLED_PSF_PROFILE_SCHEMA_VERSION, LENS_MTF_DIAGNOSTIC_PROFILE_SCHEMA_VERSION, assessMtfOnlyPsfRenderability, parseLensMtfDiagnosticProfile, parseLensSampledPsfProfile, resolveLensSampledPsf } from "./optics/lens-psf-profile.js";
|
|
@@ -182,6 +184,7 @@ export { createPanoramaTask } from "./processing/panorama.js";
|
|
|
182
184
|
export { SYNTHETIC_FILM_GRAIN_STREAM_ID, createBilateralFilterTask, createNonLocalMeansTask, createUnsharpMaskTask, createSyntheticFilmGrainTask } from "./processing/denoise.js";
|
|
183
185
|
export { calculateSensorApertureRays } from "./optics/sensor-aperture-rays.js";
|
|
184
186
|
export { SIMULATE_CAPTURE_FACADE_VERSION, SIMULATE_CAPTURE_DEFAULT_ILLUMINANCE_LUX, SIMULATE_CAPTURE_COST_OPTIONS, SIMULATE_CAPTURE_METERING_MODES, simulateCapture, SIMULATE_CAPTURE_BOX_APERTURE_DEFAULT_SAMPLES, SIMULATE_CAPTURE_FAST_OPTIONS, simulateIdealReference, serializeSimulatedCaptureDngFromParts, SIMULATE_DISPLAY_VIEW_DEFAULT_SAMPLES_PER_AXIS } from "./facade/simulate-capture.js";
|
|
187
|
+
export { simulateCaptureFromParts } from "./facade/develop-joined-parts.js";
|
|
185
188
|
export { simulateDisplayView, prepareDisplayView, serializeDisplayViewCorrectionStates, bindDisplayViewCorrectionStates } from "./facade/simulate-display-view.js";
|
|
186
189
|
export { addJpegTextMetadata, addPngTextMetadata } from "./output/text-metadata.js";
|
|
187
190
|
export { GENERIC_THIRD_STOP_ISO_SETTINGS, GENERIC_THIRD_STOP_SHUTTER_SECONDS, GENERIC_WHOLE_STOP_ISO_SETTINGS } from "./equipment/generic-tier-assets.js";
|