UNPKG

@tensorflow/tfjs-core

Version:

Hardware-accelerated JavaScript library for machine intelligence

102 lines 4.28 kB
"use strict"; 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