@tensorflow/tfjs-core
Version:
Hardware-accelerated JavaScript library for machine intelligence
102 lines • 4.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../environment");
var util = require("../../util");
var shader_compiler = require("./shader_compiler");
var NAN_UNIFORM_NAME = 'NaN';
function shouldUploadNaNUniform() {
return !environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED');
}
function compileProgram(gpgpu, program, inputs, output) {
var userCode = program.userCode;
var inputInfos = inputs.map(function (input, i) {
var shapeInfo = {
logicalShape: input.tensor.shape,
texShape: input.texData.texShape
};
return { name: program.variableNames[i], shapeInfo: shapeInfo };
});
var inShapeInfos = inputInfos.map(function (x) { return x.shapeInfo; });
var outShapeInfo = {
logicalShape: output.tensor.shape,
texShape: output.texData.texShape
};
var source = shader_compiler.makeShader(inputInfos, outShapeInfo, userCode, program.supportsBroadcasting === true);
var webGLProgram = gpgpu.createProgram(source);
var uniformLocations = {};
for (var i = 0; i < program.variableNames.length; i++) {
var uniformName = program.variableNames[i];
uniformLocations[uniformName] =
gpgpu.getUniformLocation(webGLProgram, uniformName);
}
if (shouldUploadNaNUniform()) {
var throwIfNaNUniformIsNotUsed = false;
uniformLocations[NAN_UNIFORM_NAME] = gpgpu.getUniformLocation(webGLProgram, NAN_UNIFORM_NAME, throwIfNaNUniformIsNotUsed);
}
return {
program: program,
source: source,
webGLProgram: webGLProgram,
uniformLocations: uniformLocations,
gpgpu: gpgpu,
inShapeInfos: inShapeInfos,
outShapeInfo: outShapeInfo
};
}
exports.compileProgram = compileProgram;
function validateBinaryAndProgram(shapeInfos, inputs) {
if (shapeInfos.length !== inputs.length) {
throw Error("Binary was compiled with " + shapeInfos.length + " inputs, but " +
("was executed with " + inputs.length + " inputs"));
}
shapeInfos.forEach(function (s, i) {
var shapeA = s.logicalShape;
var texShapeA = s.texShape;
var shapeB = inputs[i].tensor.shape;
var texShapeB = inputs[i].texData.texShape;
if (!util.arraysEqual(shapeA, shapeB)) {
throw Error("Binary was compiled with different shapes than " +
("the current args. Shapes " + shapeA + " and " + shapeB + " must match"));
}
if (!util.arraysEqual(texShapeA, texShapeB)) {
throw Error("Binary was compiled with different texture shapes than the" +
(" current args. Shape " + texShapeA + " and " + texShapeB + " must match"));
}
});
}
function runProgram(binary, inputs, output, customSetup) {
validateBinaryAndProgram(binary.inShapeInfos, inputs);
validateBinaryAndProgram([binary.outShapeInfo], [output]);
var outTex = output.texData.texture;
var outTexShape = output.texData.texShape;
var gpgpu = binary.gpgpu;
gpgpu.setOutputMatrixTexture(outTex, outTexShape[0], outTexShape[1]);
gpgpu.setProgram(binary.webGLProgram);
inputs.forEach(function (input, i) {
var tex = input.texData.texture;
var variableName = binary.program.variableNames[i];
var variableUniformLocation = binary.uniformLocations[variableName];
gpgpu.setInputMatrixTexture(tex, variableUniformLocation, i);
});
if (shouldUploadNaNUniform()) {
gpgpu.gl.uniform1f(binary.uniformLocations[NAN_UNIFORM_NAME], NaN);
}
if (customSetup != null) {
customSetup(gpgpu, binary.webGLProgram);
}
gpgpu.executeProgram();
}
exports.runProgram = runProgram;
function makeShaderKey(program, inputs, output) {
var keyInputs = '';
inputs.concat(output).forEach(function (x) {
keyInputs += x.tensor.shape + "_" + x.texData.texShape;
});
var keyUserCode = program.userCode;
var keyBroadcast = (program.supportsBroadcasting === true).toString();
var key = program.constructor.name;
key += '_' + keyBroadcast + '_' + keyInputs + '_' + keyUserCode;
return key;
}
exports.makeShaderKey = makeShaderKey;
//# sourceMappingURL=gpgpu_math.js.map