[js/webgpu] generate operator table for webgpu (#15954)

### Description
[js/webgpu] generate operator table for webgpu
This commit is contained in:
Yulong Wang 2023-05-20 12:20:41 -07:00 committed by GitHub
parent 18f17c555d
commit e9e6bedf37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 161 additions and 3 deletions

View file

@ -50,7 +50,10 @@ ONNX Runtime Web currently support all operators in [ai.onnx](https://github.com
#### WebGL backend
ONNX Runtime Web currently supports a subset of operators in [ai.onnx](https://github.com/onnx/onnx/blob/main/docs/Operators.md) operator set. See [operators.md](./docs/operators.md) for a complete, detailed list of which ONNX operators are supported by WebGL backend.
ONNX Runtime Web currently supports a subset of operators in [ai.onnx](https://github.com/onnx/onnx/blob/main/docs/Operators.md) operator set. See [webgl-operators.md](./docs/webgl-operators.md) for a complete, detailed list of which ONNX operators are supported by WebGL backend.
#### WebGPU backend
WebGPU backend is still an experimental feature. See [webgpu-operators.md](./docs/webgpu-operators.md) for a detailed list of which ONNX operators are supported by WebGPU backend.
## License

View file

@ -0,0 +1,54 @@
## Operators Support Table
The following table shows ONNX
operators and the supported opset domain/versions in WebGPU EP by ONNX Runtime Web. For example,
`4-6, 8+` means ONNX Runtime Web currently support opset version 4 to 6, 8 and above.
*This file is automatically generated from the
def files via [this script](../script/generate-webgpu-operator-md.ts).
Do not modify directly.*
| Operator | Opset | Comments |
|:--------:|:-------------:|-----|
| Abs | ai.onnx(6-12,13+) | |
| Acos | ai.onnx(7+) | |
| Acosh | ai.onnx(9+) | |
| Add | ai.onnx(7-12,13,14+) | |
| Asin | ai.onnx(7+) | |
| Asinh | ai.onnx(9+) | |
| Atan | ai.onnx(7+) | |
| Atanh | ai.onnx(9+) | |
| AveragePool | ai.onnx(7-9,10,11+); com.ms.internal.nhwc(11+) | need perf optimization; need implementing activation |
| Ceil | ai.onnx(6-12,13+) | |
| Clip | ai.onnx(6-10,11,12,13+) | |
| Conv | ai.onnx(1-10,11+); com.ms.internal.nhwc(11+) | need perf optimization; conv3d not supported; need implementing activation |
| Cos | ai.onnx(7+) | |
| Cosh | ai.onnx(9+) | |
| Div | ai.onnx(7-12,13,14+) | |
| Elu | ai.onnx(6+) | |
| Erf | ai.onnx(9-12,13+) | |
| Exp | ai.onnx(6-12,13+) | |
| Floor | ai.onnx(6-12,13+) | |
| Gemm | ai.onnx(7-8,9-10,11+) | |
| GlobalAveragePool | ai.onnx(1+); com.ms.internal.nhwc(1+) | |
| GlobalMaxPool | ai.onnx(1+); com.ms.internal.nhwc(1+) | |
| LeakyRelu | ai.onnx(6-15,16+) | |
| MatMul | ai.onnx(1-12,13+) | |
| MaxPool | ai.onnx(1-7,8-9,10,11,12+); com.ms.internal.nhwc(11,12+) | need perf optimization; need implementing activation |
| MemcpyFromHost | ai.onnx(1+) | |
| MemcpyToHost | ai.onnx(1+) | |
| Mul | ai.onnx(7-12,13,14+) | |
| Neg | ai.onnx(6-12,13+) | |
| Pow | ai.onnx(7-11,12,13-14,15+) | |
| Reciprocal | ai.onnx(6-12,13+) | |
| Relu | ai.onnx(6-12,13,14+) | |
| Reshape | ai.onnx(5-12,13,14+) | no GPU kernel |
| Shape | ai.onnx(1-12,13-14,15+) | no GPU kernel; an ORT warning is generated - need to fix |
| Sigmoid | ai.onnx(6-12,13+) | |
| Sin | ai.onnx(7+) | |
| Sinh | ai.onnx(9+) | |
| Sqrt | ai.onnx(6-12,13+) | |
| Sub | ai.onnx(7-12,13,14+) | |
| Tan | ai.onnx(7+) | |
| ThresholdedRelu | ai.onnx(10+) | |
| Transpose | ai.onnx(1-12,13+) | need perf optimization |

View file

@ -20,7 +20,7 @@
},
"scripts": {
"prepare": "tsc",
"build:doc": "node ./script/generate-operator-md",
"build:doc": "node ./script/generate-webgl-operator-md && node ./script/generate-webgpu-operator-md",
"pull:wasm": "node ./script/pull-prebuilt-wasm-artifacts",
"test:e2e": "node ./test/e2e/run",
"build": "node ./script/build",

View file

@ -71,7 +71,7 @@ assert.ok(opsets.length === 1 && opsets[0] === 'Onnx');
const onnxOpset = ops.get(opsets[0])!;
const opTypes = Array.from(onnxOpset.keys()).sort();
const doc = fs.createWriteStream(path.join(__dirname, '../docs/operators.md'));
const doc = fs.createWriteStream(path.join(__dirname, '../docs/webgl-operators.md'));
doc.write(`## Operators Support Table${EOL}${EOL}`);
doc.write(`The following table shows [ai.onnx](https://github.com/onnx/onnx/blob/main/docs/Operators.md)\
operators from which onnx opset version are currently supported by ONNX Runtime Web. For example, \`4-6, 8+\` means\

View file

@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import fs from 'fs';
import {EOL} from 'os';
import path from 'path';
// The following variable allows to insert comments per operator
const COMMENTS: Record<string, string> = {
'AveragePool': 'need perf optimization; need implementing activation',
'MaxPool': 'need perf optimization; need implementing activation',
'Conv': 'need perf optimization; conv3d not supported; need implementing activation',
'Transpose': 'need perf optimization',
'Reshape': 'no GPU kernel',
'Shape': 'no GPU kernel; an ORT warning is generated - need to fix',
};
/* eslint-disable max-len */
const MATCHERS = [
/class ONNX_OPERATOR_VERSIONED_KERNEL_CLASS_NAME\(\s*(?<ep>\w+),\s*(?<opsetDomain>\w+),\s*(?<opsetVersionStart>\d+),\s*(?<opsetVersionEnd>\d+),\s*(?<op>\w+)\)/g,
/class ONNX_OPERATOR_KERNEL_CLASS_NAME\(\s*(?<ep>\w+),\s*(?<opsetDomain>\w+),\s*(?<opsetVersion>\d+),\s*(?<op>\w+)\)/g,
/class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME\(\s*(?<ep>\w+),\s*(?<opsetDomain>\w+),\s*(?<opsetVersionStart>\d+),\s*(?<opsetVersionEnd>\d+),\s*(?<type>\w+),\s*(?<op>\w+)\)/g,
/class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME\(\s*(?<ep>\w+),\s*(?<opsetDomain>\w+),\s*(?<opsetVersion>\d+),\s*(?<type>\w+),\s*(?<op>\w+)\)/g,
];
/* eslint-enable max-len */
const ALL_REGISTERED_OPERATORS: Map < string, {
opset: Map<string, Array<[number, number | undefined]>>;
comments: string;
}
> = new Map();
// parse js_execution_provider.cc
const JS_EXECUTION_PROVIDER_CONTENTS =
fs.readFileSync(path.join(__dirname, '../../../onnxruntime/core/providers/js/js_execution_provider.cc'), 'utf8');
MATCHERS.forEach(m => {
for (const match of JS_EXECUTION_PROVIDER_CONTENTS.matchAll(m)) {
const groups = match.groups!;
const {ep, opsetDomain, opsetVersion, opsetVersionStart, opsetVersionEnd, op} = groups;
if (ep !== 'kJsExecutionProvider') {
throw new Error(`invalid EP registration for EP name: ${ep}`);
}
let domain = '';
switch (opsetDomain) {
case 'kOnnxDomain':
domain = 'ai.onnx';
break;
case 'kMSInternalNHWCDomain':
domain = 'com.ms.internal.nhwc';
break;
default:
throw new Error(`not supported domain: ${opsetDomain}`);
}
let opInfo = ALL_REGISTERED_OPERATORS.get(op);
if (!opInfo) {
opInfo = {opset: new Map(), comments: COMMENTS[op]};
ALL_REGISTERED_OPERATORS.set(op, opInfo);
}
const {opset} = opInfo;
let currentDomainInfo = opset.get(domain);
if (!currentDomainInfo) {
currentDomainInfo = [];
opset.set(domain, currentDomainInfo);
}
if (opsetVersion) {
currentDomainInfo.push([parseInt(opsetVersion, 10), undefined]);
} else {
currentDomainInfo.push([parseInt(opsetVersionStart, 10), parseInt(opsetVersionEnd, 10)]);
}
currentDomainInfo.sort((a, b) => a[0] - b[0]);
}
});
const doc = fs.createWriteStream(path.join(__dirname, '../docs/webgpu-operators.md'));
doc.write(`## Operators Support Table${EOL}${EOL}`);
doc.write(`The following table shows ONNX
operators and the supported opset domain/versions in WebGPU EP by ONNX Runtime Web. For example,
\`4-6, 8+\` means ONNX Runtime Web currently support opset version 4 to 6, 8 and above.${EOL}${EOL}`);
doc.write(`*This file is automatically generated from the
def files via [this script](../script/generate-webgpu-operator-md.ts).
Do not modify directly.*${EOL}${EOL}`);
doc.write(`| Operator | Opset | Comments |${EOL}`);
doc.write(`|:--------:|:-------------:|-----|${EOL}`);
Array.from(ALL_REGISTERED_OPERATORS.keys()).sort().forEach(op => {
const {opset, comments} = ALL_REGISTERED_OPERATORS.get(op)!;
const opsetString =
Array.from(opset.keys())
.sort()
.map(
domain => `${domain}(${
opset.get(domain)!
.map(ver => ver[1] ? (ver[0] === ver[1] ? `${ver[0]}` : `${ver[0]}-${ver[1]}`) : `${ver[0]}+`)
.join(',')})`)
.join('; ');
doc.write(`| ${op} | ${opsetString} | ${comments ?? ''} |${EOL}`);
});
doc.end();