onnxruntime/js/web/lib/onnxjs/backends/webgl/ops/image-scaler.ts
Yulong Wang 4ebc9c3b5e
[JS] onnxruntime-web (#7394)
* add web

* add script and test

* fix lint

* add test/data/ops

* add test/data/node/ to gitignore

* modify scripts

* add onnxjs

* fix tests

* fix test-runner

* fix sourcemap

* fix onnxjs profiling

* update test list

* update README

* resolve comments

* set wasm as default backend

* rename package

* update copyright header

* do not use class "Buffer" in browser context

* revise readme
2021-04-27 00:04:25 -07:00

60 lines
2.3 KiB
TypeScript

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
import {ImageScaler} from '../../../ops/image-scaler';
import {Tensor} from '../../../tensor';
import {WebGLInferenceHandler} from '../inference-handler';
import {ProgramInfo, RunData, WebGLOperator} from '../types';
export class WebGLImageScaler extends ImageScaler implements WebGLOperator {
run(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[]): Tensor[] {
return inferenceHandler.run(this, inputs);
}
createProgramInfo(handler: WebGLInferenceHandler, inputs: Tensor[]): ProgramInfo {
const outputShape = inputs[0].dims.slice();
const rank = outputShape.length;
const getBiasMethod = this.createGetBiasMethod(this.bias.length);
const shaderSource = `
${getBiasMethod}
float process(int indices[${rank}]) {
return _X(indices) * scale + getBias(bias, indices[1]);
}`;
return {
inputLayouts: [handler.getOrCreateTextureLayout(inputs[0])],
outputLayout: handler.createTextureLayoutFromShape(outputShape),
samplers: ['X'],
variables: [{name: 'bias', type: 'float', arrayLength: this.bias.length}, {name: 'scale', type: 'float'}],
shaderSource,
};
}
createRunData(handler: WebGLInferenceHandler, programInfo: ProgramInfo, inputs: Tensor[]): RunData {
const inputTDs = [handler.getOrCreateTextureData(inputs[0], programInfo.inputLayouts[0])];
return {
inputTextureDatas: inputTDs,
outputTextureData: handler.createTextureDataFromLayout(programInfo.outputLayout, inputTDs[0].tensor.type),
uniformData: {'bias': this.bias, 'scale': this.scale}
};
}
private createGetBiasMethod(numChannels: number): string {
const codeLines: string[] = [`float getBias(float bias[${numChannels}], int channel) {`];
for (let i = 0; i < numChannels; ++i) {
if (i === 0) {
codeLines.push(
'\t' +
`if (channel == ${i}) { return bias[${i}]; }`);
} else if (i === numChannels - 1) {
codeLines.push(
'\t' +
`else { return bias[${i}]; }`);
} else {
codeLines.push(
'\t' +
`else if (channel == ${i}) { return bias[${i}]; }`);
}
}
codeLines.push(
'\t' +
'}');
return codeLines.join('\n');
}
}