mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-21 19:18:55 +00:00
### Description Merge main to WindowsAI ### Motivation and Context <!-- - Why is this change required? What problem does it solve? - If it fixes an open issue, please link to the issue here. --> --------- Signed-off-by: Nash <george.nash@intel.com> Signed-off-by: Yiming Hu <yiming.hu@amd.com> Signed-off-by: Liqun Fu <liqfu@microsoft.com> Co-authored-by: Kaz Nishimura <kazssym@linuxfront.com> Co-authored-by: Tianlei Wu <tlwu@microsoft.com> Co-authored-by: Nat Kershaw (MSFT) <nakersha@microsoft.com> Co-authored-by: Yulong Wang <7679871+fs-eire@users.noreply.github.com> Co-authored-by: Changming Sun <chasun@microsoft.com> Co-authored-by: zesongw <zesong.wang@intel.com> Co-authored-by: Yi Zhang <zhanyi@microsoft.com> Co-authored-by: Dmitri Smirnov <yuslepukhin@users.noreply.github.com> Co-authored-by: Yifan Li <109183385+yf711@users.noreply.github.com> Co-authored-by: simonjub <78098752+simonjub@users.noreply.github.com> Co-authored-by: PeixuanZuo <94887879+PeixuanZuo@users.noreply.github.com> Co-authored-by: Adrian Lizarraga <adlizarraga@microsoft.com> Co-authored-by: Edward Chen <18449977+edgchen1@users.noreply.github.com> Co-authored-by: Arthur Islamov <arthur@islamov.ai> Co-authored-by: Jambay Kinley <jambaykinley@microsoft.com> Co-authored-by: Justin Chu <justinchuby@users.noreply.github.com> Co-authored-by: Wei-Sheng Chin <wschin@outlook.com> Co-authored-by: Bowen Bao <bowbao@microsoft.com> Co-authored-by: Hariharan Seshadri <shariharan91@gmail.com> Co-authored-by: Numfor Tiapo <numsmt2@gmail.com> Co-authored-by: Vincent Wang <wangwchpku@outlook.com> Co-authored-by: Pranav Sharma <prs@microsoft.com> Co-authored-by: George Nash <george.nash@intel.com> Co-authored-by: Abhishek Jindal <abjindal@microsoft.com> Co-authored-by: pengwa <pengwa@microsoft.com> Co-authored-by: Yiming Hu <woinck@users.noreply.github.com> Co-authored-by: Jiajia Qin <jiajia.qin@intel.com> Co-authored-by: Lukas Berbuer <36054362+lukasberbuer@users.noreply.github.com> Co-authored-by: Wanming Lin <wanming.lin@intel.com> Co-authored-by: Xavier Dupré <xadupre@users.noreply.github.com> Co-authored-by: aimilefth <60664743+aimilefth@users.noreply.github.com> Co-authored-by: Baiju Meswani <bmeswani@microsoft.com> Co-authored-by: Adam Pocock <adam.pocock@oracle.com> Co-authored-by: Chi Lo <54722500+chilo-ms@users.noreply.github.com> Co-authored-by: RandySheriffH <48490400+RandySheriffH@users.noreply.github.com> Co-authored-by: Randy Shuai <rashuai@microsoft.com> Co-authored-by: Vadym Stupakov <vadim.stupakov@gmail.com> Co-authored-by: Jian Chen <cjian@microsoft.com> Co-authored-by: Brian Lambert <98757707+brian-pieces@users.noreply.github.com> Co-authored-by: Nicolò Lucchesi <nicolo.lucchesi@gmail.com> Co-authored-by: liqun Fu <liqfu@microsoft.com> Co-authored-by: trajep <trajepl@gmail.com> Co-authored-by: Scott McKay <skottmckay@gmail.com> Co-authored-by: Mustafa Ateş Uzun <mustafauzun0@gmail.com> Co-authored-by: MistEO <mistereo@hotmail.com> Co-authored-by: satyajandhyala <satya.k.jandhyala@gmail.com> Co-authored-by: shaahji <96227573+shaahji@users.noreply.github.com> Co-authored-by: Rachel Guo <35738743+YUNQIUGUO@users.noreply.github.com> Co-authored-by: rachguo <rachguo@rachguos-Mini.attlocal.net> Co-authored-by: Caroline Zhu <wolfivyaura@gmail.com> Co-authored-by: Caroline Zhu <carolinezhu@microsoft.com> Co-authored-by: Guenther Schmuelling <guschmue@microsoft.com> Co-authored-by: xhcao <xinghua.cao@intel.com> Co-authored-by: Ella Charlaix <80481427+echarlaix@users.noreply.github.com> Co-authored-by: Xu Xing <xing.xu@intel.com> Co-authored-by: Hector Li <hecli@microsoft.com> Co-authored-by: Ye Wang <52801275+wangyems@users.noreply.github.com> Co-authored-by: Your Name <you@example.com> Co-authored-by: Benedikt Hilmes <benedikt.hilmes@rwth-aachen.de> Co-authored-by: rachguo <rachguo@rachguos-Mac-mini.local> Co-authored-by: George Wu <jywu@microsoft.com> Co-authored-by: JiCheng <wejoncy@163.com> Co-authored-by: Sheil Kumar <smk2007@gmail.com> Co-authored-by: Sheil Kumar <sheilk@microsoft.com> Co-authored-by: cloudhan <guangyunhan@microsoft.com> Co-authored-by: kyoshisuki <143475866+kyoshisuki@users.noreply.github.com> Co-authored-by: aciddelgado <139922440+aciddelgado@users.noreply.github.com> Co-authored-by: tlwu@microsoft.com <tlwu@a100.crj0ad2y1kku1j4yxl4sj10o4e.gx.internal.cloudapp.net> Co-authored-by: Maximilian Müller <44298237+gedoensmax@users.noreply.github.com> Co-authored-by: Tang, Cheng <souptc@gmail.com> Co-authored-by: Cheng Tang <chenta@microsoft.com@orttrainingdev9.d32nl1ml4oruzj4qz3bqlggovf.px.internal.cloudapp.net> Co-authored-by: Cheng Tang <chenta@microsoft.com> Co-authored-by: Jeff Daily <jeff.daily@amd.com> Co-authored-by: cloudhan <cloudhan@outlook.com> Co-authored-by: Yufeng Li <liyufeng1987@gmail.com> Co-authored-by: Zhang Lei <zhang.huanning@hotmail.com> Co-authored-by: Dwayne Robinson <fdwr@hotmail.com> Co-authored-by: Zhipeng Han <zhipeng.han@outlook.com> Co-authored-by: Thiago Crepaldi <thiago.crepaldi@microsoft.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Patrice Vignola <vignola.patrice@gmail.com> Co-authored-by: kunal-vaishnavi <115581922+kunal-vaishnavi@users.noreply.github.com> Co-authored-by: snadampal <87143774+snadampal@users.noreply.github.com> Co-authored-by: Sumit Agarwal <sumitagarwal330@gmail.com> Co-authored-by: Ashwini Khade <askhade@microsoft.com> Co-authored-by: Yang Gu <yang.gu@intel.com> Co-authored-by: Cheng Tang <chenta@a100.crj0ad2y1kku1j4yxl4sj10o4e.gx.internal.cloudapp.net> Co-authored-by: mindest <30493312+mindest@users.noreply.github.com> Co-authored-by: Scott McKay <Scott.McKay@microsoft.com> Co-authored-by: Xavier Dupre <xadupre@microsoft.com@orttrainingdev9.d32nl1ml4oruzj4qz3bqlggovf.px.internal.cloudapp.net> Co-authored-by: guyang3532 <62738430+guyang3532@users.noreply.github.com> Co-authored-by: Carson M <carson@pyke.io> Co-authored-by: sophies927 <107952697+sophies927@users.noreply.github.com>
217 lines
8.2 KiB
TypeScript
217 lines
8.2 KiB
TypeScript
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
import {resolveBackend} from './backend-impl.js';
|
|
import {InferenceSessionHandler} from './backend.js';
|
|
import {InferenceSession as InferenceSessionInterface} from './inference-session.js';
|
|
import {OnnxValue} from './onnx-value.js';
|
|
import {Tensor} from './tensor.js';
|
|
|
|
type SessionOptions = InferenceSessionInterface.SessionOptions;
|
|
type RunOptions = InferenceSessionInterface.RunOptions;
|
|
type FeedsType = InferenceSessionInterface.FeedsType;
|
|
type FetchesType = InferenceSessionInterface.FetchesType;
|
|
type ReturnType = InferenceSessionInterface.ReturnType;
|
|
|
|
export class InferenceSession implements InferenceSessionInterface {
|
|
private constructor(handler: InferenceSessionHandler) {
|
|
this.handler = handler;
|
|
}
|
|
run(feeds: FeedsType, options?: RunOptions): Promise<ReturnType>;
|
|
run(feeds: FeedsType, fetches: FetchesType, options?: RunOptions): Promise<ReturnType>;
|
|
async run(feeds: FeedsType, arg1?: FetchesType|RunOptions, arg2?: RunOptions): Promise<ReturnType> {
|
|
const fetches: {[name: string]: OnnxValue|null} = {};
|
|
let options: RunOptions = {};
|
|
// check inputs
|
|
if (typeof feeds !== 'object' || feeds === null || feeds instanceof Tensor || Array.isArray(feeds)) {
|
|
throw new TypeError(
|
|
'\'feeds\' must be an object that use input names as keys and OnnxValue as corresponding values.');
|
|
}
|
|
|
|
let isFetchesEmpty = true;
|
|
// determine which override is being used
|
|
if (typeof arg1 === 'object') {
|
|
if (arg1 === null) {
|
|
throw new TypeError('Unexpected argument[1]: cannot be null.');
|
|
}
|
|
if (arg1 instanceof Tensor) {
|
|
throw new TypeError('\'fetches\' cannot be a Tensor');
|
|
}
|
|
|
|
if (Array.isArray(arg1)) {
|
|
if (arg1.length === 0) {
|
|
throw new TypeError('\'fetches\' cannot be an empty array.');
|
|
}
|
|
isFetchesEmpty = false;
|
|
// output names
|
|
for (const name of arg1) {
|
|
if (typeof name !== 'string') {
|
|
throw new TypeError('\'fetches\' must be a string array or an object.');
|
|
}
|
|
if (this.outputNames.indexOf(name) === -1) {
|
|
throw new RangeError(`'fetches' contains invalid output name: ${name}.`);
|
|
}
|
|
fetches[name] = null;
|
|
}
|
|
|
|
if (typeof arg2 === 'object' && arg2 !== null) {
|
|
options = arg2;
|
|
} else if (typeof arg2 !== 'undefined') {
|
|
throw new TypeError('\'options\' must be an object.');
|
|
}
|
|
} else {
|
|
// decide whether arg1 is fetches or options
|
|
// if any output name is present and its value is valid OnnxValue, we consider it fetches
|
|
let isFetches = false;
|
|
const arg1Keys = Object.getOwnPropertyNames(arg1);
|
|
for (const name of this.outputNames) {
|
|
if (arg1Keys.indexOf(name) !== -1) {
|
|
const v = (arg1 as InferenceSessionInterface.NullableOnnxValueMapType)[name];
|
|
if (v === null || v instanceof Tensor) {
|
|
isFetches = true;
|
|
isFetchesEmpty = false;
|
|
fetches[name] = v;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (isFetches) {
|
|
if (typeof arg2 === 'object' && arg2 !== null) {
|
|
options = arg2;
|
|
} else if (typeof arg2 !== 'undefined') {
|
|
throw new TypeError('\'options\' must be an object.');
|
|
}
|
|
} else {
|
|
options = arg1 as RunOptions;
|
|
}
|
|
}
|
|
} else if (typeof arg1 !== 'undefined') {
|
|
throw new TypeError('Unexpected argument[1]: must be \'fetches\' or \'options\'.');
|
|
}
|
|
|
|
// check if all inputs are in feed
|
|
for (const name of this.inputNames) {
|
|
if (typeof feeds[name] === 'undefined') {
|
|
throw new Error(`input '${name}' is missing in 'feeds'.`);
|
|
}
|
|
}
|
|
|
|
// if no fetches is specified, we use the full output names list
|
|
if (isFetchesEmpty) {
|
|
for (const name of this.outputNames) {
|
|
fetches[name] = null;
|
|
}
|
|
}
|
|
|
|
// feeds, fetches and options are prepared
|
|
|
|
const results = await this.handler.run(feeds, fetches, options);
|
|
const returnValue: {[name: string]: OnnxValue} = {};
|
|
for (const key in results) {
|
|
if (Object.hasOwnProperty.call(results, key)) {
|
|
const result = results[key];
|
|
if (result instanceof Tensor) {
|
|
returnValue[key] = result;
|
|
} else {
|
|
returnValue[key] = new Tensor(result.type, result.data, result.dims);
|
|
}
|
|
}
|
|
}
|
|
return returnValue;
|
|
}
|
|
|
|
async release(): Promise<void> {
|
|
return this.handler.dispose();
|
|
}
|
|
|
|
static create(path: string, options?: SessionOptions): Promise<InferenceSessionInterface>;
|
|
static create(buffer: ArrayBufferLike, options?: SessionOptions): Promise<InferenceSessionInterface>;
|
|
static create(buffer: ArrayBufferLike, byteOffset: number, byteLength?: number, options?: SessionOptions):
|
|
Promise<InferenceSessionInterface>;
|
|
static create(buffer: Uint8Array, options?: SessionOptions): Promise<InferenceSessionInterface>;
|
|
static async create(
|
|
arg0: string|ArrayBufferLike|Uint8Array, arg1?: SessionOptions|number, arg2?: number,
|
|
arg3?: SessionOptions): Promise<InferenceSessionInterface> {
|
|
// either load from a file or buffer
|
|
let filePathOrUint8Array: string|Uint8Array;
|
|
let options: SessionOptions = {};
|
|
|
|
if (typeof arg0 === 'string') {
|
|
filePathOrUint8Array = arg0;
|
|
if (typeof arg1 === 'object' && arg1 !== null) {
|
|
options = arg1;
|
|
} else if (typeof arg1 !== 'undefined') {
|
|
throw new TypeError('\'options\' must be an object.');
|
|
}
|
|
} else if (arg0 instanceof Uint8Array) {
|
|
filePathOrUint8Array = arg0;
|
|
if (typeof arg1 === 'object' && arg1 !== null) {
|
|
options = arg1;
|
|
} else if (typeof arg1 !== 'undefined') {
|
|
throw new TypeError('\'options\' must be an object.');
|
|
}
|
|
} else if (
|
|
arg0 instanceof ArrayBuffer ||
|
|
(typeof SharedArrayBuffer !== 'undefined' && arg0 instanceof SharedArrayBuffer)) {
|
|
const buffer = arg0;
|
|
let byteOffset = 0;
|
|
let byteLength = arg0.byteLength;
|
|
if (typeof arg1 === 'object' && arg1 !== null) {
|
|
options = arg1;
|
|
} else if (typeof arg1 === 'number') {
|
|
byteOffset = arg1;
|
|
if (!Number.isSafeInteger(byteOffset)) {
|
|
throw new RangeError('\'byteOffset\' must be an integer.');
|
|
}
|
|
if (byteOffset < 0 || byteOffset >= buffer.byteLength) {
|
|
throw new RangeError(`'byteOffset' is out of range [0, ${buffer.byteLength}).`);
|
|
}
|
|
byteLength = arg0.byteLength - byteOffset;
|
|
if (typeof arg2 === 'number') {
|
|
byteLength = arg2;
|
|
if (!Number.isSafeInteger(byteLength)) {
|
|
throw new RangeError('\'byteLength\' must be an integer.');
|
|
}
|
|
if (byteLength <= 0 || byteOffset + byteLength > buffer.byteLength) {
|
|
throw new RangeError(`'byteLength' is out of range (0, ${buffer.byteLength - byteOffset}].`);
|
|
}
|
|
if (typeof arg3 === 'object' && arg3 !== null) {
|
|
options = arg3;
|
|
} else if (typeof arg3 !== 'undefined') {
|
|
throw new TypeError('\'options\' must be an object.');
|
|
}
|
|
} else if (typeof arg2 !== 'undefined') {
|
|
throw new TypeError('\'byteLength\' must be a number.');
|
|
}
|
|
} else if (typeof arg1 !== 'undefined') {
|
|
throw new TypeError('\'options\' must be an object.');
|
|
}
|
|
filePathOrUint8Array = new Uint8Array(buffer, byteOffset, byteLength);
|
|
} else {
|
|
throw new TypeError('Unexpected argument[0]: must be \'path\' or \'buffer\'.');
|
|
}
|
|
|
|
// get backend hints
|
|
const eps = options.executionProviders || [];
|
|
const backendHints = eps.map(i => typeof i === 'string' ? i : i.name);
|
|
const backend = await resolveBackend(backendHints);
|
|
const handler = await backend.createInferenceSessionHandler(filePathOrUint8Array, options);
|
|
return new InferenceSession(handler);
|
|
}
|
|
|
|
startProfiling(): void {
|
|
this.handler.startProfiling();
|
|
}
|
|
endProfiling(): void {
|
|
this.handler.endProfiling();
|
|
}
|
|
|
|
get inputNames(): readonly string[] {
|
|
return this.handler.inputNames;
|
|
}
|
|
get outputNames(): readonly string[] {
|
|
return this.handler.outputNames;
|
|
}
|
|
|
|
private handler: InferenceSessionHandler;
|
|
}
|