tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

gru_cell.https.any.js (23119B)


      1 // META: title=test WebNN API gruCell operation
      2 // META: global=window
      3 // META: variant=?cpu
      4 // META: variant=?gpu
      5 // META: variant=?npu
      6 // META: script=../resources/utils.js
      7 // META: timeout=long
      8 
      9 'use strict';
     10 
     11 // https://www.w3.org/TR/webnn/#api-mlgraphbuilder-grucell
     12 // A single time step of the Gated Recurrent Unit recurrent network using an
     13 // update gate and a reset gate to compute the hidden state that rolls into the
     14 // output across the temporal sequence of a recurrent network.
     15 //
     16 // enum MLGruWeightLayout {
     17 //   "zrn",  // update-reset-new gate ordering
     18 //   "rzn"   // reset-update-new gate ordering
     19 // };
     20 //
     21 // enum MLRecurrentNetworkActivation {
     22 //   "relu",
     23 //   "sigmoid",
     24 //   "tanh"
     25 // };
     26 //
     27 // dictionary MLGruCellOptions {
     28 //   MLOperand bias;
     29 //   MLOperand recurrentBias;
     30 //   boolean resetAfter = true;
     31 //   MLGruWeightLayout layout = "zrn";
     32 //   sequence<MLRecurrentNetworkActivation> activations;
     33 // };
     34 //
     35 // MLOperand gruCell(MLOperand input,
     36 //                   MLOperand weight,
     37 //                   MLOperand recurrentWeight,
     38 //                   MLOperand hiddenState,
     39 //                   [EnforceRange] unsigned long hiddenSize,
     40 //                   optional MLGruCellOptions options = {});
     41 
     42 
     43 const getGruCellPrecisionTolerance = (graphResources) => {
     44  const toleranceValueDict = {float32: 3, float16: 3};
     45  const expectedDataType =
     46      graphResources
     47          .expectedOutputs[Object.keys(graphResources.expectedOutputs)[0]]
     48          .descriptor.dataType;
     49  return {metricType: 'ULP', value: toleranceValueDict[expectedDataType]};
     50 };
     51 
     52 const gruCellTests = [
     53  // float32 tests
     54  {
     55    'name':
     56        "gruCell float32 tensors with options.bias, options.recurrentBias and options.activations=['relu', 'relu']",
     57    'graph': {
     58      'inputs': {
     59        'gruCellInput': {
     60          'data': [1, 2, 2, 1, 1, 1],
     61          'descriptor': {shape: [3, 2], dataType: 'float32'}
     62        },
     63        'gruCellWeight': {
     64          'data': [
     65            1,   -1,   2, -2,  0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,
     66            0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,  0.5, -0.5, 0, 0.1
     67          ],
     68          'descriptor': {shape: [12, 2], dataType: 'float32'}
     69        },
     70        'gruCellRecurrentWeight': {
     71          'data': [
     72            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
     73            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
     74            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
     75            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1
     76          ],
     77          'descriptor': {shape: [12, 4], dataType: 'float32'}
     78        },
     79        'gruCellHiddenState': {
     80          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
     81          'descriptor': {shape: [3, 4], dataType: 'float32'}
     82        },
     83        'gruCellBias': {
     84          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
     85          'descriptor': {shape: [12], dataType: 'float32'}
     86        },
     87        'gruCellRecurrentBias': {
     88          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
     89          'descriptor': {shape: [12], dataType: 'float32'}
     90        }
     91      },
     92      'operators': [{
     93        'name': 'gruCell',
     94        'arguments': [
     95          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
     96          {'recurrentWeight': 'gruCellRecurrentWeight'},
     97          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
     98            'options': {
     99              'bias': 'gruCellBias',
    100              'recurrentBias': 'gruCellRecurrentBias',
    101              'resetAfter': false,
    102              'activations': ['relu', 'relu']
    103            }
    104          }
    105        ],
    106        'outputs': 'gruCellOutput'
    107      }],
    108      'expectedOutputs': {
    109        'gruCellOutput': {
    110          'data':
    111              [0, 0, -0.25, -3.84, -4, -15, -2.25, -3.41, -1, -3, -1, -3.41],
    112          'descriptor': {shape: [3, 4], dataType: 'float32'}
    113        }
    114      }
    115    }
    116  },
    117  {
    118    'name':
    119        "gruCell float32 tensors with options.bias, options.recurrentBias, options.activations=['relu', 'relu'] and explicit options.layout='zrn'",
    120    'graph': {
    121      'inputs': {
    122        'gruCellInput': {
    123          'data': [1, 2, 2, 1, 1, 1],
    124          'descriptor': {shape: [3, 2], dataType: 'float32'}
    125        },
    126        'gruCellWeight': {
    127          'data': [
    128            1,   -1,   2, -2,  0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,
    129            0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,  0.5, -0.5, 0, 0.1
    130          ],
    131          'descriptor': {shape: [12, 2], dataType: 'float32'}
    132        },
    133        'gruCellRecurrentWeight': {
    134          'data': [
    135            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    136            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    137            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    138            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1
    139          ],
    140          'descriptor': {shape: [12, 4], dataType: 'float32'}
    141        },
    142        'gruCellHiddenState': {
    143          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    144          'descriptor': {shape: [3, 4], dataType: 'float32'}
    145        },
    146        'gruCellBias': {
    147          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    148          'descriptor': {shape: [12], dataType: 'float32'}
    149        },
    150        'gruCellRecurrentBias': {
    151          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    152          'descriptor': {shape: [12], dataType: 'float32'}
    153        }
    154      },
    155      'operators': [{
    156        'name': 'gruCell',
    157        'arguments': [
    158          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    159          {'recurrentWeight': 'gruCellRecurrentWeight'},
    160          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    161            'options': {
    162              'bias': 'gruCellBias',
    163              'recurrentBias': 'gruCellRecurrentBias',
    164              'resetAfter': false,
    165              'layout': 'zrn',
    166              'activations': ['relu', 'relu']
    167            }
    168          }
    169        ],
    170        'outputs': 'gruCellOutput'
    171      }],
    172      'expectedOutputs': {
    173        'gruCellOutput': {
    174          'data':
    175              [0, 0, -0.25, -3.84, -4, -15, -2.25, -3.41, -1, -3, -1, -3.41],
    176          'descriptor': {shape: [3, 4], dataType: 'float32'}
    177        }
    178      }
    179    }
    180  },
    181  {
    182    'name':
    183        "gruCell float32 tensors with options.bias, options.recurrentBias, options.activations=['relu', 'relu'] and and options.layout='rzn'",
    184    'graph': {
    185      'inputs': {
    186        'gruCellInput': {
    187          'data': [1, 2, 2, 1, 1, 1],
    188          'descriptor': {shape: [3, 2], dataType: 'float32'}
    189        },
    190        'gruCellWeight': {
    191          'data': [
    192            1,   -1,   2, -2,  0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,
    193            0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,  0.5, -0.5, 0, 0.1
    194          ],
    195          'descriptor': {shape: [12, 2], dataType: 'float32'}
    196        },
    197        'gruCellRecurrentWeight': {
    198          'data': [
    199            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    200            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    201            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    202            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    203          ],
    204          'descriptor': {shape: [12, 4], dataType: 'float32'}
    205        },
    206        'gruCellHiddenState': {
    207          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    208          'descriptor': {shape: [3, 4], dataType: 'float32'}
    209        },
    210        'gruCellBias': {
    211          'data': [1, 1, 1, 1, 1, 2, 1, 2, 0.5, 0.5, 0.5, 0.5],
    212          'descriptor': {shape: [12], dataType: 'float32'}
    213        },
    214        'gruCellRecurrentBias': {
    215          'data': [1, 1, 1, 1, 1, 2, 1, 2, 0.5, 0.5, 0.5, 0.5],
    216          'descriptor': {shape: [12], dataType: 'float32'}
    217        }
    218      },
    219      'operators': [{
    220        'name': 'gruCell',
    221        'arguments': [
    222          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    223          {'recurrentWeight': 'gruCellRecurrentWeight'},
    224          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    225            'options': {
    226              'bias': 'gruCellBias',
    227              'recurrentBias': 'gruCellRecurrentBias',
    228              'resetAfter': false,
    229              'layout': 'rzn',
    230              'activations': ['relu', 'relu']
    231            }
    232          }
    233        ],
    234        'outputs': 'gruCellOutput'
    235      }],
    236      'expectedOutputs': {
    237        'gruCellOutput': {
    238          'data':
    239              [0, 0, -0.25, -3.84, -4, -15, -2.25, -3.41, -1, -3, -1, -3.41],
    240          'descriptor': {shape: [3, 4], dataType: 'float32'}
    241        }
    242      }
    243    }
    244  },
    245  {
    246    'name': 'gruCell float32 tensors with all options',
    247    'graph': {
    248      'inputs': {
    249        'gruCellInput': {
    250          'data': [1, 2, 2, 1, 1, 1],
    251          'descriptor': {shape: [3, 2], dataType: 'float32'}
    252        },
    253        'gruCellWeight': {
    254          'data': [
    255            1,   -1,   2, -2,  0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,
    256            0.5, -0.5, 0, 0.1, 1,   -1,   2, -2,  0.5, -0.5, 0, 0.1
    257          ],
    258          'descriptor': {shape: [12, 2], dataType: 'float32'}
    259        },
    260        'gruCellRecurrentWeight': {
    261          'data': [
    262            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    263            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    264            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    265            0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1, 0.1,
    266          ],
    267          'descriptor': {shape: [12, 4], dataType: 'float32'}
    268        },
    269        'gruCellHiddenState': {
    270          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    271          'descriptor': {shape: [3, 4], dataType: 'float32'}
    272        },
    273        'gruCellBias': {
    274          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    275          'descriptor': {shape: [12], dataType: 'float32'}
    276        },
    277        'gruCellRecurrentBias': {
    278          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    279          'descriptor': {shape: [12], dataType: 'float32'}
    280        }
    281      },
    282      'operators': [{
    283        'name': 'gruCell',
    284        'arguments': [
    285          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    286          {'recurrentWeight': 'gruCellRecurrentWeight'},
    287          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    288            'options': {
    289              'bias': 'gruCellBias',
    290              'recurrentBias': 'gruCellRecurrentBias',
    291              'resetAfter': false,
    292              'layout': 'zrn',
    293              'activations': ['relu', 'relu']
    294            }
    295          }
    296        ],
    297        'outputs': 'gruCellOutput'
    298      }],
    299      'expectedOutputs': {
    300        'gruCellOutput': {
    301          'data':
    302              [0, 0, -0.25, -3.84, -4, -15, -2.25, -3.41, -1, -3, -1, -3.41],
    303          'descriptor': {shape: [3, 4], dataType: 'float32'}
    304        }
    305      }
    306    }
    307  },
    308 
    309  // float16 tests
    310  {
    311    'name':
    312        "gruCell float16 tensors with options.bias, options.recurrentBias and options.activations=['relu', 'relu']",
    313    'graph': {
    314      'inputs': {
    315        'gruCellInput': {
    316          'data': [1, 2, 2, 1, 1, 1],
    317          'descriptor': {shape: [3, 2], dataType: 'float16'}
    318        },
    319        'gruCellWeight': {
    320          'data': [
    321            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    322            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    323            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375
    324          ],
    325          'descriptor': {shape: [12, 2], dataType: 'float16'}
    326        },
    327        'gruCellRecurrentWeight': {
    328          'data': [
    329            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    330            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    331            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    332            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    333            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    334            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    335            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    336            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    337            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    338            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    339            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    340            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375
    341          ],
    342          'descriptor': {shape: [12, 4], dataType: 'float16'}
    343        },
    344        'gruCellHiddenState': {
    345          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    346          'descriptor': {shape: [3, 4], dataType: 'float16'}
    347        },
    348        'gruCellBias': {
    349          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    350          'descriptor': {shape: [12], dataType: 'float16'}
    351        },
    352        'gruCellRecurrentBias': {
    353          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    354          'descriptor': {shape: [12], dataType: 'float16'}
    355        }
    356      },
    357      'operators': [{
    358        'name': 'gruCell',
    359        'arguments': [
    360          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    361          {'recurrentWeight': 'gruCellRecurrentWeight'},
    362          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    363            'options': {
    364              'bias': 'gruCellBias',
    365              'recurrentBias': 'gruCellRecurrentBias',
    366              'resetAfter': false,
    367              'activations': ['relu', 'relu']
    368            }
    369          }
    370        ],
    371        'outputs': 'gruCellOutput'
    372      }],
    373      'expectedOutputs': {
    374        'gruCellOutput': {
    375          'data': [
    376            0, 0, -0.25, -3.83984375, -4, -15, -2.25, -3.41015625, -1, -3, -1,
    377            -3.41015625
    378          ],
    379          'descriptor': {shape: [3, 4], dataType: 'float16'}
    380        }
    381      }
    382    }
    383  },
    384  {
    385    'name':
    386        "gruCell float16 tensors with options.bias, options.recurrentBias, options.activations=['relu', 'relu'] and explicit options.layout='zrn'",
    387    'graph': {
    388      'inputs': {
    389        'gruCellInput': {
    390          'data': [1, 2, 2, 1, 1, 1],
    391          'descriptor': {shape: [3, 2], dataType: 'float16'}
    392        },
    393        'gruCellWeight': {
    394          'data': [
    395            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    396            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    397            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375
    398          ],
    399          'descriptor': {shape: [12, 2], dataType: 'float16'}
    400        },
    401        'gruCellRecurrentWeight': {
    402          'data': [
    403            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    404            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    405            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    406            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    407            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    408            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    409            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    410            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    411            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    412            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    413            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    414            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375
    415          ],
    416          'descriptor': {shape: [12, 4], dataType: 'float16'}
    417        },
    418        'gruCellHiddenState': {
    419          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    420          'descriptor': {shape: [3, 4], dataType: 'float16'}
    421        },
    422        'gruCellBias': {
    423          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    424          'descriptor': {shape: [12], dataType: 'float16'}
    425        },
    426        'gruCellRecurrentBias': {
    427          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    428          'descriptor': {shape: [12], dataType: 'float16'}
    429        }
    430      },
    431      'operators': [{
    432        'name': 'gruCell',
    433        'arguments': [
    434          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    435          {'recurrentWeight': 'gruCellRecurrentWeight'},
    436          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    437            'options': {
    438              'bias': 'gruCellBias',
    439              'recurrentBias': 'gruCellRecurrentBias',
    440              'resetAfter': false,
    441              'layout': 'zrn',
    442              'activations': ['relu', 'relu']
    443            }
    444          }
    445        ],
    446        'outputs': 'gruCellOutput'
    447      }],
    448      'expectedOutputs': {
    449        'gruCellOutput': {
    450          'data': [
    451            0, 0, -0.25, -3.83984375, -4, -15, -2.25, -3.41015625, -1, -3, -1,
    452            -3.41015625
    453          ],
    454          'descriptor': {shape: [3, 4], dataType: 'float16'}
    455        }
    456      }
    457    }
    458  },
    459  {
    460    'name':
    461        "gruCell float16 tensors with options.bias, options.recurrentBias, options.activations=['relu', 'relu'] and and options.layout='rzn'",
    462    'graph': {
    463      'inputs': {
    464        'gruCellInput': {
    465          'data': [1, 2, 2, 1, 1, 1],
    466          'descriptor': {shape: [3, 2], dataType: 'float16'}
    467        },
    468        'gruCellWeight': {
    469          'data': [
    470            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    471            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    472            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375
    473          ],
    474          'descriptor': {shape: [12, 2], dataType: 'float16'}
    475        },
    476        'gruCellRecurrentWeight': {
    477          'data': [
    478            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    479            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    480            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    481            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    482            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    483            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    484            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    485            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    486            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    487            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    488            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    489            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375
    490          ],
    491          'descriptor': {shape: [12, 4], dataType: 'float16'}
    492        },
    493        'gruCellHiddenState': {
    494          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    495          'descriptor': {shape: [3, 4], dataType: 'float16'}
    496        },
    497        'gruCellBias': {
    498          'data': [1, 1, 1, 1, 1, 2, 1, 2, 0.5, 0.5, 0.5, 0.5],
    499          'descriptor': {shape: [12], dataType: 'float16'}
    500        },
    501        'gruCellRecurrentBias': {
    502          'data': [1, 1, 1, 1, 1, 2, 1, 2, 0.5, 0.5, 0.5, 0.5],
    503          'descriptor': {shape: [12], dataType: 'float16'}
    504        }
    505      },
    506      'operators': [{
    507        'name': 'gruCell',
    508        'arguments': [
    509          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    510          {'recurrentWeight': 'gruCellRecurrentWeight'},
    511          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    512            'options': {
    513              'bias': 'gruCellBias',
    514              'recurrentBias': 'gruCellRecurrentBias',
    515              'resetAfter': false,
    516              'layout': 'rzn',
    517              'activations': ['relu', 'relu']
    518            }
    519          }
    520        ],
    521        'outputs': 'gruCellOutput'
    522      }],
    523      'expectedOutputs': {
    524        'gruCellOutput': {
    525          'data': [
    526            0, 0, -0.25, -3.83984375, -4, -15, -2.25, -3.41015625, -1, -3, -1,
    527            -3.41015625
    528          ],
    529          'descriptor': {shape: [3, 4], dataType: 'float16'}
    530        }
    531      }
    532    }
    533  },
    534  {
    535    'name': 'gruCell float16 tensors with all options',
    536    'graph': {
    537      'inputs': {
    538        'gruCellInput': {
    539          'data': [1, 2, 2, 1, 1, 1],
    540          'descriptor': {shape: [3, 2], dataType: 'float16'}
    541        },
    542        'gruCellWeight': {
    543          'data': [
    544            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    545            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375,
    546            1, -1, 2, -2, 0.5, -0.5, 0, 0.0999755859375
    547          ],
    548          'descriptor': {shape: [12, 2], dataType: 'float16'}
    549        },
    550        'gruCellRecurrentWeight': {
    551          'data': [
    552            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    553            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    554            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    555            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    556            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    557            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    558            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    559            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    560            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    561            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    562            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375,
    563            0.0999755859375, 0.0999755859375, 0.0999755859375, 0.0999755859375
    564          ],
    565          'descriptor': {shape: [12, 4], dataType: 'float16'}
    566        },
    567        'gruCellHiddenState': {
    568          'data': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    569          'descriptor': {shape: [3, 4], dataType: 'float16'}
    570        },
    571        'gruCellBias': {
    572          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    573          'descriptor': {shape: [12], dataType: 'float16'}
    574        },
    575        'gruCellRecurrentBias': {
    576          'data': [1, 2, 1, 2, 1, 1, 1, 1, 0.5, 0.5, 0.5, 0.5],
    577          'descriptor': {shape: [12], dataType: 'float16'}
    578        }
    579      },
    580      'operators': [{
    581        'name': 'gruCell',
    582        'arguments': [
    583          {'input': 'gruCellInput'}, {'weight': 'gruCellWeight'},
    584          {'recurrentWeight': 'gruCellRecurrentWeight'},
    585          {'hiddenState': 'gruCellHiddenState'}, {'hiddenSize': 4}, {
    586            'options': {
    587              'bias': 'gruCellBias',
    588              'recurrentBias': 'gruCellRecurrentBias',
    589              'resetAfter': false,
    590              'layout': 'zrn',
    591              'activations': ['relu', 'relu']
    592            }
    593          }
    594        ],
    595        'outputs': 'gruCellOutput'
    596      }],
    597      'expectedOutputs': {
    598        'gruCellOutput': {
    599          'data': [
    600            0, 0, -0.25, -3.83984375, -4, -15, -2.25, -3.41015625, -1, -3, -1,
    601            -3.41015625
    602          ],
    603          'descriptor': {shape: [3, 4], dataType: 'float16'}
    604        }
    605      }
    606    }
    607  }
    608 ];
    609 
    610 webnn_conformance_test(
    611    gruCellTests, buildAndExecuteGraph, getGruCellPrecisionTolerance);