-
Notifications
You must be signed in to change notification settings - Fork 3.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
webnn: Add WPTs asserting input tensors are not modified
The TFLite and CoreML backends explicitly assume that tensors passed as an input to graph execution are not modified by the underlying framework. We should specify this behavior Bug: 366130770 Change-Id: I326975b05ca1163a3cba6a90e81ee22982252a65 Cq-Include-Trybots: luci.chromium.try:win11-blink-rel,mac14-blink-rel,mac14.arm64-blink-rel Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5848368 Reviewed-by: Weizhong Xia <[email protected]> Reviewed-by: ningxin hu <[email protected]> Commit-Queue: Austin Sullivan <[email protected]> Cr-Commit-Position: refs/heads/main@{#1354900}
- Loading branch information
1 parent
d97ddaf
commit 203770a
Showing
1 changed file
with
86 additions
and
0 deletions.
There are no files selected for viewing
86 changes: 86 additions & 0 deletions
86
webnn/conformance_tests/inputs-are-not-modified.https.any.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
// META: title=test that input tensors are not modified during a call to dispatch() | ||
// META: global=window,dedicatedworker | ||
// META: variant=?cpu | ||
// META: variant=?gpu | ||
// META: variant=?npu | ||
// META: script=../resources/utils.js | ||
// META: timeout=long | ||
|
||
'use strict'; | ||
|
||
// https://www.w3.org/TR/webnn/#api-mlcontext-dispatch | ||
|
||
let mlContext; | ||
|
||
// Skip tests if WebNN is unimplemented. | ||
promise_setup(async () => { | ||
assert_implements(navigator.ml, 'missing navigator.ml'); | ||
mlContext = await navigator.ml.createContext(contextOptions); | ||
}); | ||
|
||
promise_test(async () => { | ||
const builder = new MLGraphBuilder(mlContext); | ||
const inputOperand = | ||
builder.input('input', {dataType: 'float32', dimensions: [4]}); | ||
const hardSwishOperand = builder.hardSwish(inputOperand); | ||
// Add some other operator for the output tensor to bind to; otherwise there | ||
// is no reason to implement hardSwish "in-place". | ||
const outputOperand = builder.identity(hardSwishOperand); | ||
|
||
const [inputTensor, outputTensor, mlGraph] = await Promise.all([ | ||
mlContext.createTensor({ | ||
dataType: 'float32', | ||
dimensions: [4], | ||
usage: MLTensorUsage.WRITE_TO | MLTensorUsage.READ_FROM | ||
}), | ||
mlContext.createTensor( | ||
{dataType: 'float32', dimensions: [4], usage: MLTensorUsage.READ_FROM}), | ||
builder.build({'output': outputOperand}) | ||
]); | ||
|
||
const inputData = Float32Array.from([-4, -1, 1, 4]); | ||
mlContext.writeTensor(inputTensor, inputData); | ||
|
||
mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor}); | ||
|
||
// Wait for graph execution to complete. | ||
await mlContext.readTensor(outputTensor); | ||
|
||
// The input tensor should not be modified. | ||
assert_array_equals( | ||
new Float32Array(await mlContext.readTensor(inputTensor)), inputData); | ||
}, 'input tensor is not modified: hardSwish'); | ||
|
||
promise_test(async () => { | ||
const builder = new MLGraphBuilder(mlContext); | ||
const inputOperand = | ||
builder.input('input', {dataType: 'float32', dimensions: [4]}); | ||
const constantOperand = builder.constant( | ||
{dataType: 'float32', dimensions: [4]}, Float32Array.from([-2, 0, 3, 4])); | ||
const mulOperand = builder.mul(inputOperand, constantOperand); | ||
// Add some other operator for the output tensor to bind to; otherwise there | ||
// is no reason to implement mul "in-place". | ||
const outputOperand = builder.add(mulOperand, constantOperand); | ||
|
||
const [inputTensor, outputTensor, mlGraph] = await Promise.all([ | ||
mlContext.createTensor({ | ||
dataType: 'float32', | ||
dimensions: [4], | ||
usage: MLTensorUsage.WRITE_TO | MLTensorUsage.READ_FROM | ||
}), | ||
mlContext.createTensor( | ||
{dataType: 'float32', dimensions: [4], usage: MLTensorUsage.READ_FROM}), | ||
builder.build({'output': outputOperand}) | ||
]); | ||
|
||
const inputData = Float32Array.from([1, 2, 3, 4]); | ||
mlContext.writeTensor(inputTensor, inputData); | ||
mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor}); | ||
|
||
// Wait for graph execution to complete. | ||
await mlContext.readTensor(outputTensor); | ||
|
||
// The input tensor should not be modified. | ||
assert_array_equals( | ||
new Float32Array(await mlContext.readTensor(inputTensor)), inputData); | ||
}, 'input tensor is not modified: mul'); |