WebNN
The Web Neural Network API's entry point: create an execution context on the CPU, GPU or NPU, and find out which operators that backend actually implements.
@inject Bit.Butil.WebNN webNNMDN reference
MLGraphBuilder program is dozens of
chained operator calls over tensor handles that cannot cross interop, and marshalling each one
through JSON would be slower than the inference it is meant to accelerate. Build the graph in a
JS module and call into it - and use this service to decide whether loading that module is worth
it at all.
True when the runtime exposes navigator.ml.createContext. During prerender/SSR the check returns false rather than throwing, so defer it to OnAfterRenderAsync.
@inject Bit.Butil.WebNN webNN
if (await webNN.IsSupported() is false) UseWasmInferenceInstead();The device type is a hint: the runtime may hand back another one, which is why the returned context reports what was actually created. Dispose it - a context can hold a real accelerator backend open.
await using var context = await webNN.CreateContext("gpu", "high-performance");
if (context?.Info.CanBuildGraph is true)
{
// MLGraphBuilder exists - a model could be built and run here
}Which operators the backend implements, and within what limits. The same model can run on one backend and be rejected by another, so a page offering a choice of device wants to know before it builds a graph. The detail differs per operator and per backend, so it is reported as JSON rather than modelled.
{
private WebNNContext? context; // from webNN.CreateContext
// Support is per backend, not per browser: the same runtime answers differently for "gpu" and
// "cpu", so a graph has to be checked against the context it will actually run on.
private async Task Check()
{
var limits = await context!.GetOpSupportLimits();
var hasConv = limits.Any(op => op.Name == "conv2d");
}
}API reference
ValueTask<bool> IsSupported()ValueTask<WebNNContext?> CreateContext(string deviceType = '', string powerPreference = '')WebNNContextInfo InfoValueTask<WebNNOpSupport[]> GetOpSupportLimits()ValueTask DisposeAsync()ValueTask DisposeAsync()