// META: title=test WebNN API gemm operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long
'use strict';
// https://www.w3.org/TR/webnn/#api-mlgraphbuilder-gemm
// Calculate the general matrix multiplication of the Basic Linear Algebra
// Subprograms. The calculation follows the expression alpha * A * B + beta * C
//
// dictionary MLGemmOptions {
// MLOperand c;
// double alpha = 1.0;
// double beta = 1.0;
// boolean aTranspose = false;
// boolean bTranspose = false;
// };
//
// MLOperand gemm(
// MLOperand a, MLOperand b, optional MLGemmOptions options = {});
const getGemmPrecisionTolerance = (graphResources) => {
// GEMM : alpha * (A x B) + beta * C
// An upper bound for the worst serial ordering is bounded by
// the number of lossy operations, where matrix multiplication
// is a dot product (mul and add times the number of elements)
// plus bias operations.
const args = graphResources.operators[0].arguments;
const shapeA = graphResources.inputs[args[0][Object.keys(args[0])[0]]]
.descriptor.dimensions;
const options =
args.length === 3 ? {...args[2][Object.keys(args[2])[0]]} : {};
const width = options.aTranspose ? shapeA[0] : shapeA[1];
let tolerance = width * 2;
// default options.alpha is 1.0
if (options.alpha !== undefined && options.alpha !== 1.0) {
tolerance++;
}
if (options.c && options.beta !== 0.0) {
// default options.beta is 1.0
if (options.beta !== undefined && options.beta !== 1.0) {
tolerance++;
}
tolerance++;
}
const toleranceValueDict = {float32: tolerance, float16: tolerance};
const expectedDataType =
getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]};
};
const gemmTests = [
{
'name': 'gemm two float32 2D tensors (b is non-constant) default options',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'}
}
},
'operators': [{
'name': 'gemm',
'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors default options',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [{'a': 'inputA'}, {'b': 'inputB'}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D constant tensors options.c',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'},
'constant': true
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8243.9189453125, 14117.208984375, 14620.15234375, 14068.654296875,
18825.609375, 11927.712890625, 14673.310546875, 19176.533203125,
15122.8896484375, 18303.658203125, 5586.16064453125, 9266.43359375,
9195.7294921875, 6438.0244140625, 10939.8330078125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors options.c',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8243.9189453125, 14117.208984375, 14620.15234375, 14068.654296875,
18825.609375, 11927.712890625, 14673.310546875, 19176.533203125,
15122.8896484375, 18303.658203125, 5586.16064453125, 9266.43359375,
9195.7294921875, 6438.0244140625, 10939.8330078125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors broadcast options.c [1, 5] => [3, 5]',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
85.90813446044922, 39.3753547668457, 50.942604064941406,
31.87430763244629, 31.210525512695312
],
'descriptor': {'dimensions': [1, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8247.0546875, 14065.19921875, 14658.443359375, 14080.40625,
18788.30859375, 11978.4189453125, 14699.3505859375, 19176.689453125,
15066.1513671875, 18304.291015625, 5602.5986328125, 9298.642578125,
9218.3349609375, 6379.20458984375, 10899.8125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors broadcast options.c [3, 1] => [3, 5]',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [6.20251989364624, 81.40641784667969, 73.00516510009766],
'descriptor': {'dimensions': [3, 1], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8167.349609375, 14032.0263671875, 14613.703125, 14054.734375,
18763.30078125, 11973.9169921875, 14741.3818359375, 19207.154296875,
15115.68359375, 18354.486328125, 5589.6953125, 9332.2724609375,
9240.3974609375, 6420.33544921875, 10941.607421875
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors broadcast options.c [1, 1] => [3, 5]',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [18.78192901611328],
'descriptor': {'dimensions': [1, 1], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8179.9287109375, 14044.6064453125, 14626.2822265625,
14067.314453125, 18775.87890625, 11911.29296875, 14678.7578125,
19144.529296875, 15053.0595703125, 18291.86328125, 5535.47216796875,
9278.048828125, 9186.173828125, 6366.1123046875, 10887.384765625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors broadcast options.c [5] => [3, 5]',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
85.90813446044922, 39.3753547668457, 50.942604064941406,
31.87430763244629, 31.210525512695312
],
'descriptor': {'dimensions': [5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8247.0546875, 14065.19921875, 14658.443359375, 14080.40625,
18788.30859375, 11978.4189453125, 14699.3505859375, 19176.689453125,
15066.1513671875, 18304.291015625, 5602.5986328125, 9298.642578125,
9218.3349609375, 6379.20458984375, 10899.8125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors broadcast options.c [1] => [3, 5]',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [18.78192901611328],
'descriptor': {'dimensions': [1], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8179.9287109375, 14044.6064453125, 14626.2822265625,
14067.314453125, 18775.87890625, 11911.29296875, 14678.7578125,
19144.529296875, 15053.0595703125, 18291.86328125, 5535.47216796875,
9278.048828125, 9186.173828125, 6366.1123046875, 10887.384765625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors scalar options.c',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [18.78192901611328],
'descriptor': {'dimensions': [], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments':
[{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'c': 'inputC'}}],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8179.9287109375, 14044.6064453125, 14626.2822265625,
14067.314453125, 18775.87890625, 11911.29296875, 14678.7578125,
19144.529296875, 15053.0595703125, 18291.86328125, 5535.47216796875,
9278.048828125, 9186.173828125, 6366.1123046875, 10887.384765625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors options.alpha',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'alpha': 74.43204170482103}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
607450.875, 1043970.75, 1087266.125, 1045661, 1396129.125,
885183.875, 1091172, 1423568.5, 1119032, 1360102.75, 410618.53125,
689186.1875, 682347.75, 472444.78125, 808972.3125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors options.beta',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'beta': 62.01828598608989}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors options.c and options.beta',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'c': 'inputC', 'beta': 62.01828598608989}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
13294.525390625, 19693.37890625, 15392.1494140625, 15296.4638671875,
23006.109375, 14075.7041015625, 15486.96875, 22275.375,
20529.83984375, 20169.443359375, 9825.138671875, 9703.7041015625,
10924.810546875, 11972.0244140625, 15286.1806640625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors options.aTranspose being true',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 18.9648494720459, 50.51683807373047,
90.51641082763672, 43.89479446411133, 40.45679473876953,
59.638519287109375, 98.89488220214844, 50.76741409301758,
36.271873474121094, 91.46013641357422, 9.336554527282715
],
'descriptor': {'dimensions': [4, 3], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'aTranspose': true}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name':
'gemm two float32 2D tensors options.aTranspose being explicit false',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'aTranspose': false}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors options.bTranspose being true',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 0.0037256532814353704, 75.74880981445312,
42.90679168701172, 66.6923828125, 16.4991455078125,
96.60688018798828, 34.08055114746094, 63.29909896850586,
3.036668062210083, 99.10041809082031, 87.37654876708984,
10.629964828491211, 93.14022064208984, 23.2437744140625,
92.34209442138672, 61.32737731933594, 70.08265686035156,
86.11856842041016, 60.32209014892578
],
'descriptor': {'dimensions': [5, 4], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'bTranspose': true}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name':
'gemm two float32 2D tensors options.bTranspose being explicit false',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'}, {'options': {'bTranspose': false}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8161.14697265625, 14025.82421875, 14607.5009765625,
14048.5322265625, 18757.09765625, 11892.5107421875,
14659.9755859375, 19125.74609375, 15034.27734375, 18273.080078125,
5516.6904296875, 9259.267578125, 9167.3916015625, 6347.330078125,
10868.6025390625
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm two float32 2D tensors all options',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 18.9648494720459, 50.51683807373047,
90.51641082763672, 43.89479446411133, 40.45679473876953,
59.638519287109375, 98.89488220214844, 50.76741409301758,
36.271873474121094, 91.46013641357422, 9.336554527282715
],
'descriptor': {'dimensions': [4, 3], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 0.0037256532814353704, 75.74880981445312,
42.90679168701172, 66.6923828125, 16.4991455078125,
96.60688018798828, 34.08055114746094, 63.29909896850586,
3.036668062210083, 99.10041809082031, 87.37654876708984,
10.629964828491211, 93.14022064208984, 23.2437744140625,
92.34209442138672, 61.32737731933594, 70.08265686035156,
86.11856842041016, 60.32209014892578
],
'descriptor': {'dimensions': [5, 4], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'}, {
'options': {
'c': 'inputC',
'alpha': 74.43204170482103,
'beta': 62.01828598608989,
'aTranspose': true,
'bTranspose': true
}
}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
612584.25, 1049638.375, 1088050.75, 1046908.875, 1400378.125,
887367.0625, 1091999, 1426718.125, 1124527.625, 1361999.125, 414927,
689630.625, 684105.1875, 478069.46875, 813389.875
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm both negative options.alpha and 1st float32 input tensor',
'graph': {
'inputs': {
'inputA': {
'data': [
-87.94973754882812, -14.765121459960938, -80.86310577392578,
-59.27638244628906, -28.74825096130371, -9.038779258728027,
-76.046630859375, -83.94807434082031, -95.02689361572266,
-47.89733123779297, -69.0116195678711, -86.66899108886719
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'c': 'inputC', 'alpha': -22.611149749186296}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
246101.234375, 360542.34375, 425213.25, 218520.65625, 383734.40625,
228076.8125, 277543.625, 378076, 241282.15625, 316800.71875,
256391.5625, 378711.34375, 465195.8125, 341034.875, 460338.3125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm both negative options.alpha and 2nd float32 input tensor',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
-64.35197448730469, -87.64981079101562, -96.04495239257812,
-31.07155990600586, -6.548067092895508, -64.64146423339844,
-14.02061653137207, -88.93306732177734, -24.179410934448242,
-97.31866455078125, -93.4608154296875, -39.490394592285156,
-94.37982177734375, -75.83335876464844, -11.403324127197266,
-26.2825927734375, -56.237979888916016, -46.47404861450195,
-89.20684051513672, -53.495323181152344
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'c': 'inputC', 'alpha': -22.611149749186296}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
400725.03125, 292635.75, 527642.375, 283236.40625, 270787.40625,
355130.96875, 256121.421875, 436658.0625, 391465.40625,
235557.03125, 245540.5625, 170154.125, 309239.4375, 163583.015625,
120958.7578125
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name':
'gemm both negative options.beta and 3rd float32 input tensor (options.c)',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
-42.662681579589844, -93.6637954711914, -40.708492279052734,
-45.060977935791016, -87.90338897705078, -71.1618881225586,
-85.56422424316406, -10.049134254455566, -46.105403900146484,
-66.76168060302734, -25.392492294311523, -65.62987518310547,
-40.50155258178711, -81.5303955078125, -41.39629364013672
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'c': 'inputC', 'beta': -11.68521964935509}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
8659.669921875, 15120.3056640625, 15083.1884765625,
14575.0791015625, 19784.267578125, 12724.052734375, 15659.8125,
19243.173828125, 15573.029296875, 19053.205078125, 5813.4072265625,
10026.1669921875, 9640.6611328125, 7300.03076171875,
11352.3271484375
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name': 'gemm both negative options.alpha and options.beta',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
82.77201843261719, 91.38520812988281, 12.651897430419922,
20.12200355529785, 68.51224517822266, 35.202415466308594,
13.33466625213623, 50.78546905517578, 88.61195373535156,
30.577470779418945, 69.47061920166016, 7.166217803955078,
28.337108612060547, 90.69412231445312, 71.23025512695312
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'}, {
'options': {
'c': 'inputC',
'alpha': -22.611149749186296,
'beta': -11.68521964935509
}
}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
-185500.109375, -318207.84375, -330440.21875, -317888.59375,
-424920.125, -269314.6875, -331634.71875, -433048.5625,
-340977.71875, -413532.65625, -125550.484375, -209446.40625,
-207616.390625, -144580.21875, -246583.921875
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
},
{
'name':
'gemm both negative options.alpha and 3rd float32 input tensor (options.c)',
'graph': {
'inputs': {
'inputA': {
'data': [
82.98884582519531, 90.51641082763672, 59.638519287109375,
36.271873474121094, 18.9648494720459, 43.89479446411133,
98.89488220214844, 91.46013641357422, 50.51683807373047,
40.45679473876953, 50.76741409301758, 9.336554527282715
],
'descriptor': {'dimensions': [3, 4], 'dataType': 'float32'}
},
'inputB': {
'data': [
25.14739227294922, 66.6923828125, 63.29909896850586,
10.629964828491211, 61.32737731933594, 0.0037256532814353704,
16.4991455078125, 3.036668062210083, 93.14022064208984,
70.08265686035156, 75.74880981445312, 96.60688018798828,
99.10041809082031, 23.2437744140625, 86.11856842041016,
42.90679168701172, 34.08055114746094, 87.37654876708984,
92.34209442138672, 60.32209014892578
],
'descriptor': {'dimensions': [4, 5], 'dataType': 'float32'},
'constant': true
},
'inputC': {
'data': [
-42.662681579589844, -93.6637954711914, -40.708492279052734,
-45.060977935791016, -87.90338897705078, -71.1618881225586,
-85.56422424316406, -10.049134254455566, -46.105403900146484,
-66.76168060302734, -25.392492294311523, -65.62987518310547,
-40.50155258178711, -81.5303955078125, -41.39629364013672
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'},
'constant': true
}
},
'operators': [{
'name': 'gemm',
'arguments': [
{'a': 'inputA'}, {'b': 'inputB'},
{'options': {'c': 'inputC', 'alpha': -22.611149749186296}}
],
'outputs': 'gemmOutput'
}],
'expectedOutputs': {
'gemmOutput': {
'data': [
-184575.5625, -317233.65625, -330333.09375, -317698.5, -424207.4375,
-268974.5, -331564.4375, -432465.15625, -339988.375, -413242.09375,
-124764.09375, -209428.296875, -207325.765625, -143601.96875,
-245792.984375
],
'descriptor': {'dimensions': [3, 5], 'dataType': 'float32'}
}
}
}
}
];
if (navigator.ml) {
gemmTests.forEach((test) => {
webnn_conformance_test(
buildGraphAndCompute, getGemmPrecisionTolerance, test);
});
} else {
test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}