Source code

Revision control

Copy as Markdown

Other Tools

// META: title=test WebNN API tanh operation
// META: global=window
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long
'use strict';
// Compute the hyperbolic tangent function of the input tensor. The calculation
// follows the expression (exp(2 * x) - 1) / (exp(2 * x) + 1).
//
// MLOperand tanh(MLOperand input);
const getTanhPrecisionTolerance = (graphResources) => {
const toleranceValueDict = {float32: 1 / 1024, float16: 1 / 512};
const expectedDataType =
getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
return {metricType: 'ATOL', value: toleranceValueDict[expectedDataType]};
};
const tanhTests = [
{
'name': 'tanh float32 1D constant tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.473527431488037, -1.1535595655441284, 0.4074455797672272,
1.8297704458236694, 2.869000196456909, -4.570195198059082,
4.146744251251221, -4.065934181213379, -3.7128469944000244,
0.9077175259590149, -0.11083049327135086, 5.955096244812012,
1.7831857204437256, 4.023128509521484, 5.587857723236084,
-5.280653953552246, 1.4147950410842896, -5.707716941833496,
-1.443918228149414, -1.9129083156585693, 2.7495968341827393,
-0.7420240044593811, 4.856568336486816, -0.7563357949256897
],
'descriptor': {shape: [24], dataType: 'float32'},
'constant': true
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
0.9999647736549377, -0.8189298510551453, 0.38630160689353943,
0.9498035907745361, 0.9935782551765442, -0.9997855424880981,
0.9994998574256897, -0.9994121193885803, -0.9988092184066772,
0.7200349569320679, -0.1103789210319519, 0.9999865293502808,
0.945036768913269, 0.9993596076965332, 0.9999719858169556,
-0.9999482035636902, 0.8885080814361572, -0.9999779462814331,
-0.894483745098114, -0.9573289752006531, 0.9918531775474548,
-0.6303664445877075, 0.9998790621757507, -0.6389135718345642
],
'descriptor': {shape: [24], dataType: 'float32'}
}
}
}
},
{
'name': 'tanh float32 1D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.473527431488037, -1.1535595655441284, 0.4074455797672272,
1.8297704458236694, 2.869000196456909, -4.570195198059082,
4.146744251251221, -4.065934181213379, -3.7128469944000244,
0.9077175259590149, -0.11083049327135086, 5.955096244812012,
1.7831857204437256, 4.023128509521484, 5.587857723236084,
-5.280653953552246, 1.4147950410842896, -5.707716941833496,
-1.443918228149414, -1.9129083156585693, 2.7495968341827393,
-0.7420240044593811, 4.856568336486816, -0.7563357949256897
],
'descriptor': {shape: [24], dataType: 'float32'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
0.9999647736549377, -0.8189298510551453, 0.38630160689353943,
0.9498035907745361, 0.9935782551765442, -0.9997855424880981,
0.9994998574256897, -0.9994121193885803, -0.9988092184066772,
0.7200349569320679, -0.1103789210319519, 0.9999865293502808,
0.945036768913269, 0.9993596076965332, 0.9999719858169556,
-0.9999482035636902, 0.8885080814361572, -0.9999779462814331,
-0.894483745098114, -0.9573289752006531, 0.9918531775474548,
-0.6303664445877075, 0.9998790621757507, -0.6389135718345642
],
'descriptor': {shape: [24], dataType: 'float32'}
}
}
}
},
{
'name': 'tanh float32 2D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.473527431488037, -1.1535595655441284, 0.4074455797672272,
1.8297704458236694, 2.869000196456909, -4.570195198059082,
4.146744251251221, -4.065934181213379, -3.7128469944000244,
0.9077175259590149, -0.11083049327135086, 5.955096244812012,
1.7831857204437256, 4.023128509521484, 5.587857723236084,
-5.280653953552246, 1.4147950410842896, -5.707716941833496,
-1.443918228149414, -1.9129083156585693, 2.7495968341827393,
-0.7420240044593811, 4.856568336486816, -0.7563357949256897
],
'descriptor': {shape: [4, 6], dataType: 'float32'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
0.9999647736549377, -0.8189298510551453, 0.38630160689353943,
0.9498035907745361, 0.9935782551765442, -0.9997855424880981,
0.9994998574256897, -0.9994121193885803, -0.9988092184066772,
0.7200349569320679, -0.1103789210319519, 0.9999865293502808,
0.945036768913269, 0.9993596076965332, 0.9999719858169556,
-0.9999482035636902, 0.8885080814361572, -0.9999779462814331,
-0.894483745098114, -0.9573289752006531, 0.9918531775474548,
-0.6303664445877075, 0.9998790621757507, -0.6389135718345642
],
'descriptor': {shape: [4, 6], dataType: 'float32'}
}
}
}
},
{
'name': 'tanh float32 3D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.473527431488037, -1.1535595655441284, 0.4074455797672272,
1.8297704458236694, 2.869000196456909, -4.570195198059082,
4.146744251251221, -4.065934181213379, -3.7128469944000244,
0.9077175259590149, -0.11083049327135086, 5.955096244812012,
1.7831857204437256, 4.023128509521484, 5.587857723236084,
-5.280653953552246, 1.4147950410842896, -5.707716941833496,
-1.443918228149414, -1.9129083156585693, 2.7495968341827393,
-0.7420240044593811, 4.856568336486816, -0.7563357949256897
],
'descriptor': {shape: [2, 3, 4], dataType: 'float32'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
0.9999647736549377, -0.8189298510551453, 0.38630160689353943,
0.9498035907745361, 0.9935782551765442, -0.9997855424880981,
0.9994998574256897, -0.9994121193885803, -0.9988092184066772,
0.7200349569320679, -0.1103789210319519, 0.9999865293502808,
0.945036768913269, 0.9993596076965332, 0.9999719858169556,
-0.9999482035636902, 0.8885080814361572, -0.9999779462814331,
-0.894483745098114, -0.9573289752006531, 0.9918531775474548,
-0.6303664445877075, 0.9998790621757507, -0.6389135718345642
],
'descriptor': {shape: [2, 3, 4], dataType: 'float32'}
}
}
}
},
{
'name': 'tanh float32 4D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.473527431488037, -1.1535595655441284, 0.4074455797672272,
1.8297704458236694, 2.869000196456909, -4.570195198059082,
4.146744251251221, -4.065934181213379, -3.7128469944000244,
0.9077175259590149, -0.11083049327135086, 5.955096244812012,
1.7831857204437256, 4.023128509521484, 5.587857723236084,
-5.280653953552246, 1.4147950410842896, -5.707716941833496,
-1.443918228149414, -1.9129083156585693, 2.7495968341827393,
-0.7420240044593811, 4.856568336486816, -0.7563357949256897
],
'descriptor': {shape: [2, 2, 2, 3], dataType: 'float32'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
0.9999647736549377, -0.8189298510551453, 0.38630160689353943,
0.9498035907745361, 0.9935782551765442, -0.9997855424880981,
0.9994998574256897, -0.9994121193885803, -0.9988092184066772,
0.7200349569320679, -0.1103789210319519, 0.9999865293502808,
0.945036768913269, 0.9993596076965332, 0.9999719858169556,
-0.9999482035636902, 0.8885080814361572, -0.9999779462814331,
-0.894483745098114, -0.9573289752006531, 0.9918531775474548,
-0.6303664445877075, 0.9998790621757507, -0.6389135718345642
],
'descriptor': {shape: [2, 2, 2, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'tanh float32 5D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.473527431488037, -1.1535595655441284, 0.4074455797672272,
1.8297704458236694, 2.869000196456909, -4.570195198059082,
4.146744251251221, -4.065934181213379, -3.7128469944000244,
0.9077175259590149, -0.11083049327135086, 5.955096244812012,
1.7831857204437256, 4.023128509521484, 5.587857723236084,
-5.280653953552246, 1.4147950410842896, -5.707716941833496,
-1.443918228149414, -1.9129083156585693, 2.7495968341827393,
-0.7420240044593811, 4.856568336486816, -0.7563357949256897
],
'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float32'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
0.9999647736549377, -0.8189298510551453, 0.38630160689353943,
0.9498035907745361, 0.9935782551765442, -0.9997855424880981,
0.9994998574256897, -0.9994121193885803, -0.9988092184066772,
0.7200349569320679, -0.1103789210319519, 0.9999865293502808,
0.945036768913269, 0.9993596076965332, 0.9999719858169556,
-0.9999482035636902, 0.8885080814361572, -0.9999779462814331,
-0.894483745098114, -0.9573289752006531, 0.9918531775474548,
-0.6303664445877075, 0.9998790621757507, -0.6389135718345642
],
'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float32'}
}
}
}
},
// float16 tests
{
'name': 'tanh float16 1D constant tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.47265625, -1.1533203125, 0.407470703125, 1.830078125,
2.869140625, -4.5703125, 4.1484375, -4.06640625,
-3.712890625, 0.90771484375, -0.11083984375, 5.95703125,
1.783203125, 4.0234375, 5.5859375, -5.28125,
1.4150390625, -5.70703125, -1.4443359375, -1.9130859375,
2.75, -0.7421875, 4.85546875, -0.75634765625
],
'descriptor': {shape: [24], dataType: 'float16'},
'constant': true
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
1,
-0.81884765625,
0.38623046875,
0.94970703125,
0.99365234375,
-1,
0.99951171875,
-0.99951171875,
-0.9990234375,
0.72021484375,
-0.11041259765625,
1,
0.94482421875,
0.99951171875,
1,
-1,
0.888671875,
-1,
-0.89453125,
-0.95751953125,
0.99169921875,
-0.63037109375,
1,
-0.63916015625
],
'descriptor': {shape: [24], dataType: 'float16'}
}
}
}
},
{
'name': 'tanh float16 1D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.47265625, -1.1533203125, 0.407470703125, 1.830078125,
2.869140625, -4.5703125, 4.1484375, -4.06640625,
-3.712890625, 0.90771484375, -0.11083984375, 5.95703125,
1.783203125, 4.0234375, 5.5859375, -5.28125,
1.4150390625, -5.70703125, -1.4443359375, -1.9130859375,
2.75, -0.7421875, 4.85546875, -0.75634765625
],
'descriptor': {shape: [24], dataType: 'float16'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
1,
-0.81884765625,
0.38623046875,
0.94970703125,
0.99365234375,
-1,
0.99951171875,
-0.99951171875,
-0.9990234375,
0.72021484375,
-0.11041259765625,
1,
0.94482421875,
0.99951171875,
1,
-1,
0.888671875,
-1,
-0.89453125,
-0.95751953125,
0.99169921875,
-0.63037109375,
1,
-0.63916015625
],
'descriptor': {shape: [24], dataType: 'float16'}
}
}
}
},
{
'name': 'tanh float16 2D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.47265625, -1.1533203125, 0.407470703125, 1.830078125,
2.869140625, -4.5703125, 4.1484375, -4.06640625,
-3.712890625, 0.90771484375, -0.11083984375, 5.95703125,
1.783203125, 4.0234375, 5.5859375, -5.28125,
1.4150390625, -5.70703125, -1.4443359375, -1.9130859375,
2.75, -0.7421875, 4.85546875, -0.75634765625
],
'descriptor': {shape: [4, 6], dataType: 'float16'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
1,
-0.81884765625,
0.38623046875,
0.94970703125,
0.99365234375,
-1,
0.99951171875,
-0.99951171875,
-0.9990234375,
0.72021484375,
-0.11041259765625,
1,
0.94482421875,
0.99951171875,
1,
-1,
0.888671875,
-1,
-0.89453125,
-0.95751953125,
0.99169921875,
-0.63037109375,
1,
-0.63916015625
],
'descriptor': {shape: [4, 6], dataType: 'float16'}
}
}
}
},
{
'name': 'tanh float16 3D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.47265625, -1.1533203125, 0.407470703125, 1.830078125,
2.869140625, -4.5703125, 4.1484375, -4.06640625,
-3.712890625, 0.90771484375, -0.11083984375, 5.95703125,
1.783203125, 4.0234375, 5.5859375, -5.28125,
1.4150390625, -5.70703125, -1.4443359375, -1.9130859375,
2.75, -0.7421875, 4.85546875, -0.75634765625
],
'descriptor': {shape: [2, 3, 4], dataType: 'float16'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
1,
-0.81884765625,
0.38623046875,
0.94970703125,
0.99365234375,
-1,
0.99951171875,
-0.99951171875,
-0.9990234375,
0.72021484375,
-0.11041259765625,
1,
0.94482421875,
0.99951171875,
1,
-1,
0.888671875,
-1,
-0.89453125,
-0.95751953125,
0.99169921875,
-0.63037109375,
1,
-0.63916015625
],
'descriptor': {shape: [2, 3, 4], dataType: 'float16'}
}
}
}
},
{
'name': 'tanh float16 4D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.47265625, -1.1533203125, 0.407470703125, 1.830078125,
2.869140625, -4.5703125, 4.1484375, -4.06640625,
-3.712890625, 0.90771484375, -0.11083984375, 5.95703125,
1.783203125, 4.0234375, 5.5859375, -5.28125,
1.4150390625, -5.70703125, -1.4443359375, -1.9130859375,
2.75, -0.7421875, 4.85546875, -0.75634765625
],
'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
1,
-0.81884765625,
0.38623046875,
0.94970703125,
0.99365234375,
-1,
0.99951171875,
-0.99951171875,
-0.9990234375,
0.72021484375,
-0.11041259765625,
1,
0.94482421875,
0.99951171875,
1,
-1,
0.888671875,
-1,
-0.89453125,
-0.95751953125,
0.99169921875,
-0.63037109375,
1,
-0.63916015625
],
'descriptor': {shape: [2, 2, 2, 3], dataType: 'float16'}
}
}
}
},
{
'name': 'tanh float16 5D tensor',
'graph': {
'inputs': {
'tanhInput': {
'data': [
5.47265625, -1.1533203125, 0.407470703125, 1.830078125,
2.869140625, -4.5703125, 4.1484375, -4.06640625,
-3.712890625, 0.90771484375, -0.11083984375, 5.95703125,
1.783203125, 4.0234375, 5.5859375, -5.28125,
1.4150390625, -5.70703125, -1.4443359375, -1.9130859375,
2.75, -0.7421875, 4.85546875, -0.75634765625
],
'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float16'}
}
},
'operators': [{
'name': 'tanh',
'arguments': [{'input': 'tanhInput'}],
'outputs': 'tanhOutput'
}],
'expectedOutputs': {
'tanhOutput': {
'data': [
1,
-0.81884765625,
0.38623046875,
0.94970703125,
0.99365234375,
-1,
0.99951171875,
-0.99951171875,
-0.9990234375,
0.72021484375,
-0.11041259765625,
1,
0.94482421875,
0.99951171875,
1,
-1,
0.888671875,
-1,
-0.89453125,
-0.95751953125,
0.99169921875,
-0.63037109375,
1,
-0.63916015625
],
'descriptor': {shape: [2, 1, 4, 1, 3], dataType: 'float16'}
}
}
}
}
];
if (navigator.ml) {
tanhTests.forEach((test) => {
webnn_conformance_test(
buildAndExecuteGraph, getTanhPrecisionTolerance, test);
});
} else {
test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}