UNPKG

mind-ar

Version:

web augmented reality framework

83 lines (74 loc) 2.52 kB
import {zeros,map, flatten as mathjsflatten} from 'mathjs' /** * @typedef {Object} Kernel * @property {string[]} variableNames * @property {number[]} outputShape * @property {Function} userCode */ /** * * @param {MathBackendCPU} backend * @param {Kernel} kernel * @param {Array<.TensorInfo>} inputs * @param {DataType} dtype * @returns {Tensor} */ function runCode(backend, kernel, inputs, dtype) { const inputData = inputs.map((value) => { return backend.data.get(value.dataId).values; }); //create getter functions for every variable name, clamping the input. const tempData = {} kernel.variableNames.forEach((name, index) => { const funName=`get${capFirstLetter(name)}`; //console.log("Making function:",funName,inputs[index].shape); tempData[funName] = function (...args) { const inputIndex=index; for (let i = 0; i < args.length; i++) { args[i] = clampInt(args[i], 0, inputs[inputIndex].shape[i] ); } return inputData[index][flatten(args, inputs[inputIndex].shape)]; } }); tempData.int=Math.trunc; tempData.atan=Math.atan2; //create an empty matrix to map the output size, because i'm lazy and want to use Matrix.map(...) //const temp = new Matrix(); //console.log("Creating output shape:",kernel.outputShape); const temp=zeros(kernel.outputShape);//reshape([0,0,0],kernel.outputShape); const output = map(temp,(value, index,matrix) => { tempData.getOutputCoords = () => { return index; } let out; tempData.setOutput = (newValue) => { out = Number.isNaN(newValue) ? 0 : Math.fround(newValue); } //bind the method calls and run the code kernel.userCode.bind(tempData)(); return out; }) //output.flat() //convert the output from a matrix into a tensor return backend.makeOutput(mathjsflatten(output), kernel.outputShape, dtype); } /** * * @param {string} word * @returns */ function capFirstLetter(word) { return word[0].toUpperCase() + word.substring(1); } function clampInt(n, min, max) { return Math.min(Math.max(n, min), max - 1); } /** * * @param {number[]} input * @param {number[]} max * @returns */ function flatten(input, max) { return input.reduce((prev, current, index) => { for (let i = index + 1; i < max.length; i++) { current *= max[i]; } return prev + current; },0); } export { runCode };