onnxruntime/tools/ci_build/github/azure-pipelines/templates
Yulong Wang 561aca97cf
[js/webgpu] support IO binding (#17480)
<del>
**This PR is based on a few prerequisites PRs. They are listed as
below:**
- #17465
- #17469
- #17470
- #17472
- #17473
- #17484

Please review the current change by only looking at commit
e2e6623e673ec6de55a5c1f8edcbd3a46b535a89 and later.


</del>

### Description

This PR introduces WebGPU IO binding. This new feature allows
onnxruntime-web users to use tensors created from GPU as model
input/output so that a model inferencing can be done without unnecessary
data copy between CPU and GPU for model input/output.

### Examples

An E2E demo/example is being worked on.

Following is some simple demo with code snippet.

Let's first check today how we do:
```js
// STEP.1 - create an inference session:
const mySession = await ort.InferenceSession.create('./my_model.onnx', { executionProviders: ['webgpu'] });

// STEP.2 - create model input: (supposing myImageCpuData is a Float32Array)
const feeds = {
  'input_image:0': new ort.Tensor('float32', myImageCpuData, [1, 224, 224, 3])
};

// STEP.3 - run model
const myResults = await mySession.run(feeds);

// STEP.4 - get output data
const myData = myResults['output_image:0'].data; // Float32Array

```

#### for inputs (GPU tensor):

Now, with IO binding, you can create a tensor from a GPU buffer, and
feed it to the model:
```js
// new STEP.2.A - create model input from a GPU buffer: (supposing myInputGpuBuffer is a `GPUBuffer` object with input data)
const feeds = {
  'input_image:0': ort.Tensor.fromGpuBuffer(myInputGpuBuffer, { dataType: 'float32', dims: [1, 224, 224, 3] })
};
```

### for outputs (pre-allocated GPU tensor)

you can also do that for output, **if you know the output shape**:
```js
// new STEP.2.B - create model output from a GPU buffer: (supposing myOutputGpuBuffer is a pre-allocated `GPUBuffer` object)
const fetches = {
  'output_image:0': ort.Tensor.fromGpuBuffer(myOutputGpuBuffer, { dataType: 'float32', dims: [1, 512, 512, 3] })
};

// new STEP.3 - run model with pre-allocated output (fetches)
const myResults = await mySession.run(feeds, fetches);
```

### for outputs (specify location)

if you do not know the output shape, you can specify the output location
when creating the session:

```js
// new STEP.1 - create an inference session with an option "preferredOutputLocation":
const mySession = await ort.InferenceSession.create('./my_model.onnx', {
    executionProviders: ['webgpu'],
    preferredOutputLocation: "gpu-buffer"
});
```

if the model has multiple outputs, you can specify them seperately:
```js
// new STEP.1 - create an inference session with an option "preferredOutputLocation":
const mySession = await ort.InferenceSession.create('./my_model.onnx', {
    executionProviders: ['webgpu'],
    preferredOutputLocation: {
         "output_image:0": "gpu-buffer"
    }
});
```

now you don't need to prepare the `fetches` object and onnxruntime-web
will prepare output data on the location that specified.

#### read data

when you get the output tensor, you can:
```js
// get the gpu buffer object:
const gpuBuffer = myOutputTensor.gpuBuffer; // GPUBuffer

// get the CPU data asynchronizely
const cpuData = await myOutputTensor.getData();

// get the CPU data asynchronizely and release the underlying GPU resources
const cpuData = await myOutputTensor.getData(true);

// dispose the tensor (release the underlying GPU resources). This tensor object will be invalid after dispose() is called.
myOutputTensor.dispose();
```

#### resource management

JavaScript has GC so you don't need to worry about managing JavaScript
objects. But there are 2 types of resources that are not managed by GC:
- GPU buffer that used in tensors
- Underlying ORT native resources

To simplify, most of the unmanaged resources and handled inside ORT web.
But there are a few resources that need users to manage:
- All external GPU resources, including GPU buffers inside all tensors
created by `Tensor.fromGpuBuffer()`, will not be managed by ORT. User
should manage those GPU buffers themselves.
- When a session is created with `preferredOutputLocation` ==
"gpu-buffer" specified in session options, and the corresponding output
is not pre-allocated, user need to call the output tensor's `dispose()`
or `getData(true)` to manually release the underlying GPU buffers.
- ORT internal errors (including providing a pre-allocated output tensor
with wrong type/dims) will invalidate the whole wasm memory and is not
recoverable. An exception is thrown in this situation.
2023-09-29 11:24:42 -07:00
..
jobs Update onnx python package and setuptools (#17709) 2023-09-27 07:54:48 -07:00
stages Use name of temporary provisioning profile. (#17459) 2023-09-12 10:56:35 -07:00
android-binary-size-check-stage.yml Upgrade Centos7 to Alamlinux8 (#16907) 2023-08-29 21:05:36 -07:00
android-dump-logs-from-steps.yml
android-java-api-aar-test.yml
android-java-api-aar.yml Upgrade Centos7 to Alamlinux8 (#16907) 2023-08-29 21:05:36 -07:00
build-linux-wasm-step.yml
c-api-artifacts-package-and-publish-steps-posix.yml
c-api-artifacts-package-and-publish-steps-windows.yml
c-api-cpu.yml Revert the yaml file changes in "Nodejs_Packaging_CPU" build job (#17441) 2023-09-06 20:20:55 -07:00
c-api-linux-cpu.yml Remove dnf update from docker build scripts (#17551) 2023-09-21 07:33:29 -07:00
check-cache-stats.yml
clean-agent-build-directory-step.yml Build nuget pkg for ROCm (#16791) 2023-08-28 13:35:08 +08:00
common-variables.yml Update cmake to 3.27 and upgrade Linux CUDA docker files from CentOS7 to UBI8 (#16856) 2023-09-05 18:12:10 -07:00
compliance.yml Delete all Prefast tasks (#17522) 2023-09-12 17:40:49 -07:00
component-governance-component-detection-steps.yml
download-deps.yml ONNX 1.15 integration (#17125) 2023-09-26 14:44:48 -07:00
esrp_nuget.yml
explicitly-defined-final-tasks.yml
flex-downloadPipelineArtifact.yml Run Final_Jar_Testing_Linux_GPU in docker (#17533) 2023-09-15 08:35:55 -07:00
get-docker-image-steps.yml
install-appcenter.yml
java-api-artifacts-package-and-publish-steps-posix.yml
linux-build-step-with-cache.yml
linux-ci.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
linux-cpu-packaging-pipeline.yml Update cmake to 3.27 and upgrade Linux CUDA docker files from CentOS7 to UBI8 (#16856) 2023-09-05 18:12:10 -07:00
linux-gpu-tensorrt-packaging-pipeline.yml Update cmake to 3.27 and upgrade Linux CUDA docker files from CentOS7 to UBI8 (#16856) 2023-09-05 18:12:10 -07:00
linux-wasm-ci.yml Update linux-wasm-ci.yml: remove the ln command (#17735) 2023-09-28 21:43:29 -07:00
linux-web-init-and-check.yml
mac-build-step-with-cache.yml
mac-cpu-packaging-pipeline.yml
mac-cpu-packaging-steps.yml
mac-cpu-packing-jobs.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
mac-esrp-dylib.yml
nodejs-artifacts-package-and-publish-steps-posix.yml
nodejs-artifacts-package-and-publish-steps-windows.yml
ondevice-training-cpu-packaging-pipeline.yml
orttraining-linux-gpu-test-ci-pipeline.yml Updates to training pipelines (#17292) 2023-09-08 11:57:12 -07:00
publish-nuget.yml Build nuget pkg for ROCm (#16791) 2023-08-28 13:35:08 +08:00
py-linux-gpu.yml Update cmake to 3.27 and upgrade Linux CUDA docker files from CentOS7 to UBI8 (#16856) 2023-09-05 18:12:10 -07:00
py-linux.yml Update cmake to 3.27 and upgrade Linux CUDA docker files from CentOS7 to UBI8 (#16856) 2023-09-05 18:12:10 -07:00
py-package-smoking-test.yml Remove dnf update from docker build scripts (#17551) 2023-09-21 07:33:29 -07:00
py-packaging-linux-test-cpu.yml Remove dnf update from docker build scripts (#17551) 2023-09-21 07:33:29 -07:00
py-packaging-linux-test-cuda.yml Remove dnf update from docker build scripts (#17551) 2023-09-21 07:33:29 -07:00
py-packaging-selectable-stage.yml
py-packaging-stage.yml Delete all Prefast tasks (#17522) 2023-09-12 17:40:49 -07:00
py-packaging-training-cuda-stage.yml Update cmake to 3.27 and upgrade Linux CUDA docker files from CentOS7 to UBI8 (#16856) 2023-09-05 18:12:10 -07:00
py-win-gpu.yml Delete all Prefast tasks (#17522) 2023-09-12 17:40:49 -07:00
react-native-ci.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
rocm.yml [ROCm] Remove ROCm5.4.2, ROCm 5.5 and add ROCm5.7 to python package pipeline (#17668) 2023-09-25 10:35:28 +08:00
run-docker-build-steps.yml
set-nightly-build-option-variable-step.yml
set-python-manylinux-variables-step.yml
set-version-number-variables-step.yml
telemetry-steps.yml
upload-code-coverage-data.yml
use-android-ndk.yml
use-xcode-version.yml
validate-package.yml
web-browserstack-ci.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
web-ci.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
win-ci.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
win-esrp-dll.yml
win-wasm-ci.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
win-web-ci.yml [js/webgpu] support IO binding (#17480) 2023-09-29 11:24:42 -07:00
win-web-multi-browsers.yml Update nodejs to 18.x (#17657) 2023-09-25 14:12:11 -07:00
with-container-registry-steps.yml