mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-23 19:32:23 +00:00
[js/webgpu] allow specify preferredLayout (#17756)
### Description
Allow WebGPU backend to specify `preferredLayout`. Default is NHWC.
```js
const options = {executionProviders: [{name:'webgpu', preferredLayout: 'NCHW'}]};
sess1 = await ort.InferenceSession.create('./mobilenetv2-12.onnx', options);
```
### Motivation and Context
- implement @qjia7's requirement for an easier way to do performance
comparison between NCHW vs NHWC.
- It's possible that NCHW does better on some models and NHWC on others.
So offer user the capability to switch.
This commit is contained in:
parent
f158f394d6
commit
451c02543a
5 changed files with 40 additions and 5 deletions
|
|
@ -192,6 +192,7 @@ export declare namespace InferenceSession {
|
|||
wasm: WebAssemblyExecutionProviderOption;
|
||||
webgl: WebGLExecutionProviderOption;
|
||||
xnnpack: XnnpackExecutionProviderOption;
|
||||
webgpu: WebGpuExecutionProviderOption;
|
||||
webnn: WebNNExecutionProviderOption;
|
||||
nnapi: NnapiExecutionProviderOption;
|
||||
}
|
||||
|
|
@ -233,6 +234,10 @@ export declare namespace InferenceSession {
|
|||
export interface XnnpackExecutionProviderOption extends ExecutionProviderOption {
|
||||
readonly name: 'xnnpack';
|
||||
}
|
||||
export interface WebGpuExecutionProviderOption extends ExecutionProviderOption {
|
||||
readonly name: 'webgpu';
|
||||
preferredLayout?: 'NCHW'|'NHWC';
|
||||
}
|
||||
export interface WebNNExecutionProviderOption extends ExecutionProviderOption {
|
||||
readonly name: 'webnn';
|
||||
deviceType?: 'cpu'|'gpu';
|
||||
|
|
|
|||
|
|
@ -88,6 +88,21 @@ const setExecutionProviders =
|
|||
break;
|
||||
case 'webgpu':
|
||||
epName = 'JS';
|
||||
if (typeof ep !== 'string') {
|
||||
const webgpuOptions = ep as InferenceSession.WebGpuExecutionProviderOption;
|
||||
if (webgpuOptions?.preferredLayout) {
|
||||
if (webgpuOptions.preferredLayout !== 'NCHW' && webgpuOptions.preferredLayout !== 'NHWC') {
|
||||
throw new Error(`preferredLayout must be either 'NCHW' or 'NHWC': ${webgpuOptions.preferredLayout}`);
|
||||
}
|
||||
const keyDataOffset = allocWasmString('preferredLayout', allocs);
|
||||
const valueDataOffset = allocWasmString(webgpuOptions.preferredLayout, allocs);
|
||||
if (getInstance()._OrtAddSessionConfigEntry(sessionOptionsHandle, keyDataOffset, valueDataOffset) !==
|
||||
0) {
|
||||
checkLastError(
|
||||
`Can't set a session config entry: 'preferredLayout' - ${webgpuOptions.preferredLayout}.`);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'wasm':
|
||||
case 'cpu':
|
||||
|
|
|
|||
|
|
@ -624,7 +624,8 @@ std::unique_ptr<KernelRegistry> RegisterKernels() {
|
|||
using namespace js;
|
||||
|
||||
JsExecutionProvider::JsExecutionProvider(const JsExecutionProviderInfo& info)
|
||||
: IExecutionProvider{kJsExecutionProvider, OrtDevice(OrtDevice::GPU, OrtDevice::MemType::DEFAULT, 0), true} {
|
||||
: IExecutionProvider{kJsExecutionProvider, OrtDevice(OrtDevice::GPU, OrtDevice::MemType::DEFAULT, 0), true},
|
||||
preferred_data_layout_{info.data_layout} {
|
||||
}
|
||||
|
||||
std::vector<AllocatorPtr> JsExecutionProvider::CreatePreferredAllocators() {
|
||||
|
|
|
|||
|
|
@ -19,12 +19,21 @@ KernelCreateInfo BuildKernelCreateInfo();
|
|||
|
||||
} // namespace js
|
||||
|
||||
// placeholder for future use. no options currently
|
||||
struct JsExecutionProviderInfo {
|
||||
JsExecutionProviderInfo() = default;
|
||||
|
||||
JsExecutionProviderInfo(const ProviderOptions& po) {
|
||||
auto it = po.find("preferred_layout");
|
||||
if (it != po.end()) {
|
||||
auto& value = it->second;
|
||||
if (value == "NCHW") {
|
||||
data_layout = DataLayout::NCHW;
|
||||
} else if (value == "NHWC") {
|
||||
data_layout = DataLayout::NHWC;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JSEP default preferred layout is NHWC
|
||||
DataLayout data_layout = DataLayout::NHWC;
|
||||
};
|
||||
|
||||
class JsExecutionProvider : public IExecutionProvider {
|
||||
|
|
@ -39,7 +48,7 @@ class JsExecutionProvider : public IExecutionProvider {
|
|||
std::shared_ptr<KernelRegistry> GetKernelRegistry() const override;
|
||||
std::unique_ptr<onnxruntime::IDataTransfer> GetDataTransfer() const override;
|
||||
|
||||
DataLayout GetPreferredLayout() const override { return DataLayout::NHWC; }
|
||||
DataLayout GetPreferredLayout() const override { return preferred_data_layout_; }
|
||||
|
||||
FusionStyle GetFusionStyle() const override { return FusionStyle::FilteredGraphViewer; }
|
||||
|
||||
|
|
@ -48,6 +57,7 @@ class JsExecutionProvider : public IExecutionProvider {
|
|||
bool ConcurrentRunSupported() const override { return false; }
|
||||
|
||||
std::vector<AllocatorPtr> CreatePreferredAllocators() override;
|
||||
DataLayout preferred_data_layout_;
|
||||
};
|
||||
|
||||
} // namespace onnxruntime
|
||||
|
|
|
|||
|
|
@ -109,6 +109,10 @@ ORT_API_STATUS_IMPL(OrtApis::SessionOptionsAppendExecutionProvider,
|
|||
#endif
|
||||
} else if (strcmp(provider_name, "JS") == 0) {
|
||||
#if defined(USE_JSEP)
|
||||
std::string preferred_layout;
|
||||
if (options->value.config_options.TryGetConfigEntry("preferredLayout", preferred_layout)) {
|
||||
provider_options["preferred_layout"] = preferred_layout;
|
||||
}
|
||||
options->provider_factories.push_back(JsProviderFactoryCreator::Create(provider_options));
|
||||
#else
|
||||
status = create_not_supported_status();
|
||||
|
|
|
|||
Loading…
Reference in a new issue