summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webnn/validation_tests/lstm.https.any.js
diff options
context:
space:
mode:
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.js347
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');