inputs-are-not-modified.https.any.js (3060B)
1 // META: title=test that input tensors are not modified during a call to dispatch() 2 // META: global=window,worker 3 // META: variant=?cpu 4 // META: variant=?gpu 5 // META: variant=?npu 6 // META: script=../resources/utils.js 7 // META: timeout=long 8 9 'use strict'; 10 11 // https://www.w3.org/TR/webnn/#api-mlcontext-dispatch 12 13 let mlContext; 14 15 // Skip tests if WebNN is unimplemented. 16 promise_setup(async () => { 17 assert_implements(navigator.ml, 'missing navigator.ml'); 18 mlContext = await navigator.ml.createContext(contextOptions); 19 }); 20 21 promise_test(async () => { 22 const builder = new MLGraphBuilder(mlContext); 23 const inputOperand = 24 builder.input('input', {dataType: 'float32', shape: [4]}); 25 const hardSwishOperand = builder.hardSwish(inputOperand); 26 // Add some other operator for the output tensor to bind to; otherwise there 27 // is no reason to implement hardSwish "in-place". 28 const outputOperand = builder.identity(hardSwishOperand); 29 30 const [inputTensor, outputTensor, mlGraph] = await Promise.all([ 31 mlContext.createTensor({ 32 dataType: 'float32', 33 shape: [4], 34 readable: true, 35 writable: true, 36 }), 37 mlContext.createTensor({dataType: 'float32', shape: [4], readable: true}), 38 builder.build({'output': outputOperand}) 39 ]); 40 41 const inputData = Float32Array.from([-4, -1, 1, 4]); 42 mlContext.writeTensor(inputTensor, inputData); 43 44 mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor}); 45 46 // Wait for graph execution to complete. 47 await mlContext.readTensor(outputTensor); 48 49 // The input tensor should not be modified. 50 assert_array_equals( 51 new Float32Array(await mlContext.readTensor(inputTensor)), inputData); 52 }, 'input tensor is not modified: hardSwish'); 53 54 promise_test(async () => { 55 const builder = new MLGraphBuilder(mlContext); 56 const inputOperand = 57 builder.input('input', {dataType: 'float32', shape: [4]}); 58 const constantOperand = builder.constant( 59 {dataType: 'float32', shape: [4]}, Float32Array.from([-2, 0, 3, 4])); 60 const mulOperand = builder.mul(inputOperand, constantOperand); 61 // Add some other operator for the output tensor to bind to; otherwise there 62 // is no reason to implement mul "in-place". 63 const outputOperand = builder.add(mulOperand, constantOperand); 64 65 const [inputTensor, outputTensor, mlGraph] = await Promise.all([ 66 mlContext.createTensor({ 67 dataType: 'float32', 68 shape: [4], 69 readable: true, 70 writable: true, 71 }), 72 mlContext.createTensor({dataType: 'float32', shape: [4], readable: true}), 73 builder.build({'output': outputOperand}) 74 ]); 75 76 const inputData = Float32Array.from([1, 2, 3, 4]); 77 mlContext.writeTensor(inputTensor, inputData); 78 mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor}); 79 80 // Wait for graph execution to complete. 81 await mlContext.readTensor(outputTensor); 82 83 // The input tensor should not be modified. 84 assert_array_equals( 85 new Float32Array(await mlContext.readTensor(inputTensor)), inputData); 86 }, 'input tensor is not modified: mul');