add texture cache support for pack/unpack mode (#290)

* squash change

* uncomment test verification

* clean up

* clean up and remove unused files

* adding comment

* remove unused code

* fix reshape merge

* add guid as tensor id

* add file

* fix test failure
This commit is contained in:
Xueyun Zhu 2021-04-27 18:57:29 -07:00 коммит произвёл GitHub
Родитель 290825d28c
Коммит 0c998cc45e
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 192 добавлений и 77 удалений

Просмотреть файл

@ -690,7 +690,7 @@ export class CoordsGlslLib extends GlslLib {
return ${texFuncSnippet}(${unpackedCoordsSnippet});
}
`;
return new GlslLibRoutine(source);
return new GlslLibRoutine(source, ['coordinates.getOutputCoords']);
}
/**
@ -1216,4 +1216,27 @@ export class CoordsGlslLib extends GlslLib {
}
`;
}
/**
* Produces a packed value getter function for the name and rank given
* If a transpose is set proper offsetToCoords mapping will be used
* @param name name of the function
* @param rank rank of the input
* @param transpose whether or not should generate a transpose variation
*/
protected getPackedValueFrom(varName: string, rank: number, width: number, height: number, transpose: boolean):
string {
let name = `_${varName}_Pack`;
if (transpose) {
name = name + '_T';
}
const glsl = getGlsl(this.context.glContext.version);
return `
vec4 ${name}(int m[${rank}]) {
int offset = indicesToOffset_${varName}(m);
vec2 coords = offsetToCoords(offset, ${width}, ${height});
return ${glsl.texture2D}(${varName}, coords);
}
`;
}
}

Просмотреть файл

