chore: update node_modules with new binary files and dependencies
- Add new binary files for nodemon, onnxruntime-web, and xenova/transformers - Update various JavaScript and TypeScript files in node_modules - Remove unused files and dependencies - Add new test fixtures and documentation files
This commit is contained in:
78
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-array-lib.js
generated
vendored
Normal file
78
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-array-lib.js
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ArrayGlslLib = void 0;
|
||||
const glsl_definitions_1 = require("./glsl-definitions");
|
||||
/**
|
||||
* This library produces routines needed for non-constant access to uniform arrays
|
||||
*/
|
||||
class ArrayGlslLib extends glsl_definitions_1.GlslLib {
|
||||
getFunctions() {
|
||||
return this.generate();
|
||||
}
|
||||
getCustomTypes() {
|
||||
return {};
|
||||
}
|
||||
constructor(context) {
|
||||
super(context);
|
||||
}
|
||||
generate() {
|
||||
const result = {};
|
||||
for (let i = 1; i <= 16; i++) {
|
||||
result[`setItem${i}`] = new glsl_definitions_1.GlslLibRoutine(this.generateSetItem(i));
|
||||
result[`getItem${i}`] = new glsl_definitions_1.GlslLibRoutine(this.generateGetItem(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
generateSetItem(length) {
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index = ${length} + index;
|
||||
if (index == 0)
|
||||
a[0] = value;
|
||||
`;
|
||||
for (let i = 1; i < length - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
a[${i}] = value;
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
a[${length - 1}] = value;
|
||||
`;
|
||||
const body = `
|
||||
void setItem${length}(out float a[${length}], int index, float value) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return body;
|
||||
}
|
||||
generateGetItem(length) {
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index = ${length} + index;
|
||||
if (index == 0)
|
||||
return a[0];
|
||||
`;
|
||||
for (let i = 1; i < length - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
return a[${i}];
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
return a[${length - 1}];
|
||||
`;
|
||||
const body = `
|
||||
float getItem${length}(float a[${length}], int index) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return body;
|
||||
}
|
||||
}
|
||||
exports.ArrayGlslLib = ArrayGlslLib;
|
||||
//# sourceMappingURL=glsl-array-lib.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-array-lib.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-array-lib.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-array-lib.js","sourceRoot":"","sources":["glsl-array-lib.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAElC,yDAAwE;AACxE;;GAEG;AACH,MAAa,YAAa,SAAQ,0BAAO;IACvC,YAAY;QACV,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACzB,CAAC;IACD,cAAc;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,YAAY,OAAoB;QAC9B,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IACS,QAAQ;QAChB,MAAM,MAAM,GAAqC,EAAE,CAAC;QACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE;YAC5B,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,iCAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;YACpE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,GAAG,IAAI,iCAAc,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC;SACrE;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IACS,eAAe,CAAC,MAAc;QACtC,IAAI,KAAK,GAAG;;qBAEK,MAAM;;;QAGnB,CAAC;QACL,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE;YACnC,KAAK,IAAI;2BACY,CAAC;eACb,CAAC;YACJ,CAAC;SACR;QACD,KAAK,IAAI;;eAEE,MAAM,GAAG,CAAC;QACjB,CAAC;QACL,MAAM,IAAI,GAAG;mBACE,MAAM,gBAAgB,MAAM;SACtC,KAAK;;QAEN,CAAC;QACL,OAAO,IAAI,CAAC;IACd,CAAC;IACS,eAAe,CAAC,MAAc;QACtC,IAAI,KAAK,GAAG;;qBAEK,MAAM;;;MAGrB,CAAC;QACH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE;YACnC,KAAK,IAAI;2BACY,CAAC;sBACN,CAAC;MACjB,CAAC;SACF;QACD,KAAK,IAAI;;sBAES,MAAM,GAAG,CAAC;QACxB,CAAC;QACL,MAAM,IAAI,GAAG;oBACG,MAAM,YAAY,MAAM;SACnC,KAAK;;IAEV,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAlED,oCAkEC"}
|
||||
74
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-array-lib.ts
generated
vendored
Normal file
74
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-array-lib.ts
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {GlslContext, GlslLib, GlslLibRoutine} from './glsl-definitions';
|
||||
/**
|
||||
* This library produces routines needed for non-constant access to uniform arrays
|
||||
*/
|
||||
export class ArrayGlslLib extends GlslLib {
|
||||
getFunctions(): {[name: string]: GlslLibRoutine} {
|
||||
return this.generate();
|
||||
}
|
||||
getCustomTypes(): {[name: string]: string} {
|
||||
return {};
|
||||
}
|
||||
constructor(context: GlslContext) {
|
||||
super(context);
|
||||
}
|
||||
protected generate(): {[name: string]: GlslLibRoutine} {
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
for (let i = 1; i <= 16; i++) {
|
||||
result[`setItem${i}`] = new GlslLibRoutine(this.generateSetItem(i));
|
||||
result[`getItem${i}`] = new GlslLibRoutine(this.generateGetItem(i));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
protected generateSetItem(length: number): string {
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index = ${length} + index;
|
||||
if (index == 0)
|
||||
a[0] = value;
|
||||
`;
|
||||
for (let i = 1; i < length - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
a[${i}] = value;
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
a[${length - 1}] = value;
|
||||
`;
|
||||
const body = `
|
||||
void setItem${length}(out float a[${length}], int index, float value) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return body;
|
||||
}
|
||||
protected generateGetItem(length: number): string {
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index = ${length} + index;
|
||||
if (index == 0)
|
||||
return a[0];
|
||||
`;
|
||||
for (let i = 1; i < length - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
return a[${i}];
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
return a[${length - 1}];
|
||||
`;
|
||||
const body = `
|
||||
float getItem${length}(float a[${length}], int index) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return body;
|
||||
}
|
||||
}
|
||||
1222
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.js
generated
vendored
Normal file
1222
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.js
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
1338
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts
generated
vendored
Normal file
1338
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-coordinate-lib.ts
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
104
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-definitions.js
generated
vendored
Normal file
104
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-definitions.js
generated
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TopologicalSortGlslRoutines = exports.GlslLibRoutineNode = exports.GlslLibRoutine = exports.GlslLib = exports.GlslContext = exports.FunctionType = void 0;
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
var FunctionType;
|
||||
(function (FunctionType) {
|
||||
FunctionType[FunctionType["ValueBased"] = 0] = "ValueBased";
|
||||
FunctionType[FunctionType["Positional"] = 1] = "Positional";
|
||||
})(FunctionType = exports.FunctionType || (exports.FunctionType = {}));
|
||||
class GlslContext {
|
||||
constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) {
|
||||
this.glContext = glContext;
|
||||
this.programInfo = programInfo;
|
||||
this.inputTextureLayouts = inputTextureLayouts;
|
||||
this.outputTextureLayout = outputTextureLayout;
|
||||
}
|
||||
}
|
||||
exports.GlslContext = GlslContext;
|
||||
class GlslLib {
|
||||
constructor(context) {
|
||||
this.context = context;
|
||||
}
|
||||
}
|
||||
exports.GlslLib = GlslLib;
|
||||
// abstraction to represent a GLSL library routine and it's dependencies
|
||||
class GlslLibRoutine {
|
||||
constructor(routineBody, dependencies) {
|
||||
this.routineBody = routineBody;
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
}
|
||||
exports.GlslLibRoutine = GlslLibRoutine;
|
||||
// abstraction to represent a GLSL library routine and it's dependencies AS GRAPH Nodes
|
||||
// this level of abstraction is used to topologically sort routines before fragment shade inclusion
|
||||
class GlslLibRoutineNode {
|
||||
constructor(name, routineBody, dependencies) {
|
||||
this.name = name;
|
||||
if (dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
else {
|
||||
this.dependencies = [];
|
||||
}
|
||||
if (routineBody) {
|
||||
this.routineBody = routineBody;
|
||||
}
|
||||
}
|
||||
addDependency(node) {
|
||||
if (node) {
|
||||
this.dependencies.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.GlslLibRoutineNode = GlslLibRoutineNode;
|
||||
// topologically sort GLSL library routines (graph nodes abstraction) before shader script inclusion
|
||||
class TopologicalSortGlslRoutines {
|
||||
static returnOrderedNodes(nodes) {
|
||||
if (!nodes || nodes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
if (nodes.length === 1) {
|
||||
return nodes;
|
||||
}
|
||||
const cycleCheck = new Set();
|
||||
const alreadyTraversed = new Set();
|
||||
const result = new Array();
|
||||
this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result);
|
||||
return result;
|
||||
}
|
||||
static createOrderedNodes(graphNodes, cycleCheck, alreadyTraversed, result) {
|
||||
for (let i = 0; i < graphNodes.length; ++i) {
|
||||
this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result);
|
||||
}
|
||||
}
|
||||
static dfsTraverse(root, cycleCheck, alreadyTraversed, result) {
|
||||
// if this root has already been traversed return
|
||||
if (!root || alreadyTraversed.has(root.name)) {
|
||||
return;
|
||||
}
|
||||
// cyclic dependency has been detected
|
||||
if (cycleCheck.has(root.name)) {
|
||||
throw new Error('Cyclic dependency detected. Can\'t topologically sort routines needed for shader.');
|
||||
}
|
||||
// hold this node to detect cycles if any
|
||||
cycleCheck.add(root.name);
|
||||
// traverse children in a dfs fashion
|
||||
const dependencies = root.dependencies;
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
for (let i = 0; i < dependencies.length; ++i) {
|
||||
this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result);
|
||||
}
|
||||
}
|
||||
// add to result holder
|
||||
result.push(root);
|
||||
// mark this node as traversed so that we don't traverse from this again
|
||||
alreadyTraversed.add(root.name);
|
||||
// release the hold
|
||||
cycleCheck.delete(root.name);
|
||||
}
|
||||
}
|
||||
exports.TopologicalSortGlslRoutines = TopologicalSortGlslRoutines;
|
||||
//# sourceMappingURL=glsl-definitions.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-definitions.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-definitions.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-definitions.js","sourceRoot":"","sources":["glsl-definitions.ts"],"names":[],"mappings":"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"}
|
||||
121
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-definitions.ts
generated
vendored
Normal file
121
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-definitions.ts
generated
vendored
Normal file
@@ -0,0 +1,121 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {ProgramInfo, TextureLayout} from './types';
|
||||
import {WebGLContext} from './webgl-context';
|
||||
|
||||
/* eslint-disable @typescript-eslint/naming-convention */
|
||||
export enum FunctionType {
|
||||
ValueBased,
|
||||
Positional
|
||||
}
|
||||
export interface GlslFunction<T extends FunctionType> {
|
||||
body: string;
|
||||
name: string;
|
||||
type: T;
|
||||
}
|
||||
export type GlslValueFunction = GlslFunction<FunctionType.ValueBased>;
|
||||
export interface GlslPositionalFunction extends GlslFunction<FunctionType.Positional> {
|
||||
inputShape: readonly number[];
|
||||
outputShape: readonly number[];
|
||||
}
|
||||
|
||||
export class GlslContext {
|
||||
constructor(
|
||||
public glContext: WebGLContext, public programInfo: ProgramInfo, public inputTextureLayouts: TextureLayout[],
|
||||
public outputTextureLayout: TextureLayout) {}
|
||||
}
|
||||
export abstract class GlslLib {
|
||||
constructor(public context: GlslContext) {}
|
||||
abstract getFunctions(): {[name: string]: GlslLibRoutine};
|
||||
abstract getCustomTypes(): {[name: string]: string};
|
||||
}
|
||||
|
||||
// abstraction to represent a GLSL library routine and it's dependencies
|
||||
export class GlslLibRoutine {
|
||||
constructor(public routineBody: string, public dependencies?: string[]) {}
|
||||
}
|
||||
|
||||
// abstraction to represent a GLSL library routine and it's dependencies AS GRAPH Nodes
|
||||
// this level of abstraction is used to topologically sort routines before fragment shade inclusion
|
||||
export class GlslLibRoutineNode {
|
||||
dependencies: GlslLibRoutineNode[];
|
||||
routineBody: string;
|
||||
constructor(public name: string, routineBody?: string, dependencies?: GlslLibRoutineNode[]) {
|
||||
if (dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
} else {
|
||||
this.dependencies = [];
|
||||
}
|
||||
|
||||
if (routineBody) {
|
||||
this.routineBody = routineBody;
|
||||
}
|
||||
}
|
||||
addDependency(node: GlslLibRoutineNode) {
|
||||
if (node) {
|
||||
this.dependencies.push(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// topologically sort GLSL library routines (graph nodes abstraction) before shader script inclusion
|
||||
export class TopologicalSortGlslRoutines {
|
||||
static returnOrderedNodes(nodes: GlslLibRoutineNode[]): GlslLibRoutineNode[] {
|
||||
if (!nodes || nodes.length === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
if (nodes.length === 1) {
|
||||
return nodes;
|
||||
}
|
||||
|
||||
const cycleCheck = new Set<string>();
|
||||
const alreadyTraversed = new Set<string>();
|
||||
const result = new Array<GlslLibRoutineNode>();
|
||||
|
||||
this.createOrderedNodes(nodes, cycleCheck, alreadyTraversed, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static createOrderedNodes(
|
||||
graphNodes: GlslLibRoutineNode[], cycleCheck: Set<string>, alreadyTraversed: Set<string>,
|
||||
result: GlslLibRoutineNode[]) {
|
||||
for (let i = 0; i < graphNodes.length; ++i) {
|
||||
this.dfsTraverse(graphNodes[i], cycleCheck, alreadyTraversed, result);
|
||||
}
|
||||
}
|
||||
|
||||
private static dfsTraverse(
|
||||
root: GlslLibRoutineNode, cycleCheck: Set<string>, alreadyTraversed: Set<string>, result: GlslLibRoutineNode[]) {
|
||||
// if this root has already been traversed return
|
||||
if (!root || alreadyTraversed.has(root.name)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// cyclic dependency has been detected
|
||||
if (cycleCheck.has(root.name)) {
|
||||
throw new Error('Cyclic dependency detected. Can\'t topologically sort routines needed for shader.');
|
||||
}
|
||||
|
||||
// hold this node to detect cycles if any
|
||||
cycleCheck.add(root.name);
|
||||
|
||||
// traverse children in a dfs fashion
|
||||
const dependencies = root.dependencies;
|
||||
if (dependencies && dependencies.length > 0) {
|
||||
for (let i = 0; i < dependencies.length; ++i) {
|
||||
this.dfsTraverse(dependencies[i], cycleCheck, alreadyTraversed, result);
|
||||
}
|
||||
}
|
||||
|
||||
// add to result holder
|
||||
result.push(root);
|
||||
|
||||
// mark this node as traversed so that we don't traverse from this again
|
||||
alreadyTraversed.add(root.name);
|
||||
|
||||
// release the hold
|
||||
cycleCheck.delete(root.name);
|
||||
}
|
||||
}
|
||||
102
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-encoding-lib.js
generated
vendored
Normal file
102
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-encoding-lib.js
generated
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EncodingGlslLib = void 0;
|
||||
const glsl_definitions_1 = require("./glsl-definitions");
|
||||
/**
|
||||
* This GLSL library handles routines converting
|
||||
* float32 to/from Unsigned byte or float 16
|
||||
*/
|
||||
class EncodingGlslLib extends glsl_definitions_1.GlslLib {
|
||||
constructor(context) {
|
||||
super(context);
|
||||
}
|
||||
getFunctions() {
|
||||
return Object.assign(Object.assign({}, this.encodeFloat32()), this.decodeFloat32());
|
||||
}
|
||||
getCustomTypes() {
|
||||
return {};
|
||||
}
|
||||
encodeFloat32() {
|
||||
return {
|
||||
encode: new glsl_definitions_1.GlslLibRoutine(`highp vec4 encode(highp float f) {
|
||||
return vec4(f, 0.0, 0.0, 0.0);
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
decodeFloat32() {
|
||||
return {
|
||||
decode: new glsl_definitions_1.GlslLibRoutine(`highp float decode(highp vec4 rgba) {
|
||||
return rgba.r;
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* returns the routine to encode encode a 32bit float to a vec4 (of unsigned bytes)
|
||||
* @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float
|
||||
*/
|
||||
encodeUint8() {
|
||||
const endianness = EncodingGlslLib.isLittleEndian() ? 'rgba.rgba=rgba.abgr;' : '';
|
||||
return {
|
||||
encode: new glsl_definitions_1.GlslLibRoutine(`
|
||||
highp vec4 encode(highp float f) {
|
||||
highp float F = abs(f);
|
||||
highp float Sign = step(0.0,-f);
|
||||
highp float Exponent = floor(log2(F));
|
||||
highp float Mantissa = (exp2(- Exponent) * F);
|
||||
Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa));
|
||||
highp vec4 rgba;
|
||||
rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0));
|
||||
rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0);
|
||||
rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0)));
|
||||
rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0)));
|
||||
${endianness}
|
||||
rgba = rgba / 255.0; // values need to be normalized to [0,1]
|
||||
return rgba;
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* returns the routine to encode a vec4 of unsigned bytes to float32
|
||||
* @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float
|
||||
*/
|
||||
decodeUint8() {
|
||||
const endianness = EncodingGlslLib.isLittleEndian() ? 'rgba.rgba=rgba.abgr;' : '';
|
||||
return {
|
||||
decode: new glsl_definitions_1.GlslLibRoutine(`
|
||||
highp float decode(highp vec4 rgba) {
|
||||
rgba = rgba * 255.0; // values need to be de-normalized from [0,1] to [0,255]
|
||||
${endianness}
|
||||
highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
|
||||
highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
|
||||
highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
|
||||
highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
|
||||
return Result;
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Determines if the machine is little endian or not
|
||||
* @credit: https://gist.github.com/TooTallNate/4750953
|
||||
*/
|
||||
static isLittleEndian() {
|
||||
const b = new ArrayBuffer(4);
|
||||
const a = new Uint32Array(b);
|
||||
const c = new Uint8Array(b);
|
||||
a[0] = 0xdeadbeef;
|
||||
if (c[0] === 0xef) {
|
||||
return true;
|
||||
}
|
||||
if (c[0] === 0xde) {
|
||||
return false;
|
||||
}
|
||||
throw new Error('unknown endianness');
|
||||
}
|
||||
}
|
||||
exports.EncodingGlslLib = EncodingGlslLib;
|
||||
//# sourceMappingURL=glsl-encoding-lib.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-encoding-lib.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-encoding-lib.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-encoding-lib.js","sourceRoot":"","sources":["glsl-encoding-lib.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAElC,yDAAwE;AAExE;;;GAGG;AACH,MAAa,eAAgB,SAAQ,0BAAO;IAC1C,YAAY,OAAoB;QAC9B,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IACD,YAAY;QACV,uCAAW,IAAI,CAAC,aAAa,EAAE,GAAK,IAAI,CAAC,aAAa,EAAE,EAAE;IAC5D,CAAC;IACD,cAAc;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC;IACS,aAAa;QACrB,OAAO;YACL,MAAM,EAAE,IAAI,iCAAc,CAAC;;;SAGxB,CAAC;SACL,CAAC;IACJ,CAAC;IACS,aAAa;QACrB,OAAO;YACL,MAAM,EAAE,IAAI,iCAAc,CAAC;;;SAGxB,CAAC;SACL,CAAC;IACJ,CAAC;IACD;;;OAGG;IACO,WAAW;QACnB,MAAM,UAAU,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,OAAO;YACL,MAAM,EAAE,IAAI,iCAAc,CAAC;;;;;;;;;;;;UAYvB,UAAU;;;;SAIX,CAAC;SACL,CAAC;IACJ,CAAC;IACD;;;OAGG;IACO,WAAW;QACnB,MAAM,UAAU,GAAG,eAAe,CAAC,cAAc,EAAE,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;QAClF,OAAO;YACL,MAAM,EAAE,IAAI,iCAAc,CAAC;;;YAGrB,UAAU;;;;;;;SAOb,CAAC;SACL,CAAC;IACJ,CAAC;IACD;;;OAGG;IACH,MAAM,CAAC,cAAc;QACnB,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,IAAI,WAAW,CAAC,CAAC,CAAC,CAAC;QAC7B,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;QAC5B,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC;QAClB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACjB,OAAO,IAAI,CAAC;SACb;QACD,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE;YACjB,OAAO,KAAK,CAAC;SACd;QACD,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IACxC,CAAC;CACF;AAzFD,0CAyFC"}
|
||||
99
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts
generated
vendored
Normal file
99
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-encoding-lib.ts
generated
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {GlslContext, GlslLib, GlslLibRoutine} from './glsl-definitions';
|
||||
|
||||
/**
|
||||
* This GLSL library handles routines converting
|
||||
* float32 to/from Unsigned byte or float 16
|
||||
*/
|
||||
export class EncodingGlslLib extends GlslLib {
|
||||
constructor(context: GlslContext) {
|
||||
super(context);
|
||||
}
|
||||
getFunctions(): {[name: string]: GlslLibRoutine} {
|
||||
return {...this.encodeFloat32(), ...this.decodeFloat32()};
|
||||
}
|
||||
getCustomTypes(): {[name: string]: string} {
|
||||
return {};
|
||||
}
|
||||
protected encodeFloat32(): {[name: string]: GlslLibRoutine} {
|
||||
return {
|
||||
encode: new GlslLibRoutine(`highp vec4 encode(highp float f) {
|
||||
return vec4(f, 0.0, 0.0, 0.0);
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
protected decodeFloat32(): {[name: string]: GlslLibRoutine} {
|
||||
return {
|
||||
decode: new GlslLibRoutine(`highp float decode(highp vec4 rgba) {
|
||||
return rgba.r;
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* returns the routine to encode encode a 32bit float to a vec4 (of unsigned bytes)
|
||||
* @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float
|
||||
*/
|
||||
protected encodeUint8(): {[name: string]: GlslLibRoutine} {
|
||||
const endianness = EncodingGlslLib.isLittleEndian() ? 'rgba.rgba=rgba.abgr;' : '';
|
||||
return {
|
||||
encode: new GlslLibRoutine(`
|
||||
highp vec4 encode(highp float f) {
|
||||
highp float F = abs(f);
|
||||
highp float Sign = step(0.0,-f);
|
||||
highp float Exponent = floor(log2(F));
|
||||
highp float Mantissa = (exp2(- Exponent) * F);
|
||||
Exponent = floor(log2(F) + 127.0) + floor(log2(Mantissa));
|
||||
highp vec4 rgba;
|
||||
rgba[0] = 128.0 * Sign + floor(Exponent*exp2(-1.0));
|
||||
rgba[1] = 128.0 * mod(Exponent,2.0) + mod(floor(Mantissa*128.0),128.0);
|
||||
rgba[2] = floor(mod(floor(Mantissa*exp2(23.0 -8.0)),exp2(8.0)));
|
||||
rgba[3] = floor(exp2(23.0)*mod(Mantissa,exp2(-15.0)));
|
||||
${endianness}
|
||||
rgba = rgba / 255.0; // values need to be normalized to [0,1]
|
||||
return rgba;
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* returns the routine to encode a vec4 of unsigned bytes to float32
|
||||
* @credit: https://stackoverflow.com/questions/7059962/how-do-i-convert-a-vec4-rgba-value-to-a-float
|
||||
*/
|
||||
protected decodeUint8(): {[name: string]: GlslLibRoutine} {
|
||||
const endianness = EncodingGlslLib.isLittleEndian() ? 'rgba.rgba=rgba.abgr;' : '';
|
||||
return {
|
||||
decode: new GlslLibRoutine(`
|
||||
highp float decode(highp vec4 rgba) {
|
||||
rgba = rgba * 255.0; // values need to be de-normalized from [0,1] to [0,255]
|
||||
${endianness}
|
||||
highp float Sign = 1.0 - step(128.0,rgba[0])*2.0;
|
||||
highp float Exponent = 2.0 * mod(rgba[0],128.0) + step(128.0,rgba[1]) - 127.0;
|
||||
highp float Mantissa = mod(rgba[1],128.0)*65536.0 + rgba[2]*256.0 +rgba[3] + float(0x800000);
|
||||
highp float Result = Sign * exp2(Exponent) * (Mantissa * exp2(-23.0 ));
|
||||
return Result;
|
||||
}
|
||||
`)
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Determines if the machine is little endian or not
|
||||
* @credit: https://gist.github.com/TooTallNate/4750953
|
||||
*/
|
||||
static isLittleEndian(): boolean {
|
||||
const b = new ArrayBuffer(4);
|
||||
const a = new Uint32Array(b);
|
||||
const c = new Uint8Array(b);
|
||||
a[0] = 0xdeadbeef;
|
||||
if (c[0] === 0xef) {
|
||||
return true;
|
||||
}
|
||||
if (c[0] === 0xde) {
|
||||
return false;
|
||||
}
|
||||
throw new Error('unknown endianness');
|
||||
}
|
||||
}
|
||||
44
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.js
generated
vendored
Normal file
44
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.js
generated
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FragColorGlslLib = void 0;
|
||||
const glsl_definitions_1 = require("./glsl-definitions");
|
||||
const glsl_source_1 = require("./glsl-source");
|
||||
/**
|
||||
* This GLSL library handles routines around reading a texlet and writing to it
|
||||
* Reading and writing could be more than just dealing with one channel
|
||||
* It may require encoding/decoding to/from 4 channels into one
|
||||
*/
|
||||
class FragColorGlslLib extends glsl_definitions_1.GlslLib {
|
||||
constructor(context) {
|
||||
super(context);
|
||||
}
|
||||
getFunctions() {
|
||||
return Object.assign(Object.assign({}, this.setFragColor()), this.getColorAsFloat());
|
||||
}
|
||||
getCustomTypes() {
|
||||
return {};
|
||||
}
|
||||
setFragColor() {
|
||||
const glsl = (0, glsl_source_1.getGlsl)(this.context.glContext.version);
|
||||
return {
|
||||
setFragColor: new glsl_definitions_1.GlslLibRoutine(`
|
||||
void setFragColor(float value) {
|
||||
${glsl.output} = encode(value);
|
||||
}
|
||||
`, ['encoding.encode'])
|
||||
};
|
||||
}
|
||||
getColorAsFloat() {
|
||||
return {
|
||||
getColorAsFloat: new glsl_definitions_1.GlslLibRoutine(`
|
||||
float getColorAsFloat(vec4 color) {
|
||||
return decode(color);
|
||||
}
|
||||
`, ['encoding.decode'])
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.FragColorGlslLib = FragColorGlslLib;
|
||||
//# sourceMappingURL=glsl-fragcolor-lib.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-fragcolor-lib.js","sourceRoot":"","sources":["glsl-fragcolor-lib.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAElC,yDAAwE;AACxE,+CAAsC;AAEtC;;;;GAIG;AACH,MAAa,gBAAiB,SAAQ,0BAAO;IAC3C,YAAY,OAAoB;QAC9B,KAAK,CAAC,OAAO,CAAC,CAAC;IACjB,CAAC;IACD,YAAY;QACV,uCAAW,IAAI,CAAC,YAAY,EAAE,GAAK,IAAI,CAAC,eAAe,EAAE,EAAE;IAC7D,CAAC;IACD,cAAc;QACZ,OAAO,EAAE,CAAC;IACZ,CAAC;IACS,YAAY;QACpB,MAAM,IAAI,GAAG,IAAA,qBAAO,EAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrD,OAAO;YACL,YAAY,EAAE,IAAI,iCAAc,CAC5B;;cAEI,IAAI,CAAC,MAAM;;SAEhB,EACC,CAAC,iBAAiB,CAAC,CAAC;SACzB,CAAC;IACJ,CAAC;IACS,eAAe;QACvB,OAAO;YACL,eAAe,EAAE,IAAI,iCAAc,CAC/B;;;;SAID,EACC,CAAC,iBAAiB,CAAC,CAAC;SACzB,CAAC;IACJ,CAAC;CACF;AAjCD,4CAiCC"}
|
||||
45
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts
generated
vendored
Normal file
45
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-fragcolor-lib.ts
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {GlslContext, GlslLib, GlslLibRoutine} from './glsl-definitions';
|
||||
import {getGlsl} from './glsl-source';
|
||||
|
||||
/**
|
||||
* This GLSL library handles routines around reading a texlet and writing to it
|
||||
* Reading and writing could be more than just dealing with one channel
|
||||
* It may require encoding/decoding to/from 4 channels into one
|
||||
*/
|
||||
export class FragColorGlslLib extends GlslLib {
|
||||
constructor(context: GlslContext) {
|
||||
super(context);
|
||||
}
|
||||
getFunctions(): {[name: string]: GlslLibRoutine} {
|
||||
return {...this.setFragColor(), ...this.getColorAsFloat()};
|
||||
}
|
||||
getCustomTypes(): {[name: string]: string} {
|
||||
return {};
|
||||
}
|
||||
protected setFragColor(): {[name: string]: GlslLibRoutine} {
|
||||
const glsl = getGlsl(this.context.glContext.version);
|
||||
return {
|
||||
setFragColor: new GlslLibRoutine(
|
||||
`
|
||||
void setFragColor(float value) {
|
||||
${glsl.output} = encode(value);
|
||||
}
|
||||
`,
|
||||
['encoding.encode'])
|
||||
};
|
||||
}
|
||||
protected getColorAsFloat(): {[name: string]: GlslLibRoutine} {
|
||||
return {
|
||||
getColorAsFloat: new GlslLibRoutine(
|
||||
`
|
||||
float getColorAsFloat(vec4 color) {
|
||||
return decode(color);
|
||||
}
|
||||
`,
|
||||
['encoding.decode'])
|
||||
};
|
||||
}
|
||||
}
|
||||
57
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-function-inliner.js
generated
vendored
Normal file
57
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-function-inliner.js
generated
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.replaceInlines = void 0;
|
||||
const INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm;
|
||||
const FUNC_CALL_REGEX = '(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;';
|
||||
/**
|
||||
* GLSL preprocessor responsible for resolving @inline directives
|
||||
*/
|
||||
function replaceInlines(script) {
|
||||
const inlineDefs = {};
|
||||
let match;
|
||||
while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) {
|
||||
const params = match[3]
|
||||
.split(',')
|
||||
.map(s => {
|
||||
const tokens = s.trim().split(' ');
|
||||
if (tokens && tokens.length === 2) {
|
||||
return { type: tokens[0], name: tokens[1] };
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(v => v !== null);
|
||||
inlineDefs[match[2]] = { params, body: match[4] };
|
||||
}
|
||||
for (const name in inlineDefs) {
|
||||
const regexString = FUNC_CALL_REGEX.replace('__FUNC__', name);
|
||||
const regex = new RegExp(regexString, 'gm');
|
||||
while ((match = regex.exec(script)) !== null) {
|
||||
const type = match[1];
|
||||
const variable = match[2];
|
||||
const params = match[3].split(',');
|
||||
const declLine = (type) ? `${type} ${variable};` : '';
|
||||
let newBody = inlineDefs[name].body;
|
||||
let paramRedecLine = '';
|
||||
inlineDefs[name].params.forEach((v, i) => {
|
||||
if (v) {
|
||||
paramRedecLine += `${v.type} ${v.name} = ${params[i]};\n`;
|
||||
}
|
||||
});
|
||||
newBody = `${paramRedecLine}\n ${newBody}`;
|
||||
newBody = newBody.replace('return', `${variable} = `);
|
||||
const replacement = `
|
||||
${declLine}
|
||||
{
|
||||
${newBody}
|
||||
}
|
||||
`;
|
||||
script = script.replace(match[0], replacement);
|
||||
}
|
||||
}
|
||||
script = script.replace(INLINE_FUNC_DEF_REGEX, '');
|
||||
return script;
|
||||
}
|
||||
exports.replaceInlines = replaceInlines;
|
||||
//# sourceMappingURL=glsl-function-inliner.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-function-inliner.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-function-inliner.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-function-inliner.js","sourceRoot":"","sources":["glsl-function-inliner.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAElC,MAAM,qBAAqB,GAAG,oFAAoF,CAAC;AACnH,MAAM,eAAe,GAAG,4DAA4D,CAAC;AACrF;;GAEG;AACH,SAAgB,cAAc,CAAC,MAAc;IAC3C,MAAM,UAAU,GAAuF,EAAE,CAAC;IAC1G,IAAI,KAAK,CAAC;IACV,OAAO,CAAC,KAAK,GAAG,qBAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE;QAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;aACH,KAAK,CAAC,GAAG,CAAC;aACV,GAAG,CAAC,CAAC,CAAC,EAAE;YACP,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;gBACjC,OAAO,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,EAAC,CAAC;aAC3C;YACD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QAC5C,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,EAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAC,CAAC;KACjD;IACD,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE;QAC7B,MAAM,WAAW,GAAG,eAAe,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC5C,OAAO,CAAC,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,IAAI,EAAE;YAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YAC1B,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,IAAI,OAAO,GAAW,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC;YAC5C,IAAI,cAAc,GAAG,EAAE,CAAC;YACxB,UAAU,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;gBACvC,IAAI,CAAC,EAAE;oBACL,cAAc,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC;iBAC3D;YACH,CAAC,CAAC,CAAC;YACH,OAAO,GAAG,GAAG,cAAc,MAAM,OAAO,EAAE,CAAC;YAC3C,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,EAAE,GAAG,QAAQ,KAAK,CAAC,CAAC;YACtD,MAAM,WAAW,GAAG;QAClB,QAAQ;;UAEN,OAAO;;OAEV,CAAC;YACF,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC;SAChD;KACF;IACD,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;IACnD,OAAO,MAAM,CAAC;AAChB,CAAC;AA5CD,wCA4CC"}
|
||||
53
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts
generated
vendored
Normal file
53
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-function-inliner.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
const INLINE_FUNC_DEF_REGEX = /@inline[\s\n\r]+(\w+)[\s\n\r]+([0-9a-zA-Z_]+)\s*\(([^)]*)\)\s*{(([^}]|[\n\r])*)}/gm;
|
||||
const FUNC_CALL_REGEX = '(\\w+)?\\s+([_0-9a-zA-Z]+)\\s+=\\s+__FUNC__\\((.*)\\)\\s*;';
|
||||
/**
|
||||
* GLSL preprocessor responsible for resolving @inline directives
|
||||
*/
|
||||
export function replaceInlines(script: string): string {
|
||||
const inlineDefs: {[name: string]: {params: Array<{type: string; name: string}|null>; body: string}} = {};
|
||||
let match;
|
||||
while ((match = INLINE_FUNC_DEF_REGEX.exec(script)) !== null) {
|
||||
const params = match[3]
|
||||
.split(',')
|
||||
.map(s => {
|
||||
const tokens = s.trim().split(' ');
|
||||
if (tokens && tokens.length === 2) {
|
||||
return {type: tokens[0], name: tokens[1]};
|
||||
}
|
||||
return null;
|
||||
})
|
||||
.filter(v => v !== null);
|
||||
inlineDefs[match[2]] = {params, body: match[4]};
|
||||
}
|
||||
for (const name in inlineDefs) {
|
||||
const regexString = FUNC_CALL_REGEX.replace('__FUNC__', name);
|
||||
const regex = new RegExp(regexString, 'gm');
|
||||
while ((match = regex.exec(script)) !== null) {
|
||||
const type = match[1];
|
||||
const variable = match[2];
|
||||
const params = match[3].split(',');
|
||||
const declLine = (type) ? `${type} ${variable};` : '';
|
||||
let newBody: string = inlineDefs[name].body;
|
||||
let paramRedecLine = '';
|
||||
inlineDefs[name].params.forEach((v, i) => {
|
||||
if (v) {
|
||||
paramRedecLine += `${v.type} ${v.name} = ${params[i]};\n`;
|
||||
}
|
||||
});
|
||||
newBody = `${paramRedecLine}\n ${newBody}`;
|
||||
newBody = newBody.replace('return', `${variable} = `);
|
||||
const replacement = `
|
||||
${declLine}
|
||||
{
|
||||
${newBody}
|
||||
}
|
||||
`;
|
||||
script = script.replace(match[0], replacement);
|
||||
}
|
||||
}
|
||||
script = script.replace(INLINE_FUNC_DEF_REGEX, '');
|
||||
return script;
|
||||
}
|
||||
118
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-preprocessor.js
generated
vendored
Normal file
118
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-preprocessor.js
generated
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.GlslPreprocessor = void 0;
|
||||
const glsl_definitions_1 = require("./glsl-definitions");
|
||||
const glsl_function_inliner_1 = require("./glsl-function-inliner");
|
||||
const glsl_registered_libs_1 = require("./glsl-registered-libs");
|
||||
const glsl_source_1 = require("./glsl-source");
|
||||
/**
|
||||
* Preprocessor for the additions to the GLSL language
|
||||
* It deals with:
|
||||
* @include directives
|
||||
* @inline
|
||||
* Loop unrolling (not implemented)
|
||||
* Macro resolution (not implemented)
|
||||
*/
|
||||
class GlslPreprocessor {
|
||||
constructor(glContext, programInfo, inputTextureLayouts, outputTextureLayout) {
|
||||
this.libs = {};
|
||||
this.glslLibRoutineDependencyGraph = {};
|
||||
this.context = new glsl_definitions_1.GlslContext(glContext, programInfo, inputTextureLayouts, outputTextureLayout);
|
||||
// construct GlslLibs
|
||||
Object.keys(glsl_registered_libs_1.glslRegistry).forEach((name) => {
|
||||
const lib = new glsl_registered_libs_1.glslRegistry[name](this.context);
|
||||
this.libs[name] = lib;
|
||||
});
|
||||
// construct GlslRoutineDependencyGraph
|
||||
const map = this.glslLibRoutineDependencyGraph;
|
||||
for (const libName in this.libs) {
|
||||
const lib = this.libs[libName];
|
||||
const routinesInLib = lib.getFunctions();
|
||||
for (const routine in routinesInLib) {
|
||||
const key = libName + '.' + routine;
|
||||
let currentNode;
|
||||
if (map[key]) {
|
||||
currentNode = map[key];
|
||||
currentNode.routineBody = routinesInLib[routine].routineBody;
|
||||
}
|
||||
else {
|
||||
currentNode = new glsl_definitions_1.GlslLibRoutineNode(key, routinesInLib[routine].routineBody);
|
||||
map[key] = currentNode;
|
||||
}
|
||||
const dependencies = routinesInLib[routine].dependencies;
|
||||
if (dependencies) {
|
||||
for (let i = 0; i < dependencies.length; ++i) {
|
||||
if (!map[dependencies[i]]) {
|
||||
const node = new glsl_definitions_1.GlslLibRoutineNode(dependencies[i]);
|
||||
map[dependencies[i]] = node;
|
||||
currentNode.addDependency(node);
|
||||
}
|
||||
else {
|
||||
currentNode.addDependency(map[dependencies[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
preprocess() {
|
||||
const programInfo = this.context.programInfo;
|
||||
let source = programInfo.shaderSource;
|
||||
// append main() function
|
||||
if (!this.context.programInfo.hasMain) {
|
||||
source = `${source}
|
||||
${(0, glsl_source_1.getDefaultFragShaderMain)(this.context.glContext.version, this.context.outputTextureLayout.shape.length)}`;
|
||||
}
|
||||
// replace inlines
|
||||
source = (0, glsl_function_inliner_1.replaceInlines)(source);
|
||||
// concat final source string
|
||||
return `${(0, glsl_source_1.getFragShaderPreamble)(this.context.glContext.version)}
|
||||
${this.getUniforms(programInfo.inputNames, programInfo.variables)}
|
||||
${this.getImports(source)}
|
||||
${source}`;
|
||||
}
|
||||
getImports(script) {
|
||||
const routinesIncluded = this.selectGlslLibRoutinesToBeIncluded(script);
|
||||
if (routinesIncluded.length === 0) {
|
||||
return '';
|
||||
}
|
||||
let routines = '';
|
||||
for (let i = 0; i < routinesIncluded.length; ++i) {
|
||||
if (routinesIncluded[i].routineBody) {
|
||||
routines += routinesIncluded[i].routineBody + '\n';
|
||||
}
|
||||
else {
|
||||
throw new Error(`Missing body for the Glsl Library routine: ${routinesIncluded[i].name}`);
|
||||
}
|
||||
}
|
||||
return routines;
|
||||
}
|
||||
selectGlslLibRoutinesToBeIncluded(script) {
|
||||
const nodes = [];
|
||||
Object.keys(this.glslLibRoutineDependencyGraph).forEach(classAndRoutine => {
|
||||
const routine = classAndRoutine.split('.')[1];
|
||||
if (script.indexOf(routine) !== -1) {
|
||||
nodes.push(this.glslLibRoutineDependencyGraph[classAndRoutine]);
|
||||
}
|
||||
});
|
||||
return glsl_definitions_1.TopologicalSortGlslRoutines.returnOrderedNodes(nodes);
|
||||
}
|
||||
getUniforms(samplers, variables) {
|
||||
const uniformLines = [];
|
||||
if (samplers) {
|
||||
for (const sampler of samplers) {
|
||||
uniformLines.push(`uniform sampler2D ${sampler};`);
|
||||
}
|
||||
}
|
||||
if (variables) {
|
||||
for (const variable of variables) {
|
||||
uniformLines.push(`uniform ${variable.type} ${variable.name}${variable.arrayLength ? `[${variable.arrayLength}]` : ''};`);
|
||||
}
|
||||
}
|
||||
return uniformLines.join('\n');
|
||||
}
|
||||
}
|
||||
exports.GlslPreprocessor = GlslPreprocessor;
|
||||
//# sourceMappingURL=glsl-preprocessor.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-preprocessor.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-preprocessor.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-preprocessor.js","sourceRoot":"","sources":["glsl-preprocessor.ts"],"names":[],"mappings":"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"}
|
||||
131
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts
generated
vendored
Normal file
131
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-preprocessor.ts
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {GlslContext, GlslLib, GlslLibRoutineNode, TopologicalSortGlslRoutines} from './glsl-definitions';
|
||||
import {replaceInlines} from './glsl-function-inliner';
|
||||
import {glslRegistry} from './glsl-registered-libs';
|
||||
import {getDefaultFragShaderMain, getFragShaderPreamble} from './glsl-source';
|
||||
import {ProgramInfo, TextureLayout, VariableInfo} from './types';
|
||||
import {WebGLContext} from './webgl-context';
|
||||
|
||||
/**
|
||||
* Preprocessor for the additions to the GLSL language
|
||||
* It deals with:
|
||||
* @include directives
|
||||
* @inline
|
||||
* Loop unrolling (not implemented)
|
||||
* Macro resolution (not implemented)
|
||||
*/
|
||||
export class GlslPreprocessor {
|
||||
readonly context: GlslContext;
|
||||
readonly libs: {[name: string]: GlslLib} = {};
|
||||
readonly glslLibRoutineDependencyGraph: {[routineName: string]: GlslLibRoutineNode} = {};
|
||||
|
||||
constructor(
|
||||
glContext: WebGLContext, programInfo: ProgramInfo, inputTextureLayouts: TextureLayout[],
|
||||
outputTextureLayout: TextureLayout) {
|
||||
this.context = new GlslContext(glContext, programInfo, inputTextureLayouts, outputTextureLayout);
|
||||
|
||||
// construct GlslLibs
|
||||
Object.keys(glslRegistry).forEach((name: string) => {
|
||||
const lib = new glslRegistry[name](this.context);
|
||||
this.libs[name] = lib;
|
||||
});
|
||||
|
||||
// construct GlslRoutineDependencyGraph
|
||||
const map = this.glslLibRoutineDependencyGraph;
|
||||
for (const libName in this.libs) {
|
||||
const lib = this.libs[libName];
|
||||
const routinesInLib = lib.getFunctions();
|
||||
for (const routine in routinesInLib) {
|
||||
const key = libName + '.' + routine;
|
||||
let currentNode: GlslLibRoutineNode;
|
||||
if (map[key]) {
|
||||
currentNode = map[key];
|
||||
currentNode.routineBody = routinesInLib[routine].routineBody;
|
||||
} else {
|
||||
currentNode = new GlslLibRoutineNode(key, routinesInLib[routine].routineBody);
|
||||
map[key] = currentNode;
|
||||
}
|
||||
const dependencies = routinesInLib[routine].dependencies;
|
||||
if (dependencies) {
|
||||
for (let i = 0; i < dependencies.length; ++i) {
|
||||
if (!map[dependencies[i]]) {
|
||||
const node = new GlslLibRoutineNode(dependencies[i]);
|
||||
map[dependencies[i]] = node;
|
||||
currentNode.addDependency(node);
|
||||
} else {
|
||||
currentNode.addDependency(map[dependencies[i]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preprocess(): string {
|
||||
const programInfo = this.context.programInfo;
|
||||
let source = programInfo.shaderSource;
|
||||
|
||||
// append main() function
|
||||
if (!this.context.programInfo.hasMain) {
|
||||
source = `${source}
|
||||
${getDefaultFragShaderMain(this.context.glContext.version, this.context.outputTextureLayout.shape.length)}`;
|
||||
}
|
||||
// replace inlines
|
||||
source = replaceInlines(source);
|
||||
|
||||
// concat final source string
|
||||
return `${getFragShaderPreamble(this.context.glContext.version)}
|
||||
${this.getUniforms(programInfo.inputNames, programInfo.variables)}
|
||||
${this.getImports(source)}
|
||||
${source}`;
|
||||
}
|
||||
|
||||
protected getImports(script: string): string {
|
||||
const routinesIncluded = this.selectGlslLibRoutinesToBeIncluded(script);
|
||||
|
||||
if (routinesIncluded.length === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
let routines = '';
|
||||
for (let i = 0; i < routinesIncluded.length; ++i) {
|
||||
if (routinesIncluded[i].routineBody) {
|
||||
routines += routinesIncluded[i].routineBody + '\n';
|
||||
} else {
|
||||
throw new Error(`Missing body for the Glsl Library routine: ${routinesIncluded[i].name}`);
|
||||
}
|
||||
}
|
||||
|
||||
return routines;
|
||||
}
|
||||
private selectGlslLibRoutinesToBeIncluded(script: string): GlslLibRoutineNode[] {
|
||||
const nodes: GlslLibRoutineNode[] = [];
|
||||
|
||||
Object.keys(this.glslLibRoutineDependencyGraph).forEach(classAndRoutine => {
|
||||
const routine = classAndRoutine.split('.')[1];
|
||||
if (script.indexOf(routine) !== -1) {
|
||||
nodes.push(this.glslLibRoutineDependencyGraph[classAndRoutine]);
|
||||
}
|
||||
});
|
||||
|
||||
return TopologicalSortGlslRoutines.returnOrderedNodes(nodes);
|
||||
}
|
||||
|
||||
protected getUniforms(samplers?: string[], variables?: VariableInfo[]): string {
|
||||
const uniformLines: string[] = [];
|
||||
if (samplers) {
|
||||
for (const sampler of samplers) {
|
||||
uniformLines.push(`uniform sampler2D ${sampler};`);
|
||||
}
|
||||
}
|
||||
if (variables) {
|
||||
for (const variable of variables) {
|
||||
uniformLines.push(
|
||||
`uniform ${variable.type} ${variable.name}${variable.arrayLength ? `[${variable.arrayLength}]` : ''};`);
|
||||
}
|
||||
}
|
||||
return uniformLines.join('\n');
|
||||
}
|
||||
}
|
||||
19
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-registered-libs.js
generated
vendored
Normal file
19
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-registered-libs.js
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.glslRegistry = void 0;
|
||||
const glsl_coordinate_lib_1 = require("./glsl-coordinate-lib");
|
||||
const glsl_encoding_lib_1 = require("./glsl-encoding-lib");
|
||||
const glsl_fragcolor_lib_1 = require("./glsl-fragcolor-lib");
|
||||
const glsl_shape_utils_lib_1 = require("./glsl-shape-utils-lib");
|
||||
const glsl_vec_lib_1 = require("./glsl-vec-lib");
|
||||
exports.glslRegistry = {
|
||||
'encoding': glsl_encoding_lib_1.EncodingGlslLib,
|
||||
'fragcolor': glsl_fragcolor_lib_1.FragColorGlslLib,
|
||||
'vec': glsl_vec_lib_1.VecGlslLib,
|
||||
'shapeUtils': glsl_shape_utils_lib_1.ShapeUtilsGlslLib,
|
||||
'coordinates': glsl_coordinate_lib_1.CoordsGlslLib,
|
||||
// 'arrays': ArrayGlslSLib
|
||||
};
|
||||
//# sourceMappingURL=glsl-registered-libs.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-registered-libs.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-registered-libs.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-registered-libs.js","sourceRoot":"","sources":["glsl-registered-libs.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAElC,+DAAoD;AAEpD,2DAAoD;AACpD,6DAAsD;AACtD,iEAAyD;AACzD,iDAA0C;AAE7B,QAAA,YAAY,GAA4D;IACnF,UAAU,EAAE,mCAAe;IAC3B,WAAW,EAAE,qCAAgB;IAC7B,KAAK,EAAE,yBAAU;IACjB,YAAY,EAAE,wCAAiB;IAC/B,aAAa,EAAE,mCAAa;IAC5B,2BAA2B;CAC5B,CAAC"}
|
||||
18
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts
generated
vendored
Normal file
18
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-registered-libs.ts
generated
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {CoordsGlslLib} from './glsl-coordinate-lib';
|
||||
import {GlslContext, GlslLib} from './glsl-definitions';
|
||||
import {EncodingGlslLib} from './glsl-encoding-lib';
|
||||
import {FragColorGlslLib} from './glsl-fragcolor-lib';
|
||||
import {ShapeUtilsGlslLib} from './glsl-shape-utils-lib';
|
||||
import {VecGlslLib} from './glsl-vec-lib';
|
||||
|
||||
export const glslRegistry: {[name: string]: new (context: GlslContext) => GlslLib} = {
|
||||
'encoding': EncodingGlslLib,
|
||||
'fragcolor': FragColorGlslLib,
|
||||
'vec': VecGlslLib,
|
||||
'shapeUtils': ShapeUtilsGlslLib,
|
||||
'coordinates': CoordsGlslLib,
|
||||
// 'arrays': ArrayGlslSLib
|
||||
};
|
||||
163
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.js
generated
vendored
Normal file
163
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.js
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ShapeUtilsGlslLib = void 0;
|
||||
const glsl_definitions_1 = require("./glsl-definitions");
|
||||
/**
|
||||
* GLSL Library responsible for data types and routines for manipulating
|
||||
* coordinates and mapping to/from tensor indices
|
||||
*/
|
||||
class ShapeUtilsGlslLib extends glsl_definitions_1.GlslLib {
|
||||
constructor(context) {
|
||||
super(context);
|
||||
}
|
||||
getFunctions() {
|
||||
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, this.bcastIndex()), this.bcastMatmulIndex()), this.offsetToIndices()), this.indicesToOffset()), this.incrementIndices());
|
||||
}
|
||||
getCustomTypes() {
|
||||
return {};
|
||||
}
|
||||
bcastIndex() {
|
||||
const outputRank = this.context.outputTextureLayout.shape.length;
|
||||
const result = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].unpackedShape;
|
||||
if (shape.length <= outputRank) {
|
||||
const rank = shape.length;
|
||||
const dimOffset = outputRank - rank;
|
||||
const funcName = `bcastIndices_${name}`;
|
||||
let block = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
block += `
|
||||
realIndices[${i}] = int( mod(float(bcastedIndices[${dimOffset + i}]), ${shape[i]}.0) );
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void ${funcName} (int bcastedIndices[${outputRank}], out int realIndices[${rank}]) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
result[funcName] = new glsl_definitions_1.GlslLibRoutine(body);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
bcastMatmulIndex() {
|
||||
const outputRank = this.context.outputTextureLayout.shape.length;
|
||||
const result = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
if (!(shape.length < 2 || shape.length > outputRank)) {
|
||||
const rank = shape.length;
|
||||
const dimOffset = outputRank - rank;
|
||||
const funcName = `bcastMatmulIndices_${name}`;
|
||||
let block = '';
|
||||
for (let i = 0; i < rank - 2; ++i) {
|
||||
block += `
|
||||
realIndices[${i}] = int( mod(float(bcastedIndices[${dimOffset + i}]), ${shape[i]}.0) );
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void ${funcName}(int bcastedIndices[${outputRank}], out int realIndices[${rank}]) {
|
||||
${block}
|
||||
realIndices[${rank - 1}] = bcastedIndices[${outputRank - 1}];
|
||||
realIndices[${rank - 2}] = bcastedIndices[${outputRank - 2}];
|
||||
}
|
||||
`;
|
||||
result[funcName] = new glsl_definitions_1.GlslLibRoutine(body);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
indicesToOffset() {
|
||||
const result = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
const strides = this.context.inputTextureLayouts[i].strides;
|
||||
const rank = shape.length;
|
||||
let funcName = `indicesToOffset_${name}`;
|
||||
result[funcName] = new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides));
|
||||
funcName = `indicesToOffset_${name}_T`;
|
||||
result[funcName] =
|
||||
new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides.slice().reverse()));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
static indexToOffsetSingle(name, rank, strides) {
|
||||
let block = '';
|
||||
for (let i = rank - 1; i >= 0; --i) {
|
||||
block += `
|
||||
offset += indices[${i}] * ${strides[i]};
|
||||
`;
|
||||
}
|
||||
return `
|
||||
int ${name}(int indices[${rank}]) {
|
||||
int offset = 0;
|
||||
${block}
|
||||
return offset;
|
||||
}
|
||||
`;
|
||||
}
|
||||
offsetToIndices() {
|
||||
const result = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
const strides = this.context.inputTextureLayouts[i].strides;
|
||||
const rank = shape.length;
|
||||
let funcName = `offsetToIndices_${name}`;
|
||||
result[funcName] = new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides));
|
||||
funcName = `offsetToIndices_${name}_T`;
|
||||
result[funcName] =
|
||||
new glsl_definitions_1.GlslLibRoutine(ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides.slice().reverse()));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
static offsetToIndicesSingle(name, rank, strides) {
|
||||
const stridesBlock = [];
|
||||
for (let i = 0; i < rank - 1; ++i) {
|
||||
stridesBlock.push(`
|
||||
indices[${i}] = offset / ${strides[i]};`);
|
||||
stridesBlock.push(`
|
||||
offset -= indices[${i}] * ${strides[i]};`);
|
||||
}
|
||||
stridesBlock.push(`
|
||||
indices[${rank - 1}] = offset;`);
|
||||
return `
|
||||
void ${name}(int offset, out int indices[${rank}]) {
|
||||
${stridesBlock.join('')}
|
||||
}
|
||||
`;
|
||||
}
|
||||
incrementIndices() {
|
||||
const result = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
const rank = shape.length;
|
||||
const funcName = `incrementIndices_${name}`;
|
||||
let shapeInit = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
shapeInit += `
|
||||
shape[${i}] = ${shape[i]};`;
|
||||
}
|
||||
const body = `
|
||||
void ${funcName}(int axis, out int indices[${rank}]) {
|
||||
int shape[${rank}];
|
||||
${shapeInit};
|
||||
for(int i = ${rank} -1 ; i >= 0; --i) {
|
||||
if(i > axis) continue;
|
||||
indices[i] += 1;
|
||||
if(indices[i] < shape[i]) {
|
||||
break;
|
||||
}
|
||||
indices[i] = 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
result[funcName] = new glsl_definitions_1.GlslLibRoutine(body);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
exports.ShapeUtilsGlslLib = ShapeUtilsGlslLib;
|
||||
//# sourceMappingURL=glsl-shape-utils-lib.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
166
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts
generated
vendored
Normal file
166
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-shape-utils-lib.ts
generated
vendored
Normal file
@@ -0,0 +1,166 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {GlslContext, GlslLib, GlslLibRoutine} from './glsl-definitions';
|
||||
|
||||
/**
|
||||
* GLSL Library responsible for data types and routines for manipulating
|
||||
* coordinates and mapping to/from tensor indices
|
||||
*/
|
||||
export class ShapeUtilsGlslLib extends GlslLib {
|
||||
constructor(context: GlslContext) {
|
||||
super(context);
|
||||
}
|
||||
getFunctions(): {[name: string]: GlslLibRoutine} {
|
||||
return {
|
||||
...this.bcastIndex(),
|
||||
...this.bcastMatmulIndex(),
|
||||
...this.offsetToIndices(),
|
||||
...this.indicesToOffset(),
|
||||
...this.incrementIndices()
|
||||
};
|
||||
}
|
||||
getCustomTypes() {
|
||||
return {};
|
||||
}
|
||||
protected bcastIndex(): {[name: string]: GlslLibRoutine} {
|
||||
const outputRank = this.context.outputTextureLayout.shape.length;
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].unpackedShape;
|
||||
if (shape.length <= outputRank) {
|
||||
const rank = shape.length;
|
||||
const dimOffset = outputRank - rank;
|
||||
const funcName = `bcastIndices_${name}`;
|
||||
let block = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
block += `
|
||||
realIndices[${i}] = int( mod(float(bcastedIndices[${dimOffset + i}]), ${shape[i]}.0) );
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void ${funcName} (int bcastedIndices[${outputRank}], out int realIndices[${rank}]) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
result[funcName] = new GlslLibRoutine(body);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
protected bcastMatmulIndex(): {[name: string]: GlslLibRoutine} {
|
||||
const outputRank = this.context.outputTextureLayout.shape.length;
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
if (!(shape.length < 2 || shape.length > outputRank)) {
|
||||
const rank = shape.length;
|
||||
const dimOffset = outputRank - rank;
|
||||
const funcName = `bcastMatmulIndices_${name}`;
|
||||
let block = '';
|
||||
for (let i = 0; i < rank - 2; ++i) {
|
||||
block += `
|
||||
realIndices[${i}] = int( mod(float(bcastedIndices[${dimOffset + i}]), ${shape[i]}.0) );
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void ${funcName}(int bcastedIndices[${outputRank}], out int realIndices[${rank}]) {
|
||||
${block}
|
||||
realIndices[${rank - 1}] = bcastedIndices[${outputRank - 1}];
|
||||
realIndices[${rank - 2}] = bcastedIndices[${outputRank - 2}];
|
||||
}
|
||||
`;
|
||||
result[funcName] = new GlslLibRoutine(body);
|
||||
}
|
||||
});
|
||||
return result;
|
||||
}
|
||||
protected indicesToOffset(): {[name: string]: GlslLibRoutine} {
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
const strides = this.context.inputTextureLayouts[i].strides;
|
||||
const rank = shape.length;
|
||||
let funcName = `indicesToOffset_${name}`;
|
||||
result[funcName] = new GlslLibRoutine(ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides));
|
||||
funcName = `indicesToOffset_${name}_T`;
|
||||
result[funcName] =
|
||||
new GlslLibRoutine(ShapeUtilsGlslLib.indexToOffsetSingle(funcName, rank, strides.slice().reverse()));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
static indexToOffsetSingle(name: string, rank: number, strides: readonly number[]): string {
|
||||
let block = '';
|
||||
for (let i = rank - 1; i >= 0; --i) {
|
||||
block += `
|
||||
offset += indices[${i}] * ${strides[i]};
|
||||
`;
|
||||
}
|
||||
return `
|
||||
int ${name}(int indices[${rank}]) {
|
||||
int offset = 0;
|
||||
${block}
|
||||
return offset;
|
||||
}
|
||||
`;
|
||||
}
|
||||
protected offsetToIndices(): {[name: string]: GlslLibRoutine} {
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
const strides = this.context.inputTextureLayouts[i].strides;
|
||||
const rank = shape.length;
|
||||
let funcName = `offsetToIndices_${name}`;
|
||||
result[funcName] = new GlslLibRoutine(ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides));
|
||||
funcName = `offsetToIndices_${name}_T`;
|
||||
result[funcName] =
|
||||
new GlslLibRoutine(ShapeUtilsGlslLib.offsetToIndicesSingle(funcName, rank, strides.slice().reverse()));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
static offsetToIndicesSingle(name: string, rank: number, strides: readonly number[]): string {
|
||||
const stridesBlock = [];
|
||||
for (let i = 0; i < rank - 1; ++i) {
|
||||
stridesBlock.push(`
|
||||
indices[${i}] = offset / ${strides[i]};`);
|
||||
stridesBlock.push(`
|
||||
offset -= indices[${i}] * ${strides[i]};`);
|
||||
}
|
||||
stridesBlock.push(`
|
||||
indices[${rank - 1}] = offset;`);
|
||||
return `
|
||||
void ${name}(int offset, out int indices[${rank}]) {
|
||||
${stridesBlock.join('')}
|
||||
}
|
||||
`;
|
||||
}
|
||||
protected incrementIndices(): {[name: string]: GlslLibRoutine} {
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
this.context.programInfo.inputNames.forEach((name, i) => {
|
||||
const shape = this.context.inputTextureLayouts[i].shape;
|
||||
const rank = shape.length;
|
||||
const funcName = `incrementIndices_${name}`;
|
||||
let shapeInit = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
shapeInit += `
|
||||
shape[${i}] = ${shape[i]};`;
|
||||
}
|
||||
const body = `
|
||||
void ${funcName}(int axis, out int indices[${rank}]) {
|
||||
int shape[${rank}];
|
||||
${shapeInit};
|
||||
for(int i = ${rank} -1 ; i >= 0; --i) {
|
||||
if(i > axis) continue;
|
||||
indices[i] += 1;
|
||||
if(indices[i] < shape[i]) {
|
||||
break;
|
||||
}
|
||||
indices[i] = 0;
|
||||
}
|
||||
}
|
||||
`;
|
||||
result[funcName] = new GlslLibRoutine(body);
|
||||
});
|
||||
return result;
|
||||
}
|
||||
}
|
||||
93
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-source.js
generated
vendored
Normal file
93
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-source.js
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getDefaultFragShaderMain = exports.getFragShaderPreamble = exports.getVertexShaderSource = exports.getGlsl = void 0;
|
||||
const GLSL_ES_2_0 = {
|
||||
version: '',
|
||||
attribute: 'attribute',
|
||||
varyingVertex: 'varying',
|
||||
varyingFrag: 'varying',
|
||||
texture2D: 'texture2D',
|
||||
output: 'gl_FragColor',
|
||||
outputDeclaration: '',
|
||||
};
|
||||
const GLSL_ES_3_0 = {
|
||||
version: '#version 300 es',
|
||||
attribute: 'in',
|
||||
varyingVertex: 'out',
|
||||
varyingFrag: 'in',
|
||||
texture2D: 'texture',
|
||||
output: 'outputColor',
|
||||
outputDeclaration: 'out vec4 outputColor;',
|
||||
};
|
||||
function getGlsl(version) {
|
||||
return version === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0;
|
||||
}
|
||||
exports.getGlsl = getGlsl;
|
||||
function getVertexShaderSource(version) {
|
||||
const glsl = getGlsl(version);
|
||||
return `${glsl.version}
|
||||
precision highp float;
|
||||
${glsl.attribute} vec3 position;
|
||||
${glsl.attribute} vec2 textureCoord;
|
||||
|
||||
${glsl.varyingVertex} vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 1.0);
|
||||
TexCoords = textureCoord;
|
||||
}`;
|
||||
}
|
||||
exports.getVertexShaderSource = getVertexShaderSource;
|
||||
function getFragShaderPreamble(version) {
|
||||
const glsl = getGlsl(version);
|
||||
return `${glsl.version}
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
${glsl.varyingFrag} vec2 TexCoords;
|
||||
${glsl.outputDeclaration}
|
||||
const vec2 halfCR = vec2(0.5, 0.5);
|
||||
|
||||
// Custom vector types to handle higher dimenalities.
|
||||
struct ivec5
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int w;
|
||||
int u;
|
||||
};
|
||||
|
||||
struct ivec6
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int w;
|
||||
int u;
|
||||
int v;
|
||||
};
|
||||
|
||||
int imod(int x, int y) {
|
||||
return x - y * (x / y);
|
||||
}
|
||||
|
||||
`;
|
||||
}
|
||||
exports.getFragShaderPreamble = getFragShaderPreamble;
|
||||
function getDefaultFragShaderMain(version, outputShapeLength) {
|
||||
const glsl = getGlsl(version);
|
||||
return `
|
||||
void main() {
|
||||
int indices[${outputShapeLength}];
|
||||
toVec(TexCoords, indices);
|
||||
vec4 result = vec4(process(indices));
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
}
|
||||
exports.getDefaultFragShaderMain = getDefaultFragShaderMain;
|
||||
//# sourceMappingURL=glsl-source.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-source.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-source.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-source.js","sourceRoot":"","sources":["glsl-source.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAelC,MAAM,WAAW,GAAS;IACxB,OAAO,EAAE,EAAE;IACX,SAAS,EAAE,WAAW;IACtB,aAAa,EAAE,SAAS;IACxB,WAAW,EAAE,SAAS;IACtB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,cAAc;IACtB,iBAAiB,EAAE,EAAE;CACtB,CAAC;AACF,MAAM,WAAW,GAAS;IACxB,OAAO,EAAE,iBAAiB;IAC1B,SAAS,EAAE,IAAI;IACf,aAAa,EAAE,KAAK;IACpB,WAAW,EAAE,IAAI;IACjB,SAAS,EAAE,SAAS;IACpB,MAAM,EAAE,aAAa;IACrB,iBAAiB,EAAE,uBAAuB;CAC3C,CAAC;AAEF,SAAgB,OAAO,CAAC,OAAY;IAClC,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC;AACnD,CAAC;AAFD,0BAEC;AAED,SAAgB,qBAAqB,CAAC,OAAY;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,GAAG,IAAI,CAAC,OAAO;;QAEhB,IAAI,CAAC,SAAS;QACd,IAAI,CAAC,SAAS;;QAEd,IAAI,CAAC,aAAa;;;;;;QAMlB,CAAC;AACT,CAAC;AAdD,sDAcC;AAED,SAAgB,qBAAqB,CAAC,OAAY;IAChD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,GAAG,IAAI,CAAC,OAAO;;;;MAIlB,IAAI,CAAC,WAAW;MAChB,IAAI,CAAC,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;KA2BvB,CAAC;AACN,CAAC;AAnCD,sDAmCC;AAED,SAAgB,wBAAwB,CAAC,OAAY,EAAE,iBAAyB;IAC9E,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO;;kBAES,iBAAiB;;;MAG7B,IAAI,CAAC,MAAM;;GAEd,CAAC;AACJ,CAAC;AAVD,4DAUC"}
|
||||
103
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-source.ts
generated
vendored
Normal file
103
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-source.ts
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
/**
|
||||
* represent a version irrelevant abstraction of for GLSL source code
|
||||
*/
|
||||
export interface Glsl {
|
||||
readonly version: string;
|
||||
readonly attribute: string;
|
||||
readonly varyingVertex: string;
|
||||
readonly varyingFrag: string;
|
||||
readonly texture2D: string;
|
||||
readonly output: string;
|
||||
readonly outputDeclaration: string;
|
||||
}
|
||||
|
||||
const GLSL_ES_2_0: Glsl = {
|
||||
version: '',
|
||||
attribute: 'attribute',
|
||||
varyingVertex: 'varying',
|
||||
varyingFrag: 'varying',
|
||||
texture2D: 'texture2D',
|
||||
output: 'gl_FragColor',
|
||||
outputDeclaration: '',
|
||||
};
|
||||
const GLSL_ES_3_0: Glsl = {
|
||||
version: '#version 300 es',
|
||||
attribute: 'in',
|
||||
varyingVertex: 'out',
|
||||
varyingFrag: 'in',
|
||||
texture2D: 'texture',
|
||||
output: 'outputColor',
|
||||
outputDeclaration: 'out vec4 outputColor;',
|
||||
};
|
||||
|
||||
export function getGlsl(version: 1|2) {
|
||||
return version === 1 ? GLSL_ES_2_0 : GLSL_ES_3_0;
|
||||
}
|
||||
|
||||
export function getVertexShaderSource(version: 1|2): string {
|
||||
const glsl = getGlsl(version);
|
||||
return `${glsl.version}
|
||||
precision highp float;
|
||||
${glsl.attribute} vec3 position;
|
||||
${glsl.attribute} vec2 textureCoord;
|
||||
|
||||
${glsl.varyingVertex} vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = vec4(position, 1.0);
|
||||
TexCoords = textureCoord;
|
||||
}`;
|
||||
}
|
||||
|
||||
export function getFragShaderPreamble(version: 1|2): string {
|
||||
const glsl = getGlsl(version);
|
||||
return `${glsl.version}
|
||||
precision highp float;
|
||||
precision highp int;
|
||||
precision highp sampler2D;
|
||||
${glsl.varyingFrag} vec2 TexCoords;
|
||||
${glsl.outputDeclaration}
|
||||
const vec2 halfCR = vec2(0.5, 0.5);
|
||||
|
||||
// Custom vector types to handle higher dimenalities.
|
||||
struct ivec5
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int w;
|
||||
int u;
|
||||
};
|
||||
|
||||
struct ivec6
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int z;
|
||||
int w;
|
||||
int u;
|
||||
int v;
|
||||
};
|
||||
|
||||
int imod(int x, int y) {
|
||||
return x - y * (x / y);
|
||||
}
|
||||
|
||||
`;
|
||||
}
|
||||
|
||||
export function getDefaultFragShaderMain(version: 1|2, outputShapeLength: number): string {
|
||||
const glsl = getGlsl(version);
|
||||
return `
|
||||
void main() {
|
||||
int indices[${outputShapeLength}];
|
||||
toVec(TexCoords, indices);
|
||||
vec4 result = vec4(process(indices));
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
}
|
||||
114
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-vec-lib.js
generated
vendored
Normal file
114
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-vec-lib.js
generated
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.VecGlslLib = void 0;
|
||||
const glsl_definitions_1 = require("./glsl-definitions");
|
||||
/**
|
||||
* GLSL Library responsible for vec routines
|
||||
* Vec is an varible length int array. The length is fixed at the time of
|
||||
* generating the library functions from the dimensions of the output.
|
||||
*/
|
||||
class VecGlslLib extends glsl_definitions_1.GlslLib {
|
||||
constructor(context) {
|
||||
super(context);
|
||||
}
|
||||
getCustomTypes() {
|
||||
return {};
|
||||
}
|
||||
getFunctions() {
|
||||
return Object.assign(Object.assign(Object.assign(Object.assign({}, this.binaryVecFunctions()), this.copyVec()), this.setVecItem()), this.getVecItem());
|
||||
}
|
||||
binaryVecFunctions() {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
const nameOp = { add: '+=', sub: '-=', mul: '*=', div: '/=' };
|
||||
const result = {};
|
||||
for (const name in nameOp) {
|
||||
const fname = `${name}Vec`;
|
||||
let assignmentBlock = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
assignmentBlock += `
|
||||
dest[${i}] ${nameOp[name]} src[${i}];
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void ${fname}(int src[${rank}], out int dest[${rank}]) {
|
||||
${assignmentBlock}
|
||||
}
|
||||
`;
|
||||
result[fname] = new glsl_definitions_1.GlslLibRoutine(body);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
copyVec() {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
let assignmentBlock = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
assignmentBlock += `
|
||||
dest[${i}] = src[${i}];
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void copyVec(int src[${rank}], out int dest[${rank}]) {
|
||||
${assignmentBlock}
|
||||
}
|
||||
`;
|
||||
return { copyVec: new glsl_definitions_1.GlslLibRoutine(body) };
|
||||
}
|
||||
setVecItem() {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index =${rank} + index;
|
||||
if (index == 0)
|
||||
m[0] = value;
|
||||
`;
|
||||
for (let i = 1; i < rank - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
m[${i}] = value;
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
m[${rank - 1}] = value;
|
||||
`;
|
||||
const body = `
|
||||
void setVecItem(out int m[${rank}], int index, int value) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return { setVecItem: new glsl_definitions_1.GlslLibRoutine(body) };
|
||||
}
|
||||
getVecItem() {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index = ${rank} + index;
|
||||
if (index == 0)
|
||||
return m[0];
|
||||
`;
|
||||
for (let i = 1; i < rank - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
return m[${i}];
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
return m[${rank - 1}];
|
||||
`;
|
||||
const body = `
|
||||
int getVecItem(int m[${rank}], int index) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return { getVecItem: new glsl_definitions_1.GlslLibRoutine(body) };
|
||||
}
|
||||
}
|
||||
exports.VecGlslLib = VecGlslLib;
|
||||
//# sourceMappingURL=glsl-vec-lib.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-vec-lib.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-vec-lib.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"glsl-vec-lib.js","sourceRoot":"","sources":["glsl-vec-lib.ts"],"names":[],"mappings":"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"}
|
||||
113
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts
generated
vendored
Normal file
113
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/glsl-vec-lib.ts
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {GlslContext, GlslLib, GlslLibRoutine} from './glsl-definitions';
|
||||
|
||||
/**
|
||||
* GLSL Library responsible for vec routines
|
||||
* Vec is an varible length int array. The length is fixed at the time of
|
||||
* generating the library functions from the dimensions of the output.
|
||||
*/
|
||||
export class VecGlslLib extends GlslLib {
|
||||
constructor(context: GlslContext) {
|
||||
super(context);
|
||||
}
|
||||
getCustomTypes(): {[name: string]: string} {
|
||||
return {};
|
||||
}
|
||||
getFunctions(): {[name: string]: GlslLibRoutine} {
|
||||
return {...this.binaryVecFunctions(), ...this.copyVec(), ...this.setVecItem(), ...this.getVecItem()};
|
||||
}
|
||||
protected binaryVecFunctions(): {[name: string]: GlslLibRoutine} {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
const nameOp: {[name: string]: string} = {add: '+=', sub: '-=', mul: '*=', div: '/='};
|
||||
const result: {[name: string]: GlslLibRoutine} = {};
|
||||
for (const name in nameOp) {
|
||||
const fname = `${name}Vec`;
|
||||
let assignmentBlock = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
assignmentBlock += `
|
||||
dest[${i}] ${nameOp[name]} src[${i}];
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void ${fname}(int src[${rank}], out int dest[${rank}]) {
|
||||
${assignmentBlock}
|
||||
}
|
||||
`;
|
||||
result[fname] = new GlslLibRoutine(body);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
protected copyVec(): {[name: string]: GlslLibRoutine} {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
let assignmentBlock = '';
|
||||
for (let i = 0; i < rank; ++i) {
|
||||
assignmentBlock += `
|
||||
dest[${i}] = src[${i}];
|
||||
`;
|
||||
}
|
||||
const body = `
|
||||
void copyVec(int src[${rank}], out int dest[${rank}]) {
|
||||
${assignmentBlock}
|
||||
}
|
||||
`;
|
||||
return {copyVec: new GlslLibRoutine(body)};
|
||||
}
|
||||
|
||||
protected setVecItem(): {[name: string]: GlslLibRoutine} {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index =${rank} + index;
|
||||
if (index == 0)
|
||||
m[0] = value;
|
||||
`;
|
||||
for (let i = 1; i < rank - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
m[${i}] = value;
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
m[${rank - 1}] = value;
|
||||
`;
|
||||
const body = `
|
||||
void setVecItem(out int m[${rank}], int index, int value) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return {setVecItem: new GlslLibRoutine(body)};
|
||||
}
|
||||
protected getVecItem(): {[name: string]: GlslLibRoutine} {
|
||||
const outputLayout = this.context.outputTextureLayout;
|
||||
const rank = outputLayout.shape.length;
|
||||
let block = `
|
||||
if(index < 0)
|
||||
index = ${rank} + index;
|
||||
if (index == 0)
|
||||
return m[0];
|
||||
`;
|
||||
for (let i = 1; i < rank - 1; ++i) {
|
||||
block += `
|
||||
else if (index == ${i})
|
||||
return m[${i}];
|
||||
`;
|
||||
}
|
||||
block += `
|
||||
else
|
||||
return m[${rank - 1}];
|
||||
`;
|
||||
const body = `
|
||||
int getVecItem(int m[${rank}], int index) {
|
||||
${block}
|
||||
}
|
||||
`;
|
||||
return {getVecItem: new GlslLibRoutine(body)};
|
||||
}
|
||||
}
|
||||
267
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/inference-handler.js
generated
vendored
Normal file
267
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/inference-handler.js
generated
vendored
Normal file
@@ -0,0 +1,267 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WebGLInferenceHandler = void 0;
|
||||
const instrument_1 = require("../../instrument");
|
||||
const tensor_1 = require("../../tensor");
|
||||
const util_1 = require("../../util");
|
||||
const pack_1 = require("./ops/pack");
|
||||
const reshape_packed_1 = require("./ops/reshape-packed");
|
||||
const uint8_encode_1 = require("./ops/uint8-encode");
|
||||
const unpack_1 = require("./ops/unpack");
|
||||
const texture_layout_1 = require("./texture-layout");
|
||||
const types_1 = require("./types");
|
||||
const getProgramInfoUniqueKey = (programInfo, inputTextureDatas) => {
|
||||
const inputs = inputTextureDatas.map(texture => `${texture.unpackedShape.join(',')};${texture.width}x${texture.height}`)
|
||||
.join('_');
|
||||
let key = programInfo.name;
|
||||
if (programInfo.cacheHint) {
|
||||
key += '[' + programInfo.cacheHint + ']';
|
||||
}
|
||||
key += ':' + inputs;
|
||||
return key;
|
||||
};
|
||||
class WebGLInferenceHandler {
|
||||
constructor(session) {
|
||||
this.session = session;
|
||||
this.packedTextureDataCache = new Map();
|
||||
this.unpackedTextureDataCache = new Map();
|
||||
}
|
||||
/**
|
||||
* @returns [width, height]
|
||||
*/
|
||||
calculateTextureWidthAndHeight(shape, textureType) {
|
||||
return (0, texture_layout_1.calculateTextureWidthAndHeight)(this.session.layoutStrategy, shape, textureType);
|
||||
}
|
||||
executeProgram(program, inputs) {
|
||||
if (inputs.length < program.inputNames.length) {
|
||||
throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`);
|
||||
}
|
||||
if (program.inputNames.length !== program.inputTypes.length) {
|
||||
throw new Error('input names size does not match input types');
|
||||
}
|
||||
// create texture info for input
|
||||
const inputTextureDatas = [];
|
||||
for (let i = 0; i < program.inputNames.length; ++i) {
|
||||
inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]);
|
||||
}
|
||||
const key = getProgramInfoUniqueKey(program, inputTextureDatas);
|
||||
let artifact = this.session.programManager.getArtifact(key);
|
||||
const programInfo = artifact ?
|
||||
artifact.programInfo :
|
||||
(typeof program.get === 'function' ? program.get() :
|
||||
program);
|
||||
// create texture info for output
|
||||
const outputTextureLayout = (0, texture_layout_1.createTextureLayoutFromTextureType)(this.session.layoutStrategy, programInfo.output.dims, programInfo.output.textureType);
|
||||
const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type);
|
||||
if (!artifact) {
|
||||
artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData);
|
||||
this.session.programManager.setArtifact(key, artifact);
|
||||
}
|
||||
this.runProgram(artifact, inputTextureDatas, outputTextureData);
|
||||
return outputTextureData;
|
||||
}
|
||||
run(program, inputs) {
|
||||
const outputTextureData = this.executeProgram(program, inputs);
|
||||
return outputTextureData.tensor;
|
||||
}
|
||||
runProgram(artifact, inputs, output) {
|
||||
// input should match
|
||||
for (let i = 0; i < inputs.length; ++i) {
|
||||
if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === types_1.TextureType.packed)) {
|
||||
throw new Error(`input[${i}] property packed inconsistent`);
|
||||
}
|
||||
}
|
||||
// output should match
|
||||
if (!!output.isPacked !== (artifact.programInfo.output.textureType === types_1.TextureType.packed)) {
|
||||
throw new Error('output property packed inconsistent');
|
||||
}
|
||||
this.session.programManager.run(artifact, inputs, output);
|
||||
}
|
||||
/**
|
||||
* Create a TextureData object from a tensor.
|
||||
* Usage = Encoder.Usage.UploadOnly.
|
||||
* If a related texture data is found in cache, returns it;
|
||||
* Otherwise:
|
||||
* Creates a new texture layout if not provided;
|
||||
* Creates WebGLTexture with the layout;
|
||||
* Upload tensor data to the texture;
|
||||
* Creates a texture data object associated with the given tensor.
|
||||
* @param tensor the tensor with data to upload
|
||||
*/
|
||||
getOrCreateTextureData(tensor, textureType) {
|
||||
let td = this.getTextureData(tensor.dataId, textureType === types_1.TextureType.packed);
|
||||
if (!td) {
|
||||
// check if we have texture data in different type
|
||||
td = this.getTextureData(tensor.dataId, textureType !== types_1.TextureType.packed);
|
||||
if (td) {
|
||||
if (textureType === types_1.TextureType.packed) {
|
||||
return this.pack(td);
|
||||
}
|
||||
else {
|
||||
return this.unpack(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!td) {
|
||||
const layout = (0, texture_layout_1.createTextureLayoutFromTextureType)(this.session.layoutStrategy, tensor.dims, textureType);
|
||||
if (textureType === types_1.TextureType.packedLastDimension) {
|
||||
const group = 1;
|
||||
const channels = 4;
|
||||
const shape = tensor.dims;
|
||||
if (shape.length === 4) {
|
||||
// pre-processing for kernel data of Conv.
|
||||
//
|
||||
// TODO: currently this is a hacking to overwrite Conv's weight. The correct way to do this should be:
|
||||
// 1. implement texture based const-folding
|
||||
// 2. create a WebGL program "preprocessConvWeight" to do the same work as below
|
||||
// 3. run the program before dotProduct.
|
||||
//
|
||||
const adjustedKernelShape = [shape[0], Math.ceil((shape[1] * shape[2] * shape[3]) / channels)];
|
||||
const adjustedLayout = (0, texture_layout_1.createTextureLayoutFromTextureType)(this.session.layoutStrategy, adjustedKernelShape, textureType);
|
||||
let buffer = tensor.numberData;
|
||||
if (shape[1] * shape[2] * shape[3] % channels !== 0) {
|
||||
const numFeatureMaps = shape[0];
|
||||
const oldRowSize = shape[1] * shape[2] * shape[3];
|
||||
const newRowSize = Math.ceil(oldRowSize * group / channels) * channels;
|
||||
const newSize = numFeatureMaps * newRowSize;
|
||||
buffer = new Float32Array(newSize);
|
||||
for (let f = 0; f < numFeatureMaps; ++f) {
|
||||
const oldOffset = f * oldRowSize;
|
||||
const newOffset = f * newRowSize + f % group * oldRowSize;
|
||||
buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset);
|
||||
}
|
||||
}
|
||||
return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, 1 /* Encoder.Usage.UploadOnly */);
|
||||
}
|
||||
}
|
||||
if (textureType === types_1.TextureType.packed) {
|
||||
const unpackedTextureLayout = (0, texture_layout_1.createTextureLayoutFromShape)(this.session.layoutStrategy, tensor.dims, 1, [], { reverseWH: true });
|
||||
const unpackedTextureData = this.createTextureData(unpackedTextureLayout, tensor.type, tensor.numberData, tensor, 1 /* Encoder.Usage.UploadOnly */);
|
||||
td = this.pack(unpackedTextureData);
|
||||
}
|
||||
else {
|
||||
td = this.createTextureData(layout, tensor.type, tensor.numberData, tensor, 1 /* Encoder.Usage.UploadOnly */);
|
||||
}
|
||||
}
|
||||
return td;
|
||||
}
|
||||
/**
|
||||
* Create a TextureData object using the given data and bind to the given tensor.
|
||||
* Usage = Encoder.Usage.UploadOnly.
|
||||
* NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv
|
||||
* implementation by Graph.Transformer
|
||||
* @param dataType the tensor data type
|
||||
* @param data the actual data to upload
|
||||
* @param tensor the tensor to bind. tensor's data is ignored.
|
||||
*/
|
||||
createTextureDataFromLayoutBindTensor(layout, dataType, data, tensor) {
|
||||
return this.createTextureData(layout, dataType, data, tensor, 1 /* Encoder.Usage.UploadOnly */);
|
||||
}
|
||||
createTextureData(layout, dataType, data, tensor, usage) {
|
||||
instrument_1.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);
|
||||
}
|
||||
reshapeUnpacked(input, reshapedDims) {
|
||||
const inputTD = this.getOrCreateTextureData(input, types_1.TextureType.unpacked);
|
||||
const newTextureLayout = {
|
||||
channels: inputTD.channels,
|
||||
height: inputTD.height,
|
||||
width: inputTD.width,
|
||||
// handle reshaping into scalar Tensors
|
||||
shape: reshapedDims.length !== 0 ? reshapedDims : [1],
|
||||
strides: util_1.ShapeUtil.computeStrides(reshapedDims),
|
||||
unpackedShape: reshapedDims,
|
||||
};
|
||||
const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture);
|
||||
return newTextureData.tensor;
|
||||
}
|
||||
reshapePacked(input, reshapedDims) {
|
||||
const inputTD = this.getOrCreateTextureData(input, types_1.TextureType.packed);
|
||||
// check if the reshape is 'cheap'
|
||||
if ((0, reshape_packed_1.isReshapeCheap)(input.dims, reshapedDims)) {
|
||||
const newTextureLayout = {
|
||||
channels: inputTD.channels,
|
||||
height: inputTD.height,
|
||||
width: inputTD.width,
|
||||
// handle reshaping into scalar Tensors
|
||||
shape: reshapedDims.length !== 0 ? reshapedDims : [1],
|
||||
strides: util_1.ShapeUtil.computeStrides(reshapedDims),
|
||||
unpackedShape: reshapedDims,
|
||||
isPacked: true
|
||||
};
|
||||
const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture);
|
||||
return newTextureData.tensor;
|
||||
}
|
||||
const squeezedInputShape = (0, reshape_packed_1.processDims3D)(input.dims);
|
||||
const squeezedOutputShape = (0, reshape_packed_1.processDims3D)(reshapedDims);
|
||||
const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape);
|
||||
const squeezedOutputTensor = this.run((0, reshape_packed_1.createPackedReshape3DProgramInfoLoader)(this, squeezedInputTensor, squeezedOutputShape), [squeezedInputTensor]);
|
||||
const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims);
|
||||
return outputTensor;
|
||||
}
|
||||
cast(input, type) {
|
||||
const inputTD = this.getOrCreateTextureData(input, types_1.TextureType.unpacked);
|
||||
const newTextureData = this.createTextureDataFromTexture(inputTD, type, inputTD.texture);
|
||||
return newTextureData.tensor;
|
||||
}
|
||||
createTextureDataFromTexture(layout, dataType, texture, tensor, tensorId) {
|
||||
const textureData = Object.assign(Object.assign({}, layout), { tensor: tensor ||
|
||||
new tensor_1.Tensor(layout.unpackedShape, dataType, (_id) => this.readTexture(textureData), async (_id) => this.readTextureAsync(textureData), undefined, tensorId), texture });
|
||||
this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked);
|
||||
return textureData;
|
||||
}
|
||||
getTextureData(tensorId, isPacked = false) {
|
||||
return this.session.isInitializer(tensorId) ? this.session.getTextureData(tensorId, isPacked) :
|
||||
isPacked ? this.packedTextureDataCache.get(tensorId) :
|
||||
this.unpackedTextureDataCache.get(tensorId);
|
||||
}
|
||||
setTextureData(tensorId, td, isPacked = false) {
|
||||
if (this.session.isInitializer(tensorId)) {
|
||||
this.session.setTextureData(tensorId, td, isPacked);
|
||||
}
|
||||
else {
|
||||
(isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td);
|
||||
}
|
||||
}
|
||||
isTextureLayoutCached(tensor, isPacked = false) {
|
||||
return !!this.getTextureData(tensor.dataId, isPacked);
|
||||
}
|
||||
dispose() {
|
||||
this.session.textureManager.clearActiveTextures();
|
||||
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) {
|
||||
if (textureData.isPacked) {
|
||||
return this.readTexture(this.unpack(textureData));
|
||||
}
|
||||
if (!this.session.backend.glContext.isFloat32DownloadSupported) {
|
||||
return this.session.textureManager.readUint8TextureAsFloat((0, uint8_encode_1.encodeAsUint8)(this, textureData));
|
||||
}
|
||||
return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels);
|
||||
}
|
||||
async readTextureAsync(textureData) {
|
||||
if (textureData.isPacked) {
|
||||
return this.readTextureAsync(this.unpack(textureData));
|
||||
}
|
||||
if (!this.session.backend.glContext.isFloat32DownloadSupported) {
|
||||
return this.session.textureManager.readUint8TextureAsFloat((0, uint8_encode_1.encodeAsUint8)(this, textureData));
|
||||
}
|
||||
return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels);
|
||||
}
|
||||
pack(input) {
|
||||
const outputTextureData = this.executeProgram((0, pack_1.createPackProgramInfoLoader)(this, input.tensor), [input.tensor]);
|
||||
return outputTextureData;
|
||||
}
|
||||
unpack(input) {
|
||||
const outputTextureData = this.executeProgram((0, unpack_1.createUnpackProgramInfoLoader)(this, input.tensor), [input.tensor]);
|
||||
return outputTextureData;
|
||||
}
|
||||
}
|
||||
exports.WebGLInferenceHandler = WebGLInferenceHandler;
|
||||
//# sourceMappingURL=inference-handler.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/inference-handler.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/inference-handler.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
315
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/inference-handler.ts
generated
vendored
Normal file
315
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/inference-handler.ts
generated
vendored
Normal file
@@ -0,0 +1,315 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {InferenceHandler} from '../../backend';
|
||||
import {Logger} from '../../instrument';
|
||||
import {Tensor} from '../../tensor';
|
||||
import {ShapeUtil} from '../../util';
|
||||
|
||||
import {createPackProgramInfoLoader} from './ops/pack';
|
||||
import {createPackedReshape3DProgramInfoLoader, isReshapeCheap, processDims3D} from './ops/reshape-packed';
|
||||
import {encodeAsUint8} from './ops/uint8-encode';
|
||||
import {createUnpackProgramInfoLoader} from './ops/unpack';
|
||||
import {WebGLSessionHandler} from './session-handler';
|
||||
import {Encoder} from './texture-data-encoder';
|
||||
import {calculateTextureWidthAndHeight, createTextureLayoutFromShape, createTextureLayoutFromTextureType} from './texture-layout';
|
||||
import {Artifact, ProgramInfo, ProgramInfoLoader, TextureData, TextureLayout, TextureType} from './types';
|
||||
|
||||
const getProgramInfoUniqueKey =
|
||||
(programInfo: ProgramInfo|ProgramInfoLoader, inputTextureDatas: TextureData[]): string => {
|
||||
const inputs =
|
||||
inputTextureDatas.map(texture => `${texture.unpackedShape.join(',')};${texture.width}x${texture.height}`)
|
||||
.join('_');
|
||||
let key = programInfo.name;
|
||||
if (programInfo.cacheHint) {
|
||||
key += '[' + programInfo.cacheHint + ']';
|
||||
}
|
||||
key += ':' + inputs;
|
||||
return key;
|
||||
};
|
||||
|
||||
export class WebGLInferenceHandler implements InferenceHandler {
|
||||
private packedTextureDataCache: Map<Tensor.Id, TextureData>;
|
||||
private unpackedTextureDataCache: Map<Tensor.Id, TextureData>;
|
||||
constructor(public session: WebGLSessionHandler) {
|
||||
this.packedTextureDataCache = new Map();
|
||||
this.unpackedTextureDataCache = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns [width, height]
|
||||
*/
|
||||
calculateTextureWidthAndHeight(shape: readonly number[], textureType: TextureType): [number, number] {
|
||||
return calculateTextureWidthAndHeight(this.session.layoutStrategy, shape, textureType);
|
||||
}
|
||||
|
||||
executeProgram(program: ProgramInfo|ProgramInfoLoader, inputs: readonly Tensor[]): TextureData {
|
||||
if (inputs.length < program.inputNames.length) {
|
||||
throw new Error(`Input size mustn't be less than ${program.inputNames.length}.`);
|
||||
}
|
||||
if (program.inputNames.length !== program.inputTypes.length) {
|
||||
throw new Error('input names size does not match input types');
|
||||
}
|
||||
|
||||
// create texture info for input
|
||||
const inputTextureDatas: TextureData[] = [];
|
||||
for (let i = 0; i < program.inputNames.length; ++i) {
|
||||
inputTextureDatas[i] = this.getOrCreateTextureData(inputs[i], program.inputTypes[i]);
|
||||
}
|
||||
|
||||
const key = getProgramInfoUniqueKey(program, inputTextureDatas);
|
||||
let artifact = this.session.programManager.getArtifact(key);
|
||||
const programInfo = artifact ?
|
||||
artifact.programInfo :
|
||||
(typeof (program as ProgramInfoLoader).get === 'function' ? (program as ProgramInfoLoader).get() :
|
||||
(program as ProgramInfo));
|
||||
|
||||
// create texture info for output
|
||||
const outputTextureLayout = createTextureLayoutFromTextureType(
|
||||
this.session.layoutStrategy, programInfo.output.dims, programInfo.output.textureType);
|
||||
const outputTextureData = this.createTextureData(outputTextureLayout, programInfo.output.type);
|
||||
|
||||
if (!artifact) {
|
||||
artifact = this.session.programManager.build(programInfo, inputTextureDatas, outputTextureData);
|
||||
this.session.programManager.setArtifact(key, artifact);
|
||||
}
|
||||
|
||||
this.runProgram(artifact, inputTextureDatas, outputTextureData);
|
||||
return outputTextureData;
|
||||
}
|
||||
|
||||
run(program: ProgramInfoLoader, inputs: readonly Tensor[]): Tensor {
|
||||
const outputTextureData = this.executeProgram(program, inputs);
|
||||
return outputTextureData.tensor;
|
||||
}
|
||||
|
||||
private runProgram(artifact: Artifact, inputs: TextureData[], output: TextureData): void {
|
||||
// input should match
|
||||
for (let i = 0; i < inputs.length; ++i) {
|
||||
if (!!inputs[i].isPacked !== (artifact.programInfo.inputTypes[i] === TextureType.packed)) {
|
||||
throw new Error(`input[${i}] property packed inconsistent`);
|
||||
}
|
||||
}
|
||||
|
||||
// output should match
|
||||
if (!!output.isPacked !== (artifact.programInfo.output.textureType === TextureType.packed)) {
|
||||
throw new Error('output property packed inconsistent');
|
||||
}
|
||||
|
||||
this.session.programManager.run(artifact, inputs, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TextureData object from a tensor.
|
||||
* Usage = Encoder.Usage.UploadOnly.
|
||||
* If a related texture data is found in cache, returns it;
|
||||
* Otherwise:
|
||||
* Creates a new texture layout if not provided;
|
||||
* Creates WebGLTexture with the layout;
|
||||
* Upload tensor data to the texture;
|
||||
* Creates a texture data object associated with the given tensor.
|
||||
* @param tensor the tensor with data to upload
|
||||
*/
|
||||
private getOrCreateTextureData(tensor: Tensor, textureType: TextureType) {
|
||||
let td = this.getTextureData(tensor.dataId, textureType === TextureType.packed);
|
||||
|
||||
if (!td) {
|
||||
// check if we have texture data in different type
|
||||
td = this.getTextureData(tensor.dataId, textureType !== TextureType.packed);
|
||||
if (td) {
|
||||
if (textureType === TextureType.packed) {
|
||||
return this.pack(td);
|
||||
} else {
|
||||
return this.unpack(td);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!td) {
|
||||
const layout = createTextureLayoutFromTextureType(this.session.layoutStrategy, tensor.dims, textureType);
|
||||
|
||||
if (textureType === TextureType.packedLastDimension) {
|
||||
const group = 1;
|
||||
const channels = 4;
|
||||
const shape = tensor.dims;
|
||||
if (shape.length === 4) {
|
||||
// pre-processing for kernel data of Conv.
|
||||
//
|
||||
// TODO: currently this is a hacking to overwrite Conv's weight. The correct way to do this should be:
|
||||
// 1. implement texture based const-folding
|
||||
// 2. create a WebGL program "preprocessConvWeight" to do the same work as below
|
||||
// 3. run the program before dotProduct.
|
||||
//
|
||||
const adjustedKernelShape = [shape[0], Math.ceil((shape[1] * shape[2] * shape[3]) / channels)];
|
||||
const adjustedLayout =
|
||||
createTextureLayoutFromTextureType(this.session.layoutStrategy, adjustedKernelShape, textureType);
|
||||
let buffer = tensor.numberData;
|
||||
if (shape[1] * shape[2] * shape[3] % channels !== 0) {
|
||||
const numFeatureMaps = shape[0];
|
||||
const oldRowSize = shape[1] * shape[2] * shape[3];
|
||||
const newRowSize = Math.ceil(oldRowSize * group / channels) * channels;
|
||||
const newSize = numFeatureMaps * newRowSize;
|
||||
buffer = new Float32Array(newSize);
|
||||
for (let f = 0; f < numFeatureMaps; ++f) {
|
||||
const oldOffset = f * oldRowSize;
|
||||
const newOffset = f * newRowSize + f % group * oldRowSize;
|
||||
buffer.set(tensor.numberData.subarray(oldOffset, oldOffset + oldRowSize), newOffset);
|
||||
}
|
||||
}
|
||||
return this.createTextureData(adjustedLayout, tensor.type, buffer, tensor, Encoder.Usage.UploadOnly);
|
||||
}
|
||||
}
|
||||
|
||||
if (textureType === TextureType.packed) {
|
||||
const unpackedTextureLayout =
|
||||
createTextureLayoutFromShape(this.session.layoutStrategy, tensor.dims, 1, [], {reverseWH: 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);
|
||||
}
|
||||
}
|
||||
return td;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TextureData object using the given data and bind to the given tensor.
|
||||
* Usage = Encoder.Usage.UploadOnly.
|
||||
* NOTE: this function is a hack for Conv implementation. should remove this function, after rewriting Conv
|
||||
* implementation by Graph.Transformer
|
||||
* @param dataType the tensor data type
|
||||
* @param data the actual data to upload
|
||||
* @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);
|
||||
}
|
||||
|
||||
private createTextureData(
|
||||
layout: TextureLayout, dataType: Tensor.DataType, data?: Tensor.NumberType, tensor?: Tensor,
|
||||
usage?: Encoder.Usage): 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);
|
||||
}
|
||||
|
||||
reshapeUnpacked(input: Tensor, reshapedDims: readonly number[]): Tensor {
|
||||
const inputTD = this.getOrCreateTextureData(input, TextureType.unpacked);
|
||||
const newTextureLayout: TextureLayout = {
|
||||
channels: inputTD.channels,
|
||||
height: inputTD.height,
|
||||
width: inputTD.width,
|
||||
// handle reshaping into scalar Tensors
|
||||
shape: reshapedDims.length !== 0 ? reshapedDims : [1],
|
||||
strides: ShapeUtil.computeStrides(reshapedDims),
|
||||
unpackedShape: reshapedDims,
|
||||
};
|
||||
const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture);
|
||||
return newTextureData.tensor;
|
||||
}
|
||||
|
||||
reshapePacked(input: Tensor, reshapedDims: readonly number[]): Tensor {
|
||||
const inputTD = this.getOrCreateTextureData(input, TextureType.packed);
|
||||
|
||||
// check if the reshape is 'cheap'
|
||||
if (isReshapeCheap(input.dims, reshapedDims)) {
|
||||
const newTextureLayout: TextureLayout = {
|
||||
channels: inputTD.channels,
|
||||
height: inputTD.height,
|
||||
width: inputTD.width,
|
||||
// handle reshaping into scalar Tensors
|
||||
shape: reshapedDims.length !== 0 ? reshapedDims : [1],
|
||||
strides: ShapeUtil.computeStrides(reshapedDims),
|
||||
unpackedShape: reshapedDims,
|
||||
isPacked: true
|
||||
};
|
||||
const newTextureData = this.createTextureDataFromTexture(newTextureLayout, input.type, inputTD.texture);
|
||||
return newTextureData.tensor;
|
||||
}
|
||||
|
||||
const squeezedInputShape = processDims3D(input.dims);
|
||||
const squeezedOutputShape = processDims3D(reshapedDims);
|
||||
|
||||
const squeezedInputTensor = this.reshapePacked(input, squeezedInputShape);
|
||||
const squeezedOutputTensor = this.run(
|
||||
createPackedReshape3DProgramInfoLoader(this, squeezedInputTensor, squeezedOutputShape), [squeezedInputTensor]);
|
||||
const outputTensor = this.reshapePacked(squeezedOutputTensor, reshapedDims);
|
||||
return outputTensor;
|
||||
}
|
||||
|
||||
cast(input: Tensor, type: Tensor.DataType): Tensor {
|
||||
const inputTD = this.getOrCreateTextureData(input, TextureType.unpacked);
|
||||
const newTextureData = this.createTextureDataFromTexture(inputTD as TextureLayout, type, inputTD.texture);
|
||||
return newTextureData.tensor;
|
||||
}
|
||||
|
||||
private createTextureDataFromTexture(
|
||||
layout: TextureLayout, dataType: Tensor.DataType, texture: WebGLTexture, tensor?: Tensor, tensorId?: Tensor.Id) {
|
||||
const textureData: TextureData = {
|
||||
...layout,
|
||||
tensor: tensor ||
|
||||
new Tensor(
|
||||
layout.unpackedShape, dataType, (_id: Tensor.Id) => this.readTexture(textureData),
|
||||
async (_id: Tensor.Id) => this.readTextureAsync(textureData), undefined, tensorId),
|
||||
texture
|
||||
};
|
||||
this.setTextureData(textureData.tensor.dataId, textureData, layout.isPacked);
|
||||
return textureData;
|
||||
}
|
||||
|
||||
private 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, isPacked = false): void {
|
||||
if (this.session.isInitializer(tensorId)) {
|
||||
this.session.setTextureData(tensorId, td, isPacked);
|
||||
} else {
|
||||
(isPacked ? this.packedTextureDataCache : this.unpackedTextureDataCache).set(tensorId, td);
|
||||
}
|
||||
}
|
||||
isTextureLayoutCached(tensor: Tensor, isPacked = false): boolean {
|
||||
return !!this.getTextureData(tensor.dataId, isPacked);
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this.session.textureManager.clearActiveTextures();
|
||||
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 {
|
||||
if (textureData.isPacked) {
|
||||
return this.readTexture(this.unpack(textureData));
|
||||
}
|
||||
if (!this.session.backend.glContext.isFloat32DownloadSupported) {
|
||||
return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData));
|
||||
}
|
||||
return this.session.textureManager.readTexture(textureData, textureData.tensor.type, textureData.channels);
|
||||
}
|
||||
|
||||
async readTextureAsync(textureData: TextureData): Promise<Tensor.NumberType> {
|
||||
if (textureData.isPacked) {
|
||||
return this.readTextureAsync(this.unpack(textureData));
|
||||
}
|
||||
if (!this.session.backend.glContext.isFloat32DownloadSupported) {
|
||||
return this.session.textureManager.readUint8TextureAsFloat(encodeAsUint8(this, textureData));
|
||||
}
|
||||
return this.session.textureManager.readTextureAsync(textureData, textureData.tensor.type, textureData.channels);
|
||||
}
|
||||
|
||||
pack(input: TextureData): TextureData {
|
||||
const outputTextureData = this.executeProgram(createPackProgramInfoLoader(this, input.tensor), [input.tensor]);
|
||||
return outputTextureData;
|
||||
}
|
||||
|
||||
unpack(input: TextureData): TextureData {
|
||||
const outputTextureData = this.executeProgram(createUnpackProgramInfoLoader(this, input.tensor), [input.tensor]);
|
||||
return outputTextureData;
|
||||
}
|
||||
}
|
||||
147
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/op-resolve-rules.js
generated
vendored
Normal file
147
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/op-resolve-rules.js
generated
vendored
Normal file
@@ -0,0 +1,147 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.WEBGL_OP_RESOLVE_RULES = void 0;
|
||||
const batch_normalization_1 = require("./ops/batch-normalization");
|
||||
const binaryOps = __importStar(require("./ops/binary-op"));
|
||||
const cast_1 = require("./ops/cast");
|
||||
const concat_1 = require("./ops/concat");
|
||||
const conv_1 = require("./ops/conv");
|
||||
const conv_transpose_1 = require("./ops/conv-transpose");
|
||||
const depth_to_space_1 = require("./ops/depth-to-space");
|
||||
const flatten_1 = require("./ops/flatten");
|
||||
const gather_1 = require("./ops/gather");
|
||||
const gemm_1 = require("./ops/gemm");
|
||||
const image_scaler_1 = require("./ops/image-scaler");
|
||||
const instance_normalization_1 = require("./ops/instance-normalization");
|
||||
const matmul_1 = require("./ops/matmul");
|
||||
const pad_1 = require("./ops/pad");
|
||||
const pool_1 = require("./ops/pool");
|
||||
const reduce_1 = require("./ops/reduce");
|
||||
const reshape_1 = require("./ops/reshape");
|
||||
const resize_packed_1 = require("./ops/resize-packed");
|
||||
const shape_1 = require("./ops/shape");
|
||||
const slice_1 = require("./ops/slice");
|
||||
const softmax_1 = require("./ops/softmax");
|
||||
const split_1 = require("./ops/split");
|
||||
const squeeze_1 = require("./ops/squeeze");
|
||||
const sum_1 = require("./ops/sum");
|
||||
const tile_1 = require("./ops/tile");
|
||||
const transpose_1 = require("./ops/transpose");
|
||||
const unaryOps = __importStar(require("./ops/unary-op"));
|
||||
const unsqueeze_1 = require("./ops/unsqueeze");
|
||||
const upsample_1 = require("./ops/upsample");
|
||||
exports.WEBGL_OP_RESOLVE_RULES = [
|
||||
['Abs', '', '6+', unaryOps.abs],
|
||||
['Acos', '', '7+', unaryOps.acos],
|
||||
['Add', '', '7+', binaryOps.add],
|
||||
['And', '', '7+', binaryOps.and],
|
||||
['Asin', '', '7+', unaryOps.asin],
|
||||
['Atan', '', '7+', unaryOps.atan],
|
||||
// TODO: support new attributes for AveragePool-10
|
||||
['AveragePool', '', '7+', pool_1.averagePool, pool_1.parseAveragePoolAttributes],
|
||||
['BatchNormalization', '', '7+', batch_normalization_1.batchNormalization, batch_normalization_1.parseBatchNormalizationAttributes],
|
||||
['Cast', '', '6+', cast_1.cast, cast_1.parseCastAttributes],
|
||||
['Ceil', '', '6+', unaryOps.ceil],
|
||||
['Clip', '', '6-10', unaryOps.clip, unaryOps.parseClipAttributes],
|
||||
['Clip', '', '11+', unaryOps.clipV11],
|
||||
['Concat', '', '4+', concat_1.concat, concat_1.parseConcatAttributes],
|
||||
['Conv', '', '1+', conv_1.conv, conv_1.parseConvAttributes],
|
||||
['ConvTranspose', '', '1+', conv_transpose_1.convTranspose, conv_transpose_1.parseConvTransposeAttributes],
|
||||
['Cos', '', '7+', unaryOps.cos],
|
||||
['Div', '', '7+', binaryOps.div],
|
||||
['Dropout', '', '7+', unaryOps.identity],
|
||||
['DepthToSpace', '', '1+', depth_to_space_1.depthToSpace, depth_to_space_1.parseDepthToSpaceAttributes],
|
||||
['Equal', '', '7+', binaryOps.equal],
|
||||
['Elu', '', '6+', unaryOps.elu, unaryOps.parseEluAttributes],
|
||||
['Exp', '', '6+', unaryOps.exp],
|
||||
['Flatten', '', '1+', flatten_1.flatten, flatten_1.parseFlattenAttributes],
|
||||
['Floor', '', '6+', unaryOps.floor],
|
||||
['FusedConv', 'com.microsoft', '1+', conv_1.conv, conv_1.parseConvAttributes],
|
||||
['Gather', '', '1+', gather_1.gather, gather_1.parseGatherAttributes],
|
||||
['Gemm', '', '7-10', gemm_1.gemm, gemm_1.parseGemmAttributesV7],
|
||||
['Gemm', '', '11+', gemm_1.gemm, gemm_1.parseGemmAttributesV11],
|
||||
['GlobalAveragePool', '', '1+', pool_1.globalAveragePool, pool_1.parseGlobalAveragePoolAttributes],
|
||||
['GlobalMaxPool', '', '1+', pool_1.globalMaxPool],
|
||||
['Greater', '', '7+', binaryOps.greater],
|
||||
['Identity', '', '1+', unaryOps.identity],
|
||||
['ImageScaler', '', '1+', image_scaler_1.imageScaler, image_scaler_1.parseImageScalerAttributes],
|
||||
['InstanceNormalization', '', '6+', instance_normalization_1.instanceNormalization, instance_normalization_1.parseInstanceNormalizationAttributes],
|
||||
['LeakyRelu', '', '6+', unaryOps.leakyRelu, unaryOps.parseLeakyReluAttributes],
|
||||
['Less', '', '7+', binaryOps.less],
|
||||
['Log', '', '6+', unaryOps.log],
|
||||
['MatMul', '', '1+', matmul_1.matMul, matmul_1.parseMatMulAttributes],
|
||||
// TODO: support new attributes for MaxPool-8 and MaxPool-10
|
||||
['MaxPool', '', '1+', pool_1.maxPool, pool_1.parseMaxPoolAttributes],
|
||||
['Mul', '', '7+', binaryOps.mul],
|
||||
['Neg', '', '6+', unaryOps.neg],
|
||||
['Not', '', '1+', unaryOps.not],
|
||||
['Or', '', '7+', binaryOps.or],
|
||||
['Pad', '', '2-10', pad_1.padV2, pad_1.parsePadAttributesV2],
|
||||
['Pad', '', '11+', pad_1.padV11, pad_1.parsePadAttributesV11],
|
||||
['Pow', '', '7+', binaryOps.pow],
|
||||
['PRelu', '', '7+', binaryOps.pRelu],
|
||||
['ReduceLogSum', '', '1+', reduce_1.reduceLogSum, reduce_1.parseReduceAttributes],
|
||||
['ReduceMax', '', '1+', reduce_1.reduceMax, reduce_1.parseReduceAttributes],
|
||||
['ReduceMean', '', '1+', reduce_1.reduceMean, reduce_1.parseReduceAttributes],
|
||||
['ReduceMin', '', '1+', reduce_1.reduceMin, reduce_1.parseReduceAttributes],
|
||||
['ReduceProd', '', '1+', reduce_1.reduceProd, reduce_1.parseReduceAttributes],
|
||||
['ReduceSum', '', '1-12', reduce_1.reduceSum, reduce_1.parseReduceAttributes],
|
||||
['ReduceSumSquare', '', '1+', reduce_1.reduceLogSumSquare, reduce_1.parseReduceAttributes],
|
||||
['Relu', '', '6+', unaryOps.relu],
|
||||
['Reshape', '', '5+', reshape_1.reshape],
|
||||
['Resize', '', '10', resize_packed_1.resize, resize_packed_1.parseResizeAttributesV10],
|
||||
['Resize', '', '11+', resize_packed_1.resize, resize_packed_1.parseResizeAttributesV11],
|
||||
['Shape', '', '1+', shape_1.shape],
|
||||
['Sigmoid', '', '6+', unaryOps.sigmoid],
|
||||
['Sin', '', '7+', unaryOps.sin],
|
||||
['Slice', '', '10+', slice_1.sliceV10],
|
||||
['Slice', '', '1-9', slice_1.slice, slice_1.parseSliceAttributes],
|
||||
// The "semantic" meaning of axis has changed in opset-13.
|
||||
['Softmax', '', '1-12', softmax_1.softmax, softmax_1.parseSoftmaxAttributes],
|
||||
['Softmax', '', '13+', softmax_1.softmaxV13, softmax_1.parseSoftmaxAttributesV13],
|
||||
// 'Split' operator has an optional attribute 'split'
|
||||
// this attribute determines how the specified axis of input data is split.
|
||||
// When the attribute is missing, we need the count of number of outputs
|
||||
// so that we can determine the 'split' attribute from the runtime input to the Operator
|
||||
['Split', '', '2-12', split_1.split, split_1.parseSplitAttributes],
|
||||
['Sqrt', '', '6+', unaryOps.sqrt],
|
||||
['Squeeze', '', '1-12', squeeze_1.squeeze, squeeze_1.parseSqueezeAttributes],
|
||||
['Squeeze', '', '13+', squeeze_1.squeezeV13],
|
||||
['Sub', '', '7+', binaryOps.sub],
|
||||
['Sum', '', '6+', sum_1.sum],
|
||||
['Tan', '', '7+', unaryOps.tan],
|
||||
['Tanh', '', '6+', unaryOps.tanh],
|
||||
['Tile', '', '6+', tile_1.tile],
|
||||
['Transpose', '', '1+', transpose_1.transpose, transpose_1.parseTransposeAttributes],
|
||||
['Upsample', '', '7-8', upsample_1.upsample, upsample_1.parseUpsampleAttributesV7],
|
||||
['Upsample', '', '9', upsample_1.upsample, upsample_1.parseUpsampleAttributesV9],
|
||||
['Unsqueeze', '', '1-12', unsqueeze_1.unsqueeze, unsqueeze_1.parseUnsqueezeAttributes],
|
||||
['Unsqueeze', '', '13+', unsqueeze_1.unsqueezeV13],
|
||||
['Xor', '', '7+', binaryOps.xor],
|
||||
];
|
||||
//# sourceMappingURL=op-resolve-rules.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/op-resolve-rules.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/op-resolve-rules.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
124
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/op-resolve-rules.ts
generated
vendored
Normal file
124
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/op-resolve-rules.ts
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {OpSet} from '../../opset';
|
||||
|
||||
import {batchNormalization, parseBatchNormalizationAttributes} from './ops/batch-normalization';
|
||||
import * as binaryOps from './ops/binary-op';
|
||||
import {cast, parseCastAttributes} from './ops/cast';
|
||||
import {concat, parseConcatAttributes} from './ops/concat';
|
||||
import {conv, parseConvAttributes} from './ops/conv';
|
||||
import {convTranspose, parseConvTransposeAttributes} from './ops/conv-transpose';
|
||||
import {depthToSpace, parseDepthToSpaceAttributes} from './ops/depth-to-space';
|
||||
import {flatten, parseFlattenAttributes} from './ops/flatten';
|
||||
import {gather, parseGatherAttributes} from './ops/gather';
|
||||
import {gemm, parseGemmAttributesV11, parseGemmAttributesV7} from './ops/gemm';
|
||||
import {imageScaler, parseImageScalerAttributes} from './ops/image-scaler';
|
||||
import {instanceNormalization, parseInstanceNormalizationAttributes} from './ops/instance-normalization';
|
||||
import {matMul, parseMatMulAttributes} from './ops/matmul';
|
||||
import {padV11, padV2, parsePadAttributesV11, parsePadAttributesV2} from './ops/pad';
|
||||
import {averagePool, globalAveragePool, globalMaxPool, maxPool, parseAveragePoolAttributes, parseGlobalAveragePoolAttributes, parseMaxPoolAttributes} from './ops/pool';
|
||||
import {parseReduceAttributes, reduceLogSum, reduceLogSumSquare, reduceMax, reduceMean, reduceMin, reduceProd, reduceSum} from './ops/reduce';
|
||||
import {reshape} from './ops/reshape';
|
||||
import {parseResizeAttributesV10, parseResizeAttributesV11, resize} from './ops/resize-packed';
|
||||
import {shape} from './ops/shape';
|
||||
import {parseSliceAttributes, slice, sliceV10} from './ops/slice';
|
||||
import {parseSoftmaxAttributes, parseSoftmaxAttributesV13, softmax, softmaxV13} from './ops/softmax';
|
||||
import {parseSplitAttributes, split} from './ops/split';
|
||||
import {parseSqueezeAttributes, squeeze, squeezeV13} from './ops/squeeze';
|
||||
import {sum} from './ops/sum';
|
||||
import {tile} from './ops/tile';
|
||||
import {parseTransposeAttributes, transpose} from './ops/transpose';
|
||||
import * as unaryOps from './ops/unary-op';
|
||||
import {parseUnsqueezeAttributes, unsqueeze, unsqueezeV13} from './ops/unsqueeze';
|
||||
import {parseUpsampleAttributesV7, parseUpsampleAttributesV9, upsample} from './ops/upsample';
|
||||
|
||||
export const WEBGL_OP_RESOLVE_RULES: readonly OpSet.ResolveRule[] = [
|
||||
['Abs', '', '6+', unaryOps.abs],
|
||||
['Acos', '', '7+', unaryOps.acos],
|
||||
['Add', '', '7+', binaryOps.add],
|
||||
['And', '', '7+', binaryOps.and],
|
||||
['Asin', '', '7+', unaryOps.asin],
|
||||
['Atan', '', '7+', unaryOps.atan],
|
||||
// TODO: support new attributes for AveragePool-10
|
||||
['AveragePool', '', '7+', averagePool, parseAveragePoolAttributes],
|
||||
['BatchNormalization', '', '7+', batchNormalization, parseBatchNormalizationAttributes],
|
||||
['Cast', '', '6+', cast, parseCastAttributes],
|
||||
['Ceil', '', '6+', unaryOps.ceil],
|
||||
['Clip', '', '6-10', unaryOps.clip, unaryOps.parseClipAttributes],
|
||||
['Clip', '', '11+', unaryOps.clipV11],
|
||||
['Concat', '', '4+', concat, parseConcatAttributes],
|
||||
['Conv', '', '1+', conv, parseConvAttributes],
|
||||
['ConvTranspose', '', '1+', convTranspose, parseConvTransposeAttributes],
|
||||
['Cos', '', '7+', unaryOps.cos],
|
||||
['Div', '', '7+', binaryOps.div],
|
||||
['Dropout', '', '7+', unaryOps.identity],
|
||||
['DepthToSpace', '', '1+', depthToSpace, parseDepthToSpaceAttributes],
|
||||
['Equal', '', '7+', binaryOps.equal],
|
||||
['Elu', '', '6+', unaryOps.elu, unaryOps.parseEluAttributes],
|
||||
['Exp', '', '6+', unaryOps.exp],
|
||||
['Flatten', '', '1+', flatten, parseFlattenAttributes],
|
||||
['Floor', '', '6+', unaryOps.floor],
|
||||
['FusedConv', 'com.microsoft', '1+', conv, parseConvAttributes],
|
||||
['Gather', '', '1+', gather, parseGatherAttributes],
|
||||
['Gemm', '', '7-10', gemm, parseGemmAttributesV7],
|
||||
['Gemm', '', '11+', gemm, parseGemmAttributesV11],
|
||||
['GlobalAveragePool', '', '1+', globalAveragePool, parseGlobalAveragePoolAttributes],
|
||||
['GlobalMaxPool', '', '1+', globalMaxPool],
|
||||
['Greater', '', '7+', binaryOps.greater],
|
||||
['Identity', '', '1+', unaryOps.identity],
|
||||
['ImageScaler', '', '1+', imageScaler, parseImageScalerAttributes],
|
||||
['InstanceNormalization', '', '6+', instanceNormalization, parseInstanceNormalizationAttributes],
|
||||
['LeakyRelu', '', '6+', unaryOps.leakyRelu, unaryOps.parseLeakyReluAttributes],
|
||||
['Less', '', '7+', binaryOps.less],
|
||||
['Log', '', '6+', unaryOps.log],
|
||||
['MatMul', '', '1+', matMul, parseMatMulAttributes],
|
||||
// TODO: support new attributes for MaxPool-8 and MaxPool-10
|
||||
['MaxPool', '', '1+', maxPool, parseMaxPoolAttributes],
|
||||
['Mul', '', '7+', binaryOps.mul],
|
||||
['Neg', '', '6+', unaryOps.neg],
|
||||
['Not', '', '1+', unaryOps.not],
|
||||
['Or', '', '7+', binaryOps.or],
|
||||
['Pad', '', '2-10', padV2, parsePadAttributesV2],
|
||||
['Pad', '', '11+', padV11, parsePadAttributesV11],
|
||||
['Pow', '', '7+', binaryOps.pow],
|
||||
['PRelu', '', '7+', binaryOps.pRelu],
|
||||
['ReduceLogSum', '', '1+', reduceLogSum, parseReduceAttributes],
|
||||
['ReduceMax', '', '1+', reduceMax, parseReduceAttributes],
|
||||
['ReduceMean', '', '1+', reduceMean, parseReduceAttributes],
|
||||
['ReduceMin', '', '1+', reduceMin, parseReduceAttributes],
|
||||
['ReduceProd', '', '1+', reduceProd, parseReduceAttributes],
|
||||
['ReduceSum', '', '1-12', reduceSum, parseReduceAttributes],
|
||||
['ReduceSumSquare', '', '1+', reduceLogSumSquare, parseReduceAttributes],
|
||||
['Relu', '', '6+', unaryOps.relu],
|
||||
['Reshape', '', '5+', reshape],
|
||||
['Resize', '', '10', resize, parseResizeAttributesV10],
|
||||
['Resize', '', '11+', resize, parseResizeAttributesV11],
|
||||
['Shape', '', '1+', shape],
|
||||
['Sigmoid', '', '6+', unaryOps.sigmoid],
|
||||
['Sin', '', '7+', unaryOps.sin],
|
||||
['Slice', '', '10+', sliceV10], // TODO: support 'steps' for Slice-10
|
||||
['Slice', '', '1-9', slice, parseSliceAttributes],
|
||||
// The "semantic" meaning of axis has changed in opset-13.
|
||||
['Softmax', '', '1-12', softmax, parseSoftmaxAttributes],
|
||||
['Softmax', '', '13+', softmaxV13, parseSoftmaxAttributesV13],
|
||||
// 'Split' operator has an optional attribute 'split'
|
||||
// this attribute determines how the specified axis of input data is split.
|
||||
// When the attribute is missing, we need the count of number of outputs
|
||||
// so that we can determine the 'split' attribute from the runtime input to the Operator
|
||||
['Split', '', '2-12', split, parseSplitAttributes],
|
||||
['Sqrt', '', '6+', unaryOps.sqrt],
|
||||
['Squeeze', '', '1-12', squeeze, parseSqueezeAttributes],
|
||||
['Squeeze', '', '13+', squeezeV13],
|
||||
['Sub', '', '7+', binaryOps.sub],
|
||||
['Sum', '', '6+', sum],
|
||||
['Tan', '', '7+', unaryOps.tan],
|
||||
['Tanh', '', '6+', unaryOps.tanh],
|
||||
['Tile', '', '6+', tile],
|
||||
['Transpose', '', '1+', transpose, parseTransposeAttributes],
|
||||
['Upsample', '', '7-8', upsample, parseUpsampleAttributesV7],
|
||||
['Upsample', '', '9', upsample, parseUpsampleAttributesV9],
|
||||
['Unsqueeze', '', '1-12', unsqueeze, parseUnsqueezeAttributes],
|
||||
['Unsqueeze', '', '13+', unsqueezeV13],
|
||||
['Xor', '', '7+', binaryOps.xor],
|
||||
];
|
||||
68
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/batch-normalization.js
generated
vendored
Normal file
68
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/batch-normalization.js
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseBatchNormalizationAttributes = exports.batchNormalization = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const batchNormalizationProgramMetadata = {
|
||||
name: 'BatchNormalization',
|
||||
inputNames: ['A', 'Scale', 'B', 'Mean', 'Variance'],
|
||||
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked]
|
||||
};
|
||||
const batchNormalization = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs);
|
||||
const output = inferenceHandler.run(Object.assign(Object.assign({}, batchNormalizationProgramMetadata), { cacheHint: attributes.cacheKey, get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes) }), inputs);
|
||||
return [output];
|
||||
};
|
||||
exports.batchNormalization = batchNormalization;
|
||||
const parseBatchNormalizationAttributes = (node) => {
|
||||
const epsilon = node.attributes.getFloat('epsilon', 1e-5);
|
||||
const momentum = node.attributes.getFloat('momentum', 0.9);
|
||||
const spatial = node.attributes.getInt('spatial', 1);
|
||||
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ epsilon, momentum, spatial });
|
||||
};
|
||||
exports.parseBatchNormalizationAttributes = parseBatchNormalizationAttributes;
|
||||
const createBatchNormalizationProgramInfo = (inferenceHandler, inputs, attributes) => {
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
const rank = inputs[0].dims.length;
|
||||
const [scaleWidth, scaleHeight] = inferenceHandler.calculateTextureWidthAndHeight(inputs[1].dims, types_1.TextureType.unpacked);
|
||||
const shaderSource = `
|
||||
float process(int[${rank}] indices) {
|
||||
vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight});
|
||||
float scale = getColorAsFloat(${glsl.texture2D}(Scale, position));
|
||||
float mean = getColorAsFloat(${glsl.texture2D}(Mean, position));
|
||||
float variance = getColorAsFloat(${glsl.texture2D}(Variance, position));
|
||||
float b = getColorAsFloat(${glsl.texture2D}(B, position));
|
||||
|
||||
return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, batchNormalizationProgramMetadata), { output: { dims: inputs[0].dims, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
|
||||
};
|
||||
const validateInputs = (inputs) => {
|
||||
if (!inputs || inputs.length !== 5) {
|
||||
throw new Error('BatchNormalization requires 5 inputs.');
|
||||
}
|
||||
const X = inputs[0];
|
||||
const scale = inputs[1];
|
||||
const B = inputs[2];
|
||||
const mean = inputs[3];
|
||||
const var_ = inputs[4];
|
||||
// input should atleast have three dimensions - N,C,dim1,...,dimn
|
||||
// other inputs can have only one dimensions
|
||||
if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 ||
|
||||
var_.dims.length !== 1) {
|
||||
throw new Error('invalid input shape.');
|
||||
}
|
||||
if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] ||
|
||||
var_.dims[0] !== X.dims[1]) {
|
||||
throw new Error('invalid input shape.');
|
||||
}
|
||||
if ((X.type !== 'float32' && X.type !== 'float64') || (scale.type !== 'float32' && scale.type !== 'float64') ||
|
||||
(B.type !== 'float32' && B.type !== 'float64') || (mean.type !== 'float32' && mean.type !== 'float64') ||
|
||||
(var_.type !== 'float32' && var_.type !== 'float64')) {
|
||||
throw new Error('invalid input tensor types.');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=batch-normalization.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/batch-normalization.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/batch-normalization.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"batch-normalization.js","sourceRoot":"","sources":["batch-normalization.ts"],"names":[],"mappings":"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"}
|
||||
96
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts
generated
vendored
Normal file
96
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/batch-normalization.ts
generated
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {AttributeWithCacheKey, createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, TextureType} from '../types';
|
||||
|
||||
export interface BatchNormalizationAttributes extends AttributeWithCacheKey {
|
||||
epsilon: number;
|
||||
momentum: number;
|
||||
spatial: number;
|
||||
}
|
||||
|
||||
const batchNormalizationProgramMetadata = {
|
||||
name: 'BatchNormalization',
|
||||
inputNames: ['A', 'Scale', 'B', 'Mean', 'Variance'],
|
||||
inputTypes:
|
||||
[TextureType.unpacked, TextureType.unpacked, TextureType.unpacked, TextureType.unpacked, TextureType.unpacked]
|
||||
};
|
||||
|
||||
export const batchNormalization: OperatorImplementation<BatchNormalizationAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: BatchNormalizationAttributes): Tensor[] => {
|
||||
validateInputs(inputs);
|
||||
const output = inferenceHandler.run(
|
||||
{
|
||||
...batchNormalizationProgramMetadata,
|
||||
cacheHint: attributes.cacheKey,
|
||||
get: () => createBatchNormalizationProgramInfo(inferenceHandler, inputs, attributes)
|
||||
},
|
||||
inputs);
|
||||
return [output];
|
||||
};
|
||||
|
||||
export const parseBatchNormalizationAttributes: OperatorInitialization<BatchNormalizationAttributes> =
|
||||
(node: Graph.Node): BatchNormalizationAttributes => {
|
||||
const epsilon = node.attributes.getFloat('epsilon', 1e-5);
|
||||
const momentum = node.attributes.getFloat('momentum', 0.9);
|
||||
const spatial = node.attributes.getInt('spatial', 1);
|
||||
return createAttributeWithCacheKey({epsilon, momentum, spatial});
|
||||
};
|
||||
|
||||
const createBatchNormalizationProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: BatchNormalizationAttributes):
|
||||
ProgramInfo => {
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
const rank = inputs[0].dims.length;
|
||||
const [scaleWidth, scaleHeight] =
|
||||
inferenceHandler.calculateTextureWidthAndHeight(inputs[1].dims, TextureType.unpacked);
|
||||
const shaderSource = `
|
||||
float process(int[${rank}] indices) {
|
||||
vec2 position = offsetToCoords(indices[1], ${scaleWidth}, ${scaleHeight});
|
||||
float scale = getColorAsFloat(${glsl.texture2D}(Scale, position));
|
||||
float mean = getColorAsFloat(${glsl.texture2D}(Mean, position));
|
||||
float variance = getColorAsFloat(${glsl.texture2D}(Variance, position));
|
||||
float b = getColorAsFloat(${glsl.texture2D}(B, position));
|
||||
|
||||
return scale * ( (_A(indices) - mean) / sqrt(variance + float(${attributes.epsilon})) ) + b;
|
||||
}`;
|
||||
return {
|
||||
...batchNormalizationProgramMetadata,
|
||||
output: {dims: inputs[0].dims, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[]): void => {
|
||||
if (!inputs || inputs.length !== 5) {
|
||||
throw new Error('BatchNormalization requires 5 inputs.');
|
||||
}
|
||||
|
||||
const X = inputs[0];
|
||||
const scale = inputs[1];
|
||||
const B = inputs[2];
|
||||
const mean = inputs[3];
|
||||
const var_ = inputs[4];
|
||||
|
||||
// input should atleast have three dimensions - N,C,dim1,...,dimn
|
||||
// other inputs can have only one dimensions
|
||||
if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1 || mean.dims.length !== 1 ||
|
||||
var_.dims.length !== 1) {
|
||||
throw new Error('invalid input shape.');
|
||||
}
|
||||
if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1] || mean.dims[0] !== X.dims[1] ||
|
||||
var_.dims[0] !== X.dims[1]) {
|
||||
throw new Error('invalid input shape.');
|
||||
}
|
||||
if ((X.type !== 'float32' && X.type !== 'float64') || (scale.type !== 'float32' && scale.type !== 'float64') ||
|
||||
(B.type !== 'float32' && B.type !== 'float64') || (mean.type !== 'float32' && mean.type !== 'float64') ||
|
||||
(var_.type !== 'float32' && var_.type !== 'float64')) {
|
||||
throw new Error('invalid input tensor types.');
|
||||
}
|
||||
};
|
||||
291
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/binary-op.js
generated
vendored
Normal file
291
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/binary-op.js
generated
vendored
Normal file
@@ -0,0 +1,291 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.xor = exports.sub = exports.pRelu = exports.pow = exports.or = exports.mul = exports.less = exports.greater = exports.equal = exports.div = exports.and = exports.add = exports.glslPRelu = exports.glslPow = exports.glslXor = exports.glslOr = exports.glslAnd = exports.glslLess = exports.glslGreater = exports.glslEqual = exports.glslSub = exports.glslMul = exports.glslDiv = exports.glslAdd = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const glsl_definitions_1 = require("../glsl-definitions");
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
function glslAdd() {
|
||||
const name = 'add_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a + b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 + v2;
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslAdd = glslAdd;
|
||||
function glslDiv() {
|
||||
const name = 'div_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a / b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 / v2;
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslDiv = glslDiv;
|
||||
function glslMul() {
|
||||
const name = 'mul_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a * b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 * v2;
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslMul = glslMul;
|
||||
function glslSub() {
|
||||
const name = 'sub_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a - b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 - v2;
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslSub = glslSub;
|
||||
function glslEqual() {
|
||||
const name = 'equal_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float(a == b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4(equal(v1, v2));
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslEqual = glslEqual;
|
||||
function glslGreater() {
|
||||
const name = 'greater_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float(a > b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4( v1.r > v2.r ,
|
||||
v1.g > v2.g,
|
||||
v1.b > v2.b,
|
||||
v1.a > v2.a );
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslGreater = glslGreater;
|
||||
function glslLess() {
|
||||
const name = 'less_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float(a < b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4( v1.r < v2.r ,
|
||||
v1.g < v2.g,
|
||||
v1.b < v2.b,
|
||||
v1.a < v2.a );
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslLess = glslLess;
|
||||
function glslAnd() {
|
||||
const name = 'and_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float( bool(a) && bool(b) );
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
bvec4 b1 = bvec4(v1);
|
||||
bvec4 b2 = bvec4(v2);
|
||||
return vec4( b1.r && b2.r ,
|
||||
b1.g && b2.g,
|
||||
b1.b && b2.b,
|
||||
b1.a && b2.a );
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslAnd = glslAnd;
|
||||
function glslOr() {
|
||||
const name = 'or_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float( bool(a) || bool(b) );
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
bvec4 b1 = bvec4(v1);
|
||||
bvec4 b2 = bvec4(v2);
|
||||
return vec4( b1.r || b2.r ,
|
||||
b1.g || b2.g,
|
||||
b1.b || b2.b,
|
||||
b1.a || b2.a );
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslOr = glslOr;
|
||||
function glslXor() {
|
||||
const name = 'xor_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float( bool(a) ^^ bool(b) );
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
bvec4 b1 = bvec4(v1);
|
||||
bvec4 b2 = bvec4(v2);
|
||||
return vec4( b1.r ^^ b2.r ,
|
||||
b1.g ^^ b2.g,
|
||||
b1.b ^^ b2.b,
|
||||
b1.a ^^ b2.a );
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslXor = glslXor;
|
||||
function glslPow() {
|
||||
return glslBuiltinBinary('pow');
|
||||
}
|
||||
exports.glslPow = glslPow;
|
||||
function glslPRelu() {
|
||||
const name = 'prelu_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a < 0.0 ? a * b: a;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4(
|
||||
v1.r < 0.0 ? v1.r * v2.r: v1.r,
|
||||
v1.g < 0.0 ? v1.g * v2.g: v1.g,
|
||||
v1.b < 0.0 ? v1.b * v2.b: v1.b,
|
||||
v1.a < 0.0 ? v1.a * v2.a: v1.a
|
||||
);
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
exports.glslPRelu = glslPRelu;
|
||||
function glslBuiltinBinary(fname) {
|
||||
const name = `${fname}_`;
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return ${fname}(a, b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return ${fname}(v1, v2);
|
||||
}
|
||||
`;
|
||||
return { body, name, type: glsl_definitions_1.FunctionType.ValueBased };
|
||||
}
|
||||
const createBinaryProgramInfoLoader = (handler, inputs, glslFunc, outputTensorType = inputs[0].type, cacheKey) => {
|
||||
const textureType = handler.session.pack ? types_1.TextureType.packed : types_1.TextureType.unpacked;
|
||||
return {
|
||||
name: glslFunc.name,
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [textureType, textureType],
|
||||
cacheHint: cacheKey,
|
||||
get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType)
|
||||
};
|
||||
};
|
||||
const createBinaryProgramInfo = (handler, inputs, glslFunc, outputTensorType = inputs[0].type) => {
|
||||
const textureType = handler.session.pack ? types_1.TextureType.packed : types_1.TextureType.unpacked;
|
||||
const isBroadcast = !util_1.ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
|
||||
let outputShape = inputs[0].dims;
|
||||
const usePackedTexture = handler.session.pack;
|
||||
if (isBroadcast) {
|
||||
const calculatedShape = util_1.BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false);
|
||||
if (!calculatedShape) {
|
||||
throw new Error('Can\'t perform binary op on the given tensors');
|
||||
}
|
||||
outputShape = calculatedShape;
|
||||
const outputRank = outputShape.length;
|
||||
const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1;
|
||||
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;';
|
||||
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
|
||||
const shaderSource = usePackedTexture ? `
|
||||
${glslFunc.body}
|
||||
void main() {
|
||||
vec4 a = getAAtOutCoords();
|
||||
vec4 b = getBAtOutCoords();
|
||||
vec4 result = ${glslFunc.name}(a, b);
|
||||
${glsl.output} = result;
|
||||
}` :
|
||||
`
|
||||
${glslFunc.body}
|
||||
float process(int indices[${outputRank}]) {
|
||||
int aindices[${aRank}];
|
||||
int bindices[${bRank}];
|
||||
${aBcast}
|
||||
${bBcast}
|
||||
return ${glslFunc.name}(_A(aindices), _B(bindices));
|
||||
}`;
|
||||
return {
|
||||
name: glslFunc.name,
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [textureType, textureType],
|
||||
output: { dims: outputShape, type: outputTensorType, textureType },
|
||||
shaderSource,
|
||||
hasMain: usePackedTexture
|
||||
};
|
||||
}
|
||||
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
|
||||
const shaderSource = `
|
||||
${glslFunc.body}
|
||||
void main() {
|
||||
vec4 v1 = ${glsl.texture2D}(A, TexCoords);
|
||||
vec4 v2 = ${glsl.texture2D}(B, TexCoords);
|
||||
vec4 result = ${glslFunc.name}(v1, v2);
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
return {
|
||||
name: glslFunc.name,
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [textureType, textureType],
|
||||
output: { dims: inputs[0].dims, type: outputTensorType, textureType },
|
||||
shaderSource,
|
||||
hasMain: true
|
||||
};
|
||||
};
|
||||
const add = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs)];
|
||||
exports.add = add;
|
||||
const and = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), 'bool'), inputs)];
|
||||
exports.and = and;
|
||||
const div = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs)];
|
||||
exports.div = div;
|
||||
const equal = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), 'bool'), inputs)];
|
||||
exports.equal = equal;
|
||||
const greater = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), 'bool'), inputs)];
|
||||
exports.greater = greater;
|
||||
const less = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), 'bool'), inputs)];
|
||||
exports.less = less;
|
||||
const mul = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs)];
|
||||
exports.mul = mul;
|
||||
const or = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), 'bool'), inputs)];
|
||||
exports.or = or;
|
||||
const pow = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs)];
|
||||
exports.pow = pow;
|
||||
const pRelu = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs)];
|
||||
exports.pRelu = pRelu;
|
||||
const sub = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs)];
|
||||
exports.sub = sub;
|
||||
const xor = (handler, inputs) => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), 'bool'), inputs)];
|
||||
exports.xor = xor;
|
||||
//# sourceMappingURL=binary-op.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/binary-op.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/binary-op.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
303
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/binary-op.ts
generated
vendored
Normal file
303
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/binary-op.ts
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {BroadcastUtil, ShapeUtil} from '../../../util';
|
||||
import {FunctionType, GlslValueFunction} from '../glsl-definitions';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, TextureType} from '../types';
|
||||
|
||||
export function glslAdd(): GlslValueFunction {
|
||||
const name = 'add_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a + b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 + v2;
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslDiv(): GlslValueFunction {
|
||||
const name = 'div_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a / b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 / v2;
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslMul(): GlslValueFunction {
|
||||
const name = 'mul_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a * b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 * v2;
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslSub(): GlslValueFunction {
|
||||
const name = 'sub_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a - b;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return v1 - v2;
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslEqual(): GlslValueFunction {
|
||||
const name = 'equal_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float(a == b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4(equal(v1, v2));
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslGreater(): GlslValueFunction {
|
||||
const name = 'greater_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float(a > b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4( v1.r > v2.r ,
|
||||
v1.g > v2.g,
|
||||
v1.b > v2.b,
|
||||
v1.a > v2.a );
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslLess(): GlslValueFunction {
|
||||
const name = 'less_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float(a < b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4( v1.r < v2.r ,
|
||||
v1.g < v2.g,
|
||||
v1.b < v2.b,
|
||||
v1.a < v2.a );
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslAnd(): GlslValueFunction {
|
||||
const name = 'and_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float( bool(a) && bool(b) );
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
bvec4 b1 = bvec4(v1);
|
||||
bvec4 b2 = bvec4(v2);
|
||||
return vec4( b1.r && b2.r ,
|
||||
b1.g && b2.g,
|
||||
b1.b && b2.b,
|
||||
b1.a && b2.a );
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslOr(): GlslValueFunction {
|
||||
const name = 'or_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float( bool(a) || bool(b) );
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
bvec4 b1 = bvec4(v1);
|
||||
bvec4 b2 = bvec4(v2);
|
||||
return vec4( b1.r || b2.r ,
|
||||
b1.g || b2.g,
|
||||
b1.b || b2.b,
|
||||
b1.a || b2.a );
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslXor(): GlslValueFunction {
|
||||
const name = 'xor_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return float( bool(a) ^^ bool(b) );
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
bvec4 b1 = bvec4(v1);
|
||||
bvec4 b2 = bvec4(v2);
|
||||
return vec4( b1.r ^^ b2.r ,
|
||||
b1.g ^^ b2.g,
|
||||
b1.b ^^ b2.b,
|
||||
b1.a ^^ b2.a );
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
export function glslPow(): GlslValueFunction {
|
||||
return glslBuiltinBinary('pow');
|
||||
}
|
||||
export function glslPRelu(): GlslValueFunction {
|
||||
const name = 'prelu_';
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return a < 0.0 ? a * b: a;
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return vec4(
|
||||
v1.r < 0.0 ? v1.r * v2.r: v1.r,
|
||||
v1.g < 0.0 ? v1.g * v2.g: v1.g,
|
||||
v1.b < 0.0 ? v1.b * v2.b: v1.b,
|
||||
v1.a < 0.0 ? v1.a * v2.a: v1.a
|
||||
);
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
|
||||
function glslBuiltinBinary(fname: string): GlslValueFunction {
|
||||
const name = `${fname}_`;
|
||||
const body = `
|
||||
float ${name}(float a, float b) {
|
||||
return ${fname}(a, b);
|
||||
}
|
||||
vec4 ${name}(vec4 v1, vec4 v2) {
|
||||
return ${fname}(v1, v2);
|
||||
}
|
||||
`;
|
||||
return {body, name, type: FunctionType.ValueBased};
|
||||
}
|
||||
|
||||
const createBinaryProgramInfoLoader =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], glslFunc: GlslValueFunction,
|
||||
outputTensorType: Tensor.DataType = inputs[0].type, cacheKey?: string): ProgramInfoLoader => {
|
||||
const textureType = handler.session.pack ? TextureType.packed : TextureType.unpacked;
|
||||
return {
|
||||
name: glslFunc.name,
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [textureType, textureType],
|
||||
cacheHint: cacheKey,
|
||||
get: () => createBinaryProgramInfo(handler, inputs, glslFunc, outputTensorType)
|
||||
};
|
||||
};
|
||||
|
||||
const createBinaryProgramInfo =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], glslFunc: GlslValueFunction,
|
||||
outputTensorType: Tensor.DataType = inputs[0].type): ProgramInfo => {
|
||||
const textureType = handler.session.pack ? TextureType.packed : TextureType.unpacked;
|
||||
const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
|
||||
let outputShape = inputs[0].dims;
|
||||
|
||||
const usePackedTexture = handler.session.pack;
|
||||
|
||||
if (isBroadcast) {
|
||||
const calculatedShape = BroadcastUtil.calcShape(inputs[0].dims, inputs[1].dims, false);
|
||||
if (!calculatedShape) {
|
||||
throw new Error('Can\'t perform binary op on the given tensors');
|
||||
}
|
||||
outputShape = calculatedShape;
|
||||
const outputRank = outputShape.length;
|
||||
const aRank = inputs[0].dims.length !== 0 ? inputs[0].dims.length : 1;
|
||||
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;';
|
||||
|
||||
const glsl = getGlsl(handler.session.backend.glContext.version);
|
||||
const shaderSource = usePackedTexture ? `
|
||||
${glslFunc.body}
|
||||
void main() {
|
||||
vec4 a = getAAtOutCoords();
|
||||
vec4 b = getBAtOutCoords();
|
||||
vec4 result = ${glslFunc.name}(a, b);
|
||||
${glsl.output} = result;
|
||||
}` :
|
||||
`
|
||||
${glslFunc.body}
|
||||
float process(int indices[${outputRank}]) {
|
||||
int aindices[${aRank}];
|
||||
int bindices[${bRank}];
|
||||
${aBcast}
|
||||
${bBcast}
|
||||
return ${glslFunc.name}(_A(aindices), _B(bindices));
|
||||
}`;
|
||||
|
||||
return {
|
||||
name: glslFunc.name,
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [textureType, textureType],
|
||||
output: {dims: outputShape, type: outputTensorType, textureType},
|
||||
shaderSource,
|
||||
hasMain: usePackedTexture
|
||||
};
|
||||
}
|
||||
const glsl = getGlsl(handler.session.backend.glContext.version);
|
||||
const shaderSource = `
|
||||
${glslFunc.body}
|
||||
void main() {
|
||||
vec4 v1 = ${glsl.texture2D}(A, TexCoords);
|
||||
vec4 v2 = ${glsl.texture2D}(B, TexCoords);
|
||||
vec4 result = ${glslFunc.name}(v1, v2);
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
|
||||
return {
|
||||
name: glslFunc.name,
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [textureType, textureType],
|
||||
output: {dims: inputs[0].dims, type: outputTensorType, textureType},
|
||||
shaderSource,
|
||||
hasMain: true
|
||||
};
|
||||
};
|
||||
|
||||
export const add = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAdd()), inputs)];
|
||||
|
||||
export const and = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslAnd(), 'bool'), inputs)];
|
||||
|
||||
export const div = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslDiv()), inputs)];
|
||||
|
||||
export const equal = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslEqual(), 'bool'), inputs)];
|
||||
|
||||
export const greater = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslGreater(), 'bool'), inputs)];
|
||||
|
||||
export const less = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslLess(), 'bool'), inputs)];
|
||||
|
||||
export const mul = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslMul()), inputs)];
|
||||
|
||||
export const or = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslOr(), 'bool'), inputs)];
|
||||
|
||||
export const pow = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPow()), inputs)];
|
||||
|
||||
export const pRelu = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslPRelu()), inputs)];
|
||||
|
||||
export const sub = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslSub()), inputs)];
|
||||
|
||||
export const xor = (handler: WebGLInferenceHandler, inputs: Tensor[]):
|
||||
Tensor[] => [handler.run(createBinaryProgramInfoLoader(handler, inputs, glslXor(), 'bool'), inputs)];
|
||||
22
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/cast.js
generated
vendored
Normal file
22
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/cast.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseCastAttributes = exports.cast = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const cast = (handler, inputs, to) => {
|
||||
validateInputs(inputs);
|
||||
return [handler.cast(inputs[0], to)];
|
||||
};
|
||||
exports.cast = cast;
|
||||
const parseCastAttributes = (node) => util_1.ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt('to'));
|
||||
exports.parseCastAttributes = parseCastAttributes;
|
||||
const validateInputs = (inputs) => {
|
||||
if (!inputs || inputs.length !== 1) {
|
||||
throw new Error('Cast requires 1 input.');
|
||||
}
|
||||
if (inputs[0].type === 'string') {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=cast.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/cast.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/cast.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cast.js","sourceRoot":"","sources":["cast.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAKlC,wCAAwC;AAGjC,MAAM,IAAI,GACb,CAAC,OAA8B,EAAE,MAAgB,EAAE,EAAmB,EAAY,EAAE;IAClF,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AACvC,CAAC,CAAC;AAJO,QAAA,IAAI,QAIX;AAEC,MAAM,mBAAmB,GAA4C,CAAC,IAAgB,EAAmB,EAAE,CAC9G,gBAAS,CAAC,uBAAuB,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;AADvD,QAAA,mBAAmB,uBACoC;AAEpE,MAAM,cAAc,GAAG,CAAC,MAAgB,EAAQ,EAAE;IAChD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;KAC3C;IAED,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC;KACxC;AACH,CAAC,CAAC"}
|
||||
27
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/cast.ts
generated
vendored
Normal file
27
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/cast.ts
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {ProtoUtil} from '../../../util';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
|
||||
export const cast: OperatorImplementation<Tensor.DataType> =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], to: Tensor.DataType): Tensor[] => {
|
||||
validateInputs(inputs);
|
||||
return [handler.cast(inputs[0], to)];
|
||||
};
|
||||
|
||||
export const parseCastAttributes: OperatorInitialization<Tensor.DataType> = (node: Graph.Node): Tensor.DataType =>
|
||||
ProtoUtil.tensorDataTypeFromProto(node.attributes.getInt('to'));
|
||||
|
||||
const validateInputs = (inputs: Tensor[]): void => {
|
||||
if (!inputs || inputs.length !== 1) {
|
||||
throw new Error('Cast requires 1 input.');
|
||||
}
|
||||
|
||||
if (inputs[0].type === 'string') {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
};
|
||||
125
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat-packed.js
generated
vendored
Normal file
125
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat-packed.js
generated
vendored
Normal file
@@ -0,0 +1,125 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createPackedConcatProgramInfoLoader = void 0;
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const utils_1 = require("../utils");
|
||||
const packing_utils_1 = require("./packing-utils");
|
||||
const createPackedConcatProgramMetadata = (inputCount, cacheHint) => ({
|
||||
name: 'Concat (packed)',
|
||||
inputNames: Array.from({ length: inputCount }, (v, i) => `X${i}`),
|
||||
inputTypes: Array(inputCount).fill(types_1.TextureType.packed),
|
||||
cacheHint
|
||||
});
|
||||
const createPackedConcatProgramInfo = (handler, metadata, inputs, axis) => {
|
||||
const inputShape = inputs[0].dims.slice();
|
||||
if (axis >= inputShape.length || axis < (-1 * inputShape.length)) {
|
||||
throw new Error('axis specified for concat doesn\'t match input dimensionality');
|
||||
}
|
||||
if (axis < 0) {
|
||||
axis = inputShape.length + axis;
|
||||
}
|
||||
// ensure all of the non-concatenated axes match each other
|
||||
// calculate the shape of the output tensor while we do that
|
||||
const outputShape = inputShape.slice(0);
|
||||
for (let i = 1; i < inputs.length; i++) {
|
||||
const dataNShape = inputs[i].dims.slice();
|
||||
for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) {
|
||||
// add to the placeholder for computing output shape
|
||||
if (axisIndex === axis) {
|
||||
outputShape[axis] += dataNShape[axisIndex];
|
||||
}
|
||||
// ensure all non-cancatenated axes match each other
|
||||
else if (inputShape[axisIndex] !== dataNShape[axisIndex]) {
|
||||
throw new Error('non concat dimensions must match');
|
||||
}
|
||||
}
|
||||
}
|
||||
const rank = outputShape.length;
|
||||
const coords = (0, packing_utils_1.getChannels)('coords', rank);
|
||||
const dtype = (0, utils_1.getCoordsDataType)(rank);
|
||||
const unpackChannel = (0, packing_utils_1.unpackFromChannel)();
|
||||
const shapes = inputs.map(i => i.dims);
|
||||
const channels = (0, utils_1.getGlChannels)(rank);
|
||||
const offsets = new Array(shapes.length - 1);
|
||||
offsets[0] = shapes[0][axis];
|
||||
for (let i = 1; i < offsets.length; i++) {
|
||||
offsets[i] = offsets[i - 1] + shapes[i][axis];
|
||||
}
|
||||
const channel = channels[axis];
|
||||
const lastChannels = channels.slice(-2);
|
||||
const allChannels = channels.join();
|
||||
let getValueSnippet = `if (${channel} < ${offsets[0]}) {
|
||||
return getChannel(
|
||||
getX0(${allChannels}), vec2(${lastChannels.join()}));
|
||||
}`;
|
||||
for (let i = 1; i < offsets.length; i++) {
|
||||
const shift = offsets[i - 1];
|
||||
getValueSnippet += `
|
||||
if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) {
|
||||
return getChannel(
|
||||
getX${i}(${getShiftedChannelsSnippet(channels, channel, shift)}),
|
||||
vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));
|
||||
}`;
|
||||
}
|
||||
const lastIndex = offsets.length;
|
||||
const shift = offsets[offsets.length - 1];
|
||||
getValueSnippet += `
|
||||
return getChannel(
|
||||
getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}),
|
||||
vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`;
|
||||
const glsl = (0, glsl_source_1.getGlsl)(handler.session.backend.glContext.version);
|
||||
const shaderSource = `
|
||||
${unpackChannel}
|
||||
float getValue(${channels.map(x => 'int ' + x)}) {
|
||||
${getValueSnippet}
|
||||
}
|
||||
|
||||
void main() {
|
||||
${dtype} coords = getOutputCoords();
|
||||
int lastDim = coords.${channels[rank - 1]};
|
||||
coords.${channels[rank - 1]} = coords.${channels[rank - 2]};
|
||||
coords.${channels[rank - 2]} = lastDim;
|
||||
|
||||
vec4 result = vec4(getValue(${coords}), 0., 0., 0.);
|
||||
|
||||
${coords[rank - 1]} = ${coords[rank - 1]} + 1;
|
||||
if (${coords[rank - 1]} < ${outputShape[rank - 1]}) {
|
||||
result.g = getValue(${coords});
|
||||
}
|
||||
|
||||
${coords[rank - 2]} = ${coords[rank - 2]} + 1;
|
||||
if (${coords[rank - 2]} < ${outputShape[rank - 2]}) {
|
||||
result.a = getValue(${coords});
|
||||
}
|
||||
|
||||
${coords[rank - 1]} = ${coords[rank - 1]} - 1;
|
||||
if (${coords[rank - 2]} < ${outputShape[rank - 2]} &&
|
||||
${coords[rank - 1]} < ${outputShape[rank - 1]}) {
|
||||
result.b = getValue(${coords});
|
||||
}
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
|
||||
};
|
||||
const createPackedConcatProgramInfoLoader = (handler, inputs, attributes) => {
|
||||
const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) });
|
||||
};
|
||||
exports.createPackedConcatProgramInfoLoader = createPackedConcatProgramInfoLoader;
|
||||
const getShiftedChannelsSnippet = (channels, channel, shift) => {
|
||||
const channelIdx = channels.indexOf(channel);
|
||||
const res = channels.map((c, idx) => {
|
||||
if (idx === channelIdx) {
|
||||
return `${c} - ${shift}`;
|
||||
}
|
||||
else {
|
||||
return c;
|
||||
}
|
||||
});
|
||||
return res.join();
|
||||
};
|
||||
//# sourceMappingURL=concat-packed.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat-packed.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat-packed.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"concat-packed.js","sourceRoot":"","sources":["concat-packed.ts"],"names":[],"mappings":"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"}
|
||||
143
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat-packed.ts
generated
vendored
Normal file
143
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat-packed.ts
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
import {getCoordsDataType, getGlChannels} from '../utils';
|
||||
|
||||
import {ConcatAttributes} from './concat';
|
||||
import {getChannels, unpackFromChannel} from './packing-utils';
|
||||
|
||||
const createPackedConcatProgramMetadata = (inputCount: number, cacheHint: string) => ({
|
||||
name: 'Concat (packed)',
|
||||
inputNames: Array.from({length: inputCount}, (v, i) => `X${i}`),
|
||||
inputTypes: Array(inputCount).fill(TextureType.packed),
|
||||
cacheHint
|
||||
});
|
||||
|
||||
const createPackedConcatProgramInfo =
|
||||
(handler: WebGLInferenceHandler, metadata: ProgramMetadata, inputs: Tensor[], axis: number): ProgramInfo => {
|
||||
const inputShape = inputs[0].dims.slice();
|
||||
if (axis >= inputShape.length || axis < (-1 * inputShape.length)) {
|
||||
throw new Error('axis specified for concat doesn\'t match input dimensionality');
|
||||
}
|
||||
if (axis < 0) {
|
||||
axis = inputShape.length + axis;
|
||||
}
|
||||
// ensure all of the non-concatenated axes match each other
|
||||
// calculate the shape of the output tensor while we do that
|
||||
const outputShape = inputShape.slice(0);
|
||||
for (let i = 1; i < inputs.length; i++) {
|
||||
const dataNShape = inputs[i].dims.slice();
|
||||
for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) {
|
||||
// add to the placeholder for computing output shape
|
||||
if (axisIndex === axis) {
|
||||
outputShape[axis] += dataNShape[axisIndex];
|
||||
}
|
||||
// ensure all non-cancatenated axes match each other
|
||||
else if (inputShape[axisIndex] !== dataNShape[axisIndex]) {
|
||||
throw new Error('non concat dimensions must match');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rank = outputShape.length;
|
||||
const coords = getChannels('coords', rank);
|
||||
const dtype = getCoordsDataType(rank);
|
||||
const unpackChannel = unpackFromChannel();
|
||||
|
||||
const shapes = inputs.map(i => i.dims);
|
||||
const channels = getGlChannels(rank);
|
||||
const offsets: number[] = new Array(shapes.length - 1);
|
||||
|
||||
offsets[0] = shapes[0][axis];
|
||||
for (let i = 1; i < offsets.length; i++) {
|
||||
offsets[i] = offsets[i - 1] + shapes[i][axis];
|
||||
}
|
||||
|
||||
const channel = channels[axis];
|
||||
const lastChannels = channels.slice(-2);
|
||||
const allChannels = channels.join();
|
||||
|
||||
let getValueSnippet = `if (${channel} < ${offsets[0]}) {
|
||||
return getChannel(
|
||||
getX0(${allChannels}), vec2(${lastChannels.join()}));
|
||||
}`;
|
||||
for (let i = 1; i < offsets.length; i++) {
|
||||
const shift = offsets[i - 1];
|
||||
getValueSnippet += `
|
||||
if (${channel} < ${offsets[i]} && ${channel} >= ${offsets[i - 1]}) {
|
||||
return getChannel(
|
||||
getX${i}(${getShiftedChannelsSnippet(channels, channel, shift)}),
|
||||
vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));
|
||||
}`;
|
||||
}
|
||||
const lastIndex = offsets.length;
|
||||
const shift = offsets[offsets.length - 1];
|
||||
getValueSnippet += `
|
||||
return getChannel(
|
||||
getX${lastIndex}(${getShiftedChannelsSnippet(channels, channel, shift)}),
|
||||
vec2(${getShiftedChannelsSnippet(lastChannels, channel, shift)}));`;
|
||||
|
||||
const glsl = getGlsl(handler.session.backend.glContext.version);
|
||||
|
||||
const shaderSource = `
|
||||
${unpackChannel}
|
||||
float getValue(${channels.map(x => 'int ' + x)}) {
|
||||
${getValueSnippet}
|
||||
}
|
||||
|
||||
void main() {
|
||||
${dtype} coords = getOutputCoords();
|
||||
int lastDim = coords.${channels[rank - 1]};
|
||||
coords.${channels[rank - 1]} = coords.${channels[rank - 2]};
|
||||
coords.${channels[rank - 2]} = lastDim;
|
||||
|
||||
vec4 result = vec4(getValue(${coords}), 0., 0., 0.);
|
||||
|
||||
${coords[rank - 1]} = ${coords[rank - 1]} + 1;
|
||||
if (${coords[rank - 1]} < ${outputShape[rank - 1]}) {
|
||||
result.g = getValue(${coords});
|
||||
}
|
||||
|
||||
${coords[rank - 2]} = ${coords[rank - 2]} + 1;
|
||||
if (${coords[rank - 2]} < ${outputShape[rank - 2]}) {
|
||||
result.a = getValue(${coords});
|
||||
}
|
||||
|
||||
${coords[rank - 1]} = ${coords[rank - 1]} - 1;
|
||||
if (${coords[rank - 2]} < ${outputShape[rank - 2]} &&
|
||||
${coords[rank - 1]} < ${outputShape[rank - 1]}) {
|
||||
result.b = getValue(${coords});
|
||||
}
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.packed},
|
||||
shaderSource,
|
||||
hasMain: true,
|
||||
};
|
||||
};
|
||||
|
||||
export const createPackedConcatProgramInfoLoader =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], attributes: ConcatAttributes): ProgramInfoLoader => {
|
||||
const metadata = createPackedConcatProgramMetadata(inputs.length, attributes.cacheKey);
|
||||
return {...metadata, get: () => createPackedConcatProgramInfo(handler, metadata, inputs, attributes.axis)};
|
||||
};
|
||||
|
||||
const getShiftedChannelsSnippet = (channels: string[], channel: string, shift: number): string => {
|
||||
const channelIdx = channels.indexOf(channel);
|
||||
const res = channels.map((c, idx) => {
|
||||
if (idx === channelIdx) {
|
||||
return `${c} - ${shift}`;
|
||||
} else {
|
||||
return c;
|
||||
}
|
||||
});
|
||||
return res.join();
|
||||
};
|
||||
159
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat.js
generated
vendored
Normal file
159
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat.js
generated
vendored
Normal file
@@ -0,0 +1,159 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseConcatAttributes = exports.concat = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const types_1 = require("../types");
|
||||
const concat_packed_1 = require("./concat-packed");
|
||||
const concat = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs);
|
||||
if (inferenceHandler.session.pack && inputs[0].dims.length > 1) {
|
||||
const output = inferenceHandler.run((0, concat_packed_1.createPackedConcatProgramInfoLoader)(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
}
|
||||
else {
|
||||
const output = inferenceHandler.run(createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
}
|
||||
};
|
||||
exports.concat = concat;
|
||||
const createUnpackedConcatProgramMetadata = (inputCount, cacheHint) => ({
|
||||
name: 'Concat',
|
||||
inputNames: Array.from({ length: inputCount }, (v, i) => `X${i}`),
|
||||
inputTypes: Array(inputCount).fill(types_1.TextureType.unpacked),
|
||||
cacheHint
|
||||
});
|
||||
const createUnpackedConcatProgramInfo = (handler, metadata, inputs, axis) => {
|
||||
const inputShape = inputs[0].dims.slice();
|
||||
if (axis >= inputShape.length || axis < (-1 * inputShape.length)) {
|
||||
throw new Error('axis specified for concat doesn\'t match input dimensionality');
|
||||
}
|
||||
if (axis < 0) {
|
||||
axis = inputShape.length + axis;
|
||||
}
|
||||
// ensure all of the non-concatenated axes match each other
|
||||
// calculate the shape of the output tensor while we do that
|
||||
const outputShape = inputShape.slice(0);
|
||||
for (let i = 1; i < inputs.length; i++) {
|
||||
const dataNShape = inputs[i].dims.slice();
|
||||
for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) {
|
||||
// add to the placeholder for computing output shape
|
||||
if (axisIndex === axis) {
|
||||
outputShape[axis] += dataNShape[axisIndex];
|
||||
}
|
||||
// ensure all non-cancatenated axes match each other
|
||||
else if (inputShape[axisIndex] !== dataNShape[axisIndex]) {
|
||||
throw new Error('non concat dimensions must match');
|
||||
}
|
||||
}
|
||||
}
|
||||
const rank = outputShape.length;
|
||||
const sizeInConcatAxis = new Array(inputs.length);
|
||||
let previousSum = 0;
|
||||
for (let i = 0; i < sizeInConcatAxis.length; ++i) {
|
||||
previousSum += inputs[i].dims[axis];
|
||||
sizeInConcatAxis[i] = previousSum;
|
||||
}
|
||||
let getTextureIndexWhereDataResidesMethod = '';
|
||||
// in most cases linear search is sufficient, as in most scenarios, only 2 tensors are concatenated
|
||||
if (inputs.length < 5) {
|
||||
getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis);
|
||||
}
|
||||
else {
|
||||
getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis);
|
||||
}
|
||||
const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank);
|
||||
const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis);
|
||||
const shaderSource = `
|
||||
${fetchDataFromCorrectTextureMethod}
|
||||
${getSizeInConcatAxisValueFromIndexMethod}
|
||||
${getTextureIndexWhereDataResidesMethod}
|
||||
float process(int indices[${rank}]) {
|
||||
int textureIndex = getTextureWhereDataResides (indices[${axis}]);
|
||||
|
||||
if(textureIndex != 0) {
|
||||
indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1)));
|
||||
}
|
||||
|
||||
return fetchDataFromCorrectTexture(textureIndex, indices);
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
|
||||
};
|
||||
const createUnpackedConcatProgramInfoLoader = (handler, inputs, attributes) => {
|
||||
const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis) });
|
||||
};
|
||||
const getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis) => {
|
||||
const searchAxis = sizeInConcatAxis.map((size, i) => `if(index<${size}) {return ${i};}
|
||||
`);
|
||||
return `int getTextureWhereDataResides(int index) {
|
||||
${searchAxis.join('')}
|
||||
}`;
|
||||
};
|
||||
// TODO: Implement BinarySearch in GLSL
|
||||
const getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis) => getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis);
|
||||
const getFetchDataFromCorrectTextureMethod = (numberOfTensors, tensorRank) => {
|
||||
const codeLines = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`];
|
||||
for (let i = 0; i < numberOfTensors; ++i) {
|
||||
if (i === 0) {
|
||||
codeLines.push('\t' +
|
||||
`if (textureIndex == ${i}) { return _X${i}(indices); }`);
|
||||
}
|
||||
else if (i === numberOfTensors - 1) {
|
||||
codeLines.push('\t' +
|
||||
`else { return _X${i}(indices); }`);
|
||||
}
|
||||
else {
|
||||
codeLines.push('\t' +
|
||||
`else if (textureIndex == ${i}) { return _X${i}(indices); }`);
|
||||
}
|
||||
}
|
||||
codeLines.push('\t' +
|
||||
'}');
|
||||
return codeLines.join('\n');
|
||||
};
|
||||
const getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis) => {
|
||||
const codeLines = ['int getSizeInConcatAxisValueFromIndex(int index) {'];
|
||||
for (let i = 0; i < sizeInConcatAxis.length; ++i) {
|
||||
if (i === 0) {
|
||||
codeLines.push('\t' +
|
||||
`if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`);
|
||||
}
|
||||
else if (i === sizeInConcatAxis.length - 1) {
|
||||
codeLines.push('\t' +
|
||||
`else { return ${sizeInConcatAxis[i]}; }`);
|
||||
}
|
||||
else {
|
||||
codeLines.push('\t' +
|
||||
`else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`);
|
||||
}
|
||||
}
|
||||
codeLines.push('\t' +
|
||||
'}');
|
||||
return codeLines.join('\n');
|
||||
};
|
||||
const parseConcatAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis: node.attributes.getInt('axis') });
|
||||
exports.parseConcatAttributes = parseConcatAttributes;
|
||||
const validateInputs = (inputs) => {
|
||||
if (!inputs || inputs.length < 1) {
|
||||
throw new Error('too few inputs');
|
||||
}
|
||||
const inputType = inputs[0].type;
|
||||
const inputDimensionality = inputs[0].dims.length;
|
||||
// TODO: Support string concat
|
||||
if (inputType === 'string') {
|
||||
throw new Error('string tensor is not supported yet');
|
||||
}
|
||||
for (const input of inputs) {
|
||||
// make sure types of all inputs match
|
||||
if (input.type !== inputType) {
|
||||
throw new Error('input tensors should be one type');
|
||||
}
|
||||
// make sure the dimensionality of all inputs are the same
|
||||
if (input.dims.length !== inputDimensionality) {
|
||||
throw new Error('input tensors should have the same shape');
|
||||
}
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=concat.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
195
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat.ts
generated
vendored
Normal file
195
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/concat.ts
generated
vendored
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {AttributeWithCacheKey, createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
import {createPackedConcatProgramInfoLoader} from './concat-packed';
|
||||
|
||||
export interface ConcatAttributes extends AttributeWithCacheKey {
|
||||
readonly axis: number;
|
||||
}
|
||||
|
||||
export const concat: OperatorImplementation<ConcatAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: ConcatAttributes): Tensor[] => {
|
||||
validateInputs(inputs);
|
||||
if (inferenceHandler.session.pack && inputs[0].dims.length > 1) {
|
||||
const output =
|
||||
inferenceHandler.run(createPackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
} else {
|
||||
const output =
|
||||
inferenceHandler.run(createUnpackedConcatProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
}
|
||||
};
|
||||
|
||||
const createUnpackedConcatProgramMetadata = (inputCount: number, cacheHint: string) => ({
|
||||
name: 'Concat',
|
||||
inputNames: Array.from({length: inputCount}, (v, i) => `X${i}`),
|
||||
inputTypes: Array(inputCount).fill(TextureType.unpacked),
|
||||
cacheHint
|
||||
});
|
||||
|
||||
const createUnpackedConcatProgramInfo =
|
||||
(handler: WebGLInferenceHandler, metadata: ProgramMetadata, inputs: Tensor[], axis: number): ProgramInfo => {
|
||||
const inputShape = inputs[0].dims.slice();
|
||||
if (axis >= inputShape.length || axis < (-1 * inputShape.length)) {
|
||||
throw new Error('axis specified for concat doesn\'t match input dimensionality');
|
||||
}
|
||||
if (axis < 0) {
|
||||
axis = inputShape.length + axis;
|
||||
}
|
||||
// ensure all of the non-concatenated axes match each other
|
||||
// calculate the shape of the output tensor while we do that
|
||||
const outputShape = inputShape.slice(0);
|
||||
for (let i = 1; i < inputs.length; i++) {
|
||||
const dataNShape = inputs[i].dims.slice();
|
||||
for (let axisIndex = 0; axisIndex < inputShape.length; axisIndex++) {
|
||||
// add to the placeholder for computing output shape
|
||||
if (axisIndex === axis) {
|
||||
outputShape[axis] += dataNShape[axisIndex];
|
||||
}
|
||||
// ensure all non-cancatenated axes match each other
|
||||
else if (inputShape[axisIndex] !== dataNShape[axisIndex]) {
|
||||
throw new Error('non concat dimensions must match');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rank = outputShape.length;
|
||||
|
||||
const sizeInConcatAxis = new Array<number>(inputs.length);
|
||||
let previousSum = 0;
|
||||
for (let i = 0; i < sizeInConcatAxis.length; ++i) {
|
||||
previousSum += inputs[i].dims[axis];
|
||||
sizeInConcatAxis[i] = previousSum;
|
||||
}
|
||||
|
||||
let getTextureIndexWhereDataResidesMethod = '';
|
||||
// in most cases linear search is sufficient, as in most scenarios, only 2 tensors are concatenated
|
||||
if (inputs.length < 5) {
|
||||
getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis);
|
||||
} else {
|
||||
getTextureIndexWhereDataResidesMethod = getTextureIndexWhereDataResidesBinarySearch(sizeInConcatAxis);
|
||||
}
|
||||
|
||||
const fetchDataFromCorrectTextureMethod = getFetchDataFromCorrectTextureMethod(inputs.length, rank);
|
||||
const getSizeInConcatAxisValueFromIndexMethod = getGetSizeInConcatAxisValueFromIndexMethod(sizeInConcatAxis);
|
||||
const shaderSource = `
|
||||
${fetchDataFromCorrectTextureMethod}
|
||||
${getSizeInConcatAxisValueFromIndexMethod}
|
||||
${getTextureIndexWhereDataResidesMethod}
|
||||
float process(int indices[${rank}]) {
|
||||
int textureIndex = getTextureWhereDataResides (indices[${axis}]);
|
||||
|
||||
if(textureIndex != 0) {
|
||||
indices[${axis}] = indices[${axis}] - int(getSizeInConcatAxisValueFromIndex(textureIndex-int(1)));
|
||||
}
|
||||
|
||||
return fetchDataFromCorrectTexture(textureIndex, indices);
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
shaderSource,
|
||||
};
|
||||
};
|
||||
|
||||
const createUnpackedConcatProgramInfoLoader =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], attributes: ConcatAttributes): ProgramInfoLoader => {
|
||||
const metadata = createUnpackedConcatProgramMetadata(inputs.length, attributes.cacheKey);
|
||||
return {...metadata, get: () => createUnpackedConcatProgramInfo(handler, metadata, inputs, attributes.axis)};
|
||||
};
|
||||
|
||||
const getTextureIndexWhereDataResidesLinearSearch = (sizeInConcatAxis: number[]): string => {
|
||||
const searchAxis = sizeInConcatAxis.map((size, i) => `if(index<${size}) {return ${i};}
|
||||
`);
|
||||
return `int getTextureWhereDataResides(int index) {
|
||||
${searchAxis.join('')}
|
||||
}`;
|
||||
};
|
||||
|
||||
// TODO: Implement BinarySearch in GLSL
|
||||
const getTextureIndexWhereDataResidesBinarySearch = (sizeInConcatAxis: number[]): string =>
|
||||
getTextureIndexWhereDataResidesLinearSearch(sizeInConcatAxis);
|
||||
|
||||
const getFetchDataFromCorrectTextureMethod = (numberOfTensors: number, tensorRank: number) => {
|
||||
const codeLines: string[] = [`float fetchDataFromCorrectTexture(int textureIndex, int indices[${tensorRank}]) {`];
|
||||
for (let i = 0; i < numberOfTensors; ++i) {
|
||||
if (i === 0) {
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
`if (textureIndex == ${i}) { return _X${i}(indices); }`);
|
||||
} else if (i === numberOfTensors - 1) {
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
`else { return _X${i}(indices); }`);
|
||||
} else {
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
`else if (textureIndex == ${i}) { return _X${i}(indices); }`);
|
||||
}
|
||||
}
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
'}');
|
||||
return codeLines.join('\n');
|
||||
};
|
||||
|
||||
const getGetSizeInConcatAxisValueFromIndexMethod = (sizeInConcatAxis: number[]): string => {
|
||||
const codeLines: string[] = ['int getSizeInConcatAxisValueFromIndex(int index) {'];
|
||||
for (let i = 0; i < sizeInConcatAxis.length; ++i) {
|
||||
if (i === 0) {
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
`if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`);
|
||||
} else if (i === sizeInConcatAxis.length - 1) {
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
`else { return ${sizeInConcatAxis[i]}; }`);
|
||||
} else {
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
`else if (index == ${i}) { return ${sizeInConcatAxis[i]}; }`);
|
||||
}
|
||||
}
|
||||
codeLines.push(
|
||||
'\t' +
|
||||
'}');
|
||||
|
||||
return codeLines.join('\n');
|
||||
};
|
||||
|
||||
export const parseConcatAttributes: OperatorInitialization<ConcatAttributes> = (node: Graph.Node): ConcatAttributes =>
|
||||
createAttributeWithCacheKey({axis: node.attributes.getInt('axis')});
|
||||
|
||||
const validateInputs = (inputs: Tensor[]): void => {
|
||||
if (!inputs || inputs.length < 1) {
|
||||
throw new Error('too few inputs');
|
||||
}
|
||||
|
||||
const inputType = inputs[0].type;
|
||||
const inputDimensionality = inputs[0].dims.length;
|
||||
|
||||
// TODO: Support string concat
|
||||
if (inputType === 'string') {
|
||||
throw new Error('string tensor is not supported yet');
|
||||
}
|
||||
|
||||
for (const input of inputs) {
|
||||
// make sure types of all inputs match
|
||||
if (input.type !== inputType) {
|
||||
throw new Error('input tensors should be one type');
|
||||
}
|
||||
|
||||
// make sure the dimensionality of all inputs are the same
|
||||
if (input.dims.length !== inputDimensionality) {
|
||||
throw new Error('input tensors should have the same shape');
|
||||
}
|
||||
}
|
||||
};
|
||||
73
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-grouped.js
generated
vendored
Normal file
73
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-grouped.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createUnpackedGroupedConvProgramInfoLoader = void 0;
|
||||
const instrument_1 = require("../../../instrument");
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const conv_1 = require("./conv");
|
||||
const fuse_utils_1 = require("./fuse-utils");
|
||||
const createUnpackedGroupedConvProgramMetadata = (hasBias, cacheHint) => ({
|
||||
name: 'GroupedConv',
|
||||
inputNames: hasBias ? ['X', 'W', 'Bias'] : ['X', 'W'],
|
||||
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
|
||||
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
|
||||
cacheHint
|
||||
});
|
||||
const createUnpackedGroupedConvProgramInfo = (inferenceHandler, inputs, metadata, attributes) => {
|
||||
const hasBias = inputs.length > 2;
|
||||
const processBias = hasBias ? 'value += getBias(output_channel);' : '';
|
||||
const xShape = inputs[0].dims.slice();
|
||||
const wShape = inputs[1].dims.slice();
|
||||
const outputChannelsPerGroup = wShape[0] / attributes.group;
|
||||
instrument_1.Logger.verbose('GroupedConv', `autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}`);
|
||||
const outputShape = (0, conv_1.calculateOutputShape)(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(attributes);
|
||||
const shaderSource = `
|
||||
const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]});
|
||||
const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]});
|
||||
${activationFunction}
|
||||
void main() {
|
||||
ivec4 coords = getOutputCoords();
|
||||
int batch = coords.x;
|
||||
int output_channel = coords.y;
|
||||
ivec2 xRCCorner = coords.zw * strides - pads;
|
||||
int group_id = output_channel / ${outputChannelsPerGroup};
|
||||
|
||||
float value = 0.0;
|
||||
for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) {
|
||||
int input_channel = group_id * ${wShape[1]} + wInChannel;
|
||||
for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) {
|
||||
int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]};
|
||||
|
||||
if (xHeight < 0 || xHeight >= ${xShape[2]}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) {
|
||||
int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]};
|
||||
if (xWidth < 0 || xWidth >= ${xShape[3]}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float xVal = getX(batch, input_channel, xWidth, xHeight);
|
||||
float wVal = getW(output_channel, wInChannel, wWidth, wHeight);
|
||||
value += xVal*wVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
${processBias}
|
||||
${applyActivation}
|
||||
${glsl.output} = vec4(value, .0, .0, .0);
|
||||
}
|
||||
`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource, hasMain: true });
|
||||
};
|
||||
const createUnpackedGroupedConvProgramInfoLoader = (inferenceHandler, inputs, attributes) => {
|
||||
const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes) });
|
||||
};
|
||||
exports.createUnpackedGroupedConvProgramInfoLoader = createUnpackedGroupedConvProgramInfoLoader;
|
||||
//# sourceMappingURL=conv-grouped.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-grouped.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-grouped.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"conv-grouped.js","sourceRoot":"","sources":["conv-grouped.ts"],"names":[],"mappings":"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"}
|
||||
92
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts
generated
vendored
Normal file
92
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-grouped.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Logger} from '../../../instrument';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
import {calculateOutputShape, ConvAttributes} from './conv';
|
||||
import {getActivationSnippet} from './fuse-utils';
|
||||
|
||||
const createUnpackedGroupedConvProgramMetadata = (hasBias: boolean, cacheHint: string): ProgramMetadata => ({
|
||||
name: 'GroupedConv',
|
||||
inputNames: hasBias ? ['X', 'W', 'Bias'] : ['X', 'W'],
|
||||
inputTypes: hasBias ? [TextureType.unpacked, TextureType.unpacked, TextureType.unpacked] :
|
||||
[TextureType.unpacked, TextureType.unpacked],
|
||||
cacheHint
|
||||
});
|
||||
|
||||
const createUnpackedGroupedConvProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], metadata: ProgramMetadata,
|
||||
attributes: ConvAttributes): ProgramInfo => {
|
||||
const hasBias = inputs.length > 2;
|
||||
const processBias = hasBias ? 'value += getBias(output_channel);' : '';
|
||||
const xShape = inputs[0].dims.slice();
|
||||
const wShape = inputs[1].dims.slice();
|
||||
const outputChannelsPerGroup = wShape[0] / attributes.group;
|
||||
Logger.verbose(
|
||||
'GroupedConv',
|
||||
`autpPad:${attributes.autoPad}, dilations:${attributes.dilations}, group:${attributes.group}, kernelShape:${
|
||||
attributes.kernelShape}, pads:${attributes.pads}, strides:${attributes.strides}`);
|
||||
const outputShape =
|
||||
calculateOutputShape(xShape, wShape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
const {activationFunction, applyActivation} = getActivationSnippet(attributes);
|
||||
|
||||
const shaderSource = `
|
||||
const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]});
|
||||
const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]});
|
||||
${activationFunction}
|
||||
void main() {
|
||||
ivec4 coords = getOutputCoords();
|
||||
int batch = coords.x;
|
||||
int output_channel = coords.y;
|
||||
ivec2 xRCCorner = coords.zw * strides - pads;
|
||||
int group_id = output_channel / ${outputChannelsPerGroup};
|
||||
|
||||
float value = 0.0;
|
||||
for (int wInChannel = 0; wInChannel < ${wShape[1]}; wInChannel++) {
|
||||
int input_channel = group_id * ${wShape[1]} + wInChannel;
|
||||
for (int wHeight = 0; wHeight < ${wShape[2]}; wHeight++) {
|
||||
int xHeight = xRCCorner.x + wHeight * ${attributes.dilations[0]};
|
||||
|
||||
if (xHeight < 0 || xHeight >= ${xShape[2]}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int wWidth = 0; wWidth < ${wShape[3]}; wWidth++) {
|
||||
int xWidth = xRCCorner.y + wWidth * ${attributes.dilations[1]};
|
||||
if (xWidth < 0 || xWidth >= ${xShape[3]}) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float xVal = getX(batch, input_channel, xWidth, xHeight);
|
||||
float wVal = getW(output_channel, wInChannel, wWidth, wHeight);
|
||||
value += xVal*wVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
${processBias}
|
||||
${applyActivation}
|
||||
${glsl.output} = vec4(value, .0, .0, .0);
|
||||
}
|
||||
`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
shaderSource,
|
||||
hasMain: true,
|
||||
};
|
||||
};
|
||||
|
||||
export const createUnpackedGroupedConvProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvAttributes):
|
||||
ProgramInfoLoader => {
|
||||
const metadata = createUnpackedGroupedConvProgramMetadata(inputs.length > 2, attributes.cacheKey);
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createUnpackedGroupedConvProgramInfo(inferenceHandler, inputs, metadata, attributes)
|
||||
};
|
||||
};
|
||||
36
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-pack.js
generated
vendored
Normal file
36
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-pack.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.conv2DPacked = exports.conv2DPackedPointwise = void 0;
|
||||
const conv_1 = require("./conv");
|
||||
const im2col_pack_1 = require("./im2col-pack");
|
||||
const matmul_pack_1 = require("./matmul-pack");
|
||||
const conv2DPackedPointwise = (inferenceHandler, inputs, attributes) => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape = (0, conv_1.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const reshapedX = inferenceHandler.reshapePacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]);
|
||||
const reshapedK = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1]]);
|
||||
const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX];
|
||||
const matmulOutput = inferenceHandler.run((0, matmul_pack_1.createPackedMatmulProgramInfoLoader)(inferenceHandler, matmulInputs, attributes), matmulInputs);
|
||||
return inferenceHandler.reshapePacked(matmulOutput, outputShape);
|
||||
};
|
||||
exports.conv2DPackedPointwise = conv2DPackedPointwise;
|
||||
const conv2DPacked = (inferenceHandler, inputs, attributes) => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape = (0, conv_1.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
// run im2col
|
||||
const im2colOutput = inferenceHandler.run((0, im2col_pack_1.createPackedIm2ColProgramInfoLoader)(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]]);
|
||||
// reshape kernel
|
||||
const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]);
|
||||
// run matmul
|
||||
const matmulInputs = (inputs.length === 3) ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput];
|
||||
const matmulOutput = inferenceHandler.run((0, matmul_pack_1.createPackedMatmulProgramInfoLoader)(inferenceHandler, matmulInputs, attributes), matmulInputs);
|
||||
// reshape output
|
||||
const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape);
|
||||
return outputReshaped;
|
||||
};
|
||||
exports.conv2DPacked = conv2DPacked;
|
||||
//# sourceMappingURL=conv-pack.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-pack.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-pack.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"conv-pack.js","sourceRoot":"","sources":["conv-pack.ts"],"names":[],"mappings":"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"}
|
||||
50
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-pack.ts
generated
vendored
Normal file
50
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-pack.ts
generated
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
|
||||
import {calculateOutputShape, ConvAttributes} from './conv';
|
||||
import {createPackedIm2ColProgramInfoLoader} from './im2col-pack';
|
||||
import {createPackedMatmulProgramInfoLoader} from './matmul-pack';
|
||||
|
||||
export const conv2DPackedPointwise =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvAttributes): Tensor => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape =
|
||||
calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const reshapedX = inferenceHandler.reshapePacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]);
|
||||
const reshapedK = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1]]);
|
||||
|
||||
const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX];
|
||||
const matmulOutput = inferenceHandler.run(
|
||||
createPackedMatmulProgramInfoLoader(inferenceHandler, matmulInputs, attributes), matmulInputs);
|
||||
return inferenceHandler.reshapePacked(matmulOutput, outputShape);
|
||||
};
|
||||
|
||||
export const conv2DPacked =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvAttributes): Tensor => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape =
|
||||
calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
|
||||
// run im2col
|
||||
const im2colOutput = inferenceHandler.run(
|
||||
createPackedIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes),
|
||||
[inputs[0]]);
|
||||
|
||||
// reshape kernel
|
||||
const kernelReshaped = inferenceHandler.reshapePacked(inputs[1], [kshape[0], kshape[1] * kshape[2] * kshape[3]]);
|
||||
|
||||
// run matmul
|
||||
const matmulInputs =
|
||||
(inputs.length === 3) ? [kernelReshaped, im2colOutput, inputs[2]] : [kernelReshaped, im2colOutput];
|
||||
const matmulOutput = inferenceHandler.run(
|
||||
createPackedMatmulProgramInfoLoader(inferenceHandler, matmulInputs, attributes), matmulInputs);
|
||||
|
||||
// reshape output
|
||||
const outputReshaped = inferenceHandler.reshapePacked(matmulOutput, outputShape);
|
||||
return outputReshaped;
|
||||
};
|
||||
198
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-transpose.js
generated
vendored
Normal file
198
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-transpose.js
generated
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseConvTransposeAttributes = exports.convTranspose = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const fuse_utils_1 = require("./fuse-utils");
|
||||
const computeTotalPad = (inDim, stride, adj, kernel, dilation, outSize) => (inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize;
|
||||
const distributePadding = (totalPad, autoPad, pads, head, tail) => {
|
||||
const smallPad = Math.floor(totalPad / 2);
|
||||
if (autoPad === 'SAME_UPPER') {
|
||||
pads[head] = smallPad;
|
||||
pads[tail] = totalPad - smallPad;
|
||||
}
|
||||
else if (autoPad === 'SAME_LOWER') {
|
||||
pads[head] = totalPad - smallPad;
|
||||
pads[tail] = smallPad;
|
||||
}
|
||||
};
|
||||
const calculateOutputShapeAndPads = (inputShape, kernelShape, dilations, autoPad, pads, strides, outputPadding, outputShape) => {
|
||||
const spatialRank = inputShape.length - 2;
|
||||
const updateShape = outputShape.length === 0;
|
||||
for (let i = 0; i < spatialRank; ++i) {
|
||||
const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i];
|
||||
const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize);
|
||||
distributePadding(totalPad, autoPad, pads, i, i + spatialRank);
|
||||
if (updateShape) {
|
||||
outputShape.push(strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 -
|
||||
pads[i] - pads[i + spatialRank]);
|
||||
}
|
||||
}
|
||||
};
|
||||
const convTranspose = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs, attributes); // currently will fail if not convTranspose2D
|
||||
return convTranspose2d(inferenceHandler, inputs, attributes);
|
||||
};
|
||||
exports.convTranspose = convTranspose;
|
||||
const convTranspose2d = (inferenceHandler, inputs, attributes) => {
|
||||
const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs);
|
||||
return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)];
|
||||
};
|
||||
const createConvTransposeProgramMetadata = (hasBias, cacheHint) => ({
|
||||
name: 'ConvTranspose',
|
||||
inputNames: hasBias ? ['X', 'W', 'B'] : ['X', 'W'],
|
||||
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
|
||||
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
|
||||
cacheHint
|
||||
});
|
||||
const createUnpackedConvTransposeProgramInfo = (inferenceHandler, inputs, metadata, attributes) => {
|
||||
const hasBias = inputs.length > 2;
|
||||
const valueInit = hasBias ? 'getB(output_channel)' : '0.0';
|
||||
const xShape = inputs[0].dims;
|
||||
const wShape = inputs[1].dims;
|
||||
const outputChannelsPerGroup = wShape[1];
|
||||
const inputChannelsPerGroup = wShape[0] / attributes.group;
|
||||
const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape];
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(attributes);
|
||||
const shaderSource = `
|
||||
const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]});
|
||||
const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]});
|
||||
${activationFunction}
|
||||
void main() {
|
||||
ivec4 coords = getOutputCoords();
|
||||
int batch = coords.x;
|
||||
int output_channel = coords.y;
|
||||
|
||||
ivec2 loc = coords.zw + pads;
|
||||
|
||||
int group_id = output_channel / ${outputChannelsPerGroup};
|
||||
int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup};
|
||||
|
||||
float value = ${valueInit};
|
||||
for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) {
|
||||
int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset;
|
||||
for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) {
|
||||
for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) {
|
||||
ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]});
|
||||
ivec2 wLoc = loc - wOff;
|
||||
ivec2 wLocIn = wLoc / strides;
|
||||
if (
|
||||
wLocIn * strides == wLoc &&
|
||||
wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} &&
|
||||
wLocIn.y >= 0 && wLocIn.y < ${xShape[3]}
|
||||
) {
|
||||
float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x);
|
||||
float wVal = getW(input_channel, wOutChannel, wHOff, wWOff);
|
||||
value += xVal * wVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${applyActivation}
|
||||
${glsl.output} = vec4(value, .0, .0, .0);
|
||||
}
|
||||
`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource, hasMain: true });
|
||||
};
|
||||
const createUnpackedConvTransposeProgramInfoLoader = (inferenceHandler, inputs, attributes) => {
|
||||
const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes) });
|
||||
};
|
||||
const convTranspose2DUnpacked = (inferenceHandler, inputs, attributes) => {
|
||||
const result = inferenceHandler.run(createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return result;
|
||||
};
|
||||
const getAdjustedConvTransposeAttributes = (attributes, inputs) => {
|
||||
const kernelShape = attributes.kernelShape.slice();
|
||||
// if kernelShape is not specified in the attributes of this op, infer it from the weight tensor dims
|
||||
if (attributes.kernelShape.length === 0) {
|
||||
for (let i = 2; i < inputs[1].dims.length; ++i) {
|
||||
kernelShape.push(inputs[1].dims[i]);
|
||||
}
|
||||
}
|
||||
const pads = attributes.pads.slice();
|
||||
const outputShape = attributes.outputShape.slice();
|
||||
const inputShape = inputs[0].dims;
|
||||
// If outputShape is not specified in the attributes of this op, infer it from the parameters
|
||||
// Similarly, automatically infer pads if not specified
|
||||
calculateOutputShapeAndPads(inputShape, kernelShape, attributes.dilations, attributes.autoPad, pads, attributes.strides, attributes.outputPadding, outputShape);
|
||||
// always return a new object so does not modify the original attributes
|
||||
const newAttributes = Object.assign({}, attributes);
|
||||
Object.assign(newAttributes, { kernelShape, pads, outputShape, cacheKey: attributes.cacheKey });
|
||||
return newAttributes;
|
||||
};
|
||||
const parseConvTransposeAttributes = (node) => {
|
||||
const attributes = node.attributes;
|
||||
const activationAttributes = (0, fuse_utils_1.parseInternalActivationAttributes)(attributes);
|
||||
// TODO : Make this generic enough to compute default attributes for multi-dimensional conv
|
||||
const autoPad = attributes.getString('auto_pad', 'NOTSET');
|
||||
const dilations = attributes.getInts('dilations', [1, 1]);
|
||||
const group = attributes.getInt('group', 1);
|
||||
const kernelShape = attributes.getInts('kernel_shape', []);
|
||||
const outputPadding = attributes.getInts('output_padding', [0, 0]);
|
||||
const outputShape = attributes.getInts('output_shape', []);
|
||||
const pads = attributes.getInts('pads', [0, 0, 0, 0]);
|
||||
const strides = attributes.getInts('strides', [1, 1]);
|
||||
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)(Object.assign({ autoPad, dilations, group, kernelShape, outputPadding, outputShape, pads, strides }, activationAttributes));
|
||||
};
|
||||
exports.parseConvTransposeAttributes = parseConvTransposeAttributes;
|
||||
const validateInputs = (inputs, attributes) => {
|
||||
// Refer to the below link for all input checks
|
||||
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv
|
||||
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
|
||||
throw new Error('Conv requires 2 or 3 inputs');
|
||||
}
|
||||
// TODO : Need to add support for multi-dimensional conv
|
||||
if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) {
|
||||
throw new Error('currently only support 2-dimensional conv');
|
||||
}
|
||||
// FILTER_IN_CHANNEL should be equal to DATA_CHANNEL
|
||||
const dataChannel = inputs[0].dims[1];
|
||||
const filterInChannel = inputs[1].dims[0];
|
||||
if (dataChannel !== filterInChannel) {
|
||||
throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL');
|
||||
}
|
||||
const featureMaps = inputs[1].dims[1] * attributes.group;
|
||||
// if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps
|
||||
if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) {
|
||||
throw new Error('invalid bias');
|
||||
}
|
||||
const spatialRank = inputs[0].dims.length - 2;
|
||||
// wrong dilations dimension
|
||||
if (attributes.dilations.length !== spatialRank) {
|
||||
throw new Error(`dilations should be ${spatialRank}D`);
|
||||
}
|
||||
// Wrong strides dimension
|
||||
if (attributes.strides.length !== spatialRank) {
|
||||
throw new Error(`strides should be ${spatialRank}D`);
|
||||
}
|
||||
// Wrong pads dimension
|
||||
if (attributes.pads.length !== spatialRank * 2) {
|
||||
throw new Error(`pads should be ${spatialRank * 2}D`);
|
||||
}
|
||||
// Wrong output padding dimension
|
||||
if (attributes.outputPadding.length !== spatialRank) {
|
||||
throw new Error(`output_padding should be ${spatialRank}D`);
|
||||
}
|
||||
// if kernelShape is specified, it's data length must be 2 less than dims length of the weights tensor
|
||||
// (the first 2 dims are batch_size and channels)
|
||||
if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) {
|
||||
throw new Error('invalid kernel shape');
|
||||
}
|
||||
// as with kernelShape, must have same number of spatial dims as input
|
||||
if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) {
|
||||
throw new Error('invalid output shape');
|
||||
}
|
||||
// TODO : Need to add support for float64
|
||||
if (inputs[0].type !== 'float32' || inputs[1].type !== 'float32') {
|
||||
throw new Error('ConvTranspose input(X,W) should be float tensor');
|
||||
}
|
||||
if (inputs.length === 3 && inputs[2].type !== 'float32') {
|
||||
throw new Error('ConvTranspose input(bias) should be float tensor');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=conv-transpose.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-transpose.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-transpose.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
259
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts
generated
vendored
Normal file
259
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv-transpose.ts
generated
vendored
Normal file
@@ -0,0 +1,259 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {InferenceHandler} from '../../../backend';
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
import {ConvAttributes} from './conv';
|
||||
import {getActivationSnippet, parseInternalActivationAttributes} from './fuse-utils';
|
||||
|
||||
const computeTotalPad =
|
||||
(inDim: number, stride: number, adj: number, kernel: number, dilation: number, outSize: number) =>
|
||||
(inDim - 1) * stride + adj + (kernel - 1) * dilation + 1 - outSize;
|
||||
|
||||
const distributePadding = (totalPad: number, autoPad: string, pads: number[], head: number, tail: number) => {
|
||||
const smallPad = Math.floor(totalPad / 2);
|
||||
if (autoPad === 'SAME_UPPER') {
|
||||
pads[head] = smallPad;
|
||||
pads[tail] = totalPad - smallPad;
|
||||
} else if (autoPad === 'SAME_LOWER') {
|
||||
pads[head] = totalPad - smallPad;
|
||||
pads[tail] = smallPad;
|
||||
}
|
||||
};
|
||||
|
||||
const calculateOutputShapeAndPads =
|
||||
(inputShape: readonly number[], kernelShape: readonly number[], dilations: readonly number[], autoPad: string,
|
||||
pads: number[], strides: readonly number[], outputPadding: readonly number[], outputShape: number[]) => {
|
||||
const spatialRank = inputShape.length - 2;
|
||||
const updateShape = outputShape.length === 0;
|
||||
for (let i = 0; i < spatialRank; ++i) {
|
||||
const outSize = updateShape ? inputShape[i + 2] * strides[i] : outputShape[i];
|
||||
const totalPad = computeTotalPad(inputShape[i + 2], strides[i], pads[i], kernelShape[i], dilations[i], outSize);
|
||||
distributePadding(totalPad, autoPad, pads, i, i + spatialRank);
|
||||
if (updateShape) {
|
||||
outputShape.push(
|
||||
strides[i] * (inputShape[i + 2] - 1) + outputPadding[i] + (kernelShape[i] - 1) * dilations[i] + 1 -
|
||||
pads[i] - pads[i + spatialRank]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export interface ConvTransposeAttributes extends ConvAttributes {
|
||||
readonly outputPadding: readonly number[];
|
||||
readonly outputShape: readonly number[];
|
||||
}
|
||||
|
||||
export const convTranspose: OperatorImplementation<ConvTransposeAttributes> =
|
||||
(inferenceHandler: InferenceHandler, inputs: Tensor[], attributes: ConvTransposeAttributes): Tensor[] => {
|
||||
validateInputs(inputs, attributes); // currently will fail if not convTranspose2D
|
||||
return convTranspose2d(inferenceHandler, inputs, attributes);
|
||||
};
|
||||
|
||||
const convTranspose2d: OperatorImplementation<ConvTransposeAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: ConvTransposeAttributes): Tensor[] => {
|
||||
const adjustedAttributes = getAdjustedConvTransposeAttributes(attributes, inputs);
|
||||
return [convTranspose2DUnpacked(inferenceHandler, inputs, adjustedAttributes)];
|
||||
};
|
||||
|
||||
const createConvTransposeProgramMetadata = (hasBias: boolean, cacheHint: string) => ({
|
||||
name: 'ConvTranspose',
|
||||
inputNames: hasBias ? ['X', 'W', 'B'] : ['X', 'W'],
|
||||
inputTypes: hasBias ? [TextureType.unpacked, TextureType.unpacked, TextureType.unpacked] :
|
||||
[TextureType.unpacked, TextureType.unpacked],
|
||||
cacheHint
|
||||
});
|
||||
|
||||
const createUnpackedConvTransposeProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], metadata: ProgramMetadata,
|
||||
attributes: ConvTransposeAttributes): ProgramInfo => {
|
||||
const hasBias = inputs.length > 2;
|
||||
const valueInit = hasBias ? 'getB(output_channel)' : '0.0';
|
||||
const xShape = inputs[0].dims;
|
||||
const wShape = inputs[1].dims;
|
||||
const outputChannelsPerGroup = wShape[1];
|
||||
const inputChannelsPerGroup = wShape[0] / attributes.group;
|
||||
const outputShape = [inputs[0].dims[0], inputs[1].dims[1] * attributes.group, ...attributes.outputShape];
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
const {activationFunction, applyActivation} = getActivationSnippet(attributes);
|
||||
|
||||
const shaderSource = `
|
||||
const ivec2 strides = ivec2(${attributes.strides[0]}, ${attributes.strides[1]});
|
||||
const ivec2 pads = ivec2(${attributes.pads[0]}, ${attributes.pads[1]});
|
||||
${activationFunction}
|
||||
void main() {
|
||||
ivec4 coords = getOutputCoords();
|
||||
int batch = coords.x;
|
||||
int output_channel = coords.y;
|
||||
|
||||
ivec2 loc = coords.zw + pads;
|
||||
|
||||
int group_id = output_channel / ${outputChannelsPerGroup};
|
||||
int wOutChannel = output_channel - group_id * ${outputChannelsPerGroup};
|
||||
|
||||
float value = ${valueInit};
|
||||
for (int inChannelOffset = 0; inChannelOffset < ${inputChannelsPerGroup}; inChannelOffset++) {
|
||||
int input_channel = group_id * ${inputChannelsPerGroup} + inChannelOffset;
|
||||
for (int wWOff = 0; wWOff < ${wShape[2]}; wWOff++) {
|
||||
for (int wHOff = 0; wHOff < ${wShape[3]}; wHOff++) {
|
||||
ivec2 wOff = ivec2(wWOff * ${attributes.dilations[0]}, wHOff * ${attributes.dilations[1]});
|
||||
ivec2 wLoc = loc - wOff;
|
||||
ivec2 wLocIn = wLoc / strides;
|
||||
if (
|
||||
wLocIn * strides == wLoc &&
|
||||
wLocIn.x >= 0 && wLocIn.x < ${xShape[2]} &&
|
||||
wLocIn.y >= 0 && wLocIn.y < ${xShape[3]}
|
||||
) {
|
||||
float xVal = getX(batch, input_channel, wLocIn.y, wLocIn.x);
|
||||
float wVal = getW(input_channel, wOutChannel, wHOff, wWOff);
|
||||
value += xVal * wVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
${applyActivation}
|
||||
${glsl.output} = vec4(value, .0, .0, .0);
|
||||
}
|
||||
`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
shaderSource,
|
||||
hasMain: true,
|
||||
};
|
||||
};
|
||||
|
||||
const createUnpackedConvTransposeProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvTransposeAttributes):
|
||||
ProgramInfoLoader => {
|
||||
const metadata = createConvTransposeProgramMetadata(inputs.length > 2, attributes.cacheKey);
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createUnpackedConvTransposeProgramInfo(inferenceHandler, inputs, metadata, attributes)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
const convTranspose2DUnpacked =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvTransposeAttributes):
|
||||
Tensor => {
|
||||
const result = inferenceHandler.run(
|
||||
createUnpackedConvTransposeProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return result;
|
||||
};
|
||||
|
||||
const getAdjustedConvTransposeAttributes = <T extends ConvTransposeAttributes>(attributes: T, inputs: Tensor[]): T => {
|
||||
const kernelShape = attributes.kernelShape.slice();
|
||||
// if kernelShape is not specified in the attributes of this op, infer it from the weight tensor dims
|
||||
if (attributes.kernelShape.length === 0) {
|
||||
for (let i = 2; i < inputs[1].dims.length; ++i) {
|
||||
kernelShape.push(inputs[1].dims[i]);
|
||||
}
|
||||
}
|
||||
|
||||
const pads = attributes.pads.slice();
|
||||
const outputShape = attributes.outputShape.slice();
|
||||
const inputShape = inputs[0].dims;
|
||||
// If outputShape is not specified in the attributes of this op, infer it from the parameters
|
||||
// Similarly, automatically infer pads if not specified
|
||||
calculateOutputShapeAndPads(
|
||||
inputShape, kernelShape, attributes.dilations, attributes.autoPad, pads, attributes.strides,
|
||||
attributes.outputPadding, outputShape);
|
||||
|
||||
// always return a new object so does not modify the original attributes
|
||||
const newAttributes: T = Object.assign({}, attributes);
|
||||
Object.assign(newAttributes, {kernelShape, pads, outputShape, cacheKey: attributes.cacheKey});
|
||||
return newAttributes;
|
||||
};
|
||||
|
||||
export const parseConvTransposeAttributes: OperatorInitialization<ConvTransposeAttributes> =
|
||||
(node: Graph.Node): ConvTransposeAttributes => {
|
||||
const attributes = node.attributes;
|
||||
const activationAttributes = parseInternalActivationAttributes(attributes);
|
||||
// TODO : Make this generic enough to compute default attributes for multi-dimensional conv
|
||||
const autoPad = attributes.getString('auto_pad', 'NOTSET');
|
||||
const dilations = attributes.getInts('dilations', [1, 1]);
|
||||
const group = attributes.getInt('group', 1);
|
||||
const kernelShape = attributes.getInts('kernel_shape', []);
|
||||
const outputPadding = attributes.getInts('output_padding', [0, 0]);
|
||||
const outputShape = attributes.getInts('output_shape', []);
|
||||
const pads = attributes.getInts('pads', [0, 0, 0, 0]);
|
||||
const strides = attributes.getInts('strides', [1, 1]);
|
||||
|
||||
return createAttributeWithCacheKey(
|
||||
{autoPad, dilations, group, kernelShape, outputPadding, outputShape, pads, strides, ...activationAttributes});
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[], attributes: ConvTransposeAttributes): void => {
|
||||
// Refer to the below link for all input checks
|
||||
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv
|
||||
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
|
||||
throw new Error('Conv requires 2 or 3 inputs');
|
||||
}
|
||||
|
||||
// TODO : Need to add support for multi-dimensional conv
|
||||
if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) {
|
||||
throw new Error('currently only support 2-dimensional conv');
|
||||
}
|
||||
|
||||
// FILTER_IN_CHANNEL should be equal to DATA_CHANNEL
|
||||
const dataChannel = inputs[0].dims[1];
|
||||
const filterInChannel = inputs[1].dims[0];
|
||||
if (dataChannel !== filterInChannel) {
|
||||
throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL');
|
||||
}
|
||||
|
||||
const featureMaps = inputs[1].dims[1] * attributes.group;
|
||||
|
||||
// if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps
|
||||
if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[2].dims[0] !== featureMaps)) {
|
||||
throw new Error('invalid bias');
|
||||
}
|
||||
|
||||
const spatialRank = inputs[0].dims.length - 2;
|
||||
// wrong dilations dimension
|
||||
if (attributes.dilations.length !== spatialRank) {
|
||||
throw new Error(`dilations should be ${spatialRank}D`);
|
||||
}
|
||||
|
||||
// Wrong strides dimension
|
||||
if (attributes.strides.length !== spatialRank) {
|
||||
throw new Error(`strides should be ${spatialRank}D`);
|
||||
}
|
||||
|
||||
// Wrong pads dimension
|
||||
if (attributes.pads.length !== spatialRank * 2) {
|
||||
throw new Error(`pads should be ${spatialRank * 2}D`);
|
||||
}
|
||||
|
||||
// Wrong output padding dimension
|
||||
if (attributes.outputPadding.length !== spatialRank) {
|
||||
throw new Error(`output_padding should be ${spatialRank}D`);
|
||||
}
|
||||
|
||||
// if kernelShape is specified, it's data length must be 2 less than dims length of the weights tensor
|
||||
// (the first 2 dims are batch_size and channels)
|
||||
if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) {
|
||||
throw new Error('invalid kernel shape');
|
||||
}
|
||||
|
||||
// as with kernelShape, must have same number of spatial dims as input
|
||||
if (attributes.outputShape.length !== 0 && attributes.outputShape.length !== inputs[0].dims.length - 2) {
|
||||
throw new Error('invalid output shape');
|
||||
}
|
||||
|
||||
// TODO : Need to add support for float64
|
||||
if (inputs[0].type !== 'float32' || inputs[1].type !== 'float32') {
|
||||
throw new Error('ConvTranspose input(X,W) should be float tensor');
|
||||
}
|
||||
|
||||
if (inputs.length === 3 && inputs[2].type !== 'float32') {
|
||||
throw new Error('ConvTranspose input(bias) should be float tensor');
|
||||
}
|
||||
};
|
||||
143
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv.js
generated
vendored
Normal file
143
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv.js
generated
vendored
Normal file
@@ -0,0 +1,143 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseConvAttributes = exports.conv = exports.calculateOutputShape = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const util_1 = require("../../../util");
|
||||
const conv_grouped_1 = require("./conv-grouped");
|
||||
const conv_pack_1 = require("./conv-pack");
|
||||
const dot_product_1 = require("./dot-product");
|
||||
const fuse_utils_1 = require("./fuse-utils");
|
||||
const im2col_1 = require("./im2col");
|
||||
const matmul_1 = require("./matmul");
|
||||
const calculateOutputShape = (inputShape, kernelShape, dilations, adjustPads, strides) => {
|
||||
const batchSize = inputShape[0];
|
||||
const inputSpatialShape = inputShape.slice(2);
|
||||
const spatialRank = inputSpatialShape.length;
|
||||
const outChannels = kernelShape[0];
|
||||
const kernelSpatialShape = kernelShape.slice(2);
|
||||
const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1));
|
||||
const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]);
|
||||
const outputSpatialShape = inputSpatialShapeWithPad.map((v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]));
|
||||
const outputShape = [batchSize, outChannels].concat(...outputSpatialShape);
|
||||
return outputShape;
|
||||
};
|
||||
exports.calculateOutputShape = calculateOutputShape;
|
||||
const conv = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs, attributes); // currently will fail if not conv2D
|
||||
return conv2d(inferenceHandler, inputs, attributes);
|
||||
};
|
||||
exports.conv = conv;
|
||||
const conv2d = (inferenceHandler, inputs, attributes) => {
|
||||
const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs);
|
||||
const packMode = inferenceHandler.session.pack;
|
||||
const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1;
|
||||
if (adjustedAttributes.group > 1) {
|
||||
const result = inferenceHandler.run((0, conv_grouped_1.createUnpackedGroupedConvProgramInfoLoader)(inferenceHandler, inputs, adjustedAttributes), inputs);
|
||||
return [result];
|
||||
}
|
||||
else if (isPointwise && packMode) {
|
||||
return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)];
|
||||
}
|
||||
else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) {
|
||||
return [(0, conv_pack_1.conv2DPacked)(inferenceHandler, inputs, adjustedAttributes)];
|
||||
}
|
||||
else {
|
||||
return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)];
|
||||
}
|
||||
};
|
||||
const conv2DUnpackedPointwise = (inferenceHandler, inputs, attributes) => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape = (0, exports.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]);
|
||||
const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]);
|
||||
const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX];
|
||||
const matmulOutput = inferenceHandler.run((0, matmul_1.createMatmulProgramInfoLoader)(matmulInputs, attributes), matmulInputs);
|
||||
return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape);
|
||||
};
|
||||
const conv2DUnpacked = (inferenceHandler, inputs, attributes) => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape = (0, exports.calculateOutputShape)(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const xIm2Col = inferenceHandler.run((0, im2col_1.createIm2ColProgramInfoLoader)(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]]);
|
||||
const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]];
|
||||
const output = inferenceHandler.run((0, dot_product_1.createDotProductProgramInfoLoader)(inferenceHandler, inputs, outputShape, attributes), dotProductInputs);
|
||||
return output;
|
||||
};
|
||||
const getAdjustedConvAttributes = (attributes, inputs) => {
|
||||
const kernelShape = attributes.kernelShape.slice();
|
||||
// if kernelShape is not specified in the attributes of this op, infer it from the weight tensor dims
|
||||
if (attributes.kernelShape.length === 0) {
|
||||
for (let i = 2; i < inputs[1].dims.length; ++i) {
|
||||
kernelShape.push(inputs[1].dims[i]);
|
||||
}
|
||||
}
|
||||
const pads = attributes.pads.slice();
|
||||
util_1.PoolConvUtil.adjustPadsBasedOnAutoPad(inputs[0].dims, attributes.strides, attributes.dilations, kernelShape, pads, attributes.autoPad);
|
||||
// always return a new object so does not modify the original attributes
|
||||
const newAttributes = Object.assign({}, attributes);
|
||||
Object.assign(newAttributes, { kernelShape, pads, cacheKey: attributes.cacheKey });
|
||||
return newAttributes;
|
||||
};
|
||||
const parseConvAttributes = (node) => {
|
||||
const attributes = node.attributes;
|
||||
const activationAttributes = (0, fuse_utils_1.parseInternalActivationAttributes)(attributes);
|
||||
// TODO : Make this generic enough to compute default attributes for multi-dimensional conv
|
||||
const autoPad = attributes.getString('auto_pad', 'NOTSET');
|
||||
const dilations = attributes.getInts('dilations', [1, 1]);
|
||||
const group = attributes.getInt('group', 1);
|
||||
const kernelShape = attributes.getInts('kernel_shape', []);
|
||||
const pads = attributes.getInts('pads', [0, 0, 0, 0]);
|
||||
const strides = attributes.getInts('strides', [1, 1]);
|
||||
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)(Object.assign({ autoPad, dilations, group, kernelShape, pads, strides }, activationAttributes));
|
||||
};
|
||||
exports.parseConvAttributes = parseConvAttributes;
|
||||
const validateInputs = (inputs, attributes) => {
|
||||
// Refer to the below link for all input checks
|
||||
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv
|
||||
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
|
||||
throw new Error('Conv requires 2 or 3 inputs');
|
||||
}
|
||||
// TODO : Need to add support for multi-dimensional conv
|
||||
if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) {
|
||||
throw new Error('currently only support 2-dimensional conv');
|
||||
}
|
||||
// FILTER_IN_CHANNEL should be equal to DATA_CHANNEL
|
||||
const dataChannel = inputs[0].dims[1];
|
||||
const filterInChannel = inputs[1].dims[1] * attributes.group;
|
||||
if (dataChannel !== filterInChannel) {
|
||||
throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL');
|
||||
}
|
||||
// if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps
|
||||
if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) {
|
||||
throw new Error('invalid bias');
|
||||
}
|
||||
const spatialRank = inputs[0].dims.length - 2;
|
||||
// wrong dilations dimension
|
||||
if (attributes.dilations.length !== spatialRank) {
|
||||
throw new Error(`dilations should be ${spatialRank}D`);
|
||||
}
|
||||
// Wrong strides dimension
|
||||
if (attributes.strides.length !== spatialRank) {
|
||||
throw new Error(`strides should be ${spatialRank}D`);
|
||||
}
|
||||
// Wrong pads dimension
|
||||
if (attributes.pads.length !== spatialRank * 2) {
|
||||
throw new Error(`pads should be ${spatialRank * 2}D`);
|
||||
}
|
||||
// if kernelShape is specified, it's data length must be 2 less than dims length of the weights tensor
|
||||
// (the first 2 dims are batch_size and channels)
|
||||
if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) {
|
||||
throw new Error('invalid kernel shape');
|
||||
}
|
||||
// TODO : Need to add support for float64
|
||||
if (inputs[0].type !== 'float32' || inputs[1].type !== 'float32') {
|
||||
throw new Error('Conv input(X,W) should be float tensor');
|
||||
}
|
||||
if (inputs.length === 3 && inputs[2].type !== 'float32') {
|
||||
throw new Error('Conv input(bias) should be float tensor');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=conv.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
184
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv.ts
generated
vendored
Normal file
184
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/conv.ts
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {AttributeWithCacheKey, createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {InferenceHandler} from '../../../backend';
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {PoolConvUtil} from '../../../util';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
|
||||
import {createUnpackedGroupedConvProgramInfoLoader} from './conv-grouped';
|
||||
import {conv2DPacked} from './conv-pack';
|
||||
import {createDotProductProgramInfoLoader} from './dot-product';
|
||||
import {InternalActivationAttributes, parseInternalActivationAttributes} from './fuse-utils';
|
||||
import {createIm2ColProgramInfoLoader} from './im2col';
|
||||
import {createMatmulProgramInfoLoader} from './matmul';
|
||||
|
||||
|
||||
export const calculateOutputShape =
|
||||
(inputShape: readonly number[], kernelShape: readonly number[], dilations: readonly number[],
|
||||
adjustPads: readonly number[], strides: readonly number[]): number[] => {
|
||||
const batchSize = inputShape[0];
|
||||
const inputSpatialShape = inputShape.slice(2);
|
||||
const spatialRank = inputSpatialShape.length;
|
||||
const outChannels = kernelShape[0];
|
||||
const kernelSpatialShape = kernelShape.slice(2);
|
||||
const dilatedKernelShape = kernelSpatialShape.map((v, i) => v + (v - 1) * (dilations[i] - 1));
|
||||
const inputSpatialShapeWithPad = inputSpatialShape.map((v, i) => v + adjustPads[i] + adjustPads[i + spatialRank]);
|
||||
const outputSpatialShape =
|
||||
inputSpatialShapeWithPad.map((v, i) => Math.floor((v - dilatedKernelShape[i] + strides[i]) / strides[i]));
|
||||
const outputShape = [batchSize, outChannels].concat(...outputSpatialShape);
|
||||
return outputShape;
|
||||
};
|
||||
|
||||
export interface ConvAttributes extends InternalActivationAttributes, AttributeWithCacheKey {
|
||||
readonly autoPad: string;
|
||||
readonly dilations: readonly number[];
|
||||
readonly group: number;
|
||||
readonly kernelShape: readonly number[];
|
||||
readonly pads: readonly number[];
|
||||
readonly strides: readonly number[];
|
||||
}
|
||||
|
||||
export const conv: OperatorImplementation<ConvAttributes> =
|
||||
(inferenceHandler: InferenceHandler, inputs: Tensor[], attributes: ConvAttributes): Tensor[] => {
|
||||
validateInputs(inputs, attributes); // currently will fail if not conv2D
|
||||
return conv2d(inferenceHandler, inputs, attributes);
|
||||
};
|
||||
|
||||
const conv2d: OperatorImplementation<ConvAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: ConvAttributes): Tensor[] => {
|
||||
const adjustedAttributes = getAdjustedConvAttributes(attributes, inputs);
|
||||
const packMode = inferenceHandler.session.pack;
|
||||
const isPointwise = adjustedAttributes.kernelShape[0] === 1 && adjustedAttributes.kernelShape[1] === 1;
|
||||
if (adjustedAttributes.group > 1) {
|
||||
const result = inferenceHandler.run(
|
||||
createUnpackedGroupedConvProgramInfoLoader(inferenceHandler, inputs, adjustedAttributes), inputs);
|
||||
return [result];
|
||||
} else if (isPointwise && packMode) {
|
||||
return [conv2DUnpackedPointwise(inferenceHandler, inputs, adjustedAttributes)];
|
||||
} else if (packMode && inputs[0].dims.length === 4 && inputs[0].dims[0] === 1 && !isPointwise) {
|
||||
return [conv2DPacked(inferenceHandler, inputs, adjustedAttributes)];
|
||||
} else {
|
||||
return [conv2DUnpacked(inferenceHandler, inputs, adjustedAttributes)];
|
||||
}
|
||||
};
|
||||
|
||||
const conv2DUnpackedPointwise =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvAttributes): Tensor => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape =
|
||||
calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const reshapedX = inferenceHandler.reshapeUnpacked(inputs[0], [xshape[1], xshape[2] * xshape[3]]);
|
||||
const reshapedK = inferenceHandler.reshapeUnpacked(inputs[1], [kshape[0], kshape[1]]);
|
||||
|
||||
const matmulInputs = inputs.length > 2 ? [reshapedK, reshapedX, inputs[2]] : [reshapedK, reshapedX];
|
||||
const matmulOutput = inferenceHandler.run(createMatmulProgramInfoLoader(matmulInputs, attributes), matmulInputs);
|
||||
return inferenceHandler.reshapeUnpacked(matmulOutput, outputShape);
|
||||
};
|
||||
|
||||
const conv2DUnpacked =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], attributes: ConvAttributes): Tensor => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const outputShape =
|
||||
calculateOutputShape(xshape, kshape, attributes.dilations, attributes.pads, attributes.strides);
|
||||
const xIm2Col = inferenceHandler.run(
|
||||
createIm2ColProgramInfoLoader(inferenceHandler, inputs[0], inputs[1], outputShape, attributes), [inputs[0]]);
|
||||
|
||||
const dotProductInputs = inputs.length === 3 ? [xIm2Col, inputs[1], inputs[2]] : [xIm2Col, inputs[1]];
|
||||
const output = inferenceHandler.run(
|
||||
createDotProductProgramInfoLoader(inferenceHandler, inputs, outputShape, attributes), dotProductInputs);
|
||||
return output;
|
||||
};
|
||||
|
||||
const getAdjustedConvAttributes = <T extends ConvAttributes>(attributes: T, inputs: Tensor[]): T => {
|
||||
const kernelShape = attributes.kernelShape.slice();
|
||||
// if kernelShape is not specified in the attributes of this op, infer it from the weight tensor dims
|
||||
if (attributes.kernelShape.length === 0) {
|
||||
for (let i = 2; i < inputs[1].dims.length; ++i) {
|
||||
kernelShape.push(inputs[1].dims[i]);
|
||||
}
|
||||
}
|
||||
const pads = attributes.pads.slice();
|
||||
PoolConvUtil.adjustPadsBasedOnAutoPad(
|
||||
inputs[0].dims, attributes.strides, attributes.dilations, kernelShape, pads, attributes.autoPad);
|
||||
|
||||
// always return a new object so does not modify the original attributes
|
||||
const newAttributes: T = Object.assign({}, attributes);
|
||||
Object.assign(newAttributes, {kernelShape, pads, cacheKey: attributes.cacheKey});
|
||||
return newAttributes;
|
||||
};
|
||||
|
||||
export const parseConvAttributes: OperatorInitialization<ConvAttributes> = (node: Graph.Node): ConvAttributes => {
|
||||
const attributes = node.attributes;
|
||||
const activationAttributes = parseInternalActivationAttributes(attributes);
|
||||
// TODO : Make this generic enough to compute default attributes for multi-dimensional conv
|
||||
const autoPad = attributes.getString('auto_pad', 'NOTSET');
|
||||
const dilations = attributes.getInts('dilations', [1, 1]);
|
||||
const group = attributes.getInt('group', 1);
|
||||
const kernelShape = attributes.getInts('kernel_shape', []);
|
||||
const pads = attributes.getInts('pads', [0, 0, 0, 0]);
|
||||
const strides = attributes.getInts('strides', [1, 1]);
|
||||
|
||||
return createAttributeWithCacheKey({autoPad, dilations, group, kernelShape, pads, strides, ...activationAttributes});
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[], attributes: ConvAttributes): void => {
|
||||
// Refer to the below link for all input checks
|
||||
// https://github.com/onnx/onnx/blob/main/docs/Operators.md#Conv
|
||||
if (!inputs || (inputs.length !== 2 && inputs.length !== 3)) {
|
||||
throw new Error('Conv requires 2 or 3 inputs');
|
||||
}
|
||||
|
||||
// TODO : Need to add support for multi-dimensional conv
|
||||
if (inputs[0].dims.length !== 4 || inputs[1].dims.length !== 4) {
|
||||
throw new Error('currently only support 2-dimensional conv');
|
||||
}
|
||||
|
||||
// FILTER_IN_CHANNEL should be equal to DATA_CHANNEL
|
||||
const dataChannel = inputs[0].dims[1];
|
||||
const filterInChannel = inputs[1].dims[1] * attributes.group;
|
||||
if (dataChannel !== filterInChannel) {
|
||||
throw new Error('FILTER_IN_CHANNEL should be equal to DATA_CHANNEL');
|
||||
}
|
||||
|
||||
// if bias is provided it should be 1D and the number of elements should be equal to the number of feature maps
|
||||
if (inputs.length === 3 && (inputs[2].dims.length !== 1 || inputs[1].dims[0] !== inputs[2].dims[0])) {
|
||||
throw new Error('invalid bias');
|
||||
}
|
||||
|
||||
const spatialRank = inputs[0].dims.length - 2;
|
||||
// wrong dilations dimension
|
||||
if (attributes.dilations.length !== spatialRank) {
|
||||
throw new Error(`dilations should be ${spatialRank}D`);
|
||||
}
|
||||
|
||||
// Wrong strides dimension
|
||||
if (attributes.strides.length !== spatialRank) {
|
||||
throw new Error(`strides should be ${spatialRank}D`);
|
||||
}
|
||||
|
||||
// Wrong pads dimension
|
||||
if (attributes.pads.length !== spatialRank * 2) {
|
||||
throw new Error(`pads should be ${spatialRank * 2}D`);
|
||||
}
|
||||
|
||||
// if kernelShape is specified, it's data length must be 2 less than dims length of the weights tensor
|
||||
// (the first 2 dims are batch_size and channels)
|
||||
if (attributes.kernelShape.length !== 0 && attributes.kernelShape.length !== inputs[1].dims.length - 2) {
|
||||
throw new Error('invalid kernel shape');
|
||||
}
|
||||
|
||||
// TODO : Need to add support for float64
|
||||
if (inputs[0].type !== 'float32' || inputs[1].type !== 'float32') {
|
||||
throw new Error('Conv input(X,W) should be float tensor');
|
||||
}
|
||||
|
||||
if (inputs.length === 3 && inputs[2].type !== 'float32') {
|
||||
throw new Error('Conv input(bias) should be float tensor');
|
||||
}
|
||||
};
|
||||
62
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/depth-to-space.js
generated
vendored
Normal file
62
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/depth-to-space.js
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseDepthToSpaceAttributes = exports.depthToSpace = void 0;
|
||||
const transpose_1 = require("./transpose");
|
||||
const depthToSpace = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs);
|
||||
const blocksize = attributes.blocksize;
|
||||
const blocksizeSqr = blocksize * blocksize;
|
||||
const transposePerm = attributes.mode === 'DCR' ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3];
|
||||
const firstReshapeShape = attributes.mode === 'DCR' ?
|
||||
[
|
||||
inputs[0].dims[0], blocksize, blocksize, inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2],
|
||||
inputs[0].dims[3]
|
||||
] :
|
||||
[
|
||||
inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, blocksize, blocksize, inputs[0].dims[2],
|
||||
inputs[0].dims[3]
|
||||
];
|
||||
// const transpose = new WebGLTranspose();
|
||||
// const attributes = new Attribute(undefined);
|
||||
// attributes.set('perm', 'ints', transposePerm);
|
||||
// transpose.initialize(attributes);
|
||||
// First reshape
|
||||
const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape);
|
||||
// transpose
|
||||
const transposeAttributes = { perm: transposePerm, cacheKey: `${transposePerm}` };
|
||||
const [transposeOutput] = (0, transpose_1.transpose)(inferenceHandler, [firstReshapedTensor], transposeAttributes);
|
||||
// Second reshape
|
||||
const secondReshapeShape = [
|
||||
inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2] * blocksize,
|
||||
inputs[0].dims[3] * blocksize
|
||||
];
|
||||
const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape);
|
||||
return [result];
|
||||
};
|
||||
exports.depthToSpace = depthToSpace;
|
||||
const parseDepthToSpaceAttributes = (node) => {
|
||||
// processing node attributes
|
||||
const blocksize = node.attributes.getInt('blocksize');
|
||||
if (blocksize < 1) {
|
||||
throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`);
|
||||
}
|
||||
const mode = node.attributes.getString('mode', 'DCR');
|
||||
if (mode !== 'DCR' && mode !== 'CRD') {
|
||||
throw new Error(`unrecognized mode: ${mode} for DepthToSpace`);
|
||||
}
|
||||
return { mode, blocksize };
|
||||
};
|
||||
exports.parseDepthToSpaceAttributes = parseDepthToSpaceAttributes;
|
||||
const validateInputs = (inputs) => {
|
||||
if (inputs.length !== 1) {
|
||||
throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`);
|
||||
}
|
||||
// Input has to be a 4-D tensor
|
||||
// TODO: Support string depth-to-space.
|
||||
if (inputs[0].type === 'string' || inputs[0].dims.length !== 4) {
|
||||
throw new TypeError('DepthToSpace input should be a 4-D numeric tensor');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=depth-to-space.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/depth-to-space.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/depth-to-space.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"depth-to-space.js","sourceRoot":"","sources":["depth-to-space.ts"],"names":[],"mappings":"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"}
|
||||
77
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts
generated
vendored
Normal file
77
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/depth-to-space.ts
generated
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
|
||||
import {transpose, TransposeAttributes} from './transpose';
|
||||
|
||||
export interface DepthToSpaceAttributes {
|
||||
mode: 'DCR'|'CRD';
|
||||
blocksize: number;
|
||||
}
|
||||
|
||||
export const depthToSpace: OperatorImplementation<DepthToSpaceAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: DepthToSpaceAttributes): Tensor[] => {
|
||||
validateInputs(inputs);
|
||||
const blocksize = attributes.blocksize;
|
||||
const blocksizeSqr = blocksize * blocksize;
|
||||
const transposePerm = attributes.mode === 'DCR' ? [0, 3, 4, 1, 5, 2] : [0, 1, 4, 2, 5, 3];
|
||||
const firstReshapeShape = attributes.mode === 'DCR' ?
|
||||
[
|
||||
inputs[0].dims[0], blocksize, blocksize, inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2],
|
||||
inputs[0].dims[3]
|
||||
] :
|
||||
[
|
||||
inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, blocksize, blocksize, inputs[0].dims[2],
|
||||
inputs[0].dims[3]
|
||||
];
|
||||
|
||||
// const transpose = new WebGLTranspose();
|
||||
// const attributes = new Attribute(undefined);
|
||||
// attributes.set('perm', 'ints', transposePerm);
|
||||
// transpose.initialize(attributes);
|
||||
|
||||
// First reshape
|
||||
const firstReshapedTensor = inferenceHandler.reshapeUnpacked(inputs[0], firstReshapeShape);
|
||||
|
||||
// transpose
|
||||
const transposeAttributes: TransposeAttributes = {perm: transposePerm, cacheKey: `${transposePerm}`};
|
||||
const [transposeOutput] = transpose(inferenceHandler, [firstReshapedTensor], transposeAttributes);
|
||||
|
||||
// Second reshape
|
||||
const secondReshapeShape = [
|
||||
inputs[0].dims[0], inputs[0].dims[1] / blocksizeSqr, inputs[0].dims[2] * blocksize,
|
||||
inputs[0].dims[3] * blocksize
|
||||
];
|
||||
const result = inferenceHandler.reshapeUnpacked(transposeOutput, secondReshapeShape);
|
||||
return [result];
|
||||
};
|
||||
|
||||
export const parseDepthToSpaceAttributes: OperatorInitialization<DepthToSpaceAttributes> =
|
||||
(node: Graph.Node): DepthToSpaceAttributes => {
|
||||
// processing node attributes
|
||||
const blocksize = node.attributes.getInt('blocksize');
|
||||
if (blocksize < 1) {
|
||||
throw new Error(`blocksize must be >= 1, but got : ${blocksize} for DepthToSpace`);
|
||||
}
|
||||
const mode = node.attributes.getString('mode', 'DCR');
|
||||
if (mode !== 'DCR' && mode !== 'CRD') {
|
||||
throw new Error(`unrecognized mode: ${mode} for DepthToSpace`);
|
||||
}
|
||||
return {mode, blocksize};
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[]): void => {
|
||||
if (inputs.length !== 1) {
|
||||
throw new Error(`DepthToSpace expect 1 inputs, but got ${inputs.length}`);
|
||||
}
|
||||
|
||||
// Input has to be a 4-D tensor
|
||||
// TODO: Support string depth-to-space.
|
||||
if (inputs[0].type === 'string' || inputs[0].dims.length !== 4) {
|
||||
throw new TypeError('DepthToSpace input should be a 4-D numeric tensor');
|
||||
}
|
||||
};
|
||||
60
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/dot-product.js
generated
vendored
Normal file
60
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/dot-product.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createDotProductProgramInfoLoader = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const fuse_utils_1 = require("./fuse-utils");
|
||||
const im2col_1 = require("./im2col");
|
||||
const createDotProductProgramMetadata = (hasBias, attributes) => ({
|
||||
name: 'ConvDotProduct',
|
||||
inputNames: hasBias ? ['Im2Col', 'K', 'B'] : ['Im2Col', 'K'],
|
||||
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.packedLastDimension, types_1.TextureType.unpacked] :
|
||||
[types_1.TextureType.unpacked, types_1.TextureType.packedLastDimension],
|
||||
cacheKey: attributes.activationCacheKey
|
||||
});
|
||||
const createDotProductProgramInfo = (inferenceHandler, metadata, inputs, outputShape, attributes) => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const adjustedKernelShape = [kshape[0], Math.ceil((xshape[1] * kshape[2] * kshape[3]) / 4)];
|
||||
const im2colShape = (0, im2col_1.calculateIm2ColDims)(xshape, kshape, outputShape);
|
||||
const [kWidth, kHeight] = inferenceHandler.calculateTextureWidthAndHeight(adjustedKernelShape, types_1.TextureType.packedLastDimension);
|
||||
const im2colStrides = util_1.ShapeUtil.computeStrides(im2colShape);
|
||||
const [im2colWidth, im2colHeight] = inferenceHandler.calculateTextureWidthAndHeight(im2colShape, types_1.TextureType.packedLastDimension);
|
||||
const rank = outputShape.length;
|
||||
const initValue = (inputs.length < 3) ? '0.0' : '_B(b)';
|
||||
const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4);
|
||||
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(attributes);
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
const shaderSource = `
|
||||
${activationFunction}
|
||||
float process(int indices[${rank}]) {
|
||||
int b[1];
|
||||
b[0] = indices[1];
|
||||
int im2col[4];
|
||||
im2col[0] = indices[0];
|
||||
im2col[1] = indices[2];
|
||||
im2col[2] = indices[3];
|
||||
int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${im2colStrides[2]};
|
||||
int kernelOffset = indices[1] * ${adjustedKernelShape[1]};
|
||||
float value = ${initValue};
|
||||
for (int i = 0; i < ${sharedDim}; ++i) {
|
||||
vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight});
|
||||
vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight});
|
||||
value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords));
|
||||
++im2colOffset;
|
||||
++kernelOffset;
|
||||
}
|
||||
${applyActivation}
|
||||
return value;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
|
||||
};
|
||||
const createDotProductProgramInfoLoader = (inferenceHandler, inputs, outputShape, attributes) => {
|
||||
const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes) });
|
||||
};
|
||||
exports.createDotProductProgramInfoLoader = createDotProductProgramInfoLoader;
|
||||
//# sourceMappingURL=dot-product.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/dot-product.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/dot-product.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"dot-product.js","sourceRoot":"","sources":["dot-product.ts"],"names":[],"mappings":"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"}
|
||||
78
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/dot-product.ts
generated
vendored
Normal file
78
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/dot-product.ts
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {ShapeUtil} from '../../../util';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
import {getActivationSnippet, InternalActivationAttributes} from './fuse-utils';
|
||||
import {calculateIm2ColDims} from './im2col';
|
||||
|
||||
const createDotProductProgramMetadata = (hasBias: boolean, attributes: InternalActivationAttributes) => ({
|
||||
name: 'ConvDotProduct',
|
||||
inputNames: hasBias ? ['Im2Col', 'K', 'B'] : ['Im2Col', 'K'],
|
||||
inputTypes: hasBias ? [TextureType.unpacked, TextureType.packedLastDimension, TextureType.unpacked] :
|
||||
[TextureType.unpacked, TextureType.packedLastDimension],
|
||||
cacheKey: attributes.activationCacheKey
|
||||
});
|
||||
|
||||
const createDotProductProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, metadata: ProgramMetadata, inputs: readonly Tensor[],
|
||||
outputShape: number[], attributes: InternalActivationAttributes): ProgramInfo => {
|
||||
const xshape = inputs[0].dims;
|
||||
const kshape = inputs[1].dims;
|
||||
const adjustedKernelShape = [kshape[0], Math.ceil((xshape[1] * kshape[2] * kshape[3]) / 4)];
|
||||
const im2colShape = calculateIm2ColDims(xshape, kshape, outputShape);
|
||||
const [kWidth, kHeight] =
|
||||
inferenceHandler.calculateTextureWidthAndHeight(adjustedKernelShape, TextureType.packedLastDimension);
|
||||
|
||||
const im2colStrides = ShapeUtil.computeStrides(im2colShape);
|
||||
const [im2colWidth, im2colHeight] =
|
||||
inferenceHandler.calculateTextureWidthAndHeight(im2colShape, TextureType.packedLastDimension);
|
||||
const rank = outputShape.length;
|
||||
|
||||
const initValue = (inputs.length < 3) ? '0.0' : '_B(b)';
|
||||
const sharedDim = Math.ceil(xshape[1] * kshape[2] * kshape[3] / 4);
|
||||
const {activationFunction, applyActivation} = getActivationSnippet(attributes);
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
const shaderSource = `
|
||||
${activationFunction}
|
||||
float process(int indices[${rank}]) {
|
||||
int b[1];
|
||||
b[0] = indices[1];
|
||||
int im2col[4];
|
||||
im2col[0] = indices[0];
|
||||
im2col[1] = indices[2];
|
||||
im2col[2] = indices[3];
|
||||
int im2colOffset = im2col[0] * ${im2colStrides[0]} + im2col[1] * ${im2colStrides[1]} + im2col[2] * ${
|
||||
im2colStrides[2]};
|
||||
int kernelOffset = indices[1] * ${adjustedKernelShape[1]};
|
||||
float value = ${initValue};
|
||||
for (int i = 0; i < ${sharedDim}; ++i) {
|
||||
vec2 im2colCoords = offsetToCoords(im2colOffset, ${im2colWidth}, ${im2colHeight});
|
||||
vec2 kernelCoords = offsetToCoords(kernelOffset, ${kWidth}, ${kHeight});
|
||||
value += dot(${glsl.texture2D}(Im2Col, im2colCoords), ${glsl.texture2D}(K, kernelCoords));
|
||||
++im2colOffset;
|
||||
++kernelOffset;
|
||||
}
|
||||
${applyActivation}
|
||||
return value;
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
export const createDotProductProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: readonly Tensor[], outputShape: number[],
|
||||
attributes: InternalActivationAttributes): ProgramInfoLoader => {
|
||||
const metadata = createDotProductProgramMetadata(inputs.length > 2, attributes);
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createDotProductProgramInfo(inferenceHandler, metadata, inputs, outputShape, attributes)
|
||||
};
|
||||
};
|
||||
31
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/flatten.js
generated
vendored
Normal file
31
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/flatten.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseFlattenAttributes = exports.flatten = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const flatten = (inferenceHandler, inputs, axis) => {
|
||||
validateInputs(inputs, axis);
|
||||
const outputDims = util_1.ShapeUtil.flattenShape(inputs[0].dims, axis);
|
||||
return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)];
|
||||
};
|
||||
exports.flatten = flatten;
|
||||
const parseFlattenAttributes = (node) => node.attributes.getInt('axis', 1); // default axis is 1
|
||||
exports.parseFlattenAttributes = parseFlattenAttributes;
|
||||
const validateInputs = (inputs, axis) => {
|
||||
if (!inputs || inputs.length !== 1) {
|
||||
throw new Error('Flatten requires 1 input.');
|
||||
}
|
||||
const r = inputs[0].dims.length;
|
||||
if (r === 0) {
|
||||
throw new Error('scalar tensor is not supported.');
|
||||
}
|
||||
if (axis < -r || axis > r) {
|
||||
throw new Error('Invalid axis');
|
||||
}
|
||||
// TODO: Support string type
|
||||
if (inputs[0].type === 'string') {
|
||||
throw new Error('string tensor is not supported.');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=flatten.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/flatten.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/flatten.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"flatten.js","sourceRoot":"","sources":["flatten.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAKlC,wCAAwC;AAGjC,MAAM,OAAO,GAChB,CAAC,gBAAuC,EAAE,MAAgB,EAAE,IAAY,EAAY,EAAE;IACpF,cAAc,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE7B,MAAM,UAAU,GAAG,gBAAS,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAChE,OAAO,CAAC,gBAAgB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;AACnE,CAAC,CAAC;AANO,QAAA,OAAO,WAMd;AAEC,MAAM,sBAAsB,GAAmC,CAAC,IAAgB,EAAU,EAAE,CAC/F,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAE,oBAAoB;AAD/C,QAAA,sBAAsB,0BACG;AAEtC,MAAM,cAAc,GAAG,CAAC,MAAgB,EAAE,IAAY,EAAQ,EAAE;IAC9D,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE;QAClC,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;KAC9C;IAED,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC;IAChC,IAAI,CAAC,KAAK,CAAC,EAAE;QACX,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;KACpD;IAED,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE;QACzB,MAAM,IAAI,KAAK,CAAC,cAAc,CAAC,CAAC;KACjC;IAED,4BAA4B;IAC5B,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE;QAC/B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;KACpD;AACH,CAAC,CAAC"}
|
||||
39
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/flatten.ts
generated
vendored
Normal file
39
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/flatten.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {ShapeUtil} from '../../../util';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
|
||||
export const flatten: OperatorImplementation<number> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], axis: number): Tensor[] => {
|
||||
validateInputs(inputs, axis);
|
||||
|
||||
const outputDims = ShapeUtil.flattenShape(inputs[0].dims, axis);
|
||||
return [inferenceHandler.reshapeUnpacked(inputs[0], outputDims)];
|
||||
};
|
||||
|
||||
export const parseFlattenAttributes: OperatorInitialization<number> = (node: Graph.Node): number =>
|
||||
node.attributes.getInt('axis', 1); // default axis is 1
|
||||
|
||||
const validateInputs = (inputs: Tensor[], axis: number): void => {
|
||||
if (!inputs || inputs.length !== 1) {
|
||||
throw new Error('Flatten requires 1 input.');
|
||||
}
|
||||
|
||||
const r = inputs[0].dims.length;
|
||||
if (r === 0) {
|
||||
throw new Error('scalar tensor is not supported.');
|
||||
}
|
||||
|
||||
if (axis < -r || axis > r) {
|
||||
throw new Error('Invalid axis');
|
||||
}
|
||||
|
||||
// TODO: Support string type
|
||||
if (inputs[0].type === 'string') {
|
||||
throw new Error('string tensor is not supported.');
|
||||
}
|
||||
};
|
||||
39
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/fuse-utils.js
generated
vendored
Normal file
39
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/fuse-utils.js
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseInternalActivationAttributes = exports.getActivationSnippet = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const unary_op_1 = require("./unary-op");
|
||||
function getActivationSnippet(attributes) {
|
||||
let func;
|
||||
switch (attributes.activation) {
|
||||
case 'Relu':
|
||||
func = (0, unary_op_1.glslRelu)();
|
||||
break;
|
||||
case 'Sigmoid':
|
||||
func = (0, unary_op_1.glslSigmoid)();
|
||||
break;
|
||||
case 'Clip':
|
||||
func = (0, unary_op_1.glslClip)(attributes.clipMin, attributes.clipMax);
|
||||
break;
|
||||
// TODO: adding other activations that can be fused.
|
||||
default:
|
||||
return { activationFunction: '', applyActivation: '' };
|
||||
}
|
||||
const activationName = func.name;
|
||||
const activationFunction = func.body;
|
||||
const applyActivation = `value = ${activationName}_(value);`;
|
||||
return { activationFunction, applyActivation };
|
||||
}
|
||||
exports.getActivationSnippet = getActivationSnippet;
|
||||
const parseInternalActivationAttributes = (attributes) => {
|
||||
const activation = attributes.getString('activation', '');
|
||||
if (activation === 'Clip') {
|
||||
const [clipMin, clipMax] = attributes.getFloats('activation_params', [util_1.MIN_CLIP, util_1.MAX_CLIP]);
|
||||
return { activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}` };
|
||||
}
|
||||
return { activation, activationCacheKey: activation };
|
||||
};
|
||||
exports.parseInternalActivationAttributes = parseInternalActivationAttributes;
|
||||
//# sourceMappingURL=fuse-utils.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/fuse-utils.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/fuse-utils.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"fuse-utils.js","sourceRoot":"","sources":["fuse-utils.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAGlC,wCAAiD;AAGjD,yCAA2D;AAS3D,SAAgB,oBAAoB,CAAC,UAAwC;IAC3E,IAAI,IAAuB,CAAC;IAC5B,QAAQ,UAAU,CAAC,UAAU,EAAE;QAC7B,KAAK,MAAM;YACT,IAAI,GAAG,IAAA,mBAAQ,GAAE,CAAC;YAClB,MAAM;QACR,KAAK,SAAS;YACZ,IAAI,GAAG,IAAA,sBAAW,GAAE,CAAC;YACrB,MAAM;QACR,KAAK,MAAM;YACT,IAAI,GAAG,IAAA,mBAAQ,EAAC,UAAU,CAAC,OAAQ,EAAE,UAAU,CAAC,OAAQ,CAAC,CAAC;YAC1D,MAAM;QACR,oDAAoD;QACpD;YACE,OAAO,EAAC,kBAAkB,EAAE,EAAE,EAAE,eAAe,EAAE,EAAE,EAAC,CAAC;KACxD;IAED,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC;IACjC,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC;IACrC,MAAM,eAAe,GAAG,WAAW,cAAc,WAAW,CAAC;IAC7D,OAAO,EAAC,kBAAkB,EAAE,eAAe,EAAC,CAAC;AAC/C,CAAC;AArBD,oDAqBC;AAEM,MAAM,iCAAiC,GAAG,CAAC,UAAqB,EAAgC,EAAE;IACvG,MAAM,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;IAE1D,IAAI,UAAU,KAAK,MAAM,EAAE;QACzB,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,UAAU,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC,eAAQ,EAAE,eAAQ,CAAC,CAAC,CAAC;QAC3F,OAAO,EAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,UAAU,IAAI,OAAO,IAAI,OAAO,EAAE,EAAC,CAAC;KAClG;IACD,OAAO,EAAC,UAAU,EAAE,kBAAkB,EAAE,UAAU,EAAC,CAAC;AACtD,CAAC,CAAC;AARW,QAAA,iCAAiC,qCAQ5C"}
|
||||
48
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts
generated
vendored
Normal file
48
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/fuse-utils.ts
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Attribute} from '../../../attribute';
|
||||
import {MAX_CLIP, MIN_CLIP} from '../../../util';
|
||||
import {GlslValueFunction} from '../glsl-definitions';
|
||||
|
||||
import {glslClip, glslRelu, glslSigmoid} from './unary-op';
|
||||
|
||||
export interface InternalActivationAttributes {
|
||||
readonly activation: string;
|
||||
readonly clipMin?: number;
|
||||
readonly clipMax?: number;
|
||||
readonly activationCacheKey: string;
|
||||
}
|
||||
|
||||
export function getActivationSnippet(attributes: InternalActivationAttributes) {
|
||||
let func: GlslValueFunction;
|
||||
switch (attributes.activation) {
|
||||
case 'Relu':
|
||||
func = glslRelu();
|
||||
break;
|
||||
case 'Sigmoid':
|
||||
func = glslSigmoid();
|
||||
break;
|
||||
case 'Clip':
|
||||
func = glslClip(attributes.clipMin!, attributes.clipMax!);
|
||||
break;
|
||||
// TODO: adding other activations that can be fused.
|
||||
default:
|
||||
return {activationFunction: '', applyActivation: ''};
|
||||
}
|
||||
|
||||
const activationName = func.name;
|
||||
const activationFunction = func.body;
|
||||
const applyActivation = `value = ${activationName}_(value);`;
|
||||
return {activationFunction, applyActivation};
|
||||
}
|
||||
|
||||
export const parseInternalActivationAttributes = (attributes: Attribute): InternalActivationAttributes => {
|
||||
const activation = attributes.getString('activation', '');
|
||||
|
||||
if (activation === 'Clip') {
|
||||
const [clipMin, clipMax] = attributes.getFloats('activation_params', [MIN_CLIP, MAX_CLIP]);
|
||||
return {activation, clipMax, clipMin, activationCacheKey: `${activation}:${clipMin},${clipMax}`};
|
||||
}
|
||||
return {activation, activationCacheKey: activation};
|
||||
};
|
||||
87
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gather.js
generated
vendored
Normal file
87
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gather.js
generated
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseGatherAttributes = exports.gather = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const operators_1 = require("../../../operators");
|
||||
const util_1 = require("../../../util");
|
||||
const types_1 = require("../types");
|
||||
const gather = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs, attributes.axis);
|
||||
const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
};
|
||||
exports.gather = gather;
|
||||
const parseGatherAttributes = (node) => (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ axis: node.attributes.getInt('axis', 0) });
|
||||
exports.parseGatherAttributes = parseGatherAttributes;
|
||||
const gatherProgramMetadata = {
|
||||
name: 'Gather',
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.unpacked],
|
||||
};
|
||||
const createGatherProgramInfo = (handler, metadata, inputs, axis) => {
|
||||
const inputShape = inputs[0].dims.slice();
|
||||
const indexDataShape = inputs[1].dims.slice();
|
||||
const outputShape = new Array(inputShape.length + indexDataShape.length - 1);
|
||||
axis = util_1.ShapeUtil.normalizeAxis(axis, inputShape.length);
|
||||
const indexCopyOps = [];
|
||||
for (let i = 0; i < outputShape.length; i++) {
|
||||
// outputShape is divided into three parts: A, B, C
|
||||
// |0 axis| axis + indexDataShape.length | end|
|
||||
// | A | B | C |
|
||||
//
|
||||
// inputIdx: [A, inputs[1][B], C]
|
||||
if (i < axis) { // A
|
||||
outputShape[i] = inputShape[i];
|
||||
indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`);
|
||||
}
|
||||
else {
|
||||
if (i < axis + indexDataShape.length) { // B
|
||||
outputShape[i] = indexDataShape[i - axis];
|
||||
indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`);
|
||||
}
|
||||
else { // C
|
||||
outputShape[i] = inputShape[i - indexDataShape.length + 1]; // skip 1 for axis
|
||||
indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`);
|
||||
}
|
||||
}
|
||||
}
|
||||
const orank = outputShape.length || 1;
|
||||
const irank = inputShape.length;
|
||||
const iDrank = indexDataShape.length || 1;
|
||||
const shaderSource = `
|
||||
float process(int outputIdx[${orank}]) {
|
||||
int inputIdx[${irank}];
|
||||
int indexDataIdx[${iDrank}];
|
||||
indexDataIdx[0] = 0;
|
||||
${indexCopyOps.join('\n ')}
|
||||
int idx = int(_B(indexDataIdx));
|
||||
inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx;
|
||||
return _A(inputIdx);
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
|
||||
};
|
||||
const createGatherProgramInfoLoader = (handler, inputs, attributes) => {
|
||||
const metadata = Object.assign(Object.assign({}, gatherProgramMetadata), { cacheHint: attributes.cacheKey });
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis) });
|
||||
};
|
||||
const validateInputs = (inputs, axis) => {
|
||||
if (!inputs || inputs.length !== 2) {
|
||||
throw new Error('Gather requires 2 inputs.');
|
||||
}
|
||||
const tensorRank = inputs[0].dims.length;
|
||||
if (tensorRank < 1) {
|
||||
throw new Error('Invalid input shape.');
|
||||
}
|
||||
if (axis < -tensorRank || axis > tensorRank - 1) {
|
||||
throw new Error('Invalid axis.');
|
||||
}
|
||||
if (operators_1.NUMBER_TYPES.indexOf(inputs[0].type) === -1) {
|
||||
throw new Error('Invaid input type.');
|
||||
}
|
||||
if (inputs[1].type !== 'int32' && inputs[1].type !== 'int16') {
|
||||
throw new Error('Invaid input type.');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=gather.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gather.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gather.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"gather.js","sourceRoot":"","sources":["gather.ts"],"names":[],"mappings":"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"}
|
||||
103
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gather.ts
generated
vendored
Normal file
103
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gather.ts
generated
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {AttributeWithCacheKey, createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {Graph} from '../../../graph';
|
||||
import {NUMBER_TYPES, OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {ShapeUtil} from '../../../util';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
interface GatherAttributes extends AttributeWithCacheKey {
|
||||
readonly axis: number;
|
||||
}
|
||||
|
||||
export const gather: OperatorImplementation<GatherAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: GatherAttributes): Tensor[] => {
|
||||
validateInputs(inputs, attributes.axis);
|
||||
const output = inferenceHandler.run(createGatherProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
};
|
||||
|
||||
export const parseGatherAttributes: OperatorInitialization<GatherAttributes> = (node: Graph.Node): GatherAttributes =>
|
||||
createAttributeWithCacheKey({axis: node.attributes.getInt('axis', 0)});
|
||||
|
||||
const gatherProgramMetadata = {
|
||||
name: 'Gather',
|
||||
inputNames: ['A', 'B'],
|
||||
inputTypes: [TextureType.unpacked, TextureType.unpacked],
|
||||
};
|
||||
|
||||
const createGatherProgramInfo =
|
||||
(handler: WebGLInferenceHandler, metadata: ProgramMetadata, inputs: Tensor[], axis: number): ProgramInfo => {
|
||||
const inputShape = inputs[0].dims.slice();
|
||||
const indexDataShape = inputs[1].dims.slice();
|
||||
const outputShape = new Array(inputShape.length + indexDataShape.length - 1);
|
||||
|
||||
axis = ShapeUtil.normalizeAxis(axis, inputShape.length);
|
||||
const indexCopyOps: string[] = [];
|
||||
for (let i = 0; i < outputShape.length; i++) {
|
||||
// outputShape is divided into three parts: A, B, C
|
||||
// |0 axis| axis + indexDataShape.length | end|
|
||||
// | A | B | C |
|
||||
//
|
||||
// inputIdx: [A, inputs[1][B], C]
|
||||
if (i < axis) { // A
|
||||
outputShape[i] = inputShape[i];
|
||||
indexCopyOps.push(`inputIdx[${i}] = outputIdx[${i}];`);
|
||||
} else {
|
||||
if (i < axis + indexDataShape.length) { // B
|
||||
outputShape[i] = indexDataShape[i - axis];
|
||||
indexCopyOps.push(`indexDataIdx[${i - axis}] = outputIdx[${i}];`);
|
||||
} else { // C
|
||||
outputShape[i] = inputShape[i - indexDataShape.length + 1]; // skip 1 for axis
|
||||
indexCopyOps.push(`inputIdx[${i - indexDataShape.length + 1}] = outputIdx[${i}];`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const orank = outputShape.length || 1;
|
||||
const irank = inputShape.length;
|
||||
const iDrank = indexDataShape.length || 1;
|
||||
const shaderSource = `
|
||||
float process(int outputIdx[${orank}]) {
|
||||
int inputIdx[${irank}];
|
||||
int indexDataIdx[${iDrank}];
|
||||
indexDataIdx[0] = 0;
|
||||
${indexCopyOps.join('\n ')}
|
||||
int idx = int(_B(indexDataIdx));
|
||||
inputIdx[${axis}] = idx < 0 ? idx + ${inputShape[axis]} : idx;
|
||||
return _A(inputIdx);
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
const createGatherProgramInfoLoader =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], attributes: GatherAttributes): ProgramInfoLoader => {
|
||||
const metadata = {...gatherProgramMetadata, cacheHint: attributes.cacheKey};
|
||||
return {...metadata, get: () => createGatherProgramInfo(handler, metadata, inputs, attributes.axis)};
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[], axis: number): void => {
|
||||
if (!inputs || inputs.length !== 2) {
|
||||
throw new Error('Gather requires 2 inputs.');
|
||||
}
|
||||
const tensorRank = inputs[0].dims.length;
|
||||
if (tensorRank < 1) {
|
||||
throw new Error('Invalid input shape.');
|
||||
}
|
||||
if (axis < -tensorRank || axis > tensorRank - 1) {
|
||||
throw new Error('Invalid axis.');
|
||||
}
|
||||
if (NUMBER_TYPES.indexOf(inputs[0].type) === -1) {
|
||||
throw new Error('Invaid input type.');
|
||||
}
|
||||
if (inputs[1].type !== 'int32' && inputs[1].type !== 'int16') {
|
||||
throw new Error('Invaid input type.');
|
||||
}
|
||||
};
|
||||
113
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gemm.js
generated
vendored
Normal file
113
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gemm.js
generated
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseGemmAttributesV11 = exports.parseGemmAttributesV7 = exports.gemm = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const util_1 = require("../../../util");
|
||||
const types_1 = require("../types");
|
||||
const gemm = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs, attributes);
|
||||
const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs);
|
||||
return [output];
|
||||
};
|
||||
exports.gemm = gemm;
|
||||
const parseGemmAttributes = (node, isOptionalC) => {
|
||||
const transA = node.attributes.getInt('transA', 0) !== 0;
|
||||
const transB = node.attributes.getInt('transB', 0) !== 0;
|
||||
const alpha = node.attributes.getFloat('alpha', 1.0);
|
||||
const beta = node.attributes.getFloat('beta', 1.0);
|
||||
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ transA, transB, alpha, beta, isOptionalC });
|
||||
};
|
||||
const parseGemmAttributesV7 = (node) => parseGemmAttributes(node, false);
|
||||
exports.parseGemmAttributesV7 = parseGemmAttributesV7;
|
||||
const parseGemmAttributesV11 = (node) => parseGemmAttributes(node, true);
|
||||
exports.parseGemmAttributesV11 = parseGemmAttributesV11;
|
||||
const createGemmProgramInfoLoader = (inputs, attributes) => {
|
||||
const metadata = {
|
||||
name: 'Gemm',
|
||||
inputNames: inputs.length === 3 ? ['A', 'B', 'C'] : ['A', 'B'],
|
||||
inputTypes: inputs.length === 3 ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
|
||||
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
|
||||
key: attributes.cacheKey
|
||||
};
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createGemmProgramInfo(metadata, inputs, attributes) });
|
||||
};
|
||||
const createGemmProgramInfo = (metadata, inputs, attributes) => {
|
||||
const aShape = inputs[0].dims.slice();
|
||||
const bShape = inputs[1].dims.slice();
|
||||
const [M, N] = util_1.GemmUtil.getShapeOfGemmResult(aShape, attributes.transA, bShape, attributes.transB, inputs.length === 3 ? inputs[2].dims : undefined);
|
||||
const outputShape = [M, N];
|
||||
if (!outputShape) {
|
||||
throw new Error('Can\'t use gemm on the given tensors');
|
||||
}
|
||||
let sharedDim = aShape[aShape.length - 1];
|
||||
let line = '';
|
||||
if (attributes.transA) {
|
||||
sharedDim = aShape[0];
|
||||
}
|
||||
if (attributes.transA && attributes.transB) {
|
||||
line = 'value += _A_T(a) * _B_T(b);';
|
||||
}
|
||||
else if (attributes.transA && !attributes.transB) {
|
||||
line = 'value += _A_T(a) * _B(b);';
|
||||
}
|
||||
else if (!attributes.transA && attributes.transB) {
|
||||
line = 'value += _A(a) * _B_T(b);';
|
||||
}
|
||||
else if (!attributes.transA && !attributes.transB) {
|
||||
line = 'value += _A(a) * _B(b);';
|
||||
}
|
||||
const rank = outputShape.length;
|
||||
const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : '';
|
||||
const broadcastC = inputs.length === 3 ? 'bcastIndices_C(indices, c);' : '';
|
||||
const calculateC = inputs.length === 3 ? 'value += beta * _C(c);' : '';
|
||||
const shaderSource = `
|
||||
float process(int indices[${rank}]) {
|
||||
int a[${rank}];
|
||||
int b[${rank}];
|
||||
${declareC}
|
||||
|
||||
copyVec(indices, a);
|
||||
copyVec(indices, b);
|
||||
${broadcastC}
|
||||
|
||||
float value = 0.0;
|
||||
for (int k=0; k<${sharedDim}; ++k) {
|
||||
a[${rank - 1}] = k;
|
||||
b[${rank - 2}] = k;
|
||||
${line}
|
||||
}
|
||||
|
||||
value = value * alpha;
|
||||
${calculateC}
|
||||
return value;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, variables: [
|
||||
{ name: 'alpha', type: 'float', data: attributes.alpha }, { name: 'beta', type: 'float', data: attributes.beta }
|
||||
], shaderSource });
|
||||
};
|
||||
const validateInputs = (inputs, attributes) => {
|
||||
if (!inputs) {
|
||||
throw new Error('Input is missing');
|
||||
}
|
||||
if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) {
|
||||
throw new Error('Invaid input shape.');
|
||||
}
|
||||
if (!attributes.isOptionalC && inputs.length !== 3) {
|
||||
throw new Error('Gemm requires 3 inputs');
|
||||
}
|
||||
// 'C' can be of dimensionality 1 or 2 only
|
||||
if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) {
|
||||
throw new Error('Invalid input shape of C');
|
||||
}
|
||||
if ((inputs[0].type !== 'float32' && inputs[0].type !== 'float64') ||
|
||||
(inputs[1].type !== 'float32' && inputs[1].type !== 'float64') ||
|
||||
(inputs.length === 3 && inputs[2].type !== 'float32' && inputs[2].type !== 'float64')) {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
if ((inputs[0].type !== inputs[1].type) || (inputs.length === 3 && inputs[0].type !== inputs[2].type)) {
|
||||
throw new Error('Input types are mismatched');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=gemm.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gemm.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gemm.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"gemm.js","sourceRoot":"","sources":["gemm.ts"],"names":[],"mappings":"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"}
|
||||
137
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gemm.ts
generated
vendored
Normal file
137
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/gemm.ts
generated
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {AttributeWithCacheKey, createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {GemmUtil} from '../../../util';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
export interface GemmAttributes extends AttributeWithCacheKey {
|
||||
transA: boolean;
|
||||
transB: boolean;
|
||||
alpha: number;
|
||||
beta: number;
|
||||
isOptionalC: boolean; // in opset 11, C becomes optional
|
||||
}
|
||||
|
||||
export const gemm: OperatorImplementation<GemmAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: GemmAttributes): Tensor[] => {
|
||||
validateInputs(inputs, attributes);
|
||||
const output = inferenceHandler.run(createGemmProgramInfoLoader(inputs, attributes), inputs);
|
||||
return [output];
|
||||
};
|
||||
|
||||
const parseGemmAttributes = (node: Graph.Node, isOptionalC: boolean): GemmAttributes => {
|
||||
const transA = node.attributes.getInt('transA', 0) !== 0;
|
||||
const transB = node.attributes.getInt('transB', 0) !== 0;
|
||||
const alpha = node.attributes.getFloat('alpha', 1.0);
|
||||
const beta = node.attributes.getFloat('beta', 1.0);
|
||||
return createAttributeWithCacheKey({transA, transB, alpha, beta, isOptionalC});
|
||||
};
|
||||
|
||||
export const parseGemmAttributesV7: OperatorInitialization<GemmAttributes> = (node: Graph.Node): GemmAttributes =>
|
||||
parseGemmAttributes(node, false);
|
||||
|
||||
export const parseGemmAttributesV11: OperatorInitialization<GemmAttributes> = (node: Graph.Node): GemmAttributes =>
|
||||
parseGemmAttributes(node, true);
|
||||
|
||||
const createGemmProgramInfoLoader = (inputs: Tensor[], attributes: GemmAttributes): ProgramInfoLoader => {
|
||||
const metadata = {
|
||||
name: 'Gemm',
|
||||
inputNames: inputs.length === 3 ? ['A', 'B', 'C'] : ['A', 'B'],
|
||||
inputTypes: inputs.length === 3 ? [TextureType.unpacked, TextureType.unpacked, TextureType.unpacked] :
|
||||
[TextureType.unpacked, TextureType.unpacked],
|
||||
key: attributes.cacheKey
|
||||
};
|
||||
|
||||
return {...metadata, get: () => createGemmProgramInfo(metadata, inputs, attributes)};
|
||||
};
|
||||
|
||||
const createGemmProgramInfo =
|
||||
(metadata: ProgramMetadata, inputs: Tensor[], attributes: GemmAttributes): ProgramInfo => {
|
||||
const aShape = inputs[0].dims.slice();
|
||||
const bShape = inputs[1].dims.slice();
|
||||
const [M, N] = GemmUtil.getShapeOfGemmResult(
|
||||
aShape, attributes.transA, bShape, attributes.transB, inputs.length === 3 ? inputs[2].dims : undefined);
|
||||
const outputShape = [M, N];
|
||||
if (!outputShape) {
|
||||
throw new Error('Can\'t use gemm on the given tensors');
|
||||
}
|
||||
let sharedDim = aShape[aShape.length - 1];
|
||||
let line = '';
|
||||
if (attributes.transA) {
|
||||
sharedDim = aShape[0];
|
||||
}
|
||||
if (attributes.transA && attributes.transB) {
|
||||
line = 'value += _A_T(a) * _B_T(b);';
|
||||
} else if (attributes.transA && !attributes.transB) {
|
||||
line = 'value += _A_T(a) * _B(b);';
|
||||
} else if (!attributes.transA && attributes.transB) {
|
||||
line = 'value += _A(a) * _B_T(b);';
|
||||
} else if (!attributes.transA && !attributes.transB) {
|
||||
line = 'value += _A(a) * _B(b);';
|
||||
}
|
||||
const rank = outputShape.length;
|
||||
const declareC = inputs.length === 3 ? `int c[${inputs[2].dims.length}];` : '';
|
||||
const broadcastC = inputs.length === 3 ? 'bcastIndices_C(indices, c);' : '';
|
||||
const calculateC = inputs.length === 3 ? 'value += beta * _C(c);' : '';
|
||||
const shaderSource = `
|
||||
float process(int indices[${rank}]) {
|
||||
int a[${rank}];
|
||||
int b[${rank}];
|
||||
${declareC}
|
||||
|
||||
copyVec(indices, a);
|
||||
copyVec(indices, b);
|
||||
${broadcastC}
|
||||
|
||||
float value = 0.0;
|
||||
for (int k=0; k<${sharedDim}; ++k) {
|
||||
a[${rank - 1}] = k;
|
||||
b[${rank - 2}] = k;
|
||||
${line}
|
||||
}
|
||||
|
||||
value = value * alpha;
|
||||
${calculateC}
|
||||
return value;
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
variables: [
|
||||
{name: 'alpha', type: 'float', data: attributes.alpha}, {name: 'beta', type: 'float', data: attributes.beta}
|
||||
],
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[], attributes: GemmAttributes): void => {
|
||||
if (!inputs) {
|
||||
throw new Error('Input is missing');
|
||||
}
|
||||
if (attributes.isOptionalC && (inputs.length < 2 || inputs.length > 3)) {
|
||||
throw new Error('Invaid input shape.');
|
||||
}
|
||||
if (!attributes.isOptionalC && inputs.length !== 3) {
|
||||
throw new Error('Gemm requires 3 inputs');
|
||||
}
|
||||
|
||||
// 'C' can be of dimensionality 1 or 2 only
|
||||
if (inputs.length === 3 && inputs[2].dims.length !== 1 && inputs[2].dims.length !== 2) {
|
||||
throw new Error('Invalid input shape of C');
|
||||
}
|
||||
|
||||
if ((inputs[0].type !== 'float32' && inputs[0].type !== 'float64') ||
|
||||
(inputs[1].type !== 'float32' && inputs[1].type !== 'float64') ||
|
||||
(inputs.length === 3 && inputs[2].type !== 'float32' && inputs[2].type !== 'float64')) {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
|
||||
if ((inputs[0].type !== inputs[1].type) || (inputs.length === 3 && inputs[0].type !== inputs[2].type)) {
|
||||
throw new Error('Input types are mismatched');
|
||||
}
|
||||
};
|
||||
75
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col-pack.js
generated
vendored
Normal file
75
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col-pack.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createPackedIm2ColProgramInfoLoader = void 0;
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const packing_utils_1 = require("./packing-utils");
|
||||
const createPackedIm2ColProgramMetadata = (cacheHint) => ({
|
||||
name: 'Im2Col (packed)',
|
||||
inputNames: ['A'],
|
||||
inputTypes: [types_1.TextureType.packed],
|
||||
cacheHint,
|
||||
});
|
||||
const createPackedIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => {
|
||||
const xshape = x.dims;
|
||||
const wshape = w.dims;
|
||||
const rowDim = 2;
|
||||
const colDim = 3;
|
||||
const rank = outputShape.length;
|
||||
const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]];
|
||||
const kernelSize = wshape[2] * wshape[3];
|
||||
const unpackChannel = (0, packing_utils_1.unpackFromChannel)();
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
let unrolled = '';
|
||||
for (let row = 0; row <= 1; row++) {
|
||||
for (let col = 0; col <= 1; col++) {
|
||||
unrolled += `
|
||||
blockIndex = rc.x + ${col};
|
||||
pos = rc.y + ${row};
|
||||
|
||||
if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) {
|
||||
offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} -
|
||||
${attributes.pads[0]};
|
||||
d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]});
|
||||
|
||||
if(d0 < ${xshape[rowDim]} && d0 >= 0) {
|
||||
offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} -
|
||||
${attributes.pads[1]};
|
||||
d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]});
|
||||
|
||||
if(d1 < ${xshape[colDim]} && d1 >= 0) {
|
||||
|
||||
ch = int(float(pos)/ ${kernelSize}.);
|
||||
innerDims = vec2(d0, d1);
|
||||
result[${row * 2 + col}] = getChannel(
|
||||
getA(0, ch, int(innerDims.x),
|
||||
int(innerDims.y)), innerDims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
const shaderSource = `
|
||||
${unpackChannel}
|
||||
|
||||
void main() {
|
||||
ivec2 rc = getOutputCoords();
|
||||
vec4 result = vec4(0.0);
|
||||
int blockIndex, pos, offsetY, d0, offsetX, d1, ch;
|
||||
vec2 innerDims;
|
||||
${unrolled}
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: im2colShape, type: x.type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
|
||||
};
|
||||
const createPackedIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => {
|
||||
const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) });
|
||||
};
|
||||
exports.createPackedIm2ColProgramInfoLoader = createPackedIm2ColProgramInfoLoader;
|
||||
//# sourceMappingURL=im2col-pack.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col-pack.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col-pack.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"im2col-pack.js","sourceRoot":"","sources":["im2col-pack.ts"],"names":[],"mappings":"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"}
|
||||
92
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts
generated
vendored
Normal file
92
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col-pack.ts
generated
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
import {ConvAttributes} from './conv';
|
||||
import {unpackFromChannel} from './packing-utils';
|
||||
|
||||
const createPackedIm2ColProgramMetadata = (cacheHint: string) => ({
|
||||
name: 'Im2Col (packed)',
|
||||
inputNames: ['A'],
|
||||
inputTypes: [TextureType.packed],
|
||||
cacheHint,
|
||||
});
|
||||
|
||||
const createPackedIm2ColProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, metadata: ProgramMetadata, x: Tensor, w: Tensor,
|
||||
outputShape: readonly number[], attributes: ConvAttributes): ProgramInfo => {
|
||||
const xshape = x.dims;
|
||||
const wshape = w.dims;
|
||||
const rowDim = 2;
|
||||
const colDim = 3;
|
||||
const rank = outputShape.length;
|
||||
const im2colShape = [wshape[1] * wshape[2] * wshape[3], outputShape[2] * outputShape[3]];
|
||||
const kernelSize = wshape[2] * wshape[3];
|
||||
const unpackChannel = unpackFromChannel();
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
let unrolled = '';
|
||||
|
||||
for (let row = 0; row <= 1; row++) {
|
||||
for (let col = 0; col <= 1; col++) {
|
||||
unrolled += `
|
||||
blockIndex = rc.x + ${col};
|
||||
pos = rc.y + ${row};
|
||||
|
||||
if(blockIndex < ${im2colShape[1]} && pos < ${im2colShape[0]}) {
|
||||
offsetY = int(blockIndex / (${outputShape[rank - 1]})) * ${attributes.strides[0]} -
|
||||
${attributes.pads[0]};
|
||||
d0 = offsetY + ${attributes.dilations[0]} * (imod(pos, ${kernelSize}) / ${wshape[2]});
|
||||
|
||||
if(d0 < ${xshape[rowDim]} && d0 >= 0) {
|
||||
offsetX = imod(blockIndex, ${outputShape[rank - 1]}) * ${attributes.strides[1]} -
|
||||
${attributes.pads[1]};
|
||||
d1 = offsetX + ${attributes.dilations[1]} * imod(imod(pos, ${kernelSize}), ${wshape[2]});
|
||||
|
||||
if(d1 < ${xshape[colDim]} && d1 >= 0) {
|
||||
|
||||
ch = int(float(pos)/ ${kernelSize}.);
|
||||
innerDims = vec2(d0, d1);
|
||||
result[${row * 2 + col}] = getChannel(
|
||||
getA(0, ch, int(innerDims.x),
|
||||
int(innerDims.y)), innerDims);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
const shaderSource = `
|
||||
${unpackChannel}
|
||||
|
||||
void main() {
|
||||
ivec2 rc = getOutputCoords();
|
||||
vec4 result = vec4(0.0);
|
||||
int blockIndex, pos, offsetY, d0, offsetX, d1, ch;
|
||||
vec2 innerDims;
|
||||
${unrolled}
|
||||
${glsl.output} = result;
|
||||
}
|
||||
`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: im2colShape, type: x.type, textureType: TextureType.packed},
|
||||
shaderSource,
|
||||
hasMain: true
|
||||
};
|
||||
};
|
||||
|
||||
export const createPackedIm2ColProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, x: Tensor, w: Tensor, outputShape: readonly number[],
|
||||
attributes: ConvAttributes): ProgramInfoLoader => {
|
||||
const metadata = createPackedIm2ColProgramMetadata(attributes.cacheKey);
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createPackedIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes)
|
||||
};
|
||||
};
|
||||
73
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col.js
generated
vendored
Normal file
73
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col.js
generated
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.calculateIm2ColDims = exports.createIm2ColProgramInfoLoader = void 0;
|
||||
const types_1 = require("../types");
|
||||
const createIm2ColProgramMetadata = (cacheHint) => ({
|
||||
name: 'Im2Col',
|
||||
inputNames: ['X'],
|
||||
inputTypes: [types_1.TextureType.unpacked],
|
||||
cacheHint,
|
||||
});
|
||||
const createIm2ColProgramInfo = (inferenceHandler, metadata, x, w, outputShape, attributes) => {
|
||||
const xshape = x.dims;
|
||||
const wshape = w.dims;
|
||||
const rank = outputShape.length;
|
||||
const im2colDims = (0, exports.calculateIm2ColDims)(xshape, wshape, outputShape, 4);
|
||||
const shaderSource = `
|
||||
const int XC = ${xshape[1]};
|
||||
const int XH = ${xshape[2]};
|
||||
const int XW = ${xshape[3]};
|
||||
const int KH = ${attributes.kernelShape[0]};
|
||||
const int KW = ${attributes.kernelShape[1]};
|
||||
const int dilationH = ${attributes.dilations[0]};
|
||||
const int dilationW = ${attributes.dilations[1]};
|
||||
const int strideH = ${attributes.strides[0]};
|
||||
const int strideW = ${attributes.strides[1]};
|
||||
const int padH = ${attributes.pads[0]};
|
||||
const int padW = ${attributes.pads[1]};
|
||||
const int KHKW = KH*KW;
|
||||
const int XCKHKW = XC * KHKW;
|
||||
const int outputChannels = 4;
|
||||
vec4 process(int indices[${rank}]) {
|
||||
int b = indices[0]; // batch size
|
||||
int oh = indices[1] * strideH - padH; //output height
|
||||
int ow = indices[2] * strideW - padW; //output width
|
||||
int p = indices[3] * outputChannels; //patch
|
||||
vec4 value = vec4(0.0);
|
||||
for(int i=0; i < outputChannels; ++i) {
|
||||
if(p < XCKHKW) {
|
||||
int patchC = p / KHKW;
|
||||
int patchH = (p - patchC*KHKW) / KW;
|
||||
int patchW = (p - patchC*KHKW) - patchH * KW;
|
||||
int xh2 = oh + patchH * dilationH;
|
||||
int xw2 = ow + patchW * dilationW;
|
||||
int x[${xshape.length}];
|
||||
x[0] = b;
|
||||
x[1] = patchC;
|
||||
x[2] = xh2;
|
||||
x[3] = xw2;
|
||||
if(xh2 >= 0 &&
|
||||
xh2 < XH &&
|
||||
xw2 >= 0 &&
|
||||
xw2 < XW) {
|
||||
value[i] = _X(x);
|
||||
}
|
||||
}
|
||||
++p;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: im2colDims, type: x.type, textureType: types_1.TextureType.packedLastDimension }, shaderSource });
|
||||
};
|
||||
const createIm2ColProgramInfoLoader = (inferenceHandler, x, w, outputShape, attributes) => {
|
||||
const metadata = createIm2ColProgramMetadata(attributes.cacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes) });
|
||||
};
|
||||
exports.createIm2ColProgramInfoLoader = createIm2ColProgramInfoLoader;
|
||||
const calculateIm2ColDims = (inputShape, kernelShape, outputShape, channels = 4) => [outputShape[0], outputShape[2], outputShape[3],
|
||||
Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels)];
|
||||
exports.calculateIm2ColDims = calculateIm2ColDims;
|
||||
//# sourceMappingURL=im2col.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"im2col.js","sourceRoot":"","sources":["im2col.ts"],"names":[],"mappings":";AAAA,4DAA4D;AAC5D,kCAAkC;;;AAIlC,oCAAsF;AAItF,MAAM,2BAA2B,GAAG,CAAC,SAAiB,EAAE,EAAE,CAAC,CAAC;IAC1D,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE,CAAC,GAAG,CAAC;IACjB,UAAU,EAAE,CAAC,mBAAW,CAAC,QAAQ,CAAC;IAClC,SAAS;CACV,CAAC,CAAC;AAEH,MAAM,uBAAuB,GACzB,CAAC,gBAAuC,EAAE,QAAyB,EAAE,CAAS,EAAE,CAAS,EACxF,WAA8B,EAAE,UAA0B,EAAe,EAAE;IAC1E,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC;IACtB,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC;IAEtB,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM,CAAC;IAChC,MAAM,UAAU,GAAG,IAAA,2BAAmB,EAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC;IAEvE,MAAM,YAAY,GAAG;yBACF,MAAM,CAAC,CAAC,CAAC;yBACT,MAAM,CAAC,CAAC,CAAC;yBACT,MAAM,CAAC,CAAC,CAAC;yBACT,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;yBACzB,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC;gCAClB,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;gCACvB,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;8BACzB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;8BACrB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC;2BACxB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;2BAClB,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;;;;mCAIV,IAAI;;;;;;;;;;;;;sBAajB,MAAM,CAAC,MAAM;;;;;;;;;;;;;;;;SAgB1B,CAAC;IACJ,uCACK,QAAQ,KACX,MAAM,EAAE,EAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,mBAAW,CAAC,mBAAmB,EAAC,EACtF,YAAY,IACZ;AACJ,CAAC,CAAC;AAEC,MAAM,6BAA6B,GACtC,CAAC,gBAAuC,EAAE,CAAS,EAAE,CAAS,EAAE,WAA8B,EAC7F,UAA0B,EAAqB,EAAE;IAChD,MAAM,QAAQ,GAAG,2BAA2B,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAClE,uCACK,QAAQ,KACX,GAAG,EAAE,GAAG,EAAE,CAAC,uBAAuB,CAAC,gBAAgB,EAAE,QAAQ,EAAE,CAAC,EAAE,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,IAC7F;AACJ,CAAC,CAAC;AARO,QAAA,6BAA6B,iCAQpC;AAGC,MAAM,mBAAmB,GAC5B,CAAC,UAA6B,EAAE,WAA8B,EAAE,WAA8B,EAAE,QAAQ,GAAG,CAAC,EAC/F,EAAE,CACP,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAC;IAC9C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC;AAJvE,QAAA,mBAAmB,uBAIoD"}
|
||||
93
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col.ts
generated
vendored
Normal file
93
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/im2col.ts
generated
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
import {ConvAttributes} from './conv';
|
||||
|
||||
const createIm2ColProgramMetadata = (cacheHint: string) => ({
|
||||
name: 'Im2Col',
|
||||
inputNames: ['X'],
|
||||
inputTypes: [TextureType.unpacked],
|
||||
cacheHint,
|
||||
});
|
||||
|
||||
const createIm2ColProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, metadata: ProgramMetadata, x: Tensor, w: Tensor,
|
||||
outputShape: readonly number[], attributes: ConvAttributes): ProgramInfo => {
|
||||
const xshape = x.dims;
|
||||
const wshape = w.dims;
|
||||
|
||||
const rank = outputShape.length;
|
||||
const im2colDims = calculateIm2ColDims(xshape, wshape, outputShape, 4);
|
||||
|
||||
const shaderSource = `
|
||||
const int XC = ${xshape[1]};
|
||||
const int XH = ${xshape[2]};
|
||||
const int XW = ${xshape[3]};
|
||||
const int KH = ${attributes.kernelShape[0]};
|
||||
const int KW = ${attributes.kernelShape[1]};
|
||||
const int dilationH = ${attributes.dilations[0]};
|
||||
const int dilationW = ${attributes.dilations[1]};
|
||||
const int strideH = ${attributes.strides[0]};
|
||||
const int strideW = ${attributes.strides[1]};
|
||||
const int padH = ${attributes.pads[0]};
|
||||
const int padW = ${attributes.pads[1]};
|
||||
const int KHKW = KH*KW;
|
||||
const int XCKHKW = XC * KHKW;
|
||||
const int outputChannels = 4;
|
||||
vec4 process(int indices[${rank}]) {
|
||||
int b = indices[0]; // batch size
|
||||
int oh = indices[1] * strideH - padH; //output height
|
||||
int ow = indices[2] * strideW - padW; //output width
|
||||
int p = indices[3] * outputChannels; //patch
|
||||
vec4 value = vec4(0.0);
|
||||
for(int i=0; i < outputChannels; ++i) {
|
||||
if(p < XCKHKW) {
|
||||
int patchC = p / KHKW;
|
||||
int patchH = (p - patchC*KHKW) / KW;
|
||||
int patchW = (p - patchC*KHKW) - patchH * KW;
|
||||
int xh2 = oh + patchH * dilationH;
|
||||
int xw2 = ow + patchW * dilationW;
|
||||
int x[${xshape.length}];
|
||||
x[0] = b;
|
||||
x[1] = patchC;
|
||||
x[2] = xh2;
|
||||
x[3] = xw2;
|
||||
if(xh2 >= 0 &&
|
||||
xh2 < XH &&
|
||||
xw2 >= 0 &&
|
||||
xw2 < XW) {
|
||||
value[i] = _X(x);
|
||||
}
|
||||
}
|
||||
++p;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: im2colDims, type: x.type, textureType: TextureType.packedLastDimension},
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
export const createIm2ColProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, x: Tensor, w: Tensor, outputShape: readonly number[],
|
||||
attributes: ConvAttributes): ProgramInfoLoader => {
|
||||
const metadata = createIm2ColProgramMetadata(attributes.cacheKey);
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createIm2ColProgramInfo(inferenceHandler, metadata, x, w, outputShape, attributes)
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export const calculateIm2ColDims =
|
||||
(inputShape: readonly number[], kernelShape: readonly number[], outputShape: readonly number[], channels = 4):
|
||||
number[] =>
|
||||
[outputShape[0], outputShape[2], outputShape[3],
|
||||
Math.ceil(inputShape[1] * kernelShape[2] * kernelShape[3] / channels)];
|
||||
74
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/image-scaler.js
generated
vendored
Normal file
74
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/image-scaler.js
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseImageScalerAttributes = exports.imageScaler = void 0;
|
||||
const attribute_with_cache_key_1 = require("../../../attribute-with-cache-key");
|
||||
const types_1 = require("../types");
|
||||
const imageScaler = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs);
|
||||
const output = inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
};
|
||||
exports.imageScaler = imageScaler;
|
||||
const parseImageScalerAttributes = (node) => {
|
||||
const scale = node.attributes.getFloat('scale');
|
||||
const bias = node.attributes.getFloats('bias');
|
||||
return (0, attribute_with_cache_key_1.createAttributeWithCacheKey)({ scale, bias });
|
||||
};
|
||||
exports.parseImageScalerAttributes = parseImageScalerAttributes;
|
||||
const imageScalerProgramMetadata = {
|
||||
name: 'ImageScaler',
|
||||
inputNames: ['X'],
|
||||
inputTypes: [types_1.TextureType.unpacked],
|
||||
};
|
||||
const createImageScalerProgramInfo = (handler, metadata, inputs, attributes) => {
|
||||
const outputShape = inputs[0].dims.slice();
|
||||
const rank = outputShape.length;
|
||||
const getBiasMethod = createGetBiasMethod(attributes.bias.length);
|
||||
const shaderSource = `
|
||||
${getBiasMethod}
|
||||
float process(int indices[${rank}]) {
|
||||
return _X(indices) * scale + getBias(bias, indices[1]);
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, variables: [
|
||||
{ name: 'bias', type: 'float', arrayLength: attributes.bias.length, data: attributes.bias },
|
||||
{ name: 'scale', type: 'float', data: attributes.scale }
|
||||
], shaderSource });
|
||||
};
|
||||
const createImageScalerProgramInfoLoader = (handler, inputs, attributes) => {
|
||||
const metadata = Object.assign(Object.assign({}, imageScalerProgramMetadata), { cacheHint: attributes.cacheKey });
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes) });
|
||||
};
|
||||
const createGetBiasMethod = (numChannels) => {
|
||||
const codeLines = [`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');
|
||||
};
|
||||
const validateInputs = (inputs) => {
|
||||
if (!inputs || inputs.length !== 1) {
|
||||
throw new Error('ImageScaler requires 1 input.');
|
||||
}
|
||||
if (inputs[0].dims.length !== 4) {
|
||||
throw new Error('Invalid input shape.');
|
||||
}
|
||||
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=image-scaler.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/image-scaler.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/image-scaler.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"image-scaler.js","sourceRoot":"","sources":["image-scaler.ts"],"names":[],"mappings":"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"}
|
||||
98
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/image-scaler.ts
generated
vendored
Normal file
98
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/image-scaler.ts
generated
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {AttributeWithCacheKey, createAttributeWithCacheKey} from '../../../attribute-with-cache-key';
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
export interface ImageScalerAttributes extends AttributeWithCacheKey {
|
||||
scale: number;
|
||||
bias: number[];
|
||||
}
|
||||
|
||||
export const imageScaler: OperatorImplementation<ImageScalerAttributes> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], attributes: ImageScalerAttributes): Tensor[] => {
|
||||
validateInputs(inputs);
|
||||
const output =
|
||||
inferenceHandler.run(createImageScalerProgramInfoLoader(inferenceHandler, inputs, attributes), inputs);
|
||||
return [output];
|
||||
};
|
||||
|
||||
export const parseImageScalerAttributes: OperatorInitialization<ImageScalerAttributes> =
|
||||
(node: Graph.Node): ImageScalerAttributes => {
|
||||
const scale = node.attributes.getFloat('scale');
|
||||
const bias = node.attributes.getFloats('bias');
|
||||
return createAttributeWithCacheKey({scale, bias});
|
||||
};
|
||||
|
||||
const imageScalerProgramMetadata = {
|
||||
name: 'ImageScaler',
|
||||
inputNames: ['X'],
|
||||
inputTypes: [TextureType.unpacked],
|
||||
};
|
||||
|
||||
const createImageScalerProgramInfo =
|
||||
(handler: WebGLInferenceHandler, metadata: ProgramMetadata, inputs: Tensor[], attributes: ImageScalerAttributes):
|
||||
ProgramInfo => {
|
||||
const outputShape = inputs[0].dims.slice();
|
||||
const rank = outputShape.length;
|
||||
const getBiasMethod = createGetBiasMethod(attributes.bias.length);
|
||||
const shaderSource = `
|
||||
${getBiasMethod}
|
||||
float process(int indices[${rank}]) {
|
||||
return _X(indices) * scale + getBias(bias, indices[1]);
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.unpacked},
|
||||
variables: [
|
||||
{name: 'bias', type: 'float', arrayLength: attributes.bias.length, data: attributes.bias},
|
||||
{name: 'scale', type: 'float', data: attributes.scale}
|
||||
],
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
const createImageScalerProgramInfoLoader =
|
||||
(handler: WebGLInferenceHandler, inputs: Tensor[], attributes: ImageScalerAttributes): ProgramInfoLoader => {
|
||||
const metadata = {...imageScalerProgramMetadata, cacheHint: attributes.cacheKey};
|
||||
return {...metadata, get: () => createImageScalerProgramInfo(handler, metadata, inputs, attributes)};
|
||||
};
|
||||
|
||||
const 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');
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[]): void => {
|
||||
if (!inputs || inputs.length !== 1) {
|
||||
throw new Error('ImageScaler requires 1 input.');
|
||||
}
|
||||
if (inputs[0].dims.length !== 4) {
|
||||
throw new Error('Invalid input shape.');
|
||||
}
|
||||
if (inputs[0].type !== 'float32' && inputs[0].type !== 'float64') {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
};
|
||||
120
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/instance-normalization.js
generated
vendored
Normal file
120
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/instance-normalization.js
generated
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.parseInstanceNormalizationAttributes = exports.instanceNormalization = void 0;
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const instanceNormalization = (inferenceHandler, inputs, epsilon) => {
|
||||
validateInputs(inputs);
|
||||
const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs);
|
||||
const output = inferenceHandler.run(createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims), [inputs[0], meanAndVariance, inputs[1], inputs[2]]);
|
||||
return [output];
|
||||
};
|
||||
exports.instanceNormalization = instanceNormalization;
|
||||
const parseInstanceNormalizationAttributes = (node) => node.attributes.getFloat('epsilon', 1e-5);
|
||||
exports.parseInstanceNormalizationAttributes = parseInstanceNormalizationAttributes;
|
||||
const meanAndVarianceProgramMetadata = {
|
||||
name: 'InstanceNormalization_MeanAndVariance',
|
||||
inputNames: ['X'],
|
||||
inputTypes: [types_1.TextureType.unpacked],
|
||||
};
|
||||
const createMeanAndVarianceProgramInfo = (metadata, input) => {
|
||||
const xDims = input.dims.slice();
|
||||
const channel = xDims[1];
|
||||
const channelSize = xDims[2] * xDims[3];
|
||||
const outputShape = [xDims[0], channel];
|
||||
const shaderSource = `
|
||||
vec4 process(int[2] indices) {
|
||||
vec4 v = vec4(0.0);
|
||||
int a[4];
|
||||
a[0] = indices[0];
|
||||
a[1] = indices[1];
|
||||
float temp = 0.0;
|
||||
for(int a2=0; a2<${xDims[2]}; a2++) {
|
||||
a[2] = a2;
|
||||
for(int a3=0; a3<${xDims[3]}; a3++) {
|
||||
a[3] = a3;
|
||||
float x = _X(a);
|
||||
temp += x;
|
||||
}
|
||||
}
|
||||
float mean = temp / float(${channelSize});
|
||||
temp = 0.0;
|
||||
for(int a2=0; a2<${xDims[2]}; a2++) {
|
||||
a[2] = a2;
|
||||
for(int a3=0; a3<${xDims[3]}; a3++) {
|
||||
a[3] = a3;
|
||||
float x = _X(a);
|
||||
temp += (x - mean) * (x - mean);
|
||||
}
|
||||
}
|
||||
v.r = mean;
|
||||
v.g = temp / float(${channelSize});
|
||||
|
||||
return v;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: input.type, textureType: types_1.TextureType.packedLastDimension }, shaderSource });
|
||||
};
|
||||
const createMeanAndVarianceProgramInfoLoader = (input) => (Object.assign(Object.assign({}, meanAndVarianceProgramMetadata), { get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input) }));
|
||||
const computeOutputProgramMetadata = {
|
||||
name: 'InstanceNormalization_ComputeOutput',
|
||||
inputNames: ['X', 'MeanAndVariance', 'Scale', 'B'],
|
||||
inputTypes: [types_1.TextureType.unpacked, types_1.TextureType.packedLastDimension, types_1.TextureType.unpacked, types_1.TextureType.unpacked],
|
||||
};
|
||||
const createComputeOutputProgramInfo = (inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) => {
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
const [textureWidth, textureHeight] = inferenceHandler.calculateTextureWidthAndHeight(meanAndVarianceShape, types_1.TextureType.packedLastDimension);
|
||||
const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight];
|
||||
const shaderSource = `
|
||||
vec4 get_MeanAndVariance(int[2] mv) {
|
||||
int offset = indicesToOffset_MeanAndVariance(mv);
|
||||
vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight});
|
||||
return ${glsl.texture2D}(MeanAndVariance, coords);
|
||||
}
|
||||
|
||||
float process(int[4] indices) {
|
||||
int mv[2];
|
||||
mv[0] = indices[0];
|
||||
mv[1] = indices[1];
|
||||
vec4 mean_and_variance = get_MeanAndVariance(mv);
|
||||
float mean = mean_and_variance.r;
|
||||
float variance = mean_and_variance.g;
|
||||
|
||||
int sb[1];
|
||||
sb[0] = indices[1];
|
||||
float scale = _Scale(sb);
|
||||
float b = _B(sb);
|
||||
|
||||
return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: input.dims, type: input.type, textureType: types_1.TextureType.unpacked }, variables: [{ name: 'epsilon', type: 'float', data: epsilon }], shaderSource });
|
||||
};
|
||||
const createComputeOutputProgramInfoLoader = (inferenceHandler, input, epsilon, meanAndVarianceShape) => {
|
||||
const metadata = Object.assign(Object.assign({}, computeOutputProgramMetadata), { cacheHint: `${epsilon}` });
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape) });
|
||||
};
|
||||
const validateInputs = (inputs) => {
|
||||
if (!inputs || inputs.length !== 3) {
|
||||
throw new Error('InstanceNormalization requires 3 inputs.');
|
||||
}
|
||||
const X = inputs[0];
|
||||
const scale = inputs[1];
|
||||
const B = inputs[2];
|
||||
// input should at least have three dimensions - N,C,dim1,...,dimn
|
||||
// other inputs can have only one dimensions
|
||||
if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) {
|
||||
throw new Error('Invalid input shape.');
|
||||
}
|
||||
if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) {
|
||||
throw new Error('Input shapes are mismatched.');
|
||||
}
|
||||
if ((X.type !== 'float32' && X.type !== 'float64') || (scale.type !== 'float32' && scale.type !== 'float64') ||
|
||||
(B.type !== 'float32' && B.type !== 'float64')) {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
if (inputs[0].dims.length !== 4) {
|
||||
throw new Error('Only support 4-D input shape.');
|
||||
}
|
||||
};
|
||||
//# sourceMappingURL=instance-normalization.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/instance-normalization.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/instance-normalization.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"instance-normalization.js","sourceRoot":"","sources":["instance-normalization.ts"],"names":[],"mappings":"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"}
|
||||
156
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts
generated
vendored
Normal file
156
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/instance-normalization.ts
generated
vendored
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Graph} from '../../../graph';
|
||||
import {OperatorImplementation, OperatorInitialization} from '../../../operators';
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
|
||||
export const instanceNormalization: OperatorImplementation<number> =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[], epsilon: number): Tensor[] => {
|
||||
validateInputs(inputs);
|
||||
|
||||
const meanAndVariance = inferenceHandler.run(createMeanAndVarianceProgramInfoLoader(inputs[0]), inputs);
|
||||
const output = inferenceHandler.run(
|
||||
createComputeOutputProgramInfoLoader(inferenceHandler, inputs[0], epsilon, meanAndVariance.dims),
|
||||
[inputs[0], meanAndVariance, inputs[1], inputs[2]]);
|
||||
return [output];
|
||||
};
|
||||
|
||||
export const parseInstanceNormalizationAttributes: OperatorInitialization<number> = (node: Graph.Node): number =>
|
||||
node.attributes.getFloat('epsilon', 1e-5);
|
||||
|
||||
const meanAndVarianceProgramMetadata = {
|
||||
name: 'InstanceNormalization_MeanAndVariance',
|
||||
inputNames: ['X'],
|
||||
inputTypes: [TextureType.unpacked],
|
||||
};
|
||||
|
||||
const createMeanAndVarianceProgramInfo = (metadata: ProgramMetadata, input: Tensor): ProgramInfo => {
|
||||
const xDims = input.dims.slice();
|
||||
const channel = xDims[1];
|
||||
const channelSize = xDims[2] * xDims[3];
|
||||
const outputShape = [xDims[0], channel];
|
||||
|
||||
const shaderSource = `
|
||||
vec4 process(int[2] indices) {
|
||||
vec4 v = vec4(0.0);
|
||||
int a[4];
|
||||
a[0] = indices[0];
|
||||
a[1] = indices[1];
|
||||
float temp = 0.0;
|
||||
for(int a2=0; a2<${xDims[2]}; a2++) {
|
||||
a[2] = a2;
|
||||
for(int a3=0; a3<${xDims[3]}; a3++) {
|
||||
a[3] = a3;
|
||||
float x = _X(a);
|
||||
temp += x;
|
||||
}
|
||||
}
|
||||
float mean = temp / float(${channelSize});
|
||||
temp = 0.0;
|
||||
for(int a2=0; a2<${xDims[2]}; a2++) {
|
||||
a[2] = a2;
|
||||
for(int a3=0; a3<${xDims[3]}; a3++) {
|
||||
a[3] = a3;
|
||||
float x = _X(a);
|
||||
temp += (x - mean) * (x - mean);
|
||||
}
|
||||
}
|
||||
v.r = mean;
|
||||
v.g = temp / float(${channelSize});
|
||||
|
||||
return v;
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: input.type, textureType: TextureType.packedLastDimension},
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
const createMeanAndVarianceProgramInfoLoader = (input: Tensor): ProgramInfoLoader => ({
|
||||
...meanAndVarianceProgramMetadata,
|
||||
get: () => createMeanAndVarianceProgramInfo(meanAndVarianceProgramMetadata, input)
|
||||
});
|
||||
|
||||
const computeOutputProgramMetadata = {
|
||||
name: 'InstanceNormalization_ComputeOutput',
|
||||
inputNames: ['X', 'MeanAndVariance', 'Scale', 'B'],
|
||||
inputTypes: [TextureType.unpacked, TextureType.packedLastDimension, TextureType.unpacked, TextureType.unpacked],
|
||||
};
|
||||
|
||||
const createComputeOutputProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, metadata: ProgramMetadata, input: Tensor, epsilon: number,
|
||||
meanAndVarianceShape: readonly number[]): ProgramInfo => {
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
const [textureWidth, textureHeight] =
|
||||
inferenceHandler.calculateTextureWidthAndHeight(meanAndVarianceShape, TextureType.packedLastDimension);
|
||||
const [meanAndVarianceWidth, meanAndVarianceHeight] = [textureWidth / 4, textureHeight];
|
||||
const shaderSource = `
|
||||
vec4 get_MeanAndVariance(int[2] mv) {
|
||||
int offset = indicesToOffset_MeanAndVariance(mv);
|
||||
vec2 coords = offsetToCoords(offset, ${meanAndVarianceWidth}, ${meanAndVarianceHeight});
|
||||
return ${glsl.texture2D}(MeanAndVariance, coords);
|
||||
}
|
||||
|
||||
float process(int[4] indices) {
|
||||
int mv[2];
|
||||
mv[0] = indices[0];
|
||||
mv[1] = indices[1];
|
||||
vec4 mean_and_variance = get_MeanAndVariance(mv);
|
||||
float mean = mean_and_variance.r;
|
||||
float variance = mean_and_variance.g;
|
||||
|
||||
int sb[1];
|
||||
sb[0] = indices[1];
|
||||
float scale = _Scale(sb);
|
||||
float b = _B(sb);
|
||||
|
||||
return scale * (_X(indices) - mean) / sqrt(variance + epsilon) + b;
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: input.dims, type: input.type, textureType: TextureType.unpacked},
|
||||
variables: [{name: 'epsilon', type: 'float', data: epsilon}],
|
||||
shaderSource
|
||||
};
|
||||
};
|
||||
|
||||
const createComputeOutputProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, input: Tensor, epsilon: number, meanAndVarianceShape: readonly number[]):
|
||||
ProgramInfoLoader => {
|
||||
const metadata = {...computeOutputProgramMetadata, cacheHint: `${epsilon}`};
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createComputeOutputProgramInfo(inferenceHandler, metadata, input, epsilon, meanAndVarianceShape)
|
||||
};
|
||||
};
|
||||
|
||||
const validateInputs = (inputs: Tensor[]): void => {
|
||||
if (!inputs || inputs.length !== 3) {
|
||||
throw new Error('InstanceNormalization requires 3 inputs.');
|
||||
}
|
||||
|
||||
const X = inputs[0];
|
||||
const scale = inputs[1];
|
||||
const B = inputs[2];
|
||||
|
||||
// input should at least have three dimensions - N,C,dim1,...,dimn
|
||||
// other inputs can have only one dimensions
|
||||
if (X.dims.length < 3 || scale.dims.length !== 1 || B.dims.length !== 1) {
|
||||
throw new Error('Invalid input shape.');
|
||||
}
|
||||
if (scale.dims[0] !== X.dims[1] || B.dims[0] !== X.dims[1]) {
|
||||
throw new Error('Input shapes are mismatched.');
|
||||
}
|
||||
if ((X.type !== 'float32' && X.type !== 'float64') || (scale.type !== 'float32' && scale.type !== 'float64') ||
|
||||
(B.type !== 'float32' && B.type !== 'float64')) {
|
||||
throw new Error('Invalid input type.');
|
||||
}
|
||||
if (inputs[0].dims.length !== 4) {
|
||||
throw new Error('Only support 4-D input shape.');
|
||||
}
|
||||
};
|
||||
131
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul-pack.js
generated
vendored
Normal file
131
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul-pack.js
generated
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.createPackedMatmulProgramInfoLoader = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const glsl_source_1 = require("../glsl-source");
|
||||
const types_1 = require("../types");
|
||||
const utils_1 = require("../utils");
|
||||
const fuse_utils_1 = require("./fuse-utils");
|
||||
const matmul_1 = require("./matmul");
|
||||
const createPackedMatmulProgramMetadata = (hasBias, cacheHint) => ({
|
||||
name: 'MatMul (packed)',
|
||||
inputNames: hasBias ? ['A', 'B', 'Bias'] : ['A', 'B'],
|
||||
inputTypes: hasBias ? [types_1.TextureType.packed, types_1.TextureType.packed, types_1.TextureType.packed] :
|
||||
[types_1.TextureType.packed, types_1.TextureType.packed],
|
||||
cacheHint
|
||||
});
|
||||
const createPackedMatmulProgramInfo = (inferenceHandler, metadata, inputs, activationAttributes) => {
|
||||
const hasBias = inputs.length > 2;
|
||||
const processBias = hasBias ? 'value += getBiasForMatmul();' : '';
|
||||
const aShape = inputs[0].dims;
|
||||
const bShape = inputs[1].dims;
|
||||
const outputShape = util_1.BroadcastUtil.calcShape(aShape, bShape, true);
|
||||
const isBroadcast = !util_1.ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
|
||||
if (!outputShape) {
|
||||
throw new Error('Can\'t use matmul on the given tensors');
|
||||
}
|
||||
const sharedDim = aShape[aShape.length - 1];
|
||||
const sharedDimIndex = Math.ceil(sharedDim / 2);
|
||||
const aRank = aShape.length;
|
||||
const bRank = bShape.length;
|
||||
const glsl = (0, glsl_source_1.getGlsl)(inferenceHandler.session.backend.glContext.version);
|
||||
const coordsDataType = (0, utils_1.getCoordsDataType)(outputShape.length);
|
||||
const outRank = outputShape.length;
|
||||
const allGlChannels = (0, utils_1.getGlChannels)();
|
||||
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(activationAttributes);
|
||||
const getBiasForMatmulSnippet = hasBias ? `${(0, matmul_1.getBiasForMatmul)(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : '';
|
||||
const getBcastedSamplerForMatmulSnippet = isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : '';
|
||||
const getSamplerAInLoopSnippet = isBroadcast ? 'getAAtOutCoordsMatmul(i)' : `getA(${getA(allGlChannels, aRank)})`;
|
||||
const getSamplerBInLoopSnippet = isBroadcast ? 'getBAtOutCoordsMatmul(i)' : `getB(${getB(allGlChannels, bRank)})`;
|
||||
const getOutputCoordsSnippet = isBroadcast ? '' : `${coordsDataType} rc =
|
||||
getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} =
|
||||
rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim;
|
||||
`;
|
||||
const shaderSource = `
|
||||
${getBcastedSamplerForMatmulSnippet}
|
||||
${getBiasForMatmulSnippet}
|
||||
${activationFunction}
|
||||
void main() {
|
||||
${getOutputCoordsSnippet}
|
||||
|
||||
vec4 value = vec4(0);
|
||||
for (int i = 0; i < ${sharedDimIndex}; i++) {
|
||||
vec4 a = ${getSamplerAInLoopSnippet};
|
||||
vec4 b = ${getSamplerBInLoopSnippet};
|
||||
|
||||
value += (a.rrbb * b.rgrg);
|
||||
value += (a.ggaa * b.baba);
|
||||
}
|
||||
${processBias}
|
||||
${applyActivation}
|
||||
${glsl.output} = value;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.packed }, shaderSource, hasMain: true });
|
||||
};
|
||||
const createPackedMatmulProgramInfoLoader = (inferenceHandler, inputs, activationAttributes) => {
|
||||
const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes) });
|
||||
};
|
||||
exports.createPackedMatmulProgramInfoLoader = createPackedMatmulProgramInfoLoader;
|
||||
function getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outShape) {
|
||||
let unpackedACoordsSnippet = [];
|
||||
let unpackedBCoordsSnippet = [];
|
||||
const inAShape = inputs[0].dims;
|
||||
const inBShape = inputs[1].dims;
|
||||
const inARank = inAShape.length;
|
||||
const inBRank = inBShape.length;
|
||||
const outRank = outShape.length;
|
||||
const rankADiff = outRank - inARank;
|
||||
const rankBDiff = outRank - inBRank;
|
||||
unpackedACoordsSnippet = inAShape.map((s, i) => `coords.${allGlChannels[i + rankADiff]}`);
|
||||
unpackedACoordsSnippet[inARank - 1] = 'i*2';
|
||||
unpackedACoordsSnippet.join(', ');
|
||||
unpackedBCoordsSnippet = inBShape.map((s, i) => `coords.${allGlChannels[i + rankBDiff]}`);
|
||||
unpackedBCoordsSnippet[inBRank - 2] = 'i*2';
|
||||
unpackedBCoordsSnippet.join(', ');
|
||||
const broadcastADims = util_1.BroadcastUtil.getBroadcastDims(inAShape, outShape);
|
||||
const broadcastBDims = util_1.BroadcastUtil.getBroadcastDims(inBShape, outShape);
|
||||
const coordsASnippet = broadcastADims.map(d => `coords.${allGlChannels[d + rankADiff]} = 0;`).join('\n');
|
||||
const coordsBSnippet = broadcastBDims.map(d => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join('\n');
|
||||
const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]};
|
||||
coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]};
|
||||
coords.${allGlChannels[outRank - 2]} = lastDim;`;
|
||||
const getBcastSamplerMatmulSource = `
|
||||
vec4 getAAtOutCoordsMatmul(int i) {
|
||||
${coordsDataType} coords = getOutputCoords();
|
||||
${swapDimSnippet}
|
||||
${coordsASnippet}
|
||||
vec4 outputValue = getA(${unpackedACoordsSnippet});
|
||||
return outputValue;
|
||||
}
|
||||
|
||||
vec4 getBAtOutCoordsMatmul(int i) {
|
||||
${coordsDataType} coords = getOutputCoords();
|
||||
${swapDimSnippet}
|
||||
${coordsBSnippet}
|
||||
vec4 outputValue = getB(${unpackedBCoordsSnippet});
|
||||
return outputValue;
|
||||
}`;
|
||||
return getBcastSamplerMatmulSource;
|
||||
}
|
||||
function getA(allGlChannels, rank) {
|
||||
let res = '';
|
||||
for (let i = 0; i < rank - 2; i++) {
|
||||
res += `rc.${allGlChannels[i]}, `;
|
||||
}
|
||||
res += `rc.${allGlChannels[rank - 2]}, ` +
|
||||
'i*2';
|
||||
return res;
|
||||
}
|
||||
function getB(allGlChannels, rank) {
|
||||
let res = '';
|
||||
for (let i = 0; i < rank - 2; i++) {
|
||||
res += `rc.${allGlChannels[i]}, `;
|
||||
}
|
||||
res += 'i*2, ' +
|
||||
`rc.${allGlChannels[rank - 1]}`;
|
||||
return res;
|
||||
}
|
||||
//# sourceMappingURL=matmul-pack.js.map
|
||||
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul-pack.js.map
generated
vendored
Normal file
1
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul-pack.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
164
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts
generated
vendored
Normal file
164
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul-pack.ts
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
|
||||
import {Tensor} from '../../../tensor';
|
||||
import {BroadcastUtil, ShapeUtil} from '../../../util';
|
||||
import {getGlsl} from '../glsl-source';
|
||||
import {WebGLInferenceHandler} from '../inference-handler';
|
||||
import {ProgramInfo, ProgramInfoLoader, ProgramMetadata, TextureType} from '../types';
|
||||
import {getCoordsDataType, getGlChannels} from '../utils';
|
||||
|
||||
import {getActivationSnippet, InternalActivationAttributes} from './fuse-utils';
|
||||
import {getBiasForMatmul} from './matmul';
|
||||
|
||||
const createPackedMatmulProgramMetadata = (hasBias: boolean, cacheHint: string) => ({
|
||||
name: 'MatMul (packed)',
|
||||
inputNames: hasBias ? ['A', 'B', 'Bias'] : ['A', 'B'],
|
||||
inputTypes: hasBias ? [TextureType.packed, TextureType.packed, TextureType.packed] :
|
||||
[TextureType.packed, TextureType.packed],
|
||||
cacheHint
|
||||
});
|
||||
|
||||
const createPackedMatmulProgramInfo =
|
||||
(inferenceHandler: WebGLInferenceHandler, metadata: ProgramMetadata, inputs: Tensor[],
|
||||
activationAttributes: InternalActivationAttributes): ProgramInfo => {
|
||||
const hasBias = inputs.length > 2;
|
||||
const processBias = hasBias ? 'value += getBiasForMatmul();' : '';
|
||||
const aShape = inputs[0].dims;
|
||||
const bShape = inputs[1].dims;
|
||||
const outputShape = BroadcastUtil.calcShape(aShape, bShape, true);
|
||||
const isBroadcast = !ShapeUtil.areEqual(inputs[0].dims, inputs[1].dims);
|
||||
|
||||
if (!outputShape) {
|
||||
throw new Error('Can\'t use matmul on the given tensors');
|
||||
}
|
||||
const sharedDim = aShape[aShape.length - 1];
|
||||
const sharedDimIndex = Math.ceil(sharedDim / 2);
|
||||
const aRank = aShape.length;
|
||||
const bRank = bShape.length;
|
||||
|
||||
const glsl = getGlsl(inferenceHandler.session.backend.glContext.version);
|
||||
const coordsDataType = getCoordsDataType(outputShape.length);
|
||||
const outRank = outputShape.length;
|
||||
const allGlChannels = getGlChannels();
|
||||
const {activationFunction, applyActivation} = getActivationSnippet(activationAttributes);
|
||||
|
||||
const getBiasForMatmulSnippet =
|
||||
hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, true)}` : '';
|
||||
|
||||
const getBcastedSamplerForMatmulSnippet =
|
||||
isBroadcast ? `${getBcastSamplerForMatmul(coordsDataType, allGlChannels, inputs, outputShape)}` : '';
|
||||
|
||||
const getSamplerAInLoopSnippet = isBroadcast ? 'getAAtOutCoordsMatmul(i)' : `getA(${getA(allGlChannels, aRank)})`;
|
||||
const getSamplerBInLoopSnippet = isBroadcast ? 'getBAtOutCoordsMatmul(i)' : `getB(${getB(allGlChannels, bRank)})`;
|
||||
const getOutputCoordsSnippet = isBroadcast ? '' : `${coordsDataType} rc =
|
||||
getOutputCoords(); int lastDim = rc.${allGlChannels[outRank - 1]}; rc.${allGlChannels[outRank - 1]} =
|
||||
rc.${allGlChannels[outRank - 2]}; rc.${allGlChannels[outRank - 2]} = lastDim;
|
||||
`;
|
||||
const shaderSource = `
|
||||
${getBcastedSamplerForMatmulSnippet}
|
||||
${getBiasForMatmulSnippet}
|
||||
${activationFunction}
|
||||
void main() {
|
||||
${getOutputCoordsSnippet}
|
||||
|
||||
vec4 value = vec4(0);
|
||||
for (int i = 0; i < ${sharedDimIndex}; i++) {
|
||||
vec4 a = ${getSamplerAInLoopSnippet};
|
||||
vec4 b = ${getSamplerBInLoopSnippet};
|
||||
|
||||
value += (a.rrbb * b.rgrg);
|
||||
value += (a.ggaa * b.baba);
|
||||
}
|
||||
${processBias}
|
||||
${applyActivation}
|
||||
${glsl.output} = value;
|
||||
}`;
|
||||
return {
|
||||
...metadata,
|
||||
output: {dims: outputShape, type: inputs[0].type, textureType: TextureType.packed},
|
||||
shaderSource,
|
||||
hasMain: true
|
||||
};
|
||||
};
|
||||
|
||||
export const createPackedMatmulProgramInfoLoader =
|
||||
(inferenceHandler: WebGLInferenceHandler, inputs: Tensor[],
|
||||
activationAttributes: InternalActivationAttributes): ProgramInfoLoader => {
|
||||
const metadata = createPackedMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey);
|
||||
return {
|
||||
...metadata,
|
||||
get: () => createPackedMatmulProgramInfo(inferenceHandler, metadata, inputs, activationAttributes)
|
||||
};
|
||||
};
|
||||
|
||||
function getBcastSamplerForMatmul(
|
||||
coordsDataType: string, allGlChannels: readonly string[], inputs: Tensor[], outShape: readonly number[]): string {
|
||||
let unpackedACoordsSnippet = [];
|
||||
let unpackedBCoordsSnippet = [];
|
||||
|
||||
const inAShape = inputs[0].dims;
|
||||
const inBShape = inputs[1].dims;
|
||||
|
||||
const inARank = inAShape.length;
|
||||
const inBRank = inBShape.length;
|
||||
|
||||
const outRank = outShape.length;
|
||||
const rankADiff = outRank - inARank;
|
||||
const rankBDiff = outRank - inBRank;
|
||||
|
||||
unpackedACoordsSnippet = inAShape.map((s, i) => `coords.${allGlChannels[i + rankADiff]}`);
|
||||
unpackedACoordsSnippet[inARank - 1] = 'i*2';
|
||||
unpackedACoordsSnippet.join(', ');
|
||||
unpackedBCoordsSnippet = inBShape.map((s, i) => `coords.${allGlChannels[i + rankBDiff]}`);
|
||||
unpackedBCoordsSnippet[inBRank - 2] = 'i*2';
|
||||
unpackedBCoordsSnippet.join(', ');
|
||||
|
||||
const broadcastADims = BroadcastUtil.getBroadcastDims(inAShape, outShape);
|
||||
const broadcastBDims = BroadcastUtil.getBroadcastDims(inBShape, outShape);
|
||||
|
||||
const coordsASnippet = broadcastADims.map(d => `coords.${allGlChannels[d + rankADiff]} = 0;`).join('\n');
|
||||
const coordsBSnippet = broadcastBDims.map(d => `coords.${allGlChannels[d + rankBDiff]} = 0;`).join('\n');
|
||||
const swapDimSnippet = `int lastDim = coords.${allGlChannels[outRank - 1]};
|
||||
coords.${allGlChannels[outRank - 1]} = coords.${allGlChannels[outRank - 2]};
|
||||
coords.${allGlChannels[outRank - 2]} = lastDim;`;
|
||||
|
||||
const getBcastSamplerMatmulSource = `
|
||||
vec4 getAAtOutCoordsMatmul(int i) {
|
||||
${coordsDataType} coords = getOutputCoords();
|
||||
${swapDimSnippet}
|
||||
${coordsASnippet}
|
||||
vec4 outputValue = getA(${unpackedACoordsSnippet});
|
||||
return outputValue;
|
||||
}
|
||||
|
||||
vec4 getBAtOutCoordsMatmul(int i) {
|
||||
${coordsDataType} coords = getOutputCoords();
|
||||
${swapDimSnippet}
|
||||
${coordsBSnippet}
|
||||
vec4 outputValue = getB(${unpackedBCoordsSnippet});
|
||||
return outputValue;
|
||||
}`;
|
||||
|
||||
return getBcastSamplerMatmulSource;
|
||||
}
|
||||
|
||||
function getA(allGlChannels: string[], rank: number): string {
|
||||
let res = '';
|
||||
for (let i = 0; i < rank - 2; i++) {
|
||||
res += `rc.${allGlChannels[i]}, `;
|
||||
}
|
||||
res += `rc.${allGlChannels[rank - 2]}, ` +
|
||||
'i*2';
|
||||
return res;
|
||||
}
|
||||
|
||||
function getB(allGlChannels: string[], rank: number): string {
|
||||
let res = '';
|
||||
for (let i = 0; i < rank - 2; i++) {
|
||||
res += `rc.${allGlChannels[i]}, `;
|
||||
}
|
||||
res += 'i*2, ' +
|
||||
`rc.${allGlChannels[rank - 1]}`;
|
||||
return res;
|
||||
}
|
||||
123
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul.js
generated
vendored
Normal file
123
node_modules/onnxruntime-web/lib/onnxjs/backends/webgl/ops/matmul.js
generated
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
"use strict";
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT License.
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.getBiasForMatmul = exports.createMatmulProgramInfoLoader = exports.parseMatMulAttributes = exports.matMul = void 0;
|
||||
const util_1 = require("../../../util");
|
||||
const types_1 = require("../types");
|
||||
const utils_1 = require("../utils");
|
||||
const fuse_utils_1 = require("./fuse-utils");
|
||||
const matmul_pack_1 = require("./matmul-pack");
|
||||
const matMul = (inferenceHandler, inputs, attributes) => {
|
||||
validateInputs(inputs);
|
||||
if (inferenceHandler.session.pack) {
|
||||
return [inferenceHandler.run((0, matmul_pack_1.createPackedMatmulProgramInfoLoader)(inferenceHandler, inputs, attributes), inputs)];
|
||||
}
|
||||
else {
|
||||
return [inferenceHandler.run(createMatmulProgramInfoLoader(inputs, attributes), inputs)];
|
||||
}
|
||||
};
|
||||
exports.matMul = matMul;
|
||||
const parseMatMulAttributes = (node) => (0, fuse_utils_1.parseInternalActivationAttributes)(node.attributes);
|
||||
exports.parseMatMulAttributes = parseMatMulAttributes;
|
||||
const createMatmulProgramMetadata = (hasBias, cacheHint) => ({
|
||||
name: 'MatMul',
|
||||
inputNames: hasBias ? ['A', 'B', 'Bias'] : ['A', 'B'],
|
||||
inputTypes: hasBias ? [types_1.TextureType.unpacked, types_1.TextureType.unpacked, types_1.TextureType.unpacked] :
|
||||
[types_1.TextureType.unpacked, types_1.TextureType.unpacked],
|
||||
cacheHint
|
||||
});
|
||||
function createMatmulProgramInfo(metadata, inputs, activationAttributes) {
|
||||
const aShape = inputs[0].dims;
|
||||
const bShape = inputs[1].dims;
|
||||
const outputShape = util_1.BroadcastUtil.calcShape(aShape, bShape, true);
|
||||
if (!outputShape) {
|
||||
throw new Error('Can\'t use matmul on the given tensors');
|
||||
}
|
||||
const coordsDataType = (0, utils_1.getCoordsDataType)(outputShape.length);
|
||||
const allGlChannels = (0, utils_1.getGlChannels)();
|
||||
const { activationFunction, applyActivation } = (0, fuse_utils_1.getActivationSnippet)(activationAttributes);
|
||||
const hasBias = inputs.length > 2;
|
||||
const processBias = hasBias ? 'value += getBiasForMatmul();' : '';
|
||||
const getBiasForMatmulSnippet = hasBias ? `${getBiasForMatmul(coordsDataType, allGlChannels, inputs[2].dims, outputShape, false)}` : '';
|
||||
const rank = outputShape.length;
|
||||
const arank = aShape.length;
|
||||
const brank = bShape.length;
|
||||
const sharedDim = aShape[aShape.length - 1];
|
||||
const shaderSource = `
|
||||
${activationFunction}
|
||||
${getBiasForMatmulSnippet}
|
||||
float process(int indices[${rank}]) {
|
||||
int a[${arank}];
|
||||
int b[${brank}];
|
||||
bcastMatmulIndices_A(indices, a);
|
||||
bcastMatmulIndices_B(indices, b);
|
||||
|
||||
float value;
|
||||
for (int k=0; k<${sharedDim}; ++k) {
|
||||
a[${arank - 1}] = k;
|
||||
b[${brank - 2}] = k;
|
||||
value += _A(a) * _B(b);
|
||||
}
|
||||
${processBias}
|
||||
${applyActivation}
|
||||
return value;
|
||||
}`;
|
||||
return Object.assign(Object.assign({}, metadata), { output: { dims: outputShape, type: inputs[0].type, textureType: types_1.TextureType.unpacked }, shaderSource });
|
||||
}
|
||||
function createMatmulProgramInfoLoader(inputs, activationAttributes) {
|
||||
const metadata = createMatmulProgramMetadata(inputs.length > 2, activationAttributes.activationCacheKey);
|
||||
return Object.assign(Object.assign({}, metadata), { get: () => createMatmulProgramInfo(metadata, inputs, activationAttributes) });
|
||||
}
|
||||
exports.createMatmulProgramInfoLoader = createMatmulProgramInfoLoader;
|
||||
const validateInputs = (inputs) => {
|
||||
if (!inputs || inputs.length !== 2) {
|
||||
throw new Error('MatMul requires 2 inputs.');
|
||||
}
|
||||
if (inputs[0].dims[inputs[0].dims.length - 1] !== inputs[1].dims[inputs[1].dims.length - 2]) {
|
||||
throw new Error('shared dimension does not match.');
|
||||
}
|
||||
if ((inputs[0].type !== 'float32' && inputs[0].type !== 'float64') ||
|
||||
(inputs[1].type !== 'float32' && inputs[1].type !== 'float64')) {
|
||||
throw new Error('inputs should be float type');
|
||||
}
|
||||
if (inputs[0].type !== inputs[1].type) {
|
||||
throw new Error('inputs types should match');
|
||||
}
|
||||
};
|
||||
function getBiasForMatmul(coordsDataType, allGlChannels, inShape, outShape, isPacked) {
|
||||
let unpackedCoordsSnippet = '';
|
||||
const inRank = inShape.length;
|
||||
const outRank = outShape.length;
|
||||
const rankDiff = outRank - inRank;
|
||||
if (outRank < 2 && inRank > 0) {
|
||||
unpackedCoordsSnippet = 'coords';
|
||||
}
|
||||
else {
|
||||
unpackedCoordsSnippet = inShape.map((s, i) => `coords.${allGlChannels[i + rankDiff]}`).join(', ');
|
||||
}
|
||||
const broadcastDims = util_1.BroadcastUtil.getBroadcastDims(inShape, outShape);
|
||||
const coordsSnippet = broadcastDims.map(d => `coords.${allGlChannels[d + rankDiff]} = 0;`).join('\n');
|
||||
const inSize = util_1.ShapeUtil.size(inShape);
|
||||
const isInputScalar = inSize === 1;
|
||||
let output = 'vec4(outputValue.xx, outputValue.yy)';
|
||||
if (isInputScalar) {
|
||||
output = 'vec4(outputValue.x)';
|
||||
}
|
||||
const getBiasForMatmulSource = isPacked ? `
|
||||
vec4 getBiasForMatmul() {
|
||||
${coordsDataType} coords = getOutputCoords();
|
||||
${coordsSnippet}
|
||||
vec4 outputValue = getBias(${unpackedCoordsSnippet});
|
||||
return ${output};
|
||||
}` :
|
||||
`
|
||||
float getBiasForMatmul() {
|
||||
${coordsDataType} coords = getOutputCoords();
|
||||
${coordsSnippet}
|
||||
return getBias(coords.x);
|
||||
}`;
|
||||
return getBiasForMatmulSource;
|
||||
}
|
||||
exports.getBiasForMatmul = getBiasForMatmul;
|
||||
//# sourceMappingURL=matmul.js.map
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user