diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:14:29 +0000 |
commit | fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8 (patch) | |
tree | 4c1ccaf5486d4f2009f9a338a98a83e886e29c97 /testing/web-platform/tests/webnn/resources/utils.js | |
parent | Releasing progress-linux version 124.0.1-1~progress7.99u1. (diff) | |
download | firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.tar.xz firefox-fbaf0bb26397aa498eb9156f06d5a6fe34dd7dd8.zip |
Merging upstream version 125.0.1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'testing/web-platform/tests/webnn/resources/utils.js')
-rw-r--r-- | testing/web-platform/tests/webnn/resources/utils.js | 172 |
1 files changed, 113 insertions, 59 deletions
diff --git a/testing/web-platform/tests/webnn/resources/utils.js b/testing/web-platform/tests/webnn/resources/utils.js index f91d6622d3..375c71174a 100644 --- a/testing/web-platform/tests/webnn/resources/utils.js +++ b/testing/web-platform/tests/webnn/resources/utils.js @@ -1,7 +1,5 @@ 'use strict'; -const ExecutionArray = ['sync', 'async']; - // https://webmachinelearning.github.io/webnn/#enumdef-mloperanddatatype const TypedArrayDict = { // workaround use Uint16 for Float16 @@ -193,7 +191,7 @@ const getMatmulPrecisionTolerance = (resources, operationName) => { }; /** - * Get ULP tolerance of averagePool2d operation. + * Get ULP tolerance of averagePool2d or l2Pool2d operation. * @param {Object} resources - Resources used for building a graph * @param {String} operationName - An operation name * @returns {Number} A tolerance number @@ -284,6 +282,32 @@ const getReductionPrecisionTolerance = (resources, operationName) => { return tolerance; }; +/** + * Get ULP tolerance of resample2d operations. + * @param {Object} resources - Resources used for building a graph + * @param {String} operationName - An operation name + * @returns {Number} A tolerance number + */ +const getResample2dPrecisionTolerance = (resources, operationName) => { + const options = {...resources.options}; + let tolerance; + if (options.mode && options.mode === 'linear') { + // interpolation mode is linear + const precisionType = resources.expected.type; + if (precisionType === 'float32') { + tolerance = 84; + } else if (precisionType === 'float16') { + tolerance = 10; + } else { + tolerance = 1; + } + } else { + // interpolation mode is nearest-neighbor + tolerance = 0; + } + return tolerance; +}; + // Refer to precision metrics on https://github.com/webmachinelearning/webnn/issues/265#issuecomment-1256242643 const PrecisionMetrics = { argMax: {ULP: {int64: 0}}, @@ -292,6 +316,7 @@ const PrecisionMetrics = { cast: {ULP: {float32: 1, float16: 1, int32: 0, uint32: 0, int64: 0, int8: 0, uint8: 0}}, clamp: {ULP: {float32: 0, float16: 0}}, concat: {ULP: {float32: 0, float16: 0}}, + constant: {ULP: {float32: 2, float16: 2, int32: 0, uint32: 0, int64: 0, int8: 0, uint8: 0}}, conv2d: {ULP: {float32: getConv2dPrecisionTolerance, float16: getConv2dPrecisionTolerance}}, convTranspose2d: {ULP: {float32: getConv2dPrecisionTolerance, float16: getConv2dPrecisionTolerance}}, // Begin Element-wise binary operations @@ -340,6 +365,7 @@ const PrecisionMetrics = { pad: {ULP: {float32: 0, float16: 0}}, // Begin Pooling operations averagePool2d: {ULP: {float32: getAveragePool2dPrecisionTolerance, float16: getAveragePool2dPrecisionTolerance}}, + l2Pool2d: {ULP: {float32: getAveragePool2dPrecisionTolerance, float16: getAveragePool2dPrecisionTolerance}}, maxPool2d: {ULP: {float32: 0, float16: 0}}, // End Pooling operations prelu: {ULP: {float32: 1, float16: 1}}, @@ -356,6 +382,7 @@ const PrecisionMetrics = { reduceSumSquare: {ULP: {float32: getReductionPrecisionTolerance, float16: getReductionPrecisionTolerance}}, // End Reduction operations relu: {ULP: {float32: 0, float16: 0}}, + resample2d: {ULP: {float32: getResample2dPrecisionTolerance, float16: getResample2dPrecisionTolerance}}, reshape: {ULP: {float32: 0, float16: 0}}, sigmoid: {ULP: {float32: 32+2, float16: 3}}, // float32 (leaving a few ULP for roundoff) slice: {ULP: {float32: 0, float16: 0}}, @@ -365,6 +392,7 @@ const PrecisionMetrics = { split: {ULP: {float32: 0, float16: 0}}, tanh: {ATOL: {float32: 1/1024, float16: 1/512}}, transpose: {ULP: {float32: 0, float16: 0}}, + triangular: {ULP: {float32: 0, float16: 0}}, where: {ULP: {float32: 0, float16: 0}}, }; @@ -635,6 +663,13 @@ const buildConcat = (operationName, builder, resources) => { return namedOutputOperand; }; +const buildConstantRange = (operationName, builder, resources) => { + const namedOutputOperand = {}; + // invoke builder.constant(start, step, outputShape, type) + namedOutputOperand[resources.expected.name] = builder[operationName](resources.inputs.start, resources.inputs.step, resources.outputShape, resources.type); + return namedOutputOperand; +}; + const buildConvTranspose2d = (operationName, builder, resources) => { // MLOperand convTranspose2d(MLOperand input, MLOperand filter, optional MLConvTranspose2dOptions options = {}); const namedOutputOperand = {}; @@ -793,25 +828,7 @@ const buildGraph = (operationName, builder, resources, buildFunc) => { }; /** - * Build a graph, synchronously compile graph and execute, then check computed results. - * @param {String} operationName - An operation name - * @param {MLContext} context - A ML context - * @param {MLGraphBuilder} builder - A ML graph builder - * @param {Object} resources - Resources used for building a graph - * @param {Function} buildFunc - A build function for an operation - */ -const runSync = (operationName, context, builder, resources, buildFunc) => { - // build a graph - const [namedOutputOperands, inputs, outputs] = buildGraph(operationName, builder, resources, buildFunc); - // synchronously compile the graph up to the output operand - const graph = builder.buildSync(namedOutputOperands); - // synchronously execute the compiled graph. - context.computeSync(graph, inputs, outputs); - checkResults(operationName, namedOutputOperands, outputs, resources); -}; - -/** - * Build a graph, asynchronously compile graph and execute, then check computed results. + * Build a graph, compile graph and execute, then check computed results. * @param {String} operationName - An operation name * @param {MLContext} context - A ML context * @param {MLGraphBuilder} builder - A ML graph builder @@ -821,9 +838,9 @@ const runSync = (operationName, context, builder, resources, buildFunc) => { const run = async (operationName, context, builder, resources, buildFunc) => { // build a graph const [namedOutputOperands, inputs, outputs] = buildGraph(operationName, builder, resources, buildFunc); - // asynchronously compile the graph up to the output operand + // compile the graph up to the output operand const graph = await builder.build(namedOutputOperands); - // asynchronously execute the compiled graph + // execute the compiled graph const result = await context.compute(graph, inputs, outputs); checkResults(operationName, namedOutputOperands, result.outputs, resources); }; @@ -835,6 +852,10 @@ const run = async (operationName, context, builder, resources, buildFunc) => { * @param {String} deviceType - The execution device type for this test */ const testWebNNOperation = (operationName, buildFunc, deviceType = 'cpu') => { + test(() => assert_not_equals(navigator.ml, undefined, "ml property is defined on navigator")); + if (navigator.ml === undefined) { + return; + } let operationNameArray; if (typeof operationName === 'string') { operationNameArray = [operationName]; @@ -842,41 +863,18 @@ const testWebNNOperation = (operationName, buildFunc, deviceType = 'cpu') => { operationNameArray = operationName; } - ExecutionArray.forEach(executionType => { - const isSync = executionType === 'sync'; - if (self.GLOBAL.isWindow() && isSync) { - return; - } - let context; - let builder; - if (isSync) { - // test sync - operationNameArray.forEach((subOperationName) => { - const tests = loadTests(subOperationName); - setup(() => { - context = navigator.ml.createContextSync({deviceType}); - builder = new MLGraphBuilder(context); - }); - for (const subTest of tests) { - test(() => { - runSync(subOperationName, context, builder, subTest, buildFunc); - }, `${subTest.name} / ${executionType}`); - } - }); - } else { - // test async - operationNameArray.forEach((subOperationName) => { - const tests = loadTests(subOperationName); - promise_setup(async () => { - context = await navigator.ml.createContext({deviceType}); - builder = new MLGraphBuilder(context); - }); - for (const subTest of tests) { - promise_test(async () => { - await run(subOperationName, context, builder, subTest, buildFunc); - }, `${subTest.name} / ${executionType}`); - } - }); + let context; + let builder; + operationNameArray.forEach((subOperationName) => { + const tests = loadTests(subOperationName); + promise_setup(async () => { + context = await navigator.ml.createContext({deviceType}); + builder = new MLGraphBuilder(context); + }); + for (const subTest of tests) { + promise_test(async () => { + await run(subOperationName, context, builder, subTest, buildFunc); + }, `${subTest.name}`); } }); }; @@ -926,4 +924,60 @@ const toHalf = (value) => { * the exponent, which is OK. */ bits += m & 1; return bits; +}; + + +/** + * WebNN buffer creation. + * @param {MLContext} context - the context used to create the buffer. + * @param {Number} bufferSize - Size of the buffer to create, in bytes. + */ +const createBuffer = (context, bufferSize) => { + let buffer; + try { + buffer = context.createBuffer({size: bufferSize}); + assert_equals(buffer.size, bufferSize); + } catch (e) { + assert_true(e instanceof DOMException); + assert_equals(e.name, "NotSupportedError"); + } + return buffer; +}; + +/** + * WebNN destroy buffer twice test. + * @param {String} testName - The name of the test operation. + * @param {String} deviceType - The execution device type for this test. + */ +const testDestroyWebNNBuffer = (testName, deviceType = 'cpu') => { + let context; + let buffer; + promise_setup(async () => { + context = await navigator.ml.createContext({deviceType}); + buffer = createBuffer(context, 4); + }); + promise_test(async () => { + // MLBuffer is not supported for this deviceType. + if (buffer === undefined) { + return; + } + buffer.destroy(); + buffer.destroy(); + }, `${testName}`); +}; + +/** + * WebNN create buffer test. + * @param {String} testName - The name of the test operation. + * @param {Number} bufferSize - Size of the buffer to create, in bytes. + * @param {String} deviceType - The execution device type for this test. + */ +const testCreateWebNNBuffer = (testName, bufferSize, deviceType = 'cpu') => { + let context; + promise_setup(async () => { + context = await navigator.ml.createContext({deviceType}); + }); + promise_test(async () => { + createBuffer(context, bufferSize); + }, `${testName} / ${bufferSize}`); };
\ No newline at end of file |