@ -16,9 +16,16 @@ import {Artifact, RunData, TextureData, TextureLayout, WebGLOperator} from './ty
import {getPackedShape} from './utils';
export class WebGLInferenceHandler implements InferenceHandler {
private textureDataCache: Map<Tensor.Id, TextureData>;
private packedTextureDataCache: Map<Tensor.Id, TextureData>;
private unpackedTextureDataCache: Map<Tensor.Id, TextureData>;
private pack2unpackMap: Map<Tensor.Id, Tensor.Id>;
private unpack2packMap: Map<Tensor.Id, Tensor.Id>;
constructor(public session: WebGLSessionHandler) {
this.textureDataCache = new Map();
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache = new Map();
this.pack2unpackMap = new Map();
this.unpack2packMap = new Map();
}
run(op: WebGLOperator, inputs: Tensor[]): Tensor[] {
@ -33,36 +40,18 @@ export class WebGLInferenceHandler implements InferenceHandler {
return [runData.outputTextureData.tensor];
}
/**
* Check the runData's input texture mode with the program's artifact.
* If the artifact expects a packed input, while the RunData's input
* is unpacked, perform a pack operation on this input to align the
* texture mode with artifact. Similar on unpacked input.
*/
checkAndUpdateTextureForm(artifact: Artifact, runData: RunData) {
// pack/unpack inputs
runData.inputTextureDatas.forEach(input => {
for (let i = 0; i < runData.inputTextureDatas.length; ++i) {
const input = runData.inputTextureDatas[i];
if (input.isPacked && !artifact.programInfo.expectPackedInputs) {
// unpack this input
const unpacked = this.unpack(input);
input.height = unpacked.height;
input.isPacked = unpacked.isPacked;
input.texture = unpacked.texture;
input.width = unpacked.width;
runData.inputTextureDatas[i] = this.unpack(input);
} else if (!input.isPacked && artifact.programInfo.expectPackedInputs) {
// pack this input
const packed = this.pack(input);
input.height = packed.height;
input.isPacked = packed.isPacked;
input.texture = packed.texture;
input.width = packed.width;
runData.inputTextureDatas[i] = this.pack(input);
}
});
}
}
runProgram(artifact: Artifact, runData: RunData) {
// if the runData has different expected texture pack/unpack mode, process pack/unpack
// operation on the texture before executing the kernel.
this.checkAndUpdateTextureForm(artifact, runData);
// output should match
@ -84,15 +73,28 @@ export class WebGLInferenceHandler implements InferenceHandler {
* Creates a texture data object associated with the given tensor.
* @param tensor the tensor with data to upload
*/
getOrCreateTextureData(tensor: Tensor, layout?: TextureLayout) {
let td = this.getTextureData(tensor.dataId);
getOrCreateTextureData(tensor: Tensor, layout?: TextureLayout, isPacked = false) {
let td = this.getTextureData(tensor.dataId, isPacked);
if (!td) {
Logger.verbose('InferenceHandler', `Creating new TextureData for dims: [${tensor.dims}]`);
if (!layout) {
layout = this.createTextureLayoutFromShape(tensor.dims.slice());
}
// graph inputs or initializers
td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, Encoder.Usage.UploadOnly);
// if we don't find the texture data with specific pack mode in the cache, try with the different
// pack mode to see if the tensor is cached using that pack mode. If succeed, we can return this
// tensor data and later apply a pack/unpack op on this texture, no need to create a new one here.
td = this.getTextureData(tensor.dataId, !isPacked);
if (!td) {
if (isPacked) {
const unpackedTextureLayout = this.getOrCreateTextureLayout(tensor, 1, false, [], true);
const unpackedTextureData = this.createTextureData(
unpackedTextureLayout, tensor.type, tensor.numberData, tensor, Encoder.Usage.UploadOnly);
td = this.pack(unpackedTextureData);
} else {
td = this.createTextureData(
layout, tensor.type, tensor.numberData, tensor, Encoder.Usage.UploadOnly, isPacked);
}
}
} else {
Logger.verbose('InferenceHandler', `Retrieving TextureData from cache: [${tensor.dims}]`);
}
@ -104,7 +106,7 @@ export class WebGLInferenceHandler implements InferenceHandler {
* Usage = Encoder.Usage.Default.
* @param dataType the tensor data type
*/
createTextureDataFromLayout(layout: TextureLayout, dataType: Tensor.DataType): TextureData {
createTextureDataFromLayout(layout: TextureLayout, dataType: Tensor.DataType, isPacked = false): TextureData {
return this.createTextureData(layout, dataType);
}
@ -118,13 +120,14 @@ export class WebGLInferenceHandler implements InferenceHandler {
* @param tensor the tensor to bind. tensor's data is ignored.
*/
createTextureDataFromLayoutBindTensor(
layout: TextureLayout, dataType: Tensor.DataType, data: Tensor.NumberType, tensor: Tensor): TextureData {
return this.createTextureData(layout, dataType, data, tensor, Encoder.Usage.UploadOnly);
layout: TextureLayout, dataType: Tensor.DataType, data: Tensor.NumberType, tensor: Tensor,
isPacked = false): TextureData {
return this.createTextureData(layout, dataType, data, tensor, Encoder.Usage.UploadOnly, isPacked);
}
private createTextureData(
layout: TextureLayout, dataType: Tensor.DataType, data?: Tensor.NumberType, tensor?: Tensor,
usage?: Encoder.Usage): TextureData {
usage?: Encoder.Usage, isPacked = false): TextureData {
Logger.verbose('InferenceHandler', `Creating TextureData: layout:[${JSON.stringify(layout)}]`);
const texture = this.session.textureManager.createTextureFromLayout(dataType, layout, data, usage);
return this.createTextureDataFromTexture(layout, dataType, texture, tensor);
@ -137,8 +140,9 @@ export class WebGLInferenceHandler implements InferenceHandler {
* @param texture the WebGLTexture object to share
* @param tensorId the tensor ID of the shared tensor data
*/
createSharedTextureData(layout: TextureLayout, dataType: Tensor.DataType, texture: WebGLTexture, tensorId: Tensor.Id):
TextureData {
createSharedTextureData(
layout: TextureLayout, dataType: Tensor.DataType, texture: WebGLTexture, tensorId?: Tensor.Id,
isPacked = false): TextureData {
return this.createTextureDataFromTexture(layout, dataType, texture, undefined, tensorId);
}
@ -155,29 +159,32 @@ export class WebGLInferenceHandler implements InferenceHandler {
undefined, undefined, tensorId),
texture
};
this.setTextureData(textureData.tensor.dataId, textureData);
this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked);
return textureData;
}
getTextureData(tensorId: Tensor.Id): TextureData|undefined {
return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId) :
this.textureDataCache.get(tensorId);
getTextureData(tensorId: Tensor.Id, isPacked = false): TextureData|undefined {
return this.session.isInitializer(tensorId) ?
this.session.getTextureData(tensorId, isPacked) :
isPacked ? this.packedTextureDataCache.get(tensorId) : this.unpackedTextureDataCache.get(tensorId);
}
setTextureData(tensorId: Tensor.Id, td: TextureData): void {
setTextureData(tensorId: Tensor.Id, td: TextureData, isPacked = false): void {
if (this.session.isInitializer(tensorId)) {
this.session.setTextureData(tensorId, td);
this.session.setTextureData(tensorId, td, isPacked);
} else {
this.textureDataCache.set(tensorId, td);
isPacked ? this.packedTextureDataCache.set(tensorId, td) : this.unpackedTextureDataCache.set(tensorId, td);
}
}
isTextureLayoutCached(tensor: Tensor, isPacked = false): boolean {
return !!this.getTextureData(tensor.dataId, isPacked);
}
/**
* Create a TextureLayout object from a tensor. If a related texture data is found, returns the cached texture layout.
*/
getOrCreateTextureLayout(
tensor: Tensor, channels: 1|4 = 1, isPacked = false, unpackedShape?: ReadonlyArray<number>,
reverseWH = false): TextureLayout {
const td = this.getTextureData(tensor.dataId);
const td = this.getTextureData(tensor.dataId, isPacked);
if (td) {
return td;
}
@ -229,14 +236,17 @@ export class WebGLInferenceHandler implements InferenceHandler {
isPacked,
shape: inferredDims,
strides: ShapeUtil.computeStrides(inferredDims),
unpackedShape
unpackedShape,
reversedWH: (prefs && prefs.reverseWH)
};
}
dispose(): void {
this.session.textureManager.clearActiveTextures();
this.textureDataCache.forEach(td => this.session.textureManager.releaseTexture(td));
this.textureDataCache = new Map();
this.packedTextureDataCache.forEach(td => this.session.textureManager.releaseTexture(td));
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache.forEach(td => this.session.textureManager.releaseTexture(td));
this.unpackedTextureDataCache = new Map();
}
readTexture(textureData: TextureData): Tensor.NumberType {
@ -252,6 +262,10 @@ export class WebGLInferenceHandler implements InferenceHandler {
}
pack(input: TextureData): TextureData {
const cachedId = this.unpack2packMap.get(input.tensor.dataId);
if (cachedId) {
return this.packedTextureDataCache.get(cachedId)!;
}
const key = `${input.shape}`;
let op = this.session.packOpCache.get(key);
if (!op) {
@ -266,10 +280,15 @@ export class WebGLInferenceHandler implements InferenceHandler {
}
const runData = op.createRunData(this, artifact.programInfo, [input.tensor]);
this.runProgram(artifact, runData);
this.unpack2packMap.set(input.tensor.dataId, runData.outputTextureData.tensor.dataId);
return runData.outputTextureData;
}
unpack(input: TextureData): TextureData {
const cachedId = this.pack2unpackMap.get(input.tensor.dataId);
if (cachedId) {
return this.unpackedTextureDataCache.get(cachedId)!;
}
// For unpacked kernel, cache it by using input's unpackedShape as cache key.
// Note that we need to use input.unpackedShape instead of input.shape here,
// as the shape infers the packed texture shape. Different unpackedShape can have the
@ -290,6 +309,7 @@ export class WebGLInferenceHandler implements InferenceHandler {
}
const runData = op.createRunData(this, artifact.programInfo, [input.tensor]);
this.runProgram(artifact, runData);
this.pack2unpackMap.set(input.tensor.dataId, runData.outputTextureData.tensor.dataId);
return runData.outputTextureData;
}
}

Просмотреть файл

@ -22,6 +22,10 @@ export class WebGLBinaryOp extends BinaryOp implements WebGLOperator {
const inputLayouts = handler.session.pack ?
inputs.map(t => handler.getOrCreateTextureLayout(t, 4, true, t.dims, true)) :
inputs.map(t => handler.getOrCreateTextureLayout(t));
const ouputLayout = handler.session.pack ?
handler.createTextureLayoutFromShape(inputs[0].dims, 4, inputs[0].dims, {isPacked: true, reverseWH: true}) :
handler.createTextureLayoutFromShape(inputs[0].dims);
const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
if (isBroadcast) {
const outputShape = BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false);
@ -33,6 +37,8 @@ export class WebGLBinaryOp extends BinaryOp implements WebGLOperator {
const bRank = inputs[1].dims.length !== 0 ? inputs[1].dims.length : 1;
const aBcast = inputs[0].dims.length !== 0 ? `bcastIndices_A(indices, aindices);` : `aindices[0] = 0;`;
const bBcast = inputs[1].dims.length !== 0 ? `bcastIndices_B(indices, bindices);` : `bindices[0] = 0;`;
// TODO: for packed tensors, we need to implement logic to caculate textCoords for broadcast tensor
const shaderSource = `
${this.glslFunc.body}
float process(int indices[${outputRank}]) {
@ -51,6 +57,8 @@ export class WebGLBinaryOp extends BinaryOp implements WebGLOperator {
outputLayout,
samplers: ['A', 'B'],
shaderSource,
expectPackedInputs: handler.session.pack,
expectPackedOutputs: handler.session.pack
};
}
const glsl = getGlsl(handler.session.backend.glContext.version);
@ -67,7 +75,7 @@ export class WebGLBinaryOp extends BinaryOp implements WebGLOperator {
return {
hasMain: true,
inputLayouts,
outputLayout: handler.createTextureLayoutFromShape(inputs[0].dims),
outputLayout: ouputLayout,
samplers: ['A', 'B'],
shaderSource,
expectPackedInputs: true,

Просмотреть файл

@ -117,10 +117,17 @@ export class WebGLReshapePacked extends Reshape implements WebGLOperator {
createRunData(handler: WebGLInferenceHandler, programInfo: ProgramInfo, inputs: Tensor[]): RunData {
const inputTDs =
[handler.getOrCreateTextureData(inputs[0], handler.getOrCreateTextureLayout(inputs[0], 1, false, [], false))];
let outputLayout = this.originalOutputLayout;
if (outputLayout === undefined) {
const originInputShape = inputs[0].dims;
const outputShape = ShapeUtil.calculateReshapedDims(originInputShape, inputs[1].integerData);
outputLayout =
handler.createTextureLayoutFromShape(outputShape, 4, outputShape, {isPacked: true, reverseWH: true});
}
// return run data for reshape. Here, we use the original calculate outputLayout to create the real output layout.
return {
inputTextureDatas: inputTDs,
outputTextureData: handler.createTextureDataFromLayout(this.originalOutputLayout, inputTDs[0].tensor.type),
outputTextureData: handler.createTextureDataFromLayout(outputLayout, inputTDs[0].tensor.type),
uniformData: {}
};
}

Просмотреть файл

@ -43,6 +43,6 @@ export function reshape(
unpackedShape: reshapedDims,
};
const newTextureData = inferenceHandler.createSharedTextureData(newTextureLayout, input.type, inputTD.texture, {});
const newTextureData = inferenceHandler.createSharedTextureData(newTextureLayout, input.type, inputTD.texture);
return newTextureData.tensor;
}

Просмотреть файл

@ -77,7 +77,7 @@ export class WebGLUint8Encode {
const encoder = inferenceHandler.session.backend.glContext.getEncoder('byte', 4);
const texture =
inferenceHandler.session.backend.glContext.allocateTexture(outputLayout.width, outputLayout.height, encoder);
const outputTextureData = inferenceHandler.createSharedTextureData(outputLayout, 'uint8', texture, {});
const outputTextureData = inferenceHandler.createSharedTextureData(outputLayout, 'uint8', texture);
const runData = {inputTextureDatas: [input], outputTextureData, uniformData: {}};
inferenceHandler.session.programManager.run(artifact, runData);

Просмотреть файл

@ -6,7 +6,6 @@ import {getGlsl} from '../glsl-source';
import {WebGLInferenceHandler} from '../inference-handler';
import {ProgramInfo, RunData, WebGLOperator} from '../types';
import {getCoordsDataType} from '../utils';
import {getChannels, unpackFromChannel} from './packing_utils';
export class WebGLUnpack implements WebGLOperator {
@ -18,7 +17,7 @@ export class WebGLUnpack implements WebGLOperator {
throw new Error(`Pack kernel should have input tensor count to 1.`);
}
const inputTexture = handler.getTextureData(inputs[0].dataId);
const inputTexture = handler.getTextureData(inputs[0].dataId, true);
if (!inputTexture) {
throw new Error(`packed input texture must exist`);
}
@ -49,7 +48,7 @@ export class WebGLUnpack implements WebGLOperator {
`;
return {
inputLayouts: [handler.getOrCreateTextureLayout(inputs[0])],
inputLayouts: [handler.getOrCreateTextureLayout(inputs[0], 4, true, inputs[0].dims, true)],
outputLayout,
samplers: ['A'],
shaderSource,
@ -59,7 +58,7 @@ export class WebGLUnpack implements WebGLOperator {
};
}
createRunData(handler: WebGLInferenceHandler, programInfo: ProgramInfo, inputs: Tensor[]): RunData {
const inputTDs = [handler.getOrCreateTextureData(inputs[0], programInfo.inputLayouts[0])];
const inputTDs = [handler.getOrCreateTextureData(inputs[0], programInfo.inputLayouts[0], true)];
return {
inputTextureDatas: inputTDs,
outputTextureData: handler.createTextureDataFromLayout(programInfo.outputLayout, inputTDs[0].tensor.type),

Просмотреть файл

@ -105,11 +105,12 @@ ${fragShaderScript}
return program;
}
bindOutput(td: TextureData): void {
const width = td.width;
const height = td.height;
Logger.verbose(
'ProrgramManager',
`Binding output texture to Framebuffer: w/h=${td.width}/${td.height}, shape=${td.shape}, type=${
td.tensor.type}`);
this.glContext.attachFramebuffer(td.texture, td.width, td.height);
`Binding output texture to Framebuffer: w/h=${width}/${height}, shape=${td.shape}, type=${td.tensor.type}`);
this.glContext.attachFramebuffer(td.texture, width, height);
}
bindAttributes(attribLocations: Artifact.AttribLocations): void {
const positionHandle = attribLocations.position;

Просмотреть файл

@ -21,7 +21,10 @@ export class WebGLSessionHandler implements SessionHandler {
programManager: ProgramManager;
textureManager: TextureManager;
layoutStrategy: TextureLayoutStrategy;
textureDataCache: Map<Tensor.Id, TextureData>;
packedTextureDataCache: Map<Tensor.Id, TextureData>;
unpackedTextureDataCache: Map<Tensor.Id, TextureData>;
pack2unpackMap: Map<Tensor.Id, Tensor.Id>;
unpack2packMap: Map<Tensor.Id, Tensor.Id>;
initializers: Set<Tensor.Id>;
packOpCache: Map<string, WebGLOperator>;
unpackOpCache: Map<string, WebGLOperator>;
@ -33,10 +36,13 @@ export class WebGLSessionHandler implements SessionHandler {
this.textureManager = new TextureManager(
backend.glContext, this.layoutStrategy, this.context.profiler,
{reuseTextures: backend.textureCacheMode === 'full'});
this.textureDataCache = new Map();
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache = new Map();
this.packOpCache = new Map();
this.unpackOpCache = new Map();
this.pack = backend.pack;
this.pack2unpackMap = new Map();
this.unpack2packMap = new Map();
}
createInferenceHandler() {
@ -49,18 +55,31 @@ export class WebGLSessionHandler implements SessionHandler {
isInitializer(tensorId: Tensor.Id): boolean {
return this.initializers ? this.initializers.has(tensorId) : false;
}
getTextureData(tensorId: Tensor.Id): TextureData|undefined {
return this.textureDataCache.get(tensorId);
addInitializer(tensorId: Tensor.Id): void {
this.initializers.add(tensorId);
}
setTextureData(tensorId: Tensor.Id, textureData: TextureData): void {
getTextureData(tensorId: Tensor.Id, isPacked: boolean): TextureData|undefined {
if (isPacked) {
return this.packedTextureDataCache.get(tensorId);
} else {
return this.unpackedTextureDataCache.get(tensorId);
}
}
setTextureData(tensorId: Tensor.Id, textureData: TextureData, isPacked = false): void {
Logger.verbose('WebGLSessionHandler', 'Storing Texture data in cache');
this.textureDataCache.set(tensorId, textureData);
if (isPacked) {
this.packedTextureDataCache.set(tensorId, textureData);
} else {
this.unpackedTextureDataCache.set(tensorId, textureData);
}
}
dispose(): void {
this.programManager.dispose();
this.textureManager.clearActiveTextures();
this.textureDataCache.forEach(td => this.textureManager.releaseTexture(td, true));
this.textureDataCache = new Map();
this.packedTextureDataCache.forEach(td => this.textureManager.releaseTexture(td, true));
this.packedTextureDataCache = new Map();
this.unpackedTextureDataCache.forEach(td => this.textureManager.releaseTexture(td, true));
this.unpackedTextureDataCache = new Map();
}
resolve(node: Graph.Node, opsets: ReadonlyArray<OpSet>, graph: Graph): Operator {
const op = resolveOperator(node, opsets, WEBGL_OP_RESOLVE_RULES);

Просмотреть файл

@ -196,7 +196,6 @@ export function parseAxisParam(axis: number|number[], shape: number[]): number[]
// Handle negative axis.
return axis.map(a => a < 0 ? rank + a : a);
}
export function isInt(a: number): boolean {
return a % 1 === 0;
}

Просмотреть файл

@ -42,6 +42,8 @@ export interface TextureLayout {
* the original shape(dims) of the corresponding tensor
*/
unpackedShape: ReadonlyArray<number>;
reversedWH?: boolean;
}
export interface TextureData extends TextureLayout {
tensor: Tensor;

Просмотреть файл

@ -1,13 +1,18 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
import {Guid} from 'guid-typescript';
import Long from 'long';
import {onnx} from 'onnx-proto';
import {onnxruntime} from './ortSchema/ort_generated';
import ortFbs = onnxruntime.experimental.fbs;
import {ProtoUtil, ShapeUtil} from './util';
export let globalId = 0;
export declare namespace Tensor {
export interface DataTypeMap {
bool: Uint8Array;
@ -31,16 +36,13 @@ export declare namespace Tensor {
export type FloatType = Tensor.DataTypeMap['float32']|Tensor.DataTypeMap['float64'];
export type NumberType = BooleanType|IntegerType|FloatType;
export interface Id {
// this field helps typescript to perform type check, comparing to use `Id` as an alias of object.
_tensorDataId_unused?: never;
}
export type Id = Guid;
}
type TensorData = Tensor.DataTypeMap[Tensor.DataType];
type DataProvider = (id: Tensor.Id) => TensorData;
type AsyncDataProvider = (id: Tensor.Id) => Promise<TensorData>;
type DataProvider = (id: Guid) => TensorData;
type AsyncDataProvider = (id: Guid) => Promise<TensorData>;
export class Tensor {
/**
@ -169,7 +171,7 @@ export class Tensor {
/**
* get the data ID that used to map to a tensor data
*/
public readonly dataId: Tensor.Id = {}) {
public readonly dataId: Guid = Guid.create()) {
this.size = ShapeUtil.validateDimsAndCalcSize(dims);
const size = this.size;
const empty = (dataProvider === undefined && asyncDataProvider === undefined && cache === undefined);

36
package-lock.json сгенерированный
Просмотреть файл

@ -788,6 +788,16 @@
"integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==",
"dev": true
},
"bindings": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz",
"integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==",
"dev": true,
"optional": true,
"requires": {
"file-uri-to-path": "1.0.0"
}
},
"bl": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/bl/-/bl-4.0.3.tgz",
@ -2469,6 +2479,13 @@
"integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==",
"dev": true
},
"file-uri-to-path": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
"integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==",
"dev": true,
"optional": true
},
"filename-reserved-regex": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz",
@ -3076,6 +3093,12 @@
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
"dev": true
},
"guid-typescript": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz",
"integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==",
"dev": true
},
"hard-source-webpack-plugin": {
"version": "0.13.1",
"resolved": "https://registry.npmjs.org/hard-source-webpack-plugin/-/hard-source-webpack-plugin-0.13.1.tgz",
@ -4766,6 +4789,13 @@
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
"dev": true
},
"nan": {
"version": "2.14.2",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz",
"integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==",
"dev": true,
"optional": true
},
"nanomatch": {
"version": "1.2.13",
"resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
@ -7265,7 +7295,11 @@
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz",
"integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==",
"dev": true,
"optional": true
"optional": true,
"requires": {
"bindings": "^1.5.0",
"nan": "^2.12.1"
}
},
"glob-parent": {
"version": "3.1.0",

Просмотреть файл

@ -52,6 +52,7 @@
"electron": "^9.2.0",
"fs-extra": "^9.0.1",
"globby": "^11.0.1",
"guid-typescript": "^1.0.9",
"hard-source-webpack-plugin": "^0.13.1",
"husky": "^4.2.5",
"karma": "^5.1.1",

Просмотреть файл

@ -146,7 +146,7 @@ describe('#UnitTest# - unpack - Tensor unpack', () => {
texture: webglTexture!
};
webglInferenceHandler.setTextureData(inputTensor.dataId, textureData);
webglInferenceHandler.setTextureData(inputTensor.dataId, textureData, true);
// compile shader code
const programInfo = op.createProgramInfo(inferenceHandler! as WebGLInferenceHandler, [inputTensor]);