From e9e6bedf37428e394bf24c2e706e734748e7374c Mon Sep 17 00:00:00 2001 From: Yulong Wang <7679871+fs-eire@users.noreply.github.com> Date: Sat, 20 May 2023 12:20:41 -0700 Subject: [PATCH] [js/webgpu] generate operator table for webgpu (#15954) ### Description [js/webgpu] generate operator table for webgpu --- js/web/README.md | 5 +- .../docs/{operators.md => webgl-operators.md} | 0 js/web/docs/webgpu-operators.md | 54 ++++++++++ js/web/package.json | 2 +- ...or-md.ts => generate-webgl-operator-md.ts} | 2 +- js/web/script/generate-webgpu-operator-md.ts | 101 ++++++++++++++++++ 6 files changed, 161 insertions(+), 3 deletions(-) rename js/web/docs/{operators.md => webgl-operators.md} (100%) create mode 100644 js/web/docs/webgpu-operators.md rename js/web/script/{generate-operator-md.ts => generate-webgl-operator-md.ts} (97%) create mode 100644 js/web/script/generate-webgpu-operator-md.ts diff --git a/js/web/README.md b/js/web/README.md index 9ab9a7dac7..16e4ffd1cd 100644 --- a/js/web/README.md +++ b/js/web/README.md @@ -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 diff --git a/js/web/docs/operators.md b/js/web/docs/webgl-operators.md similarity index 100% rename from js/web/docs/operators.md rename to js/web/docs/webgl-operators.md diff --git a/js/web/docs/webgpu-operators.md b/js/web/docs/webgpu-operators.md new file mode 100644 index 0000000000..3578b76e1f --- /dev/null +++ b/js/web/docs/webgpu-operators.md @@ -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 | diff --git a/js/web/package.json b/js/web/package.json index c7d04227bd..04ff55787a 100644 --- a/js/web/package.json +++ b/js/web/package.json @@ -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", diff --git a/js/web/script/generate-operator-md.ts b/js/web/script/generate-webgl-operator-md.ts similarity index 97% rename from js/web/script/generate-operator-md.ts rename to js/web/script/generate-webgl-operator-md.ts index 0a1d845faf..878a4c9a40 100644 --- a/js/web/script/generate-operator-md.ts +++ b/js/web/script/generate-webgl-operator-md.ts @@ -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\ diff --git a/js/web/script/generate-webgpu-operator-md.ts b/js/web/script/generate-webgpu-operator-md.ts new file mode 100644 index 0000000000..ea77a43a35 --- /dev/null +++ b/js/web/script/generate-webgpu-operator-md.ts @@ -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 = { + '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*(?\w+),\s*(?\w+),\s*(?\d+),\s*(?\d+),\s*(?\w+)\)/g, + /class ONNX_OPERATOR_KERNEL_CLASS_NAME\(\s*(?\w+),\s*(?\w+),\s*(?\d+),\s*(?\w+)\)/g, + /class ONNX_OPERATOR_VERSIONED_TYPED_KERNEL_CLASS_NAME\(\s*(?\w+),\s*(?\w+),\s*(?\d+),\s*(?\d+),\s*(?\w+),\s*(?\w+)\)/g, + /class ONNX_OPERATOR_TYPED_KERNEL_CLASS_NAME\(\s*(?\w+),\s*(?\w+),\s*(?\d+),\s*(?\w+),\s*(?\w+)\)/g, +]; +/* eslint-enable max-len */ + +const ALL_REGISTERED_OPERATORS: Map < string, { + opset: Map>; + 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();