Skip to content

Commit

Permalink
webnn: Immediately copy constant data
Browse files Browse the repository at this point in the history
Currently, the data of ArrayBufferViews passed to the constant() method
is copied during the build() method. This does not match the spec:
https://www.w3.org/TR/webnn/#dom-mlgraphbuilder-constant

Cq-Include-Trybots: luci.chromium.try:win11-blink-rel
Bug: 348598508
Change-Id: Ief7a686324375fb2027df8a30d2c97943149bbe6
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5649032
Commit-Queue: Reilly Grant <[email protected]>
Reviewed-by: Reilly Grant <[email protected]>
Commit-Queue: Austin Sullivan <[email protected]>
Auto-Submit: Austin Sullivan <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1318727}
  • Loading branch information
a-sully authored and chromium-wpt-export-bot committed Jun 24, 2024
1 parent ceb77f8 commit d91a229
Showing 1 changed file with 61 additions and 0 deletions.
61 changes: 61 additions & 0 deletions webnn/validation_tests/constant-changed-buffer.https.any.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// META: title=ensure MLGraphBuilder.constant() handles buffers which change
// META: global=window,dedicatedworker
// META: script=../resources/utils_validation.js

promise_test(async t => {
let backingBuffer = new ArrayBuffer(8);
let aBuffer = new Float32Array(backingBuffer, 0, 2);
aBuffer[0] = 2;
aBuffer[1] = 3;
const a = builder.constant({dataType: 'float32', dimensions: [2]}, aBuffer);

// Detach `aBuffer`. Constant data should already be copied, so changes to
// the buffer afterwards should not be reflected in the graph.
const unusedBuffer = backingBuffer.transfer();

const b = builder.input('b', {dataType: 'float32', dimensions: [2]});
const c = builder.add(a, b);
const graph = await builder.build({c});

const bBuffer = new Float32Array([5, 7]);
const cBuffer = new Float32Array(2);
const result = await context.compute(graph, {'b': bBuffer}, {'c': cBuffer});

const expectedResult = new Float32Array([7, 10]);
assert_array_equals(result.outputs.c, expectedResult);
}, 'Constant data is unaffected by detaching the buffer');

promise_test(async t => {
let aBuffer = new Float32Array([2, 3]);
const a = builder.constant({dataType: 'float32', dimensions: [2]}, aBuffer);

// Rewrite `aBuffer` contents. Constant data should already be copied, so
// changes to the buffer afterwards should not be reflected in the graph.
aBuffer[0] = 10;
aBuffer[1] = 20;

const b = builder.input('b', {dataType: 'float32', dimensions: [2]});
const c = builder.add(a, b);
const graph = await builder.build({c});

const bBuffer = new Float32Array([5, 7]);
const cBuffer = new Float32Array(2);
const result = await context.compute(graph, {'b': bBuffer}, {'c': cBuffer});

const expectedResult = new Float32Array([7, 10]);
assert_array_equals(result.outputs.c, expectedResult);
}, 'Constant data is unaffected by changes to the buffer contents');

promise_test(async t => {
let backingBuffer = new ArrayBuffer(8);
const aBuffer = new Float32Array(backingBuffer, 0, 2);
// Detach `aBuffer` _before_ calling `constant()`. This should throw, since
// detached buffers have a length of zero, which does not match the length of
// the descriptor. See
// https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy
const unusedBuffer = backingBuffer.transfer();

assert_throws_js(
TypeError,
() => builder.constant({dataType: 'float32', dimensions: [2]}, aBuffer));
}, 'Constant data cannot use a detached buffer, which is empty');

0 comments on commit d91a229

Please sign in to comment.