MLGraphBuilder
Experimental: This is an experimental technology. Check the browser compatibility table carefully before using it in production.
The MLGraphBuilder interface of the Web Neural Network (WebNN) API is used to construct a computational graph. It holds the state of a graph-building session: you declare inputs and constants, compose operations on the resulting MLOperand objects, and finally compile the graph into an MLGraph with build().
Graph construction is synchronous and validates each operation immediately: shapes and data types are computed as you go, and invalid arguments throw a TypeError at the offending call. Only build() is asynchronous.
This feature is available only in secure contexts (HTTPS or localhost), and is available in both the main thread and Web Workers .
Web IDL
typedef record<USVString, MLOperand> MLNamedOperands;
[SecureContext, Exposed=(Window, Worker)]
interface MLGraphBuilder {
// Construct the graph builder from the context.
constructor(MLContext context);
// Create an operand for a graph input.
MLOperand input(USVString name, MLOperandDescriptor descriptor);
// Create an operand for a graph constant.
MLOperand constant(MLOperandDescriptor descriptor,
AllowSharedBufferSource buffer);
// Create a scalar operand from the specified number of the specified type.
MLOperand constant(MLOperandDataType dataType, MLNumber value);
// Create an operand from a specified constant tensor.
MLOperand constant(MLTensor tensor);
// Compile the graph up to the specified output operands asynchronously.
Promise<MLGraph> build(MLNamedOperands outputs);
};The operations (add(), conv2d(), softmax() and so on) are defined as partial interfaces of MLGraphBuilder and documented in MLGraphBuilder operations.
Constructor
MLGraphBuilder()
Creates a new MLGraphBuilder associated with an MLContext.
Syntax
new MLGraphBuilder(context)Parameters
-
contextThe
MLContextthat the graph will be compiled for and executed on.
Exceptions
-
SecurityErrorDOMExceptionThrown if the document is not allowed to use the
webnnPermissions Policy feature. -
InvalidStateErrorDOMExceptionThrown if
contextis lost.
Instance properties
None.
Instance methods
| Method | Description |
|---|---|
input() | Creates a named input operand. |
constant() | Creates a constant operand from a buffer, a scalar value, or a constant MLTensor. |
build() | Compiles the graph up to the given output operands. |
| Operations | Over 90 methods such as add(), conv2d(), matmul() and softmax() that create operations. |
All methods except build() throw an InvalidStateError DOMException if the builder cannot build, that is, if build() has already been called on it or its context is lost.
input()
The input() method creates a named MLOperand that represents a graph input. When the graph is executed, a tensor with the same name, data type and shape must be supplied in the inputs argument of MLContext.dispatch().
Syntax
input(name, descriptor)Parameters
-
nameA non-empty string naming the input. Names must be unique within the builder.
-
descriptorAn
MLOperandDescriptorgiving the input’sdataTypeandshape.
Return value
An MLOperand.
Exceptions
-
TypeErrorThrown if
nameis empty or already used by another input, or ifdescriptorhas an invalid shape. -
InvalidStateErrorDOMExceptionThrown if the builder cannot build.
A graph may have no inputs at all, for example a graph that only transforms constants.
constant()
The constant() method creates an MLOperand whose value is fixed when the graph is built, typically model weights. Constants let the implementation pre-process and cache data in a device-friendly format during build() (so-called weight preprocessing), which speeds up subsequent executions.
Syntax
constant(descriptor, buffer)
constant(dataType, value)
constant(tensor)Parameters
-
descriptorAn
MLOperandDescriptorgiving the constant’sdataTypeandshape. -
bufferAn
ArrayBuffer,SharedArrayBuffer, orArrayBufferViewwith the initial data. Its byte length must equal the descriptor’s byte length, and a typed array must match the data type or be aUint8Array(see buffer requirements). The data is copied whenconstant()is called, so the buffer can be reused immediately. -
dataTypeAn
MLOperandDataTypefor a scalar (0-D) constant. -
valueAn
MLNumber(numberorbigint) with the scalar value. It is cast todataType; values outside the range of the type are truncated. -
tensorA constant
MLTensorcreated withMLContext.createConstantTensor()on the same context. The operand uses the tensor’s data type and shape. The tensor may be destroyed afterbuild()completes.
Return value
An MLOperand.
Exceptions
-
TypeErrorThrown if
descriptorhas an invalid shape orbufferdoes not match it; or, forconstant(tensor), if the tensor belongs to a different context, has been destroyed, or is not a constant tensor. -
InvalidStateErrorDOMExceptionThrown if the builder cannot build.
build()
The build() method compiles the graph, from the given output operands back to the inputs and constants they depend on, into an MLGraph. Operands that the outputs do not depend on are ignored.
An MLGraphBuilder can build only once. After build() is called, the builder can no longer create operands or build again; create a new builder for each graph.
Syntax
build(outputs)Parameters
-
outputsAn object (
MLNamedOperands) mapping each output name to anMLOperandcreated by this builder. When executing the graph, a tensor must be supplied for each of these names in theoutputsargument ofMLContext.dispatch().
Return value
A Promise that fulfills with an MLGraph.
Exceptions
The returned promise is rejected with:
-
TypeErroroutputsis empty; an output name is empty; an operand was created by a different builder; an operand is an input or constant operand; or a constant operand was created from a tensor that has since been destroyed. -
InvalidStateErrorDOMExceptionThe builder cannot build (it has already built, or the context is lost), or the context was lost during compilation.
-
OperationErrorDOMExceptionThe graph could not be compiled by the underlying platform.
Passing an input or constant operand directly as a graph output is rejected, because it usually indicates a mistake. If you really need it, wrap the operand with
identity().
Operations
Operations are methods that take one or more MLOperand objects (and usually an options dictionary derived from MLOperatorOptions) and return a new MLOperand, or a sequence of operands. See MLGraphBuilder operations for full details.
| Category | Operations |
|---|---|
| Element-wise binary | add(), sub(), mul(), div(), max(), min(), pow() |
| Comparison and logical | equal(), notEqual(), greater(), greaterOrEqual(), lesser(), lesserOrEqual(), logicalNot(), logicalAnd(), logicalOr(), logicalXor(), isNaN(), isInfinite() |
| Element-wise unary | abs(), ceil(), cos(), erf(), exp(), floor(), identity(), log(), neg(), reciprocal(), roundEven(), sign(), sin(), sqrt(), tan() |
| Activations | elu(), gelu(), hardSigmoid(), hardSwish(), leakyRelu(), linear(), prelu(), relu(), sigmoid(), softmax(), softplus(), softsign(), tanh() |
| Convolution | conv2d(), convTranspose2d() |
| Pooling | averagePool2d(), l2Pool2d(), maxPool2d() |
| Normalization | batchNormalization(), instanceNormalization(), layerNormalization() |
| Matrix | gemm(), matmul(), triangular() |
| Reduction | argMax(), argMin(), cumulativeSum(), reduceL1(), reduceL2(), reduceLogSum(), reduceLogSumExp(), reduceMax(), reduceMean(), reduceMin(), reduceProduct(), reduceSum(), reduceSumSquare() |
| Shape and data movement | cast(), clamp(), concat(), expand(), pad(), reshape(), reverse(), slice(), split(), tile(), transpose() |
| Gather and scatter | gather(), gatherElements(), gatherND(), scatterElements(), scatterND(), where() |
| Quantization | dequantizeLinear(), quantizeLinear() |
| Recurrent networks | gru(), gruCell(), lstm(), lstmCell() |
| Resampling | resample2d() |
Examples
Building a simple graph
const context = await navigator.ml.createContext();
const builder = new MLGraphBuilder(context);
const a = builder.input('a', { dataType: 'float32', shape: [3, 4] });
const b = builder.input('b', { dataType: 'float32', shape: [4, 3] });
const c = builder.matmul(a, b);
console.log(c.shape); // [3, 3]
const graph = await builder.build({ c });Using the three kinds of constants
const builder = new MLGraphBuilder(context);
const x = builder.input('x', { dataType: 'float32', shape: [2, 2] });
// 1. From a buffer.
const w = builder.constant({ dataType: 'float32', shape: [2, 2] },
new Float32Array([1, 2, 3, 4]));
// 2. A scalar; broadcast when combined with other operands.
const half = builder.constant('float32', 0.5);
// 3. From a constant MLTensor, e.g. weights shared by several graphs.
const biasTensor = await context.createConstantTensor(
{ dataType: 'float32', shape: [2] }, new Float32Array([0.1, 0.2]));
const bias = builder.constant(biasTensor);
const y = builder.add(builder.mul(builder.matmul(x, w), half), bias);
const graph = await builder.build({ y });A small convolutional block
const builder = new MLGraphBuilder(context);
const input = builder.input('input', { dataType: 'float32', shape: [1, 3, 32, 32] }); // NCHW
const filter = builder.constant({ dataType: 'float32', shape: [16, 3, 3, 3] }, filterData); // OIHW
const bias = builder.constant({ dataType: 'float32', shape: [16] }, biasData);
let x = builder.conv2d(input, filter, { padding: [1, 1, 1, 1], bias });
x = builder.relu(x);
x = builder.maxPool2d(x, { windowDimensions: [2, 2], strides: [2, 2] });
console.log(x.shape); // [1, 16, 16, 16]
const graph = await builder.build({ output: x });Handling build errors
const builder = new MLGraphBuilder(context);
const x = builder.input('x', { dataType: 'float32', shape: [4] });
try {
await builder.build({ x }); // Rejected: an input cannot be a graph output.
} catch (e) {
console.log(e.name); // "TypeError"
}
// Wrap the operand with identity() instead (using a new builder).
const builder2 = new MLGraphBuilder(context);
const x2 = builder2.input('x', { dataType: 'float32', shape: [4] });
const graph = await builder2.build({ y: builder2.identity(x2) });Specifications
| Specification | Status |
|---|---|
Web Neural Network API — MLGraphBuilder interface | Candidate Recommendation Draft |
The latest Editor’s Draft is available at webmachinelearning.github.io/webnn .
Browser compatibility
WebNN is under active development and support varies across browsers, operating systems, and hardware.
constant(tensor)is a recent addition and may not be implemented yet.
See Browser Compatibility: WebNN APIs and the per-backend operator tables for Windows ML, LiteRT and Core ML.