[js/webnn] update API of session options for WebNN (#20816)
### Description
This PR is an API-only change to address the requirements being
discussed in #20729.
There are multiple ways that users may create an ORT session by
specifying the session options differently.
All the code snippet below will use the variable `webnnOptions` as this:
```js
const myWebnnSession = await ort.InferenceSession.create('./model.onnx', {
executionProviders: [
webnnOptions
]
});
```
### The old way (backward-compatibility)
```js
// all-default, name only
const webnnOptions_0 = 'webnn';
// all-default, properties omitted
const webnnOptions_1 = { name: 'webnn' };
// partial
const webnnOptions_2 = {
name: 'webnn',
deviceType: 'cpu'
};
// full
const webnnOptions_3 = {
name: 'webnn',
deviceType: 'gpu',
numThreads: 1,
powerPreference: 'high-performance'
};
```
### The new way (specify with MLContext)
```js
// options to create MLcontext
const options = {
deviceType: 'gpu',
powerPreference: 'high-performance'
};
const myMlContext = await navigator.ml.createContext(options);
// options for session options
const webnnOptions = {
name: 'webnn',
context: myMlContext,
...options
};
```
This should throw (because no deviceType is specified):
```js
const myMlContext = await navigator.ml.createContext({ ... });
const webnnOptions = {
name: 'webnn',
context: myMlContext
};
```
### Interop with WebGPU
```js
// get WebGPU device
const adaptor = await navigator.gpu.requestAdapter({ ... });
const device = await adaptor.requestDevice({ ... });
// set WebGPU adaptor and device
ort.env.webgpu.adaptor = adaptor;
ort.env.webgpu.device = device;
const myMlContext = await navigator.ml.createContext(device);
const webnnOptions = {
name: 'webnn',
context: myMlContext,
gpuDevice: device
};
```
This should throw (because cannot specify both gpu device and MLContext
option at the same time):
```js
const webnnOptions = {
name: 'webnn',
context: myMlContext,
gpuDevice: device,
deviceType: 'gpu'
};
```