tor-browser

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

convTranspose2d.https.any.js (18328B)


      1 // META: title=validation tests for WebNN API convTranspose2d operation
      2 // META: global=window
      3 // META: variant=?cpu
      4 // META: variant=?gpu
      5 // META: variant=?npu
      6 // META: script=../resources/utils_validation.js
      7 
      8 'use strict';
      9 
     10 // Example input in NCHW layout.
     11 const kExampleInputDescriptor = {
     12  dataType: 'float32',
     13  shape: [1, 1, 5, 5]
     14 };
     15 // Example filter in OIHW layout.
     16 const kExampleFilterDescriptor = {
     17  dataType: 'float32',
     18  shape: [1, 1, 3, 3]
     19 };
     20 const kExampleBiasDescriptor = {
     21  dataType: 'float32',
     22  shape: [/* output channels */ 1]
     23 };
     24 
     25 multi_builder_test(async (t, builder, otherBuilder) => {
     26  const inputFromOtherBuilder =
     27      otherBuilder.input('input', kExampleInputDescriptor);
     28 
     29  const filter = builder.input('filter', kExampleFilterDescriptor);
     30  assert_throws_js(
     31      TypeError, () => builder.convTranspose2d(inputFromOtherBuilder, filter));
     32 }, '[convTranspose2d] throw if input is from another builder');
     33 
     34 multi_builder_test(async (t, builder, otherBuilder) => {
     35  const filterFromOtherBuilder =
     36      otherBuilder.input('filter', kExampleFilterDescriptor);
     37 
     38  const input = builder.input('input', kExampleInputDescriptor);
     39  assert_throws_js(
     40      TypeError, () => builder.convTranspose2d(input, filterFromOtherBuilder));
     41 }, '[convTranspose2d] throw if filter is from another builder');
     42 
     43 multi_builder_test(async (t, builder, otherBuilder) => {
     44  const biasFromOtherBuilder =
     45      otherBuilder.input('bias', kExampleBiasDescriptor);
     46  const options = {inputLayout: 'nchw', bias: biasFromOtherBuilder};
     47 
     48  const input = builder.input('input', kExampleInputDescriptor);
     49  const filter = builder.input('filter', kExampleFilterDescriptor);
     50  assert_throws_js(
     51      TypeError, () => builder.convTranspose2d(input, filter, options));
     52 }, '[convTranspose2d] throw if bias option is from another builder');
     53 
     54 const label = 'conv_transpose_2d';
     55 const tests = [
     56  {
     57    name: '[convTranspose2d] Test with default options.',
     58    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
     59    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
     60    output: {dataType: 'float32', shape: [1, 1, 5, 5]}
     61  },
     62  {
     63    name:
     64        '[convTranspose2d] Test with inputLayout="nchw" and filterLayout="hwoi".',
     65    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
     66    filter: {dataType: 'float32', shape: [3, 3, 2, 1]},
     67    options: {
     68      filterLayout: 'hwoi',
     69      inputLayout: 'nchw',
     70    },
     71    output: {dataType: 'float32', shape: [1, 2, 5, 5]}
     72  },
     73  {
     74    name:
     75        '[convTranspose2d] Test with inputLayout="nchw" and filterLayout="ohwi".',
     76    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
     77    filter: {dataType: 'float32', shape: [2, 3, 3, 1]},
     78    options: {
     79      filterLayout: 'ohwi',
     80      inputLayout: 'nchw',
     81    },
     82    output: {dataType: 'float32', shape: [1, 2, 5, 5]}
     83  },
     84  {
     85    name:
     86        '[convTranspose2d] Test with inputLayout="nhwc" and filterLayout="iohw".',
     87    input: {dataType: 'float32', shape: [1, 3, 3, 1]},
     88    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
     89    options: {
     90      filterLayout: 'iohw',
     91      inputLayout: 'nhwc',
     92    },
     93    output: {dataType: 'float32', shape: [1, 5, 5, 2]}
     94  },
     95  {
     96    name:
     97        '[convTranspose2d] Test with inputLayout="nhwc" and filterLayout="hwoi".',
     98    input: {dataType: 'float32', shape: [1, 3, 3, 1]},
     99    filter: {dataType: 'float32', shape: [3, 3, 2, 1]},
    100    options: {
    101      filterLayout: 'hwoi',
    102      inputLayout: 'nhwc',
    103    },
    104    output: {dataType: 'float32', shape: [1, 5, 5, 2]}
    105  },
    106  {
    107    name:
    108        '[convTranspose2d] Test with inputLayout="nhwc" and filterLayout="ohwi".',
    109    input: {dataType: 'float32', shape: [1, 3, 3, 1]},
    110    filter: {dataType: 'float32', shape: [2, 3, 3, 1]},
    111    options: {
    112      filterLayout: 'ohwi',
    113      inputLayout: 'nhwc',
    114    },
    115    output: {dataType: 'float32', shape: [1, 5, 5, 2]}
    116  },
    117  {
    118    name: '[convTranspose2d] Test with strides=[3, 2], outputSizes=[10, 8].',
    119    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    120    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    121    options: {
    122      strides: [3, 2],
    123      outputSizes: [10, 8],
    124    },
    125    output: {dataType: 'float32', shape: [1, 2, 10, 8]}
    126  },
    127  {
    128    name: '[convTranspose2d] Test with strides=[3, 2], outputPadding=[1, 1].',
    129    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    130    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    131    options: {
    132      strides: [3, 2],
    133      outputPadding: [1, 1],
    134    },
    135    output: {dataType: 'float32', shape: [1, 2, 10, 8]}
    136  },
    137  {
    138    name: '[convTranspose2d] Test with padding=1.',
    139    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    140    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    141    options: {
    142      padding: [1, 1, 1, 1],
    143    },
    144    output: {dataType: 'float32', shape: [1, 1, 5, 5]}
    145  },
    146  {
    147    name: '[convTranspose2d] Test with padding=1, groups=3.',
    148    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    149    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    150    options: {
    151      padding: [1, 1, 1, 1],
    152      groups: 3,
    153    },
    154    output: {dataType: 'float32', shape: [1, 3, 5, 5]}
    155  },
    156  {
    157    name: '[convTranspose2d] Test with strides=2.',
    158    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    159    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    160    options: {
    161      strides: [2, 2],
    162    },
    163    output: {dataType: 'float32', shape: [1, 2, 7, 7]}
    164  },
    165  {
    166    name: '[convTranspose2d] Test with strides=2 and padding=1.',
    167    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    168    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    169    options: {
    170      padding: [1, 1, 1, 1],
    171      strides: [2, 2],
    172    },
    173    output: {dataType: 'float32', shape: [1, 1, 5, 5]}
    174  },
    175  {
    176    name:
    177        '[convTranspose2d] Test when the output sizes are explicitly specified, the output padding values are ignored though padding value is not smaller than stride along the same axis.',
    178    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    179    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    180    options: {
    181      outputPadding: [3, 3],
    182      strides: [3, 2],
    183      outputSizes: [10, 8],
    184    },
    185    output: {dataType: 'float32', shape: [1, 2, 10, 8]}
    186  },
    187  {
    188    name: '[convTranspose2d] Throw if the input is not a 4-D tensor.',
    189    input: {dataType: 'float32', shape: [1, 5, 5]},
    190    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    191    options: {label},
    192  },
    193  {
    194    name:
    195        '[convTranspose2d] Throw if the input data type is not floating point.',
    196    input: {dataType: 'int32', shape: [1, 1, 5, 5]},
    197    filter: {dataType: 'int32', shape: [1, 1, 2, 2]},
    198    options: {label},
    199  },
    200  {
    201    name: '[convTranspose2d] Throw if the filter is not a 4-D tensor.',
    202    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    203    filter: {dataType: 'float32', shape: [2, 2]},
    204    options: {label},
    205  },
    206  {
    207    name:
    208        '[convTranspose2d] Throw if the filter data type doesn\'t match the input data type.',
    209    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    210    filter: {dataType: 'int32', shape: [1, 1, 2, 2]},
    211    options: {
    212      label: label,
    213    },
    214  },
    215  {
    216    name: '[convTranspose2d] Throw if the length of padding is not 4.',
    217    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    218    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    219    options: {
    220      padding: [2, 2],
    221      label: label,
    222    },
    223  },
    224  {
    225    name: '[convTranspose2d] Throw if the length of strides is not 2.',
    226    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    227    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    228    options: {
    229      strides: [2],
    230      label: label,
    231    },
    232  },
    233  {
    234    name: '[convTranspose2d] Throw if one stride value is smaller than 1.',
    235    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    236    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    237    options: {
    238      strides: [1, 0],
    239      label: label,
    240    },
    241  },
    242  {
    243    name: '[convTranspose2d] Throw if the length of dilations is not 2.',
    244    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    245    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    246    options: {
    247      dilations: [1],
    248      label: label,
    249    },
    250  },
    251  {
    252    name:
    253        '[convTranspose2d] Throw if the one dilation value is smaller than 1.',
    254    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    255    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    256    options: {
    257      dilations: [1, 0],
    258      label: label,
    259    },
    260  },
    261  {
    262    name:
    263        '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nchw" and filterLayout="iohw".',
    264    input: {dataType: 'float32', shape: [1, 3, 3, 3]},
    265    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    266    options: {
    267      filterLayout: 'iohw',
    268      inputLayout: 'nchw',
    269      groups: 1,
    270      label: label,
    271    },
    272  },
    273  {
    274    name:
    275        '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nchw" and filterLayout="hwoi".',
    276    input: {dataType: 'float32', shape: [1, 3, 3, 3]},
    277    filter: {dataType: 'float32', shape: [3, 1, 2, 1]},
    278    options: {
    279      filterLayout: 'hwoi',
    280      inputLayout: 'nchw',
    281      label: label,
    282    },
    283  },
    284  {
    285    name:
    286        '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nchw" and filterLayout="ohwi".',
    287    input: {dataType: 'float32', shape: [1, 2, 3, 3]},
    288    filter: {dataType: 'float32', shape: [2, 3, 3, 1]},
    289    options: {
    290      filterLayout: 'ohwi',
    291      inputLayout: 'nchw',
    292      label: label,
    293    },
    294  },
    295  {
    296    name:
    297        '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nhwc" and filterLayout="iohw".',
    298    input: {dataType: 'float32', shape: [1, 3, 3, 2]},
    299    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    300    options: {
    301      filterLayout: 'iohw',
    302      inputLayout: 'nhwc',
    303      label: label,
    304    },
    305  },
    306  {
    307    name:
    308        '[convTranspose2d] Throw if the input channels is not equal to the filter input channels inputLayout="nhwc" and filterLayout="hwoi".',
    309    input: {dataType: 'float32', shape: [1, 3, 3, 2]},
    310    filter: {dataType: 'float32', shape: [3, 3, 2, 1]},
    311    options: {
    312      filterLayout: 'hwoi',
    313      inputLayout: 'nhwc',
    314      label: label,
    315    },
    316  },
    317  {
    318    name:
    319        '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nhwc" and filterLayout="ohwi".',
    320    input: {dataType: 'float32', shape: [1, 3, 3, 2]},
    321    filter: {dataType: 'float32', shape: [2, 3, 3, 1]},
    322    options: {
    323      filterLayout: 'ohwi',
    324      inputLayout: 'nhwc',
    325      label: label,
    326    },
    327  },
    328  {
    329    name: '[convTranspose2d] Throw if output channels is too large.',
    330    input: {dataType: 'float32', shape: [1, 4, 5, 5]},
    331    filter: {dataType: 'float32', shape: [4, 2, 2, 2]},
    332    options: {
    333      groups: kMaxUnsignedLong,
    334      label: label,
    335    },
    336  },
    337  {
    338    name: '[convTranspose2d] Throw if the groups is smaller than 1.',
    339    input: {dataType: 'float32', shape: [1, 4, 5, 5]},
    340    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    341    options: {
    342      groups: 0,
    343      label: label,
    344    },
    345  },
    346  {
    347    name:
    348        '[convTranspose2d] Throw due to overflow when calculating the effective filter height.',
    349    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    350    filter: {dataType: 'float32', shape: [1, 1, 434983, 2]},
    351    options: {
    352      dilations: [328443, 1],
    353      label: label,
    354    },
    355  },
    356  {
    357    name:
    358        '[convTranspose2d] Throw due to overflow when calculating the effective filter width.',
    359    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    360    filter: {dataType: 'float32', shape: [1, 1, 2, 234545]},
    361    options: {
    362      dilations: [2, 843452],
    363      label: label,
    364    },
    365  },
    366  {
    367    name:
    368        '[convTranspose2d] Throw due to overflow when dilation height is too large.',
    369    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    370    filter: {dataType: 'float32', shape: [1, 1, 3, 2]},
    371    options: {
    372      dilations: [kMaxUnsignedLong, 1],
    373      label: label,
    374    },
    375  },
    376  {
    377    name:
    378        '[convTranspose2d] Throw due to overflow when dilation width is too large.',
    379    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    380    filter: {dataType: 'float32', shape: [1, 1, 3, 2]},
    381    options: {
    382      dilations: [1, kMaxUnsignedLong],
    383      label: label,
    384    },
    385  },
    386  {
    387    name: '[convTranspose2d] Throw if the bias is not a 1-D tensor.',
    388    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    389    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    390    options: {
    391      bias: {dataType: 'float32', shape: [1, 2]},
    392      label: label,
    393    },
    394  },
    395  {
    396    name:
    397        '[convTranspose2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="iohw".',
    398    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    399    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    400    options: {
    401      filterLayout: 'iohw',
    402      bias: {dataType: 'float32', shape: [2]},
    403      label: label,
    404    },
    405  },
    406  {
    407    name:
    408        '[convTranspose2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="hwoi".',
    409    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    410    filter: {dataType: 'float32', shape: [2, 2, 1, 1]},
    411    options: {
    412      filterLayout: 'hwoi',
    413      bias: {dataType: 'float32', shape: [2]},
    414      label: label,
    415    },
    416  },
    417  {
    418    name:
    419        '[convTranspose2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="ohwi".',
    420    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    421    filter: {dataType: 'float32', shape: [1, 2, 2, 1]},
    422    options: {
    423      filterLayout: 'ohwi',
    424      bias: {dataType: 'float32', shape: [2]},
    425      label: label,
    426    },
    427  },
    428  {
    429    name:
    430        '[convTranspose2d] Throw if the bias data type doesn\'t match input data type.',
    431    input: {dataType: 'float32', shape: [1, 1, 5, 5]},
    432    filter: {dataType: 'float32', shape: [1, 1, 2, 2]},
    433    options: {
    434      bias: {dataType: 'int32', shape: [1]},
    435      label: label,
    436    },
    437  },
    438  {
    439    name:
    440        '[convTranspose2d] Throw if the outputPadding is not a sequence of length 2.',
    441    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    442    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    443    options: {
    444      strides: [3, 2],
    445      outputPadding: [1, 1, 1, 1],
    446      label: label,
    447    },
    448  },
    449  {
    450    name:
    451        '[convTranspose2d] Throw if the outputPadding is not smaller than stride along the width dimension.',
    452    input: {dataType: 'float32', shape: [1, 1, 2, 2]},
    453    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    454    options: {
    455      padding: [0, 0, 3, 3],
    456      strides: [2, 2],
    457      outputPadding: [0, 2],
    458      label: label,
    459    },
    460  },
    461  {
    462    name:
    463        '[convTranspose2d] Throw if the outputPadding is not smaller than stride along the height dimension.',
    464    input: {dataType: 'float32', shape: [1, 1, 2, 2]},
    465    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    466    options: {
    467      padding: [0, 0, 3, 3],
    468      strides: [2, 2],
    469      outputPadding: [2, 0],
    470      label: label,
    471    },
    472  },
    473  {
    474    name:
    475        '[convTranspose2d] Throw if the outputSizes is not a sequence of length 2.',
    476    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    477    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    478    options: {
    479      strides: [3, 2],
    480      outputSizes: [1, 2, 10, 8],
    481      label: label,
    482    },
    483  },
    484  {
    485    name: '[convTranspose2d] Throw if outputSizes[0] is not greater than 0.',
    486    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    487    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    488    options: {
    489      strides: [3, 2],
    490      outputSizes: [0, 7],
    491      label: label,
    492    },
    493  },
    494  {
    495    name: '[convTranspose2d] Throw if outputSizes[1] is not greater than 0.',
    496    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    497    filter: {dataType: 'float32', shape: [1, 2, 3, 3]},
    498    options: {
    499      strides: [3, 2],
    500      outputSizes: [9, 0],
    501      label: label,
    502    },
    503  },
    504  {
    505    name: '[convTranspose2d] Throw if the padding height is too large.',
    506    input: {dataType: 'float32', shape: [1, 1, 2, 2]},
    507    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    508    options: {
    509      padding: [4, 4, 0, 0],
    510      strides: [2, 2],
    511      outputPadding: [1, 0],
    512      label: label,
    513    },
    514  },
    515  {
    516    name: '[convTranspose2d] Throw if the padding width is too large.',
    517    input: {dataType: 'float32', shape: [1, 1, 2, 2]},
    518    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    519    options: {
    520      padding: [0, 0, 4, 4],
    521      strides: [2, 2],
    522      outputPadding: [0, 1],
    523      label: label,
    524    },
    525  },
    526  {
    527    name:
    528        '[convTranspose2d] Throw due to outputSizes values are smaller than the output sizes calculated by not using outputPadding.',
    529    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    530    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    531    options: {
    532      padding: [1, 1, 1, 1],
    533      strides: [2, 2],
    534      outputSizes: [4, 4],
    535      outputPadding: [1, 1],
    536      label: label,
    537    },
    538  },
    539  {
    540    name:
    541        '[convTranspose2d] Throw due to outputSizes values are greater than the output sizes calculated by not using outputPadding.',
    542    input: {dataType: 'float32', shape: [1, 1, 3, 3]},
    543    filter: {dataType: 'float32', shape: [1, 1, 3, 3]},
    544    options: {
    545      padding: [1, 1, 1, 1],
    546      strides: [2, 2],
    547      outputSizes: [6, 8],
    548      outputPadding: [1, 1],
    549      label: label,
    550    },
    551  },
    552 ];
    553 
    554 tests.forEach(
    555    test => promise_test(async t => {
    556      const builder = new MLGraphBuilder(context);
    557      const input = builder.input('input', test.input);
    558      const filter = builder.input('filter', test.filter);
    559 
    560      if (test.options && test.options.bias) {
    561        test.options.bias = builder.input('bias', test.options.bias);
    562      }
    563 
    564      if (test.output &&
    565          context.opSupportLimits().convTranspose2d.input.dataTypes.includes(
    566              test.input.dataType)) {
    567        const output = builder.convTranspose2d(input, filter, test.options);
    568        assert_equals(output.dataType, test.output.dataType);
    569        assert_array_equals(output.shape, test.output.shape);
    570      } else {
    571        const regrexp = new RegExp('\\[' + label + '\\]');
    572        assert_throws_with_label(
    573            () => builder.convTranspose2d(input, filter, test.options),
    574            regrexp);
    575      }
    576    }, test.name));