|
| 1 | +// META: title=ensure MLGraphBuilder.constant() handles buffers which change |
| 2 | +// META: global=window,dedicatedworker |
| 3 | +// META: script=../resources/utils_validation.js |
| 4 | + |
| 5 | +promise_test(async t => { |
| 6 | + let backingBuffer = new ArrayBuffer(8); |
| 7 | + let aBuffer = new Float32Array(backingBuffer, 0, 2); |
| 8 | + aBuffer[0] = 2; |
| 9 | + aBuffer[1] = 3; |
| 10 | + const a = builder.constant({dataType: 'float32', dimensions: [2]}, aBuffer); |
| 11 | + |
| 12 | + // Detach `aBuffer`. Constant data should already be copied, so changes to |
| 13 | + // the buffer afterwards should not be reflected in the graph. |
| 14 | + const unusedBuffer = backingBuffer.transfer(); |
| 15 | + |
| 16 | + const b = builder.input('b', {dataType: 'float32', dimensions: [2]}); |
| 17 | + const c = builder.add(a, b); |
| 18 | + const graph = await builder.build({c}); |
| 19 | + |
| 20 | + const bBuffer = new Float32Array([5, 7]); |
| 21 | + const cBuffer = new Float32Array(2); |
| 22 | + const result = await context.compute(graph, {'b': bBuffer}, {'c': cBuffer}); |
| 23 | + |
| 24 | + const expectedResult = new Float32Array([7, 10]); |
| 25 | + assert_array_equals(result.outputs.c, expectedResult); |
| 26 | +}, 'Constant data is unaffected by detaching the buffer'); |
| 27 | + |
| 28 | +promise_test(async t => { |
| 29 | + let aBuffer = new Float32Array([2, 3]); |
| 30 | + const a = builder.constant({dataType: 'float32', dimensions: [2]}, aBuffer); |
| 31 | + |
| 32 | + // Rewrite `aBuffer` contents. Constant data should already be copied, so |
| 33 | + // changes to the buffer afterwards should not be reflected in the graph. |
| 34 | + aBuffer[0] = 10; |
| 35 | + aBuffer[1] = 20; |
| 36 | + |
| 37 | + const b = builder.input('b', {dataType: 'float32', dimensions: [2]}); |
| 38 | + const c = builder.add(a, b); |
| 39 | + const graph = await builder.build({c}); |
| 40 | + |
| 41 | + const bBuffer = new Float32Array([5, 7]); |
| 42 | + const cBuffer = new Float32Array(2); |
| 43 | + const result = await context.compute(graph, {'b': bBuffer}, {'c': cBuffer}); |
| 44 | + |
| 45 | + const expectedResult = new Float32Array([7, 10]); |
| 46 | + assert_array_equals(result.outputs.c, expectedResult); |
| 47 | +}, 'Constant data is unaffected by changes to the buffer contents'); |
| 48 | + |
| 49 | +promise_test(async t => { |
| 50 | + let backingBuffer = new ArrayBuffer(8); |
| 51 | + const aBuffer = new Float32Array(backingBuffer, 0, 2); |
| 52 | + // Detach `aBuffer` _before_ calling `constant()`. This should throw, since |
| 53 | + // detached buffers have a length of zero, which does not match the length of |
| 54 | + // the descriptor. See |
| 55 | + // https://webidl.spec.whatwg.org/#dfn-get-buffer-source-copy |
| 56 | + const unusedBuffer = backingBuffer.transfer(); |
| 57 | + |
| 58 | + assert_throws_js( |
| 59 | + TypeError, |
| 60 | + () => builder.constant({dataType: 'float32', dimensions: [2]}, aBuffer)); |
| 61 | +}, 'Constant data cannot use a detached buffer, which is empty'); |
0 commit comments