feat: add WebGPU DAS backend
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
import { computeDasMap } from "../acoustics-core/das.js";
|
||||
import { computeDasWebGpu } from "./das.js";
|
||||
import { isRecoverableWebGpuError } from "./device.js";
|
||||
|
||||
function createAbortError(signal) {
|
||||
if (signal?.reason instanceof Error && signal.reason.name === "AbortError") return signal.reason;
|
||||
const error = new Error("DAS 계산이 취소되었습니다.");
|
||||
error.name = "AbortError";
|
||||
return error;
|
||||
}
|
||||
|
||||
function throwIfAborted(signal) {
|
||||
if (signal?.aborted) throw createAbortError(signal);
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the requested DAS backend. `auto` falls back only for typed WebGPU
|
||||
* operational errors; invalid inputs and AbortError remain visible to callers.
|
||||
*/
|
||||
export async function computeDasWithBackend(options, dependencies = {}) {
|
||||
const computeGpu = dependencies.computeGpu ?? computeDasWebGpu;
|
||||
const computeCpu = dependencies.computeCpu ?? computeDasMap;
|
||||
const requestedBackend = options?.experiment?.beamforming?.backend ?? "auto";
|
||||
|
||||
if (requestedBackend === "cpu") return computeCpu(options);
|
||||
if (requestedBackend === "webgpu") return computeGpu(options);
|
||||
if (requestedBackend !== "auto") {
|
||||
throw new TypeError(`지원하지 않는 DAS backend입니다: ${requestedBackend}`);
|
||||
}
|
||||
|
||||
try {
|
||||
return await computeGpu(options);
|
||||
} catch (gpuError) {
|
||||
if (!isRecoverableWebGpuError(gpuError)) throw gpuError;
|
||||
throwIfAborted(options.signal);
|
||||
options.onFallback?.({ from: "webgpu", to: "cpu", error: gpuError });
|
||||
throwIfAborted(options.signal);
|
||||
try {
|
||||
const cpuResult = await computeCpu(options);
|
||||
return {
|
||||
...cpuResult,
|
||||
requestedBackend: "auto",
|
||||
fallback: {
|
||||
from: "webgpu",
|
||||
code: gpuError.code,
|
||||
message: gpuError.message,
|
||||
},
|
||||
};
|
||||
} catch (cpuError) {
|
||||
if (cpuError?.name === "AbortError") throw cpuError;
|
||||
throwIfAborted(options.signal);
|
||||
throw new AggregateError(
|
||||
[gpuError, cpuError],
|
||||
`WebGPU 실행 실패 후 CPU fallback도 실패했습니다: ${cpuError.message}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user