diff --git a/js/common/lib/tensor-impl-type-mapping.ts b/js/common/lib/tensor-impl-type-mapping.ts index c4a43ea27fea1..b7cb176db393b 100644 --- a/js/common/lib/tensor-impl-type-mapping.ts +++ b/js/common/lib/tensor-impl-type-mapping.ts @@ -1,11 +1,17 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import {Float16Array} from '@petamoriken/float16'; + import {Tensor} from './tensor.js'; -export type SupportedTypedArrayConstructors = Float32ArrayConstructor|Uint8ArrayConstructor|Int8ArrayConstructor| - Uint16ArrayConstructor|Int16ArrayConstructor|Int32ArrayConstructor|BigInt64ArrayConstructor|Uint8ArrayConstructor| - Float64ArrayConstructor|Uint32ArrayConstructor|BigUint64ArrayConstructor; +interface Float16ArrayConstructor { + new(): Float16Array; +} + +export type SupportedTypedArrayConstructors = Float32ArrayConstructor|Float16ArrayConstructor|Uint8ArrayConstructor| + Int8ArrayConstructor|Uint16ArrayConstructor|Int16ArrayConstructor|Int32ArrayConstructor|BigInt64ArrayConstructor| + Uint8ArrayConstructor|Float64ArrayConstructor|Uint32ArrayConstructor|BigUint64ArrayConstructor; export type SupportedTypedArray = InstanceType; // a runtime map that maps type string to TypedArray constructor. Should match Tensor.DataTypeMap. @@ -14,7 +20,7 @@ export const NUMERIC_TENSOR_TYPE_TO_TYPEDARRAY_MAP = new Map + BigUint64Array|Uint8Array|Float16Array|Float32Array|Float64Array|Int8Array|Int16Array|Uint16Array => new (tensorTypeToTypedArrayConstructor(type))(dataBuffer); /** diff --git a/js/web/lib/wasm/wasm-common.ts b/js/web/lib/wasm/wasm-common.ts index b9eff45e890c4..4227343390092 100644 --- a/js/web/lib/wasm/wasm-common.ts +++ b/js/web/lib/wasm/wasm-common.ts @@ -1,8 +1,13 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import {Float16Array} from '@petamoriken/float16'; import {Tensor} from 'onnxruntime-common'; +interface Float16ArrayConstructor { + new(): Float16Array; +} + // This file includes common definitions. They do NOT have dependency on the WebAssembly instance. /** @@ -112,12 +117,13 @@ export const getTensorElementSize = (dateType: number): number| /** * get typed array constructor by the given tensor type */ -export const tensorTypeToTypedArrayConstructor = (type: Tensor.Type): Float32ArrayConstructor|Uint8ArrayConstructor| - Int8ArrayConstructor|Uint16ArrayConstructor|Int16ArrayConstructor|Int32ArrayConstructor|BigInt64ArrayConstructor| - Uint8ArrayConstructor|Float64ArrayConstructor|Uint32ArrayConstructor|BigUint64ArrayConstructor => { +export const tensorTypeToTypedArrayConstructor = + (type: Tensor.Type): Float16ArrayConstructor|Float32ArrayConstructor|Uint8ArrayConstructor|Int8ArrayConstructor| + Uint16ArrayConstructor|Int16ArrayConstructor|Int32ArrayConstructor|BigInt64ArrayConstructor|Uint8ArrayConstructor| + Float64ArrayConstructor|Uint32ArrayConstructor|BigUint64ArrayConstructor => { switch (type) { case 'float16': - return Uint16Array; + return Float16Array; case 'float32': return Float32Array; case 'uint8': diff --git a/js/web/package.json b/js/web/package.json index a502c2b6b032d..12e75faa137e9 100644 --- a/js/web/package.json +++ b/js/web/package.json @@ -11,6 +11,7 @@ "version": "1.18.0", "jsdelivr": "dist/ort.min.js", "dependencies": { + "@petamoriken/float16": "^3.8.4", "flatbuffers": "^1.12.0", "guid-typescript": "^1.0.9", "long": "^5.2.3", diff --git a/js/web/test/data/ops/padf16.jsonc b/js/web/test/data/ops/padf16.jsonc new file mode 100644 index 0000000000000..e7b18281c5c66 --- /dev/null +++ b/js/web/test/data/ops/padf16.jsonc @@ -0,0 +1,35 @@ +[ + { + "name": "constant 2D", + "operator": "Pad", + "opset": { "domain": "", "version": 10 }, + "attributes": [ + { "name": "mode", "data": "constant", "type": "string" }, + { "name": "value", "data": 1.2, "type": "float" }, + { "name": "pads", "data": [3, 2, 2, 3], "type": "ints" } + ], + "cases": [ + { + "name": "[2,2]->[7,7]", + "inputs": [ + { + "data": [1.0, 2.0, 3.0, 4.0], + "dims": [2, 2], + "type": "float16" + } + ], + "outputs": [ + { + "data": [ + 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, + 1.2, 1.2, 1.0, 2.0, 1.2, 1.2, 1.2, 1.2, 1.2, 3.0, 4.0, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, + 1.2, 1.2, 1.2, 1.2, 1.2, 1.2, 1.2 + ], + "dims": [7, 7], + "type": "float16" + } + ] + } + ] + } +] diff --git a/js/web/test/test-runner.ts b/js/web/test/test-runner.ts index 442cb1bcf1f34..2e804bc353a3e 100644 --- a/js/web/test/test-runner.ts +++ b/js/web/test/test-runner.ts @@ -1,6 +1,7 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import {Float16Array} from '@petamoriken/float16'; import {expect} from 'chai'; import * as ort from 'onnxruntime-common'; import {extname} from 'path'; @@ -393,11 +394,12 @@ export class TensorResultValidator { case 'string': return this.strictEqual(actual.stringData, expected.stringData); + case 'float16': case 'float32': case 'float64': return this.floatEqual( - actual.numberData as number[] | Float32Array | Float64Array, - expected.numberData as number[] | Float32Array | Float64Array); + actual.numberData as number[] | Float16Array | Float32Array | Float64Array, + expected.numberData as number[] | Float16Array | Float32Array | Float64Array); case 'uint8': case 'int8': @@ -425,7 +427,10 @@ export class TensorResultValidator { return false; } } - floatEqual(actual: number[]|Float32Array|Float64Array, expected: number[]|Float32Array|Float64Array): boolean { + + floatEqual( + actual: number[]|Float16Array|Float32Array|Float64Array, + expected: number[]|Float16Array|Float32Array|Float64Array): boolean { if (actual.length !== expected.length) { return false; } diff --git a/js/web/test/unittests/backends/webgl/test-conv-utils.ts b/js/web/test/unittests/backends/webgl/test-conv-utils.ts index 32cace1ea9040..8e7f0f5d21b9a 100644 --- a/js/web/test/unittests/backends/webgl/test-conv-utils.ts +++ b/js/web/test/unittests/backends/webgl/test-conv-utils.ts @@ -1,14 +1,18 @@ // Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. +import {Float16Array} from '@petamoriken/float16'; + import {Tensor} from '../../../../lib/onnxjs/tensor'; /* eslint-disable no-bitwise */ +type FloatTypedArray = Float16Array|Float32Array|Float64Array; + // eslint-disable-next-line no-underscore-dangle function matMul2d_( - A: Float32Array|Float64Array, B: Float32Array|Float64Array, C: Float32Array|Float64Array, alpha: number, - beta: number, M: number, N: number, K: number) { + A: FloatTypedArray, B: FloatTypedArray, C: FloatTypedArray, alpha: number, beta: number, M: number, N: number, + K: number) { let offsetA = 0, offsetB = 0, offsetC = 0; for (let mm = 0; mm < M; mm++) { for (let nn = 0; nn < N; nn++) { @@ -30,8 +34,8 @@ function matMul2d_( } function matMul2d_tA( - A: Float32Array|Float64Array, B: Float32Array|Float64Array, C: Float32Array|Float64Array, alpha: number, - beta: number, M: number, N: number, K: number) { + A: FloatTypedArray, B: FloatTypedArray, C: FloatTypedArray, alpha: number, beta: number, M: number, N: number, + K: number) { let offsetA = 0, offsetB = 0, offsetC = 0; for (let mm = 0; mm < M; mm++) { for (let nn = 0; nn < N; nn++) { @@ -53,8 +57,8 @@ function matMul2d_tA( } function matMul2d_tB( - A: Float32Array|Float64Array, B: Float32Array|Float64Array, C: Float32Array|Float64Array, alpha: number, - beta: number, M: number, N: number, K: number) { + A: FloatTypedArray, B: FloatTypedArray, C: FloatTypedArray, alpha: number, beta: number, M: number, N: number, + K: number) { let offsetA = 0, offsetB = 0, offsetC = 0; for (let mm = 0; mm < M; mm++) { for (let nn = 0; nn < N; nn++) { @@ -76,8 +80,8 @@ function matMul2d_tB( } function matMul2d_tAtB( - A: Float32Array|Float64Array, B: Float32Array|Float64Array, C: Float32Array|Float64Array, alpha: number, - beta: number, M: number, N: number, K: number) { + A: FloatTypedArray, B: FloatTypedArray, C: FloatTypedArray, alpha: number, beta: number, M: number, N: number, + K: number) { let offsetA = 0, offsetB = 0, offsetC = 0; for (let mm = 0; mm < M; mm++) { for (let nn = 0; nn < N; nn++) { @@ -105,8 +109,8 @@ function matMul2d_tAtB( * @param C data of tensor C, whose shape is [M,N] */ export function matMul2d( - A: Float32Array|Float64Array, B: Float32Array|Float64Array, C: Float32Array|Float64Array, transA: boolean, - transB: boolean, alpha: number, beta: number, M: number, N: number, K: number): void { + A: FloatTypedArray, B: FloatTypedArray, C: FloatTypedArray, transA: boolean, transB: boolean, alpha: number, + beta: number, M: number, N: number, K: number): void { if (transA && transB) { matMul2d_tAtB(A, B, C, alpha, beta, M, N, K); } else if (transA) { @@ -119,9 +123,9 @@ export function matMul2d( } function im2col( - data_im: Float32Array|Float64Array, data_col: Float32Array|Float64Array, channels: number, height: number, - width: number, kernel_h: number, kernel_w: number, dilation_h: number, dilation_w: number, pad_t: number, - pad_l: number, pad_b: number, pad_r: number, stride_h: number, stride_w: number) { + data_im: FloatTypedArray, data_col: FloatTypedArray, channels: number, height: number, width: number, + kernel_h: number, kernel_w: number, dilation_h: number, dilation_w: number, pad_t: number, pad_l: number, + pad_b: number, pad_r: number, stride_h: number, stride_w: number) { const output_h = ~~((height + pad_b + pad_t - (dilation_h * (kernel_h - 1) + 1)) / stride_h) + 1; const output_w = ~~((width + pad_l + pad_r - (dilation_w * (kernel_w - 1) + 1)) / stride_w) + 1;