diff --git a/webnn/idlharness.https.any.js b/webnn/idlharness.https.any.js index a5f0dcc2f915228..6c95e534a4cd6b5 100644 --- a/webnn/idlharness.https.any.js +++ b/webnn/idlharness.https.any.js @@ -22,7 +22,6 @@ idl_test( ML: ['navigator.ml'], MLContext: ['context'], MLOperand: ['input', 'constant', 'output'], - MLActivation: ['relu'], MLGraphBuilder: ['builder'], MLGraph: ['graph'] }); @@ -35,9 +34,6 @@ idl_test( {dataType: 'float32', dimensions: [2, 3]}, new Float32Array(2 * 3).fill(1)); - // Create an activation which won't be used in the graph. - self.relu = builder.relu(); - self.output = builder.add(input, constant); self.graph = await builder.build({output}); diff --git a/webnn/resources/utils_validation.js b/webnn/resources/utils_validation.js index 7e4369ac7da07d3..69fe14fa45ba939 100644 --- a/webnn/resources/utils_validation.js +++ b/webnn/resources/utils_validation.js @@ -407,11 +407,8 @@ function validateOptionsAxes(operationName) { * @param {String} operationName - An operation name * @param {Array} supportedDataTypes - Test building with these data types * succeeds and test building with all other data types fails - * @param {Boolean} alsoBuildActivation - If test building this operation as an - * activation */ -function validateUnaryOperation( - operationName, supportedDataTypes, alsoBuildActivation = false) { +function validateUnaryOperation(operationName, supportedDataTypes) { promise_test(async t => { const builder = new MLGraphBuilder(context); for (let dataType of supportedDataTypes) { @@ -451,23 +448,13 @@ function validateUnaryOperation( } } }, `[${operationName}] Throw if the dataType is not supported for an unary operator.`); - - if (alsoBuildActivation) { - promise_test(async t => { - const builder = new MLGraphBuilder(context); - builder[operationName](); - }, `[${operationName}] Test building an activation`); - } } /** * Validate a single input operation * @param {String} operationName - An operation name - * @param {Boolean} alsoBuildActivation - If test building this operation as an - * activation */ -function validateSingleInputOperation( - operationName, alsoBuildActivation = false) { +function validateSingleInputOperation(operationName) { promise_test(async t => { const builder = new MLGraphBuilder(context); const supportedDataTypes = @@ -503,13 +490,6 @@ function validateSingleInputOperation( } } }, `[${operationName}] Throw if the data type is not supported for the operator.`); - - if (alsoBuildActivation) { - promise_test(async t => { - const builder = new MLGraphBuilder(context); - builder[operationName](); - }, `[${operationName}] Test building an activation.`); - } } /** diff --git a/webnn/validation_tests/clamp.https.any.js b/webnn/validation_tests/clamp.https.any.js index 5a55dbec29fa1d3..a9ad62c18613252 100644 --- a/webnn/validation_tests/clamp.https.any.js +++ b/webnn/validation_tests/clamp.https.any.js @@ -23,7 +23,7 @@ promise_test(async t => { const output = builder.clamp(input, options); assert_equals(output.dataType(), 'uint32'); assert_array_equals(output.shape(), [1, 2, 3]); -}, '[clamp] Test building an operator with options'); +}, '[clamp] Build with options'); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -40,7 +40,7 @@ promise_test(async t => { const output = builder.clamp(input, options); assert_equals(output.dataType(), 'int32'); assert_array_equals(output.shape(), [1, 2, 3, 4]); -}, '[clamp] Test building an operator with options.minValue == options.maxValue'); +}, '[clamp] Build with options.minValue == options.maxValue'); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -55,7 +55,7 @@ promise_test(async t => { const input = builder.input('input', {dataType: 'uint8', dimensions: [1, 2, 3]}); assert_throws_js(TypeError, () => builder.clamp(input, options)); -}, '[clamp] Throw if options.minValue > options.maxValue when building an operator'); +}, '[clamp] Throw if options.minValue > options.maxValue'); // To be removed once infinite `minValue` is allowed. Tracked in // https://github.com/webmachinelearning/webnn/pull/647. @@ -64,4 +64,4 @@ promise_test(async t => { const options = {minValue: -Infinity}; const input = builder.input('input', {dataType: 'float16', dimensions: []}); assert_throws_js(TypeError, () => builder.clamp(input, options)); -}, '[clamp] Throw if options.minValue is -Infinity when building an operator'); +}, '[clamp] Throw if options.minValue is -Infinity'); diff --git a/webnn/validation_tests/elu.https.any.js b/webnn/validation_tests/elu.https.any.js index f0f72de9ba3b0a2..a84848c2c39b6ef 100644 --- a/webnn/validation_tests/elu.https.any.js +++ b/webnn/validation_tests/elu.https.any.js @@ -6,7 +6,7 @@ validateInputFromAnotherBuilder('elu'); -validateSingleInputOperation('elu', /*alsoBuildActivation=*/ true); +validateSingleInputOperation('elu'); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -16,13 +16,7 @@ promise_test(async t => { const output = builder.elu(input, options); assert_equals(output.dataType(), 'float32'); assert_array_equals(output.shape(), [1, 2, 3]); -}, '[elu] Test building an operator with options'); - -promise_test(async t => { - const builder = new MLGraphBuilder(context); - const options = {alpha: 1.5}; - builder.elu(options); -}, '[elu] Test building an activation with options'); +}, '[elu] Build with options'); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -30,23 +24,25 @@ promise_test(async t => { const input = builder.input('input', {dataType: 'float32', dimensions: [1, 2, 3]}); assert_throws_js(TypeError, () => builder.elu(input, options)); -}, '[elu] Throw if options.alpha <= 0 when building an operator'); +}, '[elu] Throw if options.alpha < 0'); promise_test(async t => { const builder = new MLGraphBuilder(context); - const options = {alpha: NaN}; - const input = builder.input('input', {dataType: 'float16', dimensions: []}); + const options = {alpha: 0}; + const input = builder.input('input', {dataType: 'float32', dimensions: [1]}); assert_throws_js(TypeError, () => builder.elu(input, options)); -}, '[elu] Throw if options.alpha is NaN when building an operator'); +}, '[elu] Throw if options.alpha == 0'); promise_test(async t => { const builder = new MLGraphBuilder(context); - const options = {alpha: 0}; - assert_throws_js(TypeError, () => builder.elu(options)); -}, '[elu] Throw if options.alpha <= 0 when building an activation'); + const options = {alpha: NaN}; + const input = builder.input('input', {dataType: 'float16', dimensions: []}); + assert_throws_js(TypeError, () => builder.elu(input, options)); +}, '[elu] Throw if options.alpha is NaN'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {alpha: Infinity}; - assert_throws_js(TypeError, () => builder.elu(options)); -}, '[elu] Throw if options.alpha is Infinity when building an activation'); + const input = builder.input('input', {dataType: 'float32', dimensions: [1]}); + assert_throws_js(TypeError, () => builder.elu(input, options)); +}, '[elu] Throw if options.alpha is Infinity'); diff --git a/webnn/validation_tests/gelu.https.any.js b/webnn/validation_tests/gelu.https.any.js index 9d89fe36e384ef3..498dc509cee8f05 100644 --- a/webnn/validation_tests/gelu.https.any.js +++ b/webnn/validation_tests/gelu.https.any.js @@ -6,4 +6,4 @@ validateInputFromAnotherBuilder('gelu'); -validateSingleInputOperation('gelu', /*alsoBuildActivation=*/ true); +validateSingleInputOperation('gelu'); diff --git a/webnn/validation_tests/gru.https.any.js b/webnn/validation_tests/gru.https.any.js index b105e97a7e7fb92..ac69fcf83024c93 100644 --- a/webnn/validation_tests/gru.https.any.js +++ b/webnn/validation_tests/gru.https.any.js @@ -323,9 +323,7 @@ tests.forEach( options.layout = test.options.layout; } if (test.options.activations) { - options.activations = []; - test.options.activations.forEach( - activation => options.activations.push(builder[activation]())); + options.activations = test.options.activations; } } @@ -429,18 +427,3 @@ multi_builder_test(async (t, builder, otherBuilder) => { () => builder.gru( input, weight, recurrentWeight, steps, hiddenSize, options)); }, '[gru] throw if initialHiddenState option is from another builder'); - -multi_builder_test(async (t, builder, otherBuilder) => { - const activation = builder.relu(); - const activationFromOtherBuilder = otherBuilder.relu(); - const options = {activations: [activation, activationFromOtherBuilder]}; - - const input = builder.input('input', kExampleInputDescriptor); - const weight = builder.input('weight', kExampleWeightDescriptor); - const recurrentWeight = - builder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); - assert_throws_js( - TypeError, - () => builder.gru( - input, weight, recurrentWeight, steps, hiddenSize, options)); -}, '[gru] throw if any activation option is from another builder'); diff --git a/webnn/validation_tests/gruCell.https.any.js b/webnn/validation_tests/gruCell.https.any.js index 493efc827361bfc..98ba3eec62c43c3 100644 --- a/webnn/validation_tests/gruCell.https.any.js +++ b/webnn/validation_tests/gruCell.https.any.js @@ -340,10 +340,7 @@ tests.forEach( options.layout = test.options.layout; } if (test.options.activations) { - options.activations = []; - test.options.activations.forEach( - activation => - options.activations.push(builder[activation]())); + options.activations = test.options.activations; } } @@ -457,20 +454,3 @@ multi_builder_test(async (t, builder, otherBuilder) => { () => builder.gruCell( input, weight, recurrentWeight, hiddenState, hiddenSize, options)); }, '[gruCell] throw if recurrentBias option is from another builder'); - -multi_builder_test(async (t, builder, otherBuilder) => { - const activation = builder.relu(); - const activationFromOtherBuilder = otherBuilder.relu(); - const options = {activations: [activation, activationFromOtherBuilder]}; - - const input = builder.input('input', kExampleInputDescriptor); - const weight = builder.input('weight', kExampleWeightDescriptor); - const recurrentWeight = - builder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); - const hiddenState = - builder.input('hiddenState', kExampleHiddenStateDescriptor); - assert_throws_js( - TypeError, - () => builder.gruCell( - input, weight, recurrentWeight, hiddenState, hiddenSize, options)); -}, '[gruCell] throw if any activation option is from another builder'); diff --git a/webnn/validation_tests/hardSigmoid.https.any.js b/webnn/validation_tests/hardSigmoid.https.any.js index 65e8eddcf48440e..154e82936f797ca 100644 --- a/webnn/validation_tests/hardSigmoid.https.any.js +++ b/webnn/validation_tests/hardSigmoid.https.any.js @@ -6,8 +6,7 @@ validateInputFromAnotherBuilder('hardSigmoid'); -validateUnaryOperation( - 'hardSigmoid', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('hardSigmoid', floatingPointTypes); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -17,23 +16,18 @@ promise_test(async t => { const output = builder.hardSigmoid(input, options); assert_equals(output.dataType(), 'float16'); assert_array_equals(output.shape(), [1, 2, 3]); -}, '[hardSigmoid] Test building an operator with options'); - -promise_test(async t => { - const builder = new MLGraphBuilder(context); - const options = {alpha: 0.2}; - builder.hardSigmoid(options); -}, '[hardSigmoid] Test building an activation with options'); +}, '[hardSigmoid] Test building with options'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {beta: NaN}; const input = builder.input('input', {dataType: 'float32', dimensions: []}); assert_throws_js(TypeError, () => builder.hardSigmoid(input, options)); -}, '[hardSigmoid] Throw if options.beta is NaN when building an operator'); +}, '[hardSigmoid] Throw if options.beta is NaN'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {alpha: Infinity}; - assert_throws_js(TypeError, () => builder.hardSigmoid(options)); -}, '[hardSigmoid] Throw if options.alpha is Infinity when building an activation'); + const input = builder.input('input', {dataType: 'float32', dimensions: [1]}); + assert_throws_js(TypeError, () => builder.hardSigmoid(input, options)); +}, '[hardSigmoid] Throw if options.alpha is Infinity'); diff --git a/webnn/validation_tests/hardSwish.https.any.js b/webnn/validation_tests/hardSwish.https.any.js index 97ecfb4142de4aa..7bdf6eb1db341c9 100644 --- a/webnn/validation_tests/hardSwish.https.any.js +++ b/webnn/validation_tests/hardSwish.https.any.js @@ -6,5 +6,4 @@ validateInputFromAnotherBuilder('hardSwish'); -validateUnaryOperation( - 'hardSwish', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('hardSwish', floatingPointTypes); diff --git a/webnn/validation_tests/leakyRelu.https.any.js b/webnn/validation_tests/leakyRelu.https.any.js index 8237837f8a7f252..3a8ac892b98d72e 100644 --- a/webnn/validation_tests/leakyRelu.https.any.js +++ b/webnn/validation_tests/leakyRelu.https.any.js @@ -6,7 +6,7 @@ validateInputFromAnotherBuilder('leakyRelu'); -validateSingleInputOperation('leakyRelu', /*alsoBuildActivation=*/ true); +validateSingleInputOperation('leakyRelu'); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -16,23 +16,18 @@ promise_test(async t => { const output = builder.leakyRelu(input, options); assert_equals(output.dataType(), 'float32'); assert_array_equals(output.shape(), [1, 2, 3]); -}, '[leakyRelu] Test building an operator with options'); - -promise_test(async t => { - const builder = new MLGraphBuilder(context); - const options = {alpha: 0.03}; - builder.leakyRelu(options); -}, '[leakyRelu] Test building an activation with options'); +}, '[leakyRelu] Build with options'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {alpha: Infinity}; const input = builder.input('input', {dataType: 'float16', dimensions: []}); assert_throws_js(TypeError, () => builder.leakyRelu(input, options)); -}, '[leakyRelu] Throw if options.alpha is Infinity when building an operator'); +}, '[leakyRelu] Throw if options.alpha is Infinity'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {alpha: -NaN}; - assert_throws_js(TypeError, () => builder.leakyRelu(options)); -}, '[leakyRelu] Throw if options.alpha is -NaN when building an activation'); + const input = builder.input('input', {dataType: 'float32', dimensions: [1]}); + assert_throws_js(TypeError, () => builder.leakyRelu(input, options)); +}, '[leakyRelu] Throw if options.alpha is -NaN'); diff --git a/webnn/validation_tests/linear.https.any.js b/webnn/validation_tests/linear.https.any.js index 6ebca3323f914d2..05f88a34dc7cc44 100644 --- a/webnn/validation_tests/linear.https.any.js +++ b/webnn/validation_tests/linear.https.any.js @@ -6,8 +6,7 @@ validateInputFromAnotherBuilder('linear'); -validateUnaryOperation( - 'linear', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('linear', floatingPointTypes); promise_test(async t => { const builder = new MLGraphBuilder(context); @@ -17,23 +16,18 @@ promise_test(async t => { const output = builder.linear(input, options); assert_equals(output.dataType(), 'float32'); assert_array_equals(output.shape(), [1, 2, 3]); -}, '[linear] Test building an operator with options'); - -promise_test(async t => { - const builder = new MLGraphBuilder(context); - const options = {beta: 1.5}; - builder.linear(options); -}, '[linear] Test building an activation with options'); +}, '[linear] Build with options'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {beta: -Infinity}; const input = builder.input('input', {dataType: 'float16', dimensions: []}); assert_throws_js(TypeError, () => builder.linear(input, options)); -}, '[linear] Throw if options.beta is -Infinity when building an operator'); +}, '[linear] Throw if options.beta is -Infinity'); promise_test(async t => { const builder = new MLGraphBuilder(context); const options = {alpha: NaN}; - assert_throws_js(TypeError, () => builder.linear(options)); -}, '[linear] Throw if options.alpha is NaN when building an activation'); + const input = builder.input('input', {dataType: 'float32', dimensions: [1]}); + assert_throws_js(TypeError, () => builder.linear(input, options)); +}, '[linear] Throw if options.alpha is NaN'); diff --git a/webnn/validation_tests/lstm.https.any.js b/webnn/validation_tests/lstm.https.any.js index 1cb6943c70c5a29..00f6b129dfa9982 100644 --- a/webnn/validation_tests/lstm.https.any.js +++ b/webnn/validation_tests/lstm.https.any.js @@ -318,9 +318,7 @@ tests.forEach( options.layout = test.options.layout; } if (test.options.activations) { - options.activations = []; - test.options.activations.forEach( - activation => options.activations.push(builder[activation]())); + options.activations = test.options.activations; } } @@ -455,18 +453,3 @@ multi_builder_test(async (t, builder, otherBuilder) => { () => builder.lstm( input, weight, recurrentWeight, steps, hiddenSize, options)); }, '[lstm] throw if initialCellState option is from another builder'); - -multi_builder_test(async (t, builder, otherBuilder) => { - const activation = builder.relu(); - const activationFromOtherBuilder = otherBuilder.relu(); - const options = {activations: [activation, activationFromOtherBuilder]}; - - const input = builder.input('input', kExampleInputDescriptor); - const weight = builder.input('weight', kExampleWeightDescriptor); - const recurrentWeight = - builder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); - assert_throws_js( - TypeError, - () => builder.lstm( - input, weight, recurrentWeight, steps, hiddenSize, options)); -}, '[lstm] throw if any activation option is from another builder'); diff --git a/webnn/validation_tests/lstmCell.https.any.js b/webnn/validation_tests/lstmCell.https.any.js index 934ab176bdbf320..28a9cb8dd3f7f1b 100644 --- a/webnn/validation_tests/lstmCell.https.any.js +++ b/webnn/validation_tests/lstmCell.https.any.js @@ -186,25 +186,6 @@ multi_builder_test(async (t, builder, otherBuilder) => { options)); }, '[lstmCell] throw if peepholeWeight option is from another builder'); -multi_builder_test(async (t, builder, otherBuilder) => { - const activation = builder.relu(); - const activationFromOtherBuilder = otherBuilder.relu(); - const options = {activations: [activation, activationFromOtherBuilder]}; - - const input = builder.input('input', kExampleInputDescriptor); - const weight = builder.input('weight', kExampleWeightDescriptor); - const recurrentWeight = - builder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); - const hiddenState = - builder.input('hiddenState', kExampleHiddenStateDescriptor); - const cellState = builder.input('cellState', kExampleCellStateDescriptor); - assert_throws_js( - TypeError, - () => builder.lstmCell( - input, weight, recurrentWeight, hiddenState, cellState, hiddenSize, - options)); -}, '[lstmCell] throw if activation option is from another builder'); - const tests = [ { name: '[lstmCell] Test with default options', @@ -576,9 +557,7 @@ tests.forEach( options.layout = test.options.layout; } if (test.options.activations) { - options.activations = []; - test.options.activations.forEach( - activation => options.activations.push(builder[activation]())); + options.activations = test.options.activations; } } diff --git a/webnn/validation_tests/relu.https.any.js b/webnn/validation_tests/relu.https.any.js index f62e800922564dd..caebba9b316a20b 100644 --- a/webnn/validation_tests/relu.https.any.js +++ b/webnn/validation_tests/relu.https.any.js @@ -6,4 +6,4 @@ validateInputFromAnotherBuilder('relu'); -validateSingleInputOperation('relu', /*alsoBuildActivation=*/ true); +validateSingleInputOperation('relu'); diff --git a/webnn/validation_tests/sigmoid.https.any.js b/webnn/validation_tests/sigmoid.https.any.js index b40ddc3fd4a7bc0..e5401367683ad65 100644 --- a/webnn/validation_tests/sigmoid.https.any.js +++ b/webnn/validation_tests/sigmoid.https.any.js @@ -6,5 +6,4 @@ validateInputFromAnotherBuilder('sigmoid'); -validateUnaryOperation( - 'sigmoid', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('sigmoid', floatingPointTypes); diff --git a/webnn/validation_tests/softplus.https.any.js b/webnn/validation_tests/softplus.https.any.js index 3cf91d26ecb9316..fd1836bfdb6ca12 100644 --- a/webnn/validation_tests/softplus.https.any.js +++ b/webnn/validation_tests/softplus.https.any.js @@ -6,5 +6,4 @@ validateInputFromAnotherBuilder('softplus'); -validateUnaryOperation( - 'softplus', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('softplus', floatingPointTypes); diff --git a/webnn/validation_tests/softsign.https.any.js b/webnn/validation_tests/softsign.https.any.js index 58ec4871599686e..11b462c3a3efce8 100644 --- a/webnn/validation_tests/softsign.https.any.js +++ b/webnn/validation_tests/softsign.https.any.js @@ -6,5 +6,4 @@ validateInputFromAnotherBuilder('softsign'); -validateUnaryOperation( - 'softsign', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('softsign', floatingPointTypes); diff --git a/webnn/validation_tests/tanh.https.any.js b/webnn/validation_tests/tanh.https.any.js index 4f9de919f61e2f1..deb9f3614eb97fa 100644 --- a/webnn/validation_tests/tanh.https.any.js +++ b/webnn/validation_tests/tanh.https.any.js @@ -6,5 +6,4 @@ validateInputFromAnotherBuilder('tanh'); -validateUnaryOperation( - 'tanh', floatingPointTypes, /*alsoBuildActivation=*/ true); +validateUnaryOperation('tanh', floatingPointTypes);