constant.https.any.js (12816B)
1 // META: title=validation tests for WebNN API constant interface 2 // META: global=window,worker 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 const tests = [ 11 // Tests for constant(descriptor, buffer) 12 { 13 name: 14 '[constant] Test building a 0-D scalar constant with empty dimensions', 15 descriptor: {dataType: 'float32', shape: []}, 16 buffer: {type: Float32Array, byteLength: 1 * 4}, 17 output: {dataType: 'float32', shape: []} 18 }, 19 { 20 name: '[constant] Test building a constant with float32 data type', 21 descriptor: {dataType: 'float32', shape: [2, 3]}, 22 buffer: {type: Float32Array, byteLength: 6 * 4}, 23 output: {dataType: 'float32', shape: [2, 3]} 24 }, 25 { 26 name: 27 '[constant] Throw if byte length of float32 buffer doesn\'t match the given dimensions', 28 descriptor: {dataType: 'float32', shape: [2, 3]}, 29 buffer: { 30 type: Float32Array, 31 byteLength: 6 * 4 - 4 // The buffer's byte length is less than the 32 // one by given dimensions 33 } 34 }, 35 { 36 name: '[constant] Test building a constant with float16 data type', 37 descriptor: {dataType: 'float16', shape: [2, 3]}, 38 buffer: {type: Float16Array, byteLength: 6 * 2}, 39 output: {dataType: 'float16', shape: [2, 3]} 40 }, 41 { 42 name: 43 '[constant] Throw if byte length of float16 buffer doesn\'t match the given dimensions', 44 descriptor: {dataType: 'float16', shape: [2, 3]}, 45 buffer: { 46 type: Float16Array, 47 byteLength: 6 * 2 - 2 // The buffer's byte length is less than the 48 // one by given dimensions 49 } 50 }, 51 { 52 name: 53 '[constant] Throw if using Float32Array buffer for float16 operand data type', 54 descriptor: {dataType: 'float16', shape: [2, 3]}, 55 buffer: { 56 type: Float32Array, 57 byteLength: 6 * 4, 58 }, 59 viewTestOnly: true 60 }, 61 { 62 name: 63 '[constant] Throw if using Int16Array buffer for float16 operand data type', 64 descriptor: {dataType: 'float16', shape: [2, 3]}, 65 buffer: { 66 type: Int16Array, 67 byteLength: 6 * 2, 68 }, 69 viewTestOnly: true 70 }, 71 72 // TODO(crbug.com/399459942): remove below two Uint16Array buffer tests for 73 // float16 data type when implementation removes it. 74 { 75 name: 76 '[constant] Test building a constant with float16 data type using Uint16Array buffer', 77 descriptor: {dataType: 'float16', shape: [2, 3]}, 78 buffer: {type: Uint16Array, byteLength: 6 * 2}, 79 output: {dataType: 'float16', shape: [2, 3]} 80 }, 81 { 82 name: 83 '[constant] Throw if byte length of float16 buffer (using Uint16Array buffer) doesn\'t match the given dimensions', 84 descriptor: {dataType: 'float16', shape: [2, 3]}, 85 buffer: { 86 type: Uint16Array, 87 byteLength: 6 * 2 - 2 // The buffer's byte length is less than the 88 // one by given dimensions 89 } 90 }, 91 { 92 name: '[constant] Test building a constant with int32 data type', 93 descriptor: {dataType: 'int32', shape: [2, 3]}, 94 buffer: {type: Int32Array, byteLength: 6 * 4}, 95 output: {dataType: 'int32', shape: [2, 3]} 96 }, 97 { 98 name: 99 '[constant] Throw if byte length of int32 buffer doesn\'t match the given dimensions', 100 descriptor: {dataType: 'int32', shape: [2, 3]}, 101 buffer: { 102 type: Int32Array, 103 byteLength: 6 * 4 + 4 // The buffer's byte length is greater than the 104 // one by given dimensions 105 } 106 }, 107 { 108 name: '[constant] Test building a constant with uint32 data type', 109 descriptor: {dataType: 'uint32', shape: [2, 3]}, 110 buffer: {type: Uint32Array, byteLength: 6 * 4}, 111 output: {dataType: 'uint32', shape: [2, 3]} 112 }, 113 { 114 name: 115 '[constant] Throw if byte length of uint32 buffer doesn\'t match the given dimensions', 116 descriptor: {dataType: 'uint32', shape: [2, 3]}, 117 buffer: {type: Uint32Array, byteLength: 6 * 4 + 4} 118 }, 119 { 120 name: '[constant] Test building a constant with int64 data type', 121 descriptor: {dataType: 'int64', shape: [2, 3]}, 122 buffer: {type: BigInt64Array, byteLength: 6 * 8}, 123 output: {dataType: 'int64', shape: [2, 3]} 124 }, 125 { 126 name: 127 '[constant] Throw if byte length of int64 buffer doesn\'t match the given dimensions', 128 descriptor: {dataType: 'int64', shape: [2, 3]}, 129 buffer: {type: BigInt64Array, byteLength: 6 * 8 + 8} 130 }, 131 { 132 name: '[constant] Test building a constant with uint64 data type', 133 descriptor: {dataType: 'uint64', shape: [2, 3]}, 134 buffer: {type: BigUint64Array, byteLength: 6 * 8}, 135 output: {dataType: 'uint64', shape: [2, 3]} 136 }, 137 { 138 name: 139 '[constant] Throw if byte length of uint64 buffer doesn\'t match the given dimensions', 140 descriptor: {dataType: 'uint64', shape: [2, 3]}, 141 buffer: {type: BigUint64Array, byteLength: 6 * 8 + 8} 142 }, 143 { 144 name: '[constant] Test building a constant with int8 data type', 145 descriptor: {dataType: 'int8', shape: [2, 3]}, 146 buffer: {type: Int8Array, byteLength: 6 * 1}, 147 output: {dataType: 'int8', shape: [2, 3]} 148 }, 149 { 150 name: 151 '[constant] Throw if byte length of int8 buffer doesn\'t match the given dimensions', 152 descriptor: {dataType: 'int8', shape: [2, 3]}, 153 buffer: {type: Int8Array, byteLength: 6 * 4 - 4} 154 }, 155 { 156 name: '[constant] Test building a constant with uint8 data type', 157 descriptor: {dataType: 'uint8', shape: [2, 3]}, 158 buffer: {type: Uint8Array, byteLength: 6 * 1}, 159 output: {dataType: 'uint8', shape: [2, 3]} 160 }, 161 { 162 name: 163 '[constant] Throw if byte length of uint8 buffer doesn\'t match the given dimensions', 164 descriptor: {dataType: 'uint8', shape: [2, 3]}, 165 buffer: {type: Uint8Array, byteLength: 6 * 4 - 4} 166 }, 167 { 168 name: '[constant] Throw if a dimension is 0', 169 descriptor: {dataType: 'float32', shape: [2, 0]}, 170 buffer: {type: Float32Array, byteLength: 2 * 4} 171 }, 172 { 173 name: 174 '[constant] Throw if using Int32Array buffer for float32 operand data type', 175 descriptor: {dataType: 'float32', shape: [2, 3]}, 176 buffer: {type: Int32Array, byteLength: 6 * 4}, 177 viewTestOnly: true 178 }, 179 { 180 name: 181 '[constant] Throw if the operand data type isn\'t of type MLOperandDataType', 182 descriptor: {dataType: 'int16', shape: [2, 3]}, 183 buffer: {type: Int16Array, byteLength: 6 * 2} 184 }, 185 { 186 name: 187 '[constant] Uint8Array should be allowed for float32 operand data type', 188 descriptor: {dataType: 'float32', shape: [2, 3]}, 189 buffer: {type: Uint8Array, byteLength: 6 * 4}, 190 output: {dataType: 'float32', shape: [2, 3]} 191 }, 192 { 193 name: 194 '[constant] Uint8Array should be allowed for float16 operand data type', 195 descriptor: {dataType: 'float16', shape: [2, 3]}, 196 buffer: {type: Uint8Array, byteLength: 6 * 2}, 197 output: {dataType: 'float16', shape: [2, 3]} 198 }, 199 { 200 name: '[constant] Uint8Array should be allowed for int32 operand data type', 201 descriptor: {dataType: 'int32', shape: [2, 3]}, 202 buffer: {type: Uint8Array, byteLength: 6 * 4}, 203 output: {dataType: 'int32', shape: [2, 3]} 204 } 205 ]; 206 207 // Tests for constant(type, value) 208 const scalarTests = [ 209 { 210 name: '[constant] Test building a scalar constant with float32 data type', 211 dataType: 'float32', 212 value: 3.14, 213 output: {dataType: 'float32'} 214 }, 215 { 216 name: '[constant] Test building a scalar constant with float16 data type', 217 dataType: 'float16', 218 value: 2.5, 219 output: {dataType: 'float16'} 220 }, 221 { 222 name: '[constant] Test building a scalar constant with int32 data type', 223 dataType: 'int32', 224 value: 42, 225 output: {dataType: 'int32'} 226 }, 227 { 228 name: '[constant] Test building a scalar constant with uint32 data type', 229 dataType: 'uint32', 230 value: 123, 231 output: {dataType: 'uint32'} 232 }, 233 { 234 name: '[constant] Test building a scalar constant with max safe integer as BigInt', 235 dataType: 'int64', 236 value: 9007199254740991n, 237 output: {dataType: 'int64'} 238 }, 239 { 240 name: '[constant] Test building a scalar constant with max uint64 as BigInt', 241 dataType: 'uint64', 242 value: 18446744073709551615n, 243 output: {dataType: 'uint64'} 244 }, 245 { 246 name: '[constant] Test building a scalar constant with int8 data type', 247 dataType: 'int8', 248 value: -128, 249 output: {dataType: 'int8'} 250 }, 251 { 252 name: '[constant] Test building a scalar constant with uint8 data type', 253 dataType: 'uint8', 254 value: 255, 255 output: {dataType: 'uint8'} 256 }, 257 { 258 name: '[constant] Test building a scalar constant with zero value', 259 dataType: 'float32', 260 value: 0.0, 261 output: {dataType: 'float32'} 262 }, 263 { 264 name: '[constant] Test building a scalar constant with negative value', 265 dataType: 'int32', 266 value: -42, 267 output: {dataType: 'int32'} 268 }, 269 { 270 name: '[constant] Test building a scalar constant with large float32 value', 271 dataType: 'float32', 272 value: 3.4028235e+38, 273 output: {dataType: 'float32'} 274 }, 275 { 276 name: '[constant] Test building a scalar constant with small float32 value', 277 dataType: 'float32', 278 value: 1.175494e-38, 279 output: {dataType: 'float32'} 280 }, 281 { 282 name: '[constant] Throw if building a scalar constant with int4 data type', 283 dataType: 'int4', 284 value: -2 285 }, 286 { 287 name: '[constant] Throw if building a scalar constant with uint4 data type', 288 dataType: 'uint4', 289 value: 2 290 }, 291 { 292 name: '[constant] Throw if using operand data type that isn\'t of type MLOperandDataType', 293 dataType: 'int16', 294 value: 123 295 }, 296 { 297 name: '[constant] Throw if using BigInt value for float32 data type', 298 dataType: 'float32', 299 value: 123n 300 }, 301 ]; 302 303 tests.forEach( 304 test => promise_test(async t => { 305 const builder = new MLGraphBuilder(context); 306 const buffer = new ArrayBuffer(test.buffer.byteLength); 307 const bufferView = new test.buffer.type(buffer); 308 309 if (test.viewTestOnly === undefined || test.viewTestOnly === false) { 310 // Test building constant from ArrayBuffer. 311 if (test.output) { 312 const constantOperand = builder.constant(test.descriptor, buffer); 313 assert_equals(constantOperand.dataType, test.output.dataType); 314 assert_array_equals(constantOperand.shape, test.output.shape); 315 } else { 316 assert_throws_js( 317 TypeError, () => builder.constant(test.descriptor, buffer)); 318 } 319 if ('SharedArrayBuffer' in globalThis) { 320 // Test building constant from SharedArrayBuffer. 321 const sharedBuffer = new SharedArrayBuffer(test.buffer.byteLength); 322 if (test.output) { 323 const constantOperand = 324 builder.constant(test.descriptor, sharedBuffer); 325 assert_equals(constantOperand.dataType, test.output.dataType); 326 assert_array_equals(constantOperand.shape, test.output.shape); 327 } else { 328 assert_throws_js( 329 TypeError, 330 () => builder.constant(test.descriptor, sharedBuffer)); 331 } 332 } 333 } 334 335 // Test building constant from ArrayBufferView. 336 if (test.output) { 337 const constantOperand = builder.constant(test.descriptor, bufferView); 338 assert_equals(constantOperand.dataType, test.output.dataType); 339 assert_array_equals(constantOperand.shape, test.output.shape); 340 } else { 341 assert_throws_js( 342 TypeError, () => builder.constant(test.descriptor, bufferView)); 343 } 344 if ('SharedArrayBuffer' in globalThis) { 345 // Test building constant from shared ArrayBufferView. 346 const sharedBuffer = new SharedArrayBuffer(test.buffer.byteLength); 347 const sharedBufferView = new test.buffer.type(sharedBuffer); 348 if (test.output) { 349 const constantOperand = 350 builder.constant(test.descriptor, sharedBufferView); 351 assert_equals(constantOperand.dataType, test.output.dataType); 352 assert_array_equals(constantOperand.shape, test.output.shape); 353 } else { 354 assert_throws_js( 355 TypeError, 356 () => builder.constant(test.descriptor, sharedBufferView)); 357 } 358 } 359 }, test.name)); 360 361 // Test scalar constant cases 362 scalarTests.forEach( 363 test => promise_test(async t => { 364 const builder = new MLGraphBuilder(context); 365 366 if (test.output) { 367 // Test successful case 368 const constantOperand = builder.constant(test.dataType, test.value); 369 assert_equals(constantOperand.dataType, test.output.dataType); 370 assert_array_equals(constantOperand.shape, []); 371 } else { 372 // Test error case 373 assert_throws_js( 374 TypeError, () => builder.constant(test.dataType, test.value)); 375 } 376 }, test.name));