e904b667c6
Build/Publish Develop Docs / deploy (push) Failing after 1s
PaddleOCR Code Style Check / check-code-style (push) Failing after 1s
PaddleOCR PR Tests GPU / detect-changes (push) Failing after 1s
PaddleOCR PR Tests / detect-changes (push) Failing after 1s
PaddleOCR PR Tests GPU / test-pr-gpu (push) Has been cancelled
PaddleOCR PR Tests / test-pr (push) Has been cancelled
PaddleOCR PR Tests GPU / test-pr-gpu-impl (push) Has been cancelled
PaddleOCR PR Tests / test-pr-python (3.13) (push) Has been cancelled
PaddleOCR PR Tests / test-pr-python (3.8) (push) Has been cancelled
PaddleOCR PR Tests / test-pr-python (3.9) (push) Has been cancelled
175 lines
5.3 KiB
TypeScript
175 lines
5.3 KiB
TypeScript
import { afterEach, describe, expect, it, vi } from "vitest";
|
|
|
|
async function loadOrtModule(mockedOrt = { env: { wasm: {} } }) {
|
|
vi.resetModules();
|
|
vi.doMock("onnxruntime-web", () => ({
|
|
__esModule: true,
|
|
...mockedOrt
|
|
}));
|
|
return import("../src/runtime/ort");
|
|
}
|
|
|
|
afterEach(() => {
|
|
vi.resetModules();
|
|
vi.doUnmock("onnxruntime-web");
|
|
vi.unstubAllGlobals();
|
|
});
|
|
|
|
describe("runtime/ort", () => {
|
|
it("reports when WebGPU is unavailable", async () => {
|
|
vi.stubGlobal("navigator", {});
|
|
const { detectWebGpuAvailability } = await loadOrtModule();
|
|
|
|
await expect(detectWebGpuAvailability()).resolves.toEqual({
|
|
available: false,
|
|
reason: "navigator.gpu is unavailable in this browser."
|
|
});
|
|
});
|
|
|
|
it("reports WebGPU available when the browser returns an adapter", async () => {
|
|
vi.stubGlobal("navigator", {
|
|
gpu: {
|
|
requestAdapter: vi.fn().mockResolvedValue({})
|
|
}
|
|
});
|
|
const { detectWebGpuAvailability } = await loadOrtModule();
|
|
await expect(detectWebGpuAvailability()).resolves.toEqual({
|
|
available: true,
|
|
reason: ""
|
|
});
|
|
});
|
|
|
|
it("reports WebGPU unavailable when the browser returns no adapter", async () => {
|
|
vi.stubGlobal("navigator", {
|
|
gpu: {
|
|
requestAdapter: vi.fn().mockResolvedValue(null)
|
|
}
|
|
});
|
|
const { detectWebGpuAvailability } = await loadOrtModule();
|
|
await expect(detectWebGpuAvailability()).resolves.toEqual({
|
|
available: false,
|
|
reason: "The browser did not return a WebGPU adapter."
|
|
});
|
|
});
|
|
|
|
it("reports WebGPU unavailable when adapter lookup throws", async () => {
|
|
vi.stubGlobal("navigator", {
|
|
gpu: {
|
|
requestAdapter: vi.fn().mockRejectedValue(new Error("GPU blocked"))
|
|
}
|
|
});
|
|
const { detectWebGpuAvailability } = await loadOrtModule();
|
|
await expect(detectWebGpuAvailability()).resolves.toEqual({
|
|
available: false,
|
|
reason: "GPU blocked"
|
|
});
|
|
});
|
|
|
|
it("selects provider candidates from backend preference and WebGPU availability", async () => {
|
|
const { getProviderCandidates } = await loadOrtModule();
|
|
|
|
expect(getProviderCandidates("webgpu", { available: true, reason: "" })).toEqual([["webgpu"]]);
|
|
expect(getProviderCandidates("wasm", { available: false, reason: "n/a" })).toEqual([["wasm"]]);
|
|
expect(getProviderCandidates("auto", { available: true, reason: "" })).toEqual([
|
|
["webgpu"],
|
|
["wasm"]
|
|
]);
|
|
expect(getProviderCandidates("auto", { available: false, reason: "n/a" })).toEqual([["wasm"]]);
|
|
expect(() => getProviderCandidates("webgpu", { available: false, reason: "missing" })).toThrow(
|
|
/WebGPU is unavailable: missing/
|
|
);
|
|
});
|
|
|
|
it("initializes ORT runtime and applies wasm environment options", async () => {
|
|
vi.stubGlobal("navigator", {});
|
|
const mockedOrt = {
|
|
env: {
|
|
wasm: {}
|
|
}
|
|
};
|
|
const { initOrtRuntime } = await loadOrtModule(mockedOrt);
|
|
|
|
const runtime = await initOrtRuntime({
|
|
wasmPaths: "/wasm/",
|
|
numThreads: 2,
|
|
simd: true,
|
|
proxy: true,
|
|
disableWasmProxy: true
|
|
});
|
|
|
|
expect(runtime.backend).toBe("auto");
|
|
expect(runtime.webgpuState.available).toBe(false);
|
|
expect(runtime.ort.env.wasm).toEqual({
|
|
wasmPaths: "/wasm/",
|
|
numThreads: 2,
|
|
simd: true,
|
|
proxy: false
|
|
});
|
|
expect(mockedOrt.env.wasm).toEqual({
|
|
wasmPaths: "/wasm/",
|
|
numThreads: 2,
|
|
simd: true,
|
|
proxy: false
|
|
});
|
|
});
|
|
|
|
it("creates sessions by trying providers in order", async () => {
|
|
const create = vi
|
|
.fn()
|
|
.mockRejectedValueOnce(new Error("webgpu failed"))
|
|
.mockResolvedValueOnce({ id: "session" });
|
|
const mockedOrt = {
|
|
InferenceSession: { create }
|
|
};
|
|
const { createSession } = await loadOrtModule({
|
|
env: { wasm: {} },
|
|
InferenceSession: { create }
|
|
});
|
|
const modelBytes = new Uint8Array([1, 2, 3]);
|
|
|
|
const result = await createSession(mockedOrt, modelBytes, [["webgpu"], ["wasm"]]);
|
|
|
|
expect(create).toHaveBeenNthCalledWith(1, modelBytes, {
|
|
executionProviders: ["webgpu"],
|
|
graphOptimizationLevel: "all"
|
|
});
|
|
expect(create).toHaveBeenNthCalledWith(2, modelBytes, {
|
|
executionProviders: ["wasm"],
|
|
graphOptimizationLevel: "all"
|
|
});
|
|
expect(result).toEqual({
|
|
session: { id: "session" },
|
|
provider: "wasm"
|
|
});
|
|
});
|
|
|
|
it("throws the last session creation error when all providers fail", async () => {
|
|
const create = vi
|
|
.fn()
|
|
.mockRejectedValueOnce(new Error("webgpu failed"))
|
|
.mockRejectedValueOnce(new Error("wasm failed"));
|
|
const mockedOrt = {
|
|
InferenceSession: { create }
|
|
};
|
|
const { createSession } = await loadOrtModule({
|
|
env: { wasm: {} },
|
|
InferenceSession: { create }
|
|
});
|
|
|
|
await expect(
|
|
createSession(mockedOrt, new Uint8Array([1]), [["webgpu"], ["wasm"]])
|
|
).rejects.toThrow("wasm failed");
|
|
});
|
|
|
|
it("releases every session that exposes a release method", async () => {
|
|
const releaseA = vi.fn().mockResolvedValue(undefined);
|
|
const releaseB = vi.fn().mockResolvedValue(undefined);
|
|
const { releaseSessions } = await loadOrtModule();
|
|
|
|
await releaseSessions({ release: releaseA }, null, { release: releaseB }, {});
|
|
|
|
expect(releaseA).toHaveBeenCalledTimes(1);
|
|
expect(releaseB).toHaveBeenCalledTimes(1);
|
|
});
|
|
});
|