# WebGPU Plugin EP — NuGet Packaging

This directory contains the C# NuGet package project and test app for the WebGPU plugin Execution Provider.

## Directory Structure

```
csharp/
├── pack_nuget.py                                   # Helper script to build the NuGet package
├── Microsoft.ML.OnnxRuntime.EP.WebGpu/
│   ├── Microsoft.ML.OnnxRuntime.EP.WebGpu.csproj   # NuGet package project (netstandard2.0)
│   ├── WebGpuEp.cs                                 # Helper class for native library resolution
│   └── README.md                                   # Package readme (shipped inside .nupkg)
└── test/
    └── WebGpuEpNuGetTest/
        ├── WebGpuEpNuGetTest.csproj                # Test console app (net8.0)
        ├── Program.cs                              # Registers EP, runs inference, validates output
        ├── mul.onnx                                # Test model (element-wise multiply)
        └── generate_mul_model.py                   # Script to regenerate mul.onnx
```

## Prerequisites

- .NET SDK 8.0 or later
- A built WebGPU plugin EP shared library

## Building the NuGet Package

Use `pack_nuget.py` to stage native binaries and run `dotnet pack`. The script copies everything into a staging
directory before building — the source tree is never modified. By default, an auto-cleaned temporary directory is used;
pass `--staging-dir` to use an explicit one (required when running with `--build-only` or `--pack-only`).

At least one binary directory (or `--artifacts-dir` with matching subdirectories) must be provided. Platforms without
a binary directory are skipped. Run `python pack_nuget.py --help` for the full list of options and their defaults.

### Pack with a local build (single platform)

```powershell
cd plugin-ep-webgpu/csharp

python pack_nuget.py --version 0.1.0-dev `
  --binary-dir-win-x64 <path-to-win-x64-binaries>
```

### Pack multiple platforms

Each `--binary-dir-*` points at the directory containing that platform's already-built native binaries. In practice
the four binaries are produced on different machines and combined in CI; locally you'd typically only set the one(s)
you have available.

```powershell
python pack_nuget.py --version 0.1.0-dev `
  --binary-dir-win-x64 <path-to-win-x64-binaries> `
  --binary-dir-win-arm64 <path-to-win-arm64-binaries> `
  --binary-dir-linux-x64 <path-to-linux-x64-binaries> `
  --binary-dir-macos-arm64 <path-to-macos-arm64-binaries>
```

## Versioning

The package version is supplied to `pack_nuget.py` via `--version`. In the packaging pipeline, the release or
pre-release version is derived from [`plugin-ep-webgpu/VERSION_NUMBER`](../VERSION_NUMBER).

## Testing the Package

The test app registers the WebGPU EP, creates a session, runs a simple Mul model, and validates the output.

```powershell
# Point the test project's nuget.config at the pack output
$localFeed = (Resolve-Path nuget_output).Path
@"
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <packageSources>
    <clear />
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
    <add key="local" value="$localFeed" />
  </packageSources>
</configuration>
"@ | Set-Content test/WebGpuEpNuGetTest/nuget.config

# Build and run
dotnet run --project test/WebGpuEpNuGetTest/WebGpuEpNuGetTest.csproj --configuration Release
```

A successful run prints `PASSED: All outputs match expected values.` and exits with code 0.

## Regenerating the Test Model

```bash
python test/WebGpuEpNuGetTest/generate_mul_model.py
```

Requires the `onnx` Python package.

## CI Pipeline

The NuGet packaging is integrated into the WebGPU plugin pipeline:

- **Pipeline:** `tools/ci_build/github/azure-pipelines/plugin-webgpu-pipeline.yml`
- **Packaging stage:** `tools/ci_build/github/azure-pipelines/stages/plugin-webgpu-nuget-packaging-stage.yml`

The CI stage downloads build artifacts from all enabled platform stages, invokes `pack_nuget.py`, ESRP-signs the
package, and runs the test app on a GPU agent.

## Native Binaries Per Platform

| RID | Required Files |
|---|---|
| `win-x64` | `onnxruntime_providers_webgpu.dll`, `dxil.dll`, `dxcompiler.dll` |
| `win-arm64` | `onnxruntime_providers_webgpu.dll`, `dxil.dll`, `dxcompiler.dll` |
| `linux-x64` | `libonnxruntime_providers_webgpu.so` |
| `osx-arm64` | `libonnxruntime_providers_webgpu.dylib` |

On Windows, `dxil.dll` and `dxcompiler.dll` are the DirectX Shader Compiler binaries downloaded from the
[DXC GitHub releases](https://github.com/microsoft/DirectXShaderCompiler/releases). The CI pipeline handles this
automatically.
