diff options
Diffstat (limited to 'testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js')
-rw-r--r-- | testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js | 347 |
1 files changed, 216 insertions, 131 deletions
diff --git a/testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js b/testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js index efa05090ca..18d609798c 100644 --- a/testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js @@ -1,25 +1,56 @@ // META: title=validation tests for WebNN API lstm operation // META: global=window,dedicatedworker // META: script=../resources/utils_validation.js -// META: timeout=long 'use strict'; const steps = 10, batchSize = 5, inputSize = 3, hiddenSize = 8, numDirections = 1; +// Dimensions required of required inputs. +const kValidInputDimensions = [steps, batchSize, inputSize]; +const kValidWeightDimensions = [numDirections, 4 * hiddenSize, inputSize]; +const kValidRecurrentWeightDimensions = + [numDirections, 4 * hiddenSize, hiddenSize]; +// Dimensions required of optional inputs. +const kValidBiasDimensions = [numDirections, 4 * hiddenSize]; +const kValidPeepholeWeightDimensions = [numDirections, 3 * hiddenSize]; +const kValidInitialHiddenStateDimensions = + [numDirections, batchSize, hiddenSize]; + +// Example descriptors which are valid according to the above dimensions. +const kExampleInputDescriptor = { + dataType: 'float32', + dimensions: kValidInputDimensions +}; +const kExampleWeightDescriptor = { + dataType: 'float32', + dimensions: kValidWeightDimensions +}; +const kExampleRecurrentWeightDescriptor = { + dataType: 'float32', + dimensions: kValidRecurrentWeightDimensions +}; +const kExampleBiasDescriptor = { + dataType: 'float32', + dimensions: kValidBiasDimensions +}; +const kExamplePeepholeWeightDescriptor = { + dataType: 'float32', + dimensions: kValidPeepholeWeightDimensions +}; +const kExampleInitialHiddenStateDescriptor = { + dataType: 'float32', + dimensions: kValidInitialHiddenStateDimensions +}; + const tests = [ { name: '[lstm] Test with default options', - input: {dataType: 'float16', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: {dataType: 'float16', dimensions: kValidInputDimensions}, + weight: {dataType: 'float16', dimensions: kValidWeightDimensions}, + recurrentWeight: + {dataType: 'float16', dimensions: kValidRecurrentWeightDimensions}, steps: steps, hiddenSize: hiddenSize, outputs: [ @@ -29,7 +60,7 @@ const tests = [ }, { name: '[lstm] Test with given options', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, + input: kExampleInputDescriptor, weight: { dataType: 'float32', dimensions: [/*numDirections=*/ 2, 4 * hiddenSize, inputSize] @@ -83,73 +114,43 @@ const tests = [ }, { name: '[lstm] DataError is expected if hiddenSize equals to zero', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: kExampleInputDescriptor, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: 0 }, { name: '[lstm] DataError is expected if hiddenSize is too large', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: kExampleInputDescriptor, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: 4294967295, }, { name: '[lstm] DataError is expected if steps equals to zero', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: kExampleInputDescriptor, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: 0, hiddenSize: hiddenSize, }, { name: '[lstm] DataError is expected if the data type is not one of the floating point types', - input: {dataType: 'uint32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'uint32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'uint32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: {dataType: 'uint32', dimensions: kValidInputDimensions}, + weight: {dataType: 'uint32', dimensions: kValidWeightDimensions}, + recurrentWeight: + {dataType: 'uint32', dimensions: kValidRecurrentWeightDimensions}, steps: steps, hiddenSize: hiddenSize }, { - name: - '[lstm] DataError is expected if the rank of input is not 3', + name: '[lstm] DataError is expected if the rank of input is not 3', input: {dataType: 'float32', dimensions: [steps, batchSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: hiddenSize }, @@ -157,39 +158,27 @@ const tests = [ name: '[lstm] DataError is expected if input.dimensions[0] is not equal to steps', input: {dataType: 'float32', dimensions: [1000, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: hiddenSize }, { name: '[lstm] DataError is expected if the shape of weight is incorrect', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, + input: kExampleInputDescriptor, weight: { dataType: 'float32', dimensions: [numDirections, 4 * hiddenSize, 1000] }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: hiddenSize }, { name: '[lstm] DataError is expected if the rank of recurrentWeight is not 3', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, + input: kExampleInputDescriptor, + weight: kExampleWeightDescriptor, recurrentWeight: {dataType: 'float32', dimensions: [numDirections, 4 * hiddenSize]}, steps: steps, @@ -198,31 +187,19 @@ const tests = [ { name: '[lstm] DataError is expected if the size of options.activations is not 3', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: kExampleInputDescriptor, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: hiddenSize, options: {activations: ['sigmoid', 'tanh']} }, { - name: - '[lstm] DataError is expected if the rank of options.bias is not 2', - input: {dataType: 'float16', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + name: '[lstm] DataError is expected if the rank of options.bias is not 2', + input: {dataType: 'float16', dimensions: kValidInputDimensions}, + weight: {dataType: 'float16', dimensions: kValidWeightDimensions}, + recurrentWeight: + {dataType: 'float16', dimensions: kValidRecurrentWeightDimensions}, steps: steps, hiddenSize: hiddenSize, options: {bias: {dataType: 'float16', dimensions: [numDirections]}} @@ -230,15 +207,10 @@ const tests = [ { name: '[lstm] DataError is expected if the shape of options.recurrentBias.dimensions is incorrect', - input: {dataType: 'float16', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: {dataType: 'float16', dimensions: kValidInputDimensions}, + weight: {dataType: 'float16', dimensions: kValidWeightDimensions}, + recurrentWeight: + {dataType: 'float16', dimensions: kValidRecurrentWeightDimensions}, steps: steps, hiddenSize: hiddenSize, options: { @@ -248,15 +220,10 @@ const tests = [ { name: '[lstm] DataError is expected if the dataType of options.peepholeWeight is incorrect', - input: {dataType: 'float16', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: {dataType: 'float16', dimensions: kValidInputDimensions}, + weight: {dataType: 'float16', dimensions: kValidWeightDimensions}, + recurrentWeight: + {dataType: 'float16', dimensions: kValidRecurrentWeightDimensions}, steps: steps, hiddenSize: hiddenSize, options: { @@ -267,15 +234,10 @@ const tests = [ { name: '[lstm] DataError is expected if the dataType of options.initialHiddenState is incorrect', - input: {dataType: 'float16', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float16', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: {dataType: 'float16', dimensions: kValidInputDimensions}, + weight: {dataType: 'float16', dimensions: kValidWeightDimensions}, + recurrentWeight: + {dataType: 'float16', dimensions: kValidRecurrentWeightDimensions}, steps: steps, hiddenSize: hiddenSize, options: { @@ -288,15 +250,9 @@ const tests = [ { name: '[lstm] DataError is expected if the shape of options.initialCellState is incorrect', - input: {dataType: 'float32', dimensions: [steps, batchSize, inputSize]}, - weight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, inputSize] - }, - recurrentWeight: { - dataType: 'float32', - dimensions: [numDirections, 4 * hiddenSize, hiddenSize] - }, + input: kExampleInputDescriptor, + weight: kExampleWeightDescriptor, + recurrentWeight: kExampleRecurrentWeightDescriptor, steps: steps, hiddenSize: hiddenSize, options: { @@ -384,3 +340,132 @@ tests.forEach( options)); } }, test.name)); + +multi_builder_test(async (t, builder, otherBuilder) => { + const inputFromOtherBuilder = + otherBuilder.input('input', kExampleInputDescriptor); + const weight = builder.input('weight', kExampleWeightDescriptor); + const recurrentWeight = + builder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); + + assert_throws_js( + TypeError, + () => builder.lstm( + inputFromOtherBuilder, weight, recurrentWeight, steps, hiddenSize)); +}, '[lstm] throw if input is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const input = builder.input('input', kExampleInputDescriptor); + const weightFromOtherBuilder = + otherBuilder.input('weight', kExampleWeightDescriptor); + const recurrentWeight = + builder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); + + assert_throws_js( + TypeError, + () => builder.lstm( + input, weightFromOtherBuilder, recurrentWeight, steps, hiddenSize)); +}, '[lstm] throw if weight is from another builder'); + + +multi_builder_test(async (t, builder, otherBuilder) => { + const input = builder.input('input', kExampleInputDescriptor); + const weight = builder.input('weight', kExampleWeightDescriptor); + const recurrentWeightFromOtherBuilder = + otherBuilder.input('recurrentWeight', kExampleRecurrentWeightDescriptor); + + assert_throws_js( + TypeError, + () => builder.lstm( + input, weight, recurrentWeightFromOtherBuilder, steps, hiddenSize)); +}, '[lstm] throw if recurrentWeight is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const biasFromOtherBuilder = + otherBuilder.input('bias', kExampleBiasDescriptor); + const options = {bias: biasFromOtherBuilder}; + + 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 bias option is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const recurrentBiasFromOtherBuilder = + otherBuilder.input('bias', kExampleBiasDescriptor); + const options = {recurrentBias: recurrentBiasFromOtherBuilder}; + + 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 recurrentBias option is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const peepholeWeightFromOtherBuilder = + otherBuilder.input('peepholeWeight', kExamplePeepholeWeightDescriptor); + const options = {peepholeWeight: peepholeWeightFromOtherBuilder}; + + 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 peepholeWeight option is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const initialHiddenStateFromOtherBuilder = otherBuilder.input( + 'initialHiddenState', kExampleInitialHiddenStateDescriptor); + const options = {initialHiddenState: initialHiddenStateFromOtherBuilder}; + + 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 initialHiddenState option is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const initialCellStateFromOtherBuilder = otherBuilder.input( + 'initialCellState', kExampleInitialHiddenStateDescriptor); + const options = {initialCellState: initialCellStateFromOtherBuilder}; + + 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 initialCellState option is from another builder'); + +multi_builder_test(async (t, builder, otherBuilder) => { + const activation = builder.clamp(); + const activationFromOtherBuilder = otherBuilder.clamp(); + 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'); |