Skip to content

Commit d495e6c

Browse files
authored
adds support for Uint8ClampedArray (microsoft#21985)
Fixes microsoft#21753
1 parent d8e64bb commit d495e6c

File tree

4 files changed

+60
-3
lines changed

4 files changed

+60
-3
lines changed

js/common/lib/tensor-impl.ts

+16-3
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,16 @@ export class Tensor implements TensorInterface {
5151
*/
5252
constructor(
5353
type: TensorType,
54-
data: TensorDataType | readonly string[] | readonly number[] | readonly boolean[],
54+
data: TensorDataType | Uint8ClampedArray | readonly string[] | readonly number[] | readonly boolean[],
5555
dims?: readonly number[],
5656
);
5757
/**
5858
* Construct a new CPU tensor object from the given data and dims. Type is inferred from data.
5959
*/
60-
constructor(data: TensorDataType | readonly string[] | readonly boolean[], dims?: readonly number[]);
60+
constructor(
61+
data: TensorDataType | Uint8ClampedArray | readonly string[] | readonly boolean[],
62+
dims?: readonly number[],
63+
);
6164
/**
6265
* Construct a new tensor object from the pinned CPU data with the given type and dims.
6366
*
@@ -90,12 +93,13 @@ export class Tensor implements TensorInterface {
9093
arg0:
9194
| TensorType
9295
| TensorDataType
96+
| Uint8ClampedArray
9397
| readonly string[]
9498
| readonly boolean[]
9599
| CpuPinnedConstructorParameters
96100
| TextureConstructorParameters
97101
| GpuBufferConstructorParameters,
98-
arg1?: TensorDataType | readonly number[] | readonly string[] | readonly boolean[],
102+
arg1?: TensorDataType | Uint8ClampedArray | readonly number[] | readonly string[] | readonly boolean[],
99103
arg2?: readonly number[],
100104
) {
101105
// perform one-time check for BigInt/Float16Array support
@@ -216,6 +220,12 @@ export class Tensor implements TensorInterface {
216220
}
217221
} else if (arg1 instanceof typedArrayConstructor) {
218222
data = arg1;
223+
} else if (arg1 instanceof Uint8ClampedArray) {
224+
if (arg0 === 'uint8') {
225+
data = Uint8Array.from(arg1);
226+
} else {
227+
throw new TypeError(`A Uint8ClampedArray tensor's data must be type of uint8`);
228+
}
219229
} else {
220230
throw new TypeError(`A ${type} tensor's data must be type of ${typedArrayConstructor}`);
221231
}
@@ -243,6 +253,9 @@ export class Tensor implements TensorInterface {
243253
} else {
244254
throw new TypeError(`Invalid element type of data array: ${firstElementType}.`);
245255
}
256+
} else if (arg0 instanceof Uint8ClampedArray) {
257+
type = 'uint8';
258+
data = Uint8Array.from(arg0);
246259
} else {
247260
// get tensor type from TypedArray
248261
const mappedType = NUMERIC_TENSOR_TYPEDARRAY_TO_TYPE_MAP.get(

js/common/lib/tensor.ts

+17
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,15 @@ export interface TensorConstructor extends TensorFactory {
192192
dims?: readonly number[],
193193
): TypedTensor<'bool'>;
194194

195+
/**
196+
* Construct a new uint8 tensor object from a Uint8ClampedArray, data and dims.
197+
*
198+
* @param type - Specify the element type.
199+
* @param data - Specify the CPU tensor data.
200+
* @param dims - Specify the dimension of the tensor. If omitted, a 1-D tensor is assumed.
201+
*/
202+
new (type: 'uint8', data: Uint8ClampedArray, dims?: readonly number[]): TypedTensor<'uint8'>;
203+
195204
/**
196205
* Construct a new 64-bit integer typed tensor object from the given type, data and dims.
197206
*
@@ -245,6 +254,14 @@ export interface TensorConstructor extends TensorFactory {
245254
*/
246255
new (data: Uint8Array, dims?: readonly number[]): TypedTensor<'uint8'>;
247256

257+
/**
258+
* Construct a new uint8 tensor object from the given data and dims.
259+
*
260+
* @param data - Specify the CPU tensor data.
261+
* @param dims - Specify the dimension of the tensor. If omitted, a 1-D tensor is assumed.
262+
*/
263+
new (data: Uint8ClampedArray, dims?: readonly number[]): TypedTensor<'uint8'>;
264+
248265
/**
249266
* Construct a new uint16 tensor object from the given data and dims.
250267
*
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
import * as ort from 'onnxruntime-common';
5+
6+
// construct from Uint8Array
7+
//
8+
// {type-tests}|pass
9+
new ort.Tensor(new Uint8Array(1));
10+
11+
// construct from Uint8ClampedArray
12+
//
13+
// {type-tests}|pass
14+
new ort.Tensor(new Uint8ClampedArray(1));
15+
16+
// construct from type (bool), data (Uint8ClampedArray) and shape (number array)
17+
//
18+
// {type-tests}|fail|1|2769
19+
new ort.Tensor('bool', new Uint8ClampedArray([255, 256]), [2]);

js/common/test/unit-tests/tensor/constructor-type.ts

+8
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,14 @@ describe('Tensor Constructor Tests - check types', () => {
8282
assert.equal(tensor.type, 'bool', "tensor.type should be 'bool'");
8383
});
8484

85+
it('[uint8] new Tensor(uint8ClampedArray, dims): uint8 tensor can be constructed from Uint8ClampedArray', () => {
86+
const uint8ClampedArray = new Uint8ClampedArray(2);
87+
uint8ClampedArray[0] = 0;
88+
uint8ClampedArray[1] = 256; // clamped
89+
const tensor = new Tensor('uint8', uint8ClampedArray, [2]);
90+
assert.equal(tensor.type, 'uint8', "tensor.type should be 'uint8'");
91+
});
92+
8593
it("[bool] new Tensor('bool', uint8Array, dims): tensor can be constructed from Uint8Array", () => {
8694
const tensor = new Tensor('bool', new Uint8Array([1, 0, 1, 0]), [2, 2]);
8795
assert.equal(tensor.type, 'bool', "tensor.type should be 'bool'");

0 commit comments

Comments
 (0)