mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-05-31 23:27:43 +00:00
### Description This PR is to update the win-ort-main branch to the tip main branch as of 2025-01-16. ### Motivation and Context This update includes the OpenVino fix for debug builds. --------- Signed-off-by: Liqun Fu <liqfu@microsoft.com> Signed-off-by: Liqun Fu <liqun.fu@microsoft.com> Signed-off-by: Junze Wu <junze.wu@intel.com> Signed-off-by: dependabot[bot] <support@github.com> Signed-off-by: Jianhui Dai <jianhui.j.dai@intel.com> Co-authored-by: Yueqing Zhang <yuz75@Pitt.edu> Co-authored-by: amancini-N <63410090+amancini-N@users.noreply.github.com> Co-authored-by: Adrian Lizarraga <adlizarraga@microsoft.com> Co-authored-by: liqun Fu <liqfu@microsoft.com> Co-authored-by: Guenther Schmuelling <guschmue@microsoft.com> Co-authored-by: Yifan Li <109183385+yf711@users.noreply.github.com> Co-authored-by: yf711 <yifanl@microsoft.com> Co-authored-by: Wanming Lin <wanming.lin@intel.com> Co-authored-by: wejoncy <wejoncy@163.com> Co-authored-by: wejoncy <wejoncy@.com> Co-authored-by: Scott McKay <skottmckay@gmail.com> Co-authored-by: Changming Sun <chasun@microsoft.com> Co-authored-by: Jean-Michaël Celerier <jeanmichael.celerier+github@gmail.com> Co-authored-by: Dmitry Deshevoy <mityada@gmail.com> Co-authored-by: xhcao <xinghua.cao@intel.com> Co-authored-by: Yueqing Zhang <yueqingz@amd.com> Co-authored-by: Yulong Wang <7679871+fs-eire@users.noreply.github.com> Co-authored-by: Jiajia Qin <jiajiaqin@microsoft.com> Co-authored-by: Wu, Junze <junze.wu@intel.com> Co-authored-by: Jian Chen <cjian@microsoft.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Matthieu Darbois <mayeut@users.noreply.github.com> Co-authored-by: Prathik Rao <prathik.rao@gmail.com> Co-authored-by: wonchung-microsoft <wonchung@microsoft.com> Co-authored-by: Vincent Wang <wangwchpku@outlook.com> Co-authored-by: PARK DongHa <luncliff@gmail.com> Co-authored-by: Hector Li <hecli@microsoft.com> Co-authored-by: Sam Webster <13457618+samwebster@users.noreply.github.com> Co-authored-by: Adrian Lizarraga <adrianlm2@gmail.com> Co-authored-by: Preetha Veeramalai <preetha.veeramalai@intel.com> Co-authored-by: jatinwadhwa921 <jatin.wadhwa@intel.com> Co-authored-by: Satya Kumar Jandhyala <satya.k.jandhyala@gmail.com> Co-authored-by: Corentin Maravat <101636442+cocotdf@users.noreply.github.com> Co-authored-by: Xiaoyu <85524621+xiaoyu-work@users.noreply.github.com> Co-authored-by: Tianlei Wu <tlwu@microsoft.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Jie Chen <jie.a.chen@intel.com> Co-authored-by: Jianhui Dai <jianhui.j.dai@intel.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com> Co-authored-by: Baiju Meswani <bmeswani@microsoft.com> Co-authored-by: kunal-vaishnavi <115581922+kunal-vaishnavi@users.noreply.github.com> Co-authored-by: Justin Chu <justinchuby@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Ted Themistokleous <107195283+TedThemistokleous@users.noreply.github.com> Co-authored-by: Jeff Daily <jeff.daily@amd.com> Co-authored-by: Artur Wojcik <artur.wojcik@outlook.com> Co-authored-by: Ted Themistokleous <tedthemistokleous@amd.com> Co-authored-by: Xinya Zhang <Xinya.Zhang@amd.com> Co-authored-by: ikalinic <ilija.kalinic@amd.com> Co-authored-by: sstamenk <sstamenk@amd.com> Co-authored-by: Yi-Hong Lyu <yilyu@microsoft.com> Co-authored-by: Ti-Tai Wang <titaiwang@microsoft.com>
262 lines
9.1 KiB
TypeScript
262 lines
9.1 KiB
TypeScript
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
import { env, InferenceSession } from 'onnxruntime-common';
|
|
|
|
import {
|
|
OrtWasmMessage,
|
|
SerializableInternalBuffer,
|
|
SerializableSessionMetadata,
|
|
SerializableTensorMetadata,
|
|
TensorMetadata,
|
|
} from './proxy-messages';
|
|
import * as core from './wasm-core-impl';
|
|
import { initializeWebAssembly } from './wasm-factory';
|
|
import { importProxyWorker, inferWasmPathPrefixFromScriptSrc } from './wasm-utils-import';
|
|
|
|
const isProxy = (): boolean => !!env.wasm.proxy && typeof document !== 'undefined';
|
|
let proxyWorker: Worker | undefined;
|
|
let initializing = false;
|
|
let initialized = false;
|
|
let aborted = false;
|
|
let temporaryObjectUrl: string | undefined;
|
|
|
|
type PromiseCallbacks<T = void> = [resolve: (result: T) => void, reject: (reason: unknown) => void];
|
|
let initWasmCallbacks: PromiseCallbacks;
|
|
const queuedCallbacks: Map<OrtWasmMessage['type'], Array<PromiseCallbacks<unknown>>> = new Map();
|
|
|
|
const enqueueCallbacks = (type: OrtWasmMessage['type'], callbacks: PromiseCallbacks<unknown>): void => {
|
|
const queue = queuedCallbacks.get(type);
|
|
if (queue) {
|
|
queue.push(callbacks);
|
|
} else {
|
|
queuedCallbacks.set(type, [callbacks]);
|
|
}
|
|
};
|
|
|
|
const ensureWorker = (): void => {
|
|
if (initializing || !initialized || aborted || !proxyWorker) {
|
|
throw new Error('worker not ready');
|
|
}
|
|
};
|
|
|
|
const onProxyWorkerMessage = (ev: MessageEvent<OrtWasmMessage>): void => {
|
|
switch (ev.data.type) {
|
|
case 'init-wasm':
|
|
initializing = false;
|
|
if (ev.data.err) {
|
|
aborted = true;
|
|
initWasmCallbacks[1](ev.data.err);
|
|
} else {
|
|
initialized = true;
|
|
initWasmCallbacks[0]();
|
|
}
|
|
if (temporaryObjectUrl) {
|
|
URL.revokeObjectURL(temporaryObjectUrl);
|
|
temporaryObjectUrl = undefined;
|
|
}
|
|
break;
|
|
case 'init-ep':
|
|
case 'copy-from':
|
|
case 'create':
|
|
case 'release':
|
|
case 'run':
|
|
case 'end-profiling': {
|
|
const callbacks = queuedCallbacks.get(ev.data.type)!;
|
|
if (ev.data.err) {
|
|
callbacks.shift();
|
|
} else {
|
|
callbacks.shift();
|
|
}
|
|
break;
|
|
}
|
|
default:
|
|
}
|
|
};
|
|
|
|
export const initializeWebAssemblyAndOrtRuntime = async (): Promise<void> => {
|
|
if (initialized) {
|
|
return;
|
|
}
|
|
if (initializing) {
|
|
throw new Error("multiple calls to 'initWasm()' detected.");
|
|
}
|
|
if (aborted) {
|
|
throw new Error("previous call to 'initWasm()' failed.");
|
|
}
|
|
|
|
initializing = true;
|
|
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
return new Promise<void>((resolve, reject) => {
|
|
proxyWorker?.terminate();
|
|
|
|
void importProxyWorker().then(([objectUrl, worker]) => {
|
|
try {
|
|
proxyWorker = worker;
|
|
proxyWorker.onerror = (ev: ErrorEvent) => reject(ev);
|
|
proxyWorker.onmessage = onProxyWorkerMessage;
|
|
initWasmCallbacks = [resolve, reject];
|
|
const message: OrtWasmMessage = { type: 'init-wasm', in: env };
|
|
|
|
// if the proxy worker is loaded from a blob URL, we need to make sure the path information is not lost.
|
|
//
|
|
// when `env.wasm.wasmPaths` is not set, we need to pass the path information to the worker.
|
|
//
|
|
if (!BUILD_DEFS.ENABLE_BUNDLE_WASM_JS && !message.in!.wasm.wasmPaths && objectUrl) {
|
|
// for a build not bundled the wasm JS, we need to pass the path prefix to the worker.
|
|
// the path prefix will be used to resolve the path to both the wasm JS and the wasm file.
|
|
const inferredWasmPathPrefix = inferWasmPathPrefixFromScriptSrc();
|
|
if (inferredWasmPathPrefix) {
|
|
message.in!.wasm.wasmPaths = inferredWasmPathPrefix;
|
|
}
|
|
}
|
|
|
|
if (
|
|
BUILD_DEFS.IS_ESM &&
|
|
BUILD_DEFS.ENABLE_BUNDLE_WASM_JS &&
|
|
!message.in!.wasm.wasmPaths &&
|
|
(objectUrl || BUILD_DEFS.ESM_IMPORT_META_URL?.startsWith('file:'))
|
|
) {
|
|
// for a build bundled the wasm JS, if either of the following conditions is met:
|
|
// - the proxy worker is loaded from a blob URL
|
|
// - `import.meta.url` is a file URL, it means it is overwriten by the bundler.
|
|
//
|
|
// in either case, the path information is lost, we need to pass the path of the .wasm file to the worker.
|
|
// we need to use the bundler preferred URL format:
|
|
// new URL('filename', import.meta.url)
|
|
// so that the bundler can handle the file using corresponding loaders.
|
|
message.in!.wasm.wasmPaths = {
|
|
wasm: !BUILD_DEFS.DISABLE_JSEP
|
|
? new URL('ort-wasm-simd-threaded.jsep.wasm', BUILD_DEFS.ESM_IMPORT_META_URL).href
|
|
: new URL('ort-wasm-simd-threaded.wasm', BUILD_DEFS.ESM_IMPORT_META_URL).href,
|
|
};
|
|
}
|
|
proxyWorker.postMessage(message);
|
|
temporaryObjectUrl = objectUrl;
|
|
} catch (e) {
|
|
reject(e);
|
|
}
|
|
}, reject);
|
|
});
|
|
} else {
|
|
try {
|
|
await initializeWebAssembly(env.wasm);
|
|
await core.initRuntime(env);
|
|
initialized = true;
|
|
} catch (e) {
|
|
aborted = true;
|
|
throw e;
|
|
} finally {
|
|
initializing = false;
|
|
}
|
|
}
|
|
};
|
|
|
|
export const initializeOrtEp = async (epName: string): Promise<void> => {
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
ensureWorker();
|
|
return new Promise<void>((resolve, reject) => {
|
|
enqueueCallbacks('init-ep', [resolve, reject]);
|
|
const message: OrtWasmMessage = { type: 'init-ep', in: { epName, env } };
|
|
proxyWorker!.postMessage(message);
|
|
});
|
|
} else {
|
|
await core.initEp(env, epName);
|
|
}
|
|
};
|
|
|
|
export const copyFromExternalBuffer = async (buffer: Uint8Array): Promise<SerializableInternalBuffer> => {
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
ensureWorker();
|
|
return new Promise<SerializableInternalBuffer>((resolve, reject) => {
|
|
enqueueCallbacks('copy-from', [resolve, reject]);
|
|
const message: OrtWasmMessage = { type: 'copy-from', in: { buffer } };
|
|
proxyWorker!.postMessage(message, [buffer.buffer]);
|
|
});
|
|
} else {
|
|
return core.copyFromExternalBuffer(buffer);
|
|
}
|
|
};
|
|
|
|
export const createSession = async (
|
|
model: SerializableInternalBuffer | Uint8Array,
|
|
options?: InferenceSession.SessionOptions,
|
|
): Promise<SerializableSessionMetadata> => {
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
// check unsupported options
|
|
if (options?.preferredOutputLocation) {
|
|
throw new Error('session option "preferredOutputLocation" is not supported for proxy.');
|
|
}
|
|
ensureWorker();
|
|
return new Promise<SerializableSessionMetadata>((resolve, reject) => {
|
|
enqueueCallbacks('create', [resolve, reject]);
|
|
const message: OrtWasmMessage = { type: 'create', in: { model, options: { ...options } } };
|
|
const transferable: Transferable[] = [];
|
|
if (model instanceof Uint8Array) {
|
|
transferable.push(model.buffer);
|
|
}
|
|
proxyWorker!.postMessage(message, transferable);
|
|
});
|
|
} else {
|
|
return core.createSession(model, options);
|
|
}
|
|
};
|
|
|
|
export const releaseSession = async (sessionId: number): Promise<void> => {
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
ensureWorker();
|
|
return new Promise<void>((resolve, reject) => {
|
|
enqueueCallbacks('release', [resolve, reject]);
|
|
const message: OrtWasmMessage = { type: 'release', in: sessionId };
|
|
proxyWorker!.postMessage(message);
|
|
});
|
|
} else {
|
|
core.releaseSession(sessionId);
|
|
}
|
|
};
|
|
|
|
export const run = async (
|
|
sessionId: number,
|
|
inputIndices: number[],
|
|
inputs: TensorMetadata[],
|
|
outputIndices: number[],
|
|
outputs: Array<TensorMetadata | null>,
|
|
options: InferenceSession.RunOptions,
|
|
): Promise<TensorMetadata[]> => {
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
// check inputs location
|
|
if (inputs.some((t) => t[3] !== 'cpu')) {
|
|
throw new Error('input tensor on GPU is not supported for proxy.');
|
|
}
|
|
// check outputs location
|
|
if (outputs.some((t) => t)) {
|
|
throw new Error('pre-allocated output tensor is not supported for proxy.');
|
|
}
|
|
ensureWorker();
|
|
return new Promise<SerializableTensorMetadata[]>((resolve, reject) => {
|
|
enqueueCallbacks('run', [resolve, reject]);
|
|
const serializableInputs = inputs as SerializableTensorMetadata[]; // every input is on CPU.
|
|
const message: OrtWasmMessage = {
|
|
type: 'run',
|
|
in: { sessionId, inputIndices, inputs: serializableInputs, outputIndices, options },
|
|
};
|
|
proxyWorker!.postMessage(message, core.extractTransferableBuffers(serializableInputs));
|
|
});
|
|
} else {
|
|
return core.run(sessionId, inputIndices, inputs, outputIndices, outputs, options);
|
|
}
|
|
};
|
|
|
|
export const endProfiling = async (sessionId: number): Promise<void> => {
|
|
if (!BUILD_DEFS.DISABLE_WASM_PROXY && isProxy()) {
|
|
ensureWorker();
|
|
return new Promise<void>((resolve, reject) => {
|
|
enqueueCallbacks('end-profiling', [resolve, reject]);
|
|
const message: OrtWasmMessage = { type: 'end-profiling', in: sessionId };
|
|
proxyWorker!.postMessage(message);
|
|
});
|
|
} else {
|
|
core.endProfiling(sessionId);
|
|
}
|
|
};
|