constant-changed-buffer.https.any.js (3024B)
1 // META: title=ensure MLGraphBuilder.constant() handles buffers which change 2 // META: global=window,worker 3 // META: variant=?cpu 4 // META: variant=?gpu 5 // META: variant=?npu 6 // META: script=../resources/utils_validation.js 7 8 promise_test(async t => { 9 const builder = new MLGraphBuilder(context); 10 let backingBuffer = new ArrayBuffer(8); 11 let aBuffer = new Float32Array(backingBuffer, 0, 2); 12 aBuffer[0] = 2; 13 aBuffer[1] = 3; 14 const a = builder.constant({dataType: 'float32', shape: [2]}, aBuffer); 15 16 // Detach `aBuffer`. Constant data should already be copied, so changes to 17 // the buffer afterwards should not be reflected in the graph. 18 const unusedBuffer = backingBuffer.transfer(); 19 20 const b = builder.input('b', {dataType: 'float32', shape: [2]}); 21 const c = builder.add(a, b); 22 23 const [graph, bTensor, cTensor] = await Promise.all([ 24 builder.build({c}), 25 context.createTensor({dataType: 'float32', shape: [2], writable: true}), 26 context.createTensor({dataType: 'float32', shape: [2], readable: true}) 27 ]); 28 29 context.writeTensor(bTensor, new Float32Array([5, 7])); 30 31 context.dispatch(graph, {'b': bTensor}, {'c': cTensor}); 32 const result = new Float32Array(await context.readTensor(cTensor)); 33 assert_array_equals(result, new Float32Array([7, 10])); 34 }, 'Constant data is unaffected by detaching the buffer'); 35 36 promise_test(async t => { 37 const builder = new MLGraphBuilder(context); 38 let aBuffer = new Float32Array([2, 3]); 39 const a = builder.constant({dataType: 'float32', shape: [2]}, aBuffer); 40 41 // Rewrite `aBuffer` contents. Constant data should already be copied, so 42 // changes to the buffer afterwards should not be reflected in the graph. 43 aBuffer[0] = 10; 44 aBuffer[1] = 20; 45 46 const b = builder.input('b', {dataType: 'float32', shape: [2]}); 47 const c = builder.add(a, b); 48 49 const [graph, bTensor, cTensor] = await Promise.all([ 50 builder.build({c}), 51 context.createTensor({dataType: 'float32', shape: [2], writable: true}), 52 context.createTensor({dataType: 'float32', shape: [2], readable: true}) 53 ]); 54 55 context.writeTensor(bTensor, new Float32Array([5, 7])); 56 57 context.dispatch(graph, {'b': bTensor}, {'c': cTensor}); 58 const result = new Float32Array(await context.readTensor(cTensor)); 59 assert_array_equals(result, new Float32Array([7, 10])); 60 }, 'Constant data is unaffected by changes to the buffer contents'); 61 62 promise_test(async t => { 63 const builder = new MLGraphBuilder(context); 64 let backingBuffer = new ArrayBuffer(8); 65 const aBuffer = new Float32Array(backingBuffer, 0, 2); 66 // Detach `aBuffer` _before_ calling `constant()`. This should throw, since 67 // detached buffers have a length of zero, which does not match the length of 68 // the descriptor. See 69 // https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy 70 const unusedBuffer = backingBuffer.transfer(); 71 72 assert_throws_js( 73 TypeError, 74 () => builder.constant({dataType: 'float32', shape: [2]}, aBuffer)); 75 }, 'Constant data cannot use a detached buffer, which is empty');