From 822ba0452706d1ef9b7f83075f8a1b3064be37cb Mon Sep 17 00:00:00 2001 From: Ningxin Hu Date: Mon, 8 Apr 2024 18:19:14 -0700 Subject: [PATCH] WebNN: Respect ArrayBufferView's byte offset and length for MLGraphMojo An `ArrayBufferView` can be created from an `ArrayBuffer` with bigger size and with a proper byte offset, i.e. `new Float32Array(arrayBuffer, byteOffset, length)`. `MLGraphMojo::ComputeImpl()` should use `ArrayBufferView`'s byte offset and length when copying the input or output data into or from the mojo `BigBuffer`. Bug: 332151809 Change-Id: Ib8873a100de0e5565ae39b483f6fa06b024cb6f6 Cq-Include-Trybots: luci.chromium.try:win11-blink-rel Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5409911 Reviewed-by: Austin Sullivan Commit-Queue: ningxin hu Reviewed-by: Reilly Grant Cr-Commit-Position: refs/heads/main@{#1284226} --- ...rview-with-bigger-arraybuffer.https.any.js | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 webnn/conformance_tests/gpu/compute-arraybufferview-with-bigger-arraybuffer.https.any.js diff --git a/webnn/conformance_tests/gpu/compute-arraybufferview-with-bigger-arraybuffer.https.any.js b/webnn/conformance_tests/gpu/compute-arraybufferview-with-bigger-arraybuffer.https.any.js new file mode 100644 index 00000000000000..ddc39011813a4f --- /dev/null +++ b/webnn/conformance_tests/gpu/compute-arraybufferview-with-bigger-arraybuffer.https.any.js @@ -0,0 +1,37 @@ +// META: title=test WebNN MLContext.compute() for ArrayBufferView created from bigger ArrayBuffer +// META: global=window,dedicatedworker +// META: script=../../resources/utils.js + +'use strict'; + +// These tests are used to reproduce the Chromium issue: +// https://issues.chromium.org/issues/332151809 +promise_test(async t => { + const context = await navigator.ml.createContext({deviceType: 'gpu'}); + const builder = new MLGraphBuilder(context); + const a = builder.input('a', {dataType: 'float32', dimensions: [2]}); + const b = builder.relu(a); + const graph = await builder.build({b}); + const arraybuffer = new ArrayBuffer(100); + const aBuffer = new Float32Array(arraybuffer, /*byteOffset*/ 4, /*length*/ 2) + aBuffer.set([1, -1]); + const bBuffer = new Float32Array(2); + const results = await context.compute(graph, {'a': aBuffer}, {'b': bBuffer}); + assert_array_approx_equals_ulp( + results.outputs.b, [1, 0], /*nulp*/ 0, 'float32'); +}, 'Test compute() working for input ArrayBufferView created from bigger ArrayBuffer'); + +promise_test(async t => { + const context = await navigator.ml.createContext({deviceType: 'gpu'}); + const builder = new MLGraphBuilder(context); + const a = builder.input('a', {dataType: 'float32', dimensions: [2]}); + const b = builder.relu(a); + const graph = await builder.build({b}); + const aBuffer = new Float32Array(2); + aBuffer.set([1, -1]); + const arraybuffer = new ArrayBuffer(100); + const bBuffer = new Float32Array(arraybuffer, /*byteOffset*/ 8, /*length*/ 2); + const results = await context.compute(graph, {'a': aBuffer}, {'b': bBuffer}); + assert_array_approx_equals_ulp( + results.outputs.b, [1, 0], /*nulp*/ 0, 'float32'); +}, 'Test compute() working for output ArrayBufferView created from bigger ArrayBuffer');