Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

// META: title=test WebNN API layerNormalization operation
// META: global=window,dedicatedworker
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils.js
// META: timeout=long
'use strict';
// Normalize the input using Layer-Normalization.
//
// dictionary MLLayerNormalizationOptions {
// MLOperand scale;
// MLOperand bias;
// sequence<[EnforceRange] unsigned long> axes;
// double epsilon = 1e-5;
// };
//
// MLOperand layerNormalization(
// MLOperand input, optional MLLayerNormalizationOptions options = {});
const getLayerNormPrecisionTolerance = (graphResources) => {
const toleranceValueDict = {float32: 1 / 1024, float16: 1 / 512};
const expectedDataType =
getExpectedDataTypeOfSingleOutput(graphResources.expectedOutputs);
return {metricType: 'ATOL', value: toleranceValueDict[expectedDataType]};
};
const layerNormTests = [
{
'name': 'layerNormalization float32 2D tensor default options',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [4, 6], dataType: 'float32'}
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [{'input': 'layerNormInput'}],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-1.5257738828659058, 0.997844934463501, 0.017018765211105347,
-0.9768186211585999, 1.2984753847122192, 0.18925349414348602,
1.0812907218933105, -0.915019690990448, 0.4270379841327667,
-1.6873507499694824, 0.9745554327964783, 0.11948632448911667,
-1.5086692571640015, 0.6123882532119751, 0.5316619873046875,
1.2018805742263794, -1.215880036354065, 0.378618448972702,
-1.795186161994934, -0.6376377940177917, 1.1961140632629395,
0.034106940031051636, 0.9297415614128113, 0.2728613615036011
],
'descriptor': {shape: [4, 6], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 3D tensor default options',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 3, 4], dataType: 'float32'}
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [{'input': 'layerNormInput'}],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-1.4057259559631348, 0.5396455526351929, -0.21643976867198944,
-0.9825550317764282, 0.7713912725448608, -0.08366990834474564,
1.46259605884552, -0.8138729333877563, 0.7165266871452332,
-1.6945916414260864, 1.3408818244934082, 0.3658137917518616,
-1.5234858989715576, 0.5162702202796936, 0.43863821029663086,
1.0831668376922607, -1.2419193983078003, 0.29146093130111694,
-1.7796510457992554, -0.5852779150009155, 1.3068104982376099,
0.10783683508634567, 1.0319640636444092, 0.35418668389320374
],
'descriptor': {shape: [2, 3, 4], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 4D tensor default options',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [{'input': 'layerNormInput'}],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-1.4057259559631348, 0.5396455526351929, -0.21643976867198944,
-0.9825550317764282, 0.7713912725448608, -0.08366990834474564,
1.46259605884552, -0.8138729333877563, 0.7165266871452332,
-1.6945916414260864, 1.3408818244934082, 0.3658137917518616,
-1.5234858989715576, 0.5162702202796936, 0.43863821029663086,
1.0831668376922607, -1.2419193983078003, 0.29146093130111694,
-1.7796510457992554, -0.5852779150009155, 1.3068104982376099,
0.10783683508634567, 1.0319640636444092, 0.35418668389320374
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 5D tensor default options',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 2, 2, 3], dataType: 'float32'}
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [{'input': 'layerNormInput'}],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-1.4057259559631348, 0.5396455526351929, -0.21643976867198944,
-0.9825550317764282, 0.7713912725448608, -0.08366990834474564,
1.46259605884552, -0.8138729333877563, 0.7165266871452332,
-1.6945916414260864, 1.3408818244934082, 0.3658137917518616,
-1.5234858989715576, 0.5162702202796936, 0.43863821029663086,
1.0831668376922607, -1.2419193983078003, 0.29146093130111694,
-1.7796510457992554, -0.5852779150009155, 1.3068104982376099,
0.10783683508634567, 1.0319640636444092, 0.35418668389320374
],
'descriptor': {shape: [2, 1, 2, 2, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 4D tensor options.scale',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
},
'layerNormScale': {
'data': [
-3.8228423595428467, -5.452458381652832, 0.6776165962219238,
-4.027037620544434, -3.7771618366241455, -9.327335357666016,
7.1816911697387695, 1.5054303407669067, 3.120894193649292,
0.5214731693267822, 2.6719748973846436, -3.571370840072632
],
'descriptor': {shape: [1, 4, 3], dataType: 'float32'},
'constant': true
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [
{'input': 'layerNormInput'}, {'options': {'scale': 'layerNormScale'}}
],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
5.373868465423584, -2.942394971847534, -0.14666318893432617,
3.9567861557006836, -2.9136698246002197, 0.780417263507843,
10.503913879394531, -1.225229024887085, 2.236203908920288,
-0.8836840987205505, 3.5828025341033936, -1.3064566850662231,
5.824046611785889, -2.814941883087158, 0.29722854495048523,
-4.3619537353515625, 4.6909308433532715, -2.7185537815093994,
-12.780903816223145, -0.8810951709747314, 4.0784173011779785,
0.05623401328921318, 2.7573819160461426, -1.2649319171905518
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 4D tensor options.bias',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
},
'layerNormBias': {
'data': [
7.862982749938965, -3.6603047847747803, -6.955524444580078,
-6.397322654724121, 3.268958568572998, -2.7498080730438232,
-4.080942153930664, -7.137991905212402, 8.465653419494629,
2.762545108795166, 0.8230442404747009, -3.827561378479004
],
'descriptor': {shape: [1, 4, 3], dataType: 'float32'},
'constant': true
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [
{'input': 'layerNormInput'}, {'options': {'bias': 'layerNormBias'}}
],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
6.45725679397583, -3.120659112930298, -7.171964168548584,
-7.37987756729126, 4.040349960327148, -2.8334779739379883,
-2.6183459758758545, -7.951864719390869, 9.182180404663086,
1.0679534673690796, 2.163926124572754, -3.461747646331787,
6.339496612548828, -3.1440346240997314, -6.516886234283447,
-5.314155578613281, 2.027039051055908, -2.4583470821380615,
-5.860593318939209, -7.723269939422607, 9.77246379852295,
2.8703818321228027, 1.8550082445144653, -3.473374605178833
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 4D tensor options.axes=[2]',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [{'input': 'layerNormInput'}, {'options': {'axes': [2]}}],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-0.6012066006660461, 0.10132180899381638, -1.112992763519287,
-0.26228588819503784, 0.3943416476249695, -0.7543209195137024,
1.6960537433624268, -1.6100702285766602, 1.4073745012283325,
-0.8325613141059875, 1.114406704902649, 0.45993921160697937,
-0.8445013165473938, 0.6554933190345764, -0.3856155574321747,
1.3668763637542725, -1.3111618757247925, -0.7422532439231873,
-1.0618212223052979, -0.5766634941101074, 1.7181260585784912,
0.539446234703064, 1.2323321104049683, -0.5902572274208069
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 4D tensor options.epsilon',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
},
'operators': [{
'name': 'layerNormalization',
'arguments':
[{'input': 'layerNormInput'}, {'options': {'epsilon': 0.0001}}],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-1.4057258367538452, 0.5396455526351929, -0.21643976867198944,
-0.9825550317764282, 0.7713912725448608, -0.08366990089416504,
1.46259605884552, -0.8138729333877563, 0.7165266871452332,
-1.6945916414260864, 1.3408817052841187, 0.3658137619495392,
-1.5234858989715576, 0.5162702202796936, 0.43863821029663086,
1.0831668376922607, -1.2419193983078003, 0.29146093130111694,
-1.7796509265899658, -0.5852779150009155, 1.3068104982376099,
0.10783682763576508, 1.0319639444351196, 0.35418668389320374
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name':
'layerNormalization float32 4D tensor options.scale and options.axes=[0, 2]',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
},
'layerNormScale': {
'data': [
8.72657299041748, -5.388210773468018, -6.811323165893555,
4.707905292510986, -4.705780029296875, -5.143046855926514,
-1.1115549802780151, 5.250569820404053
],
'descriptor': {shape: [2, 4], dataType: 'float32'},
'constant': true
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [
{'input': 'layerNormInput'},
{'options': {'scale': 'layerNormScale', 'axes': [0, 2]}}
],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-3.3744184970855713, 5.22746467590332, -7.580371856689453,
0.3324689269065857, -4.414334774017334, 2.973374605178833,
-12.369945526123047, 4.680946350097656, -9.247408866882324,
-2.8648624420166016, 6.40486478805542, 2.4516794681549072,
4.884079456329346, -0.44672244787216187, 2.521172285079956,
-6.083702564239502, 9.044846534729004, 4.759283065795898,
1.3962621688842773, 1.185346245765686, -1.959165334701538,
1.8479242324829102, 3.3530402183532715, -3.986907958984375
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name':
'layerNormalization float32 4D tensor options.bias and options.axes=[3, 1, 2]',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
},
'layerNormBias': {
'data': [
-0.1396923065185547, -6.156772136688232, 4.363296031951904,
8.8598051071167, 9.772650718688965, -3.4626545906066895,
9.744950294494629, -0.3958968222141266, -8.497353553771973,
6.172536849975586, -2.8930461406707764, 1.7220044136047363
],
'descriptor': {shape: [3, 1, 4], dataType: 'float32'},
'constant': true
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [
{'input': 'layerNormInput'},
{'options': {'bias': 'layerNormBias', 'axes': [3, 1, 2]}}
],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-1.5454182624816895, 10.312295913696289, -8.713793754577637,
-7.139327049255371, -2.691263198852539, 6.088866710662842,
5.825891971588135, 8.931077003479004, -2.1765193939208984,
7.165213584899902, 0.9449849724769592, 2.087818145751953,
-1.6631782054901123, 10.288921356201172, -8.058714866638184,
-5.073605060577393, -4.704574108123779, 6.463997840881348,
2.5836451053619385, 9.159672737121582, -1.5862356424331665,
8.967641830444336, 0.6360672116279602, 2.0761911869049072
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
},
{
'name': 'layerNormalization float32 4D tensor all options',
'graph': {
'inputs': {
'layerNormInput': {
'data': [
-35.51446533203125, 54.735408782958984, 19.659019470214844,
-15.882678031921387, 65.48657989501953, 25.818492889404297,
97.55302429199219, -8.057161331176758, 62.9412956237793,
-48.91555404663086, 91.90644073486328, 46.67098617553711,
-74.85331726074219, 30.126361846923828, 26.13089370727539,
59.30270767211914, -60.361995697021484, 18.55615234375,
-88.03730773925781, -26.5667724609375, 70.81292724609375,
9.105611801147461, 56.66746139526367, 21.78444480895996
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
},
'layerNormScale': {
'data': [
7.715926647186279, 1.7371079921722412, 9.13965129852295,
5.758823394775391, -2.8198351860046387, -0.6866958141326904
],
'descriptor': {shape: [2, 3, 1], dataType: 'float32'},
'constant': true
},
'layerNormBias': {
'data': [
-8.710672378540039, -7.642981052398682, 4.937538146972656,
-2.1876745223999023, -4.067612648010254, -6.836254596710205
],
'descriptor': {shape: [2, 3, 1], dataType: 'float32'},
'constant': true
}
},
'operators': [{
'name': 'layerNormalization',
'arguments': [
{'input': 'layerNormInput'}, {
'options': {
'scale': 'layerNormScale',
'bias': 'layerNormBias',
'axes': [0, 3, 1],
'epsilon': 0.0001
}
}
],
'outputs': 'layerNormOutput'
}],
'expectedOutputs': {
'layerNormOutput': {
'data': [
-15.487034797668457, -5.628695964813232, 8.29687786102295,
-14.294686317443848, -5.639192581176758, 7.11608362197876,
0.7769554257392883, -8.346451759338379, 11.279659271240234,
-22.506288528442383, -5.173816204071045, 8.506545066833496,
-12.360523223876953, -5.77052116394043, -7.18900203704834,
3.6336634159088135, 0.8666883707046509, -6.884884357452393,
-11.648612976074219, -2.117840528488159, -7.396423816680908,
-4.869131088256836, -5.8111701011657715, -6.714934349060059
],
'descriptor': {shape: [2, 1, 4, 3], dataType: 'float32'}
}
}
}
}
];
if (navigator.ml) {
layerNormTests.forEach((test) => {
webnn_conformance_test(
buildAndExecuteGraph, getLayerNormPrecisionTolerance, test);
});
} else {
test(() => assert_implements(navigator.ml, 'missing navigator.ml'));
}