destroyContext.https.any.js (5294B)
1 // META: timeout=long 2 // META: title=validation tests for WebNN API MLContext::destroy() 3 // META: global=window,worker 4 // META: variant=?cpu 5 // META: variant=?gpu 6 // META: variant=?npu 7 8 'use strict'; 9 10 let contextOptions; 11 12 promise_setup(async () => { 13 if (navigator.ml === undefined) { 14 return; 15 } 16 contextOptions = {deviceType: location.search.substring(1)}; 17 }, {explicit_timeout: true}); 18 19 promise_test(async t => { 20 const context = await navigator.ml.createContext(contextOptions); 21 context.destroy(); 22 await context.lost; 23 }, 'Context will be lost by destroyed.'); 24 25 promise_test(async t => { 26 const context = await navigator.ml.createContext(contextOptions); 27 context.destroy(); 28 context.destroy(); 29 await context.lost; 30 }, 'Context can be destroyed twice.'); 31 32 promise_test(async t => { 33 const context = await navigator.ml.createContext(contextOptions); 34 const builder = new MLGraphBuilder(context); 35 context.destroy(); 36 assert_throws_dom('InvalidStateError', () => { 37 const operandType = {dataType: 'float32', shape: [1]}; 38 builder.input('input', operandType); 39 }); 40 }, 'Destroyed context can not build operator.'); 41 42 promise_test(async t => { 43 const context = await navigator.ml.createContext(contextOptions); 44 context.destroy(); 45 assert_throws_dom('InvalidStateError', () => { 46 new MLGraphBuilder(context); 47 }); 48 }, 'Destroyed context can not create graph builder.'); 49 50 promise_test(async t => { 51 const context = await navigator.ml.createContext(contextOptions); 52 const builder = new MLGraphBuilder(context); 53 const operandType = {dataType: 'float32', shape: [1]}; 54 const input_operand = builder.input('input', operandType); 55 const const_operand = builder.constant(operandType, Float32Array.from([2])); 56 const output_operand = builder.mul(input_operand, const_operand); 57 58 context.destroy(); 59 promise_rejects_dom( 60 t, 'InvalidStateError', builder.build({'output': output_operand})); 61 }, 'Destroyed context can not build graph.'); 62 63 promise_test(async t => { 64 const context = await navigator.ml.createContext(contextOptions); 65 const builder = new MLGraphBuilder(context); 66 const operandType = {dataType: 'float32', shape: [1]}; 67 const lhsOperand = builder.input('lhs', operandType); 68 const rhsOperand = builder.input('rhs', operandType); 69 const graph = 70 await builder.build({'output': builder.sub(lhsOperand, rhsOperand)}); 71 72 const lhsTensor = await context.createTensor(operandType); 73 const rhsTensor = await context.createTensor(operandType); 74 75 const dispatchOutputs = {'output': await context.createTensor(operandType)}; 76 context.destroy(); 77 assert_throws_dom('InvalidStateError', () => { 78 context.dispatch( 79 graph, { 80 'lhs': lhsTensor, 81 'rhs': rhsTensor, 82 }, 83 dispatchOutputs); 84 }); 85 }, 'Destroyed context can not dispatch.'); 86 87 promise_test(async t => { 88 const context = await navigator.ml.createContext(contextOptions); 89 const builder = new MLGraphBuilder(context); 90 const operandType = {dataType: 'float32', shape: [1]}; 91 const lhsOperand = builder.input('lhs', operandType); 92 const rhsOperand = builder.input('rhs', operandType); 93 const graph = 94 await builder.build({'output': builder.sub(lhsOperand, rhsOperand)}); 95 96 const lhsTensor = await context.createTensor(operandType); 97 const rhsTensor = await context.createTensor(operandType); 98 99 const dispatchOutputs = {'output': await context.createTensor(operandType)}; 100 context.dispatch( 101 graph, { 102 'lhs': lhsTensor, 103 'rhs': rhsTensor, 104 }, 105 dispatchOutputs); 106 context.destroy(); 107 }, 'Executing dispatch() before context destroyed is OK.'); 108 109 promise_test(async t => { 110 const context = await navigator.ml.createContext(contextOptions); 111 context.destroy(); 112 promise_rejects_dom( 113 t, 'InvalidStateError', 114 context.createTensor({dataType: 'float32', shape: [1]})); 115 }, 'Destroyed context can not create tensor.'); 116 117 promise_test(async t => { 118 const context = await navigator.ml.createContext(contextOptions); 119 const tensor = await context.createTensor({ 120 dataType: 'float32', 121 shape: [1], 122 readable: true, 123 }); 124 context.destroy(); 125 promise_rejects_dom(t, 'InvalidStateError', context.readTensor(tensor)); 126 }, 'Destroyed context can not read tensor.'); 127 128 promise_test(async t => { 129 const context = await navigator.ml.createContext(contextOptions); 130 const tensor = await context.createTensor({ 131 dataType: 'float32', 132 shape: [1], 133 readable: true, 134 }); 135 let promise = context.readTensor(tensor); 136 context.destroy(); 137 promise_rejects_dom(t, 'InvalidStateError', promise); 138 }, 'Pending promise of readtensor() will be rejected immediately when context is destroyed.'); 139 140 promise_test(async t => { 141 const context = await navigator.ml.createContext(contextOptions); 142 // Destroying another context doesn't impact the first context. 143 const another_context = await navigator.ml.createContext(contextOptions); 144 another_context.destroy(); 145 const tensor = await context.createTensor({ 146 dataType: 'float32', 147 shape: [1], 148 writable: true, 149 }); 150 let arrayBuffer = new ArrayBuffer(4); 151 context.destroy(); 152 assert_throws_dom('InvalidStateError', () => { 153 context.writeTensor(tensor, new Uint8Array(arrayBuffer)); 154 }); 155 }, 'Destroyed context can not write tensor.');