@tensorflow/tfjs-core
Version:
Hardware-accelerated JavaScript library for machine intelligence
1,134 lines • 85.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var seedrandom = require("seedrandom");
var environment_1 = require("../environment");
var log_1 = require("../log");
var array_ops_util = require("../ops/array_ops_util");
var axis_util = require("../ops/axis_util");
var broadcast_util = require("../ops/broadcast_util");
var concat_util = require("../ops/concat_util");
var erf_util = require("../ops/erf_util");
var ops = require("../ops/ops");
var ops_1 = require("../ops/ops");
var selu_util = require("../ops/selu_util");
var slice_util_1 = require("../ops/slice_util");
var tensor_1 = require("../tensor");
var types_1 = require("../types");
var util = require("../util");
var util_1 = require("../util");
var backend_util = require("./backend_util");
var non_max_suppression_impl_1 = require("./non_max_suppression_impl");
var topk_impl_1 = require("./topk_impl");
var where_impl_1 = require("./where_impl");
var MathBackendCPU = (function () {
function MathBackendCPU() {
this.data = new WeakMap();
this.firstUse = true;
if (environment_1.ENV.get('IS_BROWSER')) {
this.canvas = document.createElement('canvas');
}
}
MathBackendCPU.prototype.register = function (dataId, shape, dtype) {
if (this.firstUse) {
this.firstUse = false;
if (environment_1.ENV.get('IS_NODE')) {
log_1.warn('\n============================\n' +
'Hi there 👋. Looks like you are running TensorFlow.js in ' +
'Node.js. To speed things up dramatically, install our node ' +
'backend, which binds to TensorFlow C++, by running ' +
'npm i @tensorflow/tfjs-node, ' +
'or npm i @tensorflow/tfjs-node-gpu if you have CUDA. ' +
'Then call require(\'@tensorflow/tfjs-node\'); (-gpu ' +
'suffix for CUDA) at the start of your program. ' +
'Visit https://github.com/tensorflow/tfjs-node for more details.' +
'\n============================\n');
}
}
if (this.data.has(dataId)) {
throw new Error("Data buffer is already registered");
}
this.data.set(dataId, null);
};
MathBackendCPU.prototype.write = function (dataId, values) {
if (values == null) {
throw new Error('MathBackendCPU.write(): values can not be null');
}
this.throwIfNoData(dataId);
this.data.set(dataId, values);
};
MathBackendCPU.prototype.fromPixels = function (pixels, numChannels) {
if (pixels == null) {
throw new Error('pixels passed to tf.fromPixels() can not be null');
}
var vals;
if (environment_1.ENV.get('IS_NODE') && pixels.getContext == null) {
throw new Error('When running in node, pixels must be an HTMLCanvasElement ' +
'like the one returned by the `canvas` npm package');
}
if (pixels.getContext != null) {
vals = pixels
.getContext('2d')
.getImageData(0, 0, pixels.width, pixels.height)
.data;
}
else if (pixels instanceof ImageData) {
vals = pixels.data;
}
else if (pixels instanceof HTMLImageElement ||
pixels instanceof HTMLVideoElement) {
if (this.canvas == null) {
throw new Error('Can\'t read pixels from HTMLImageElement outside ' +
'the browser.');
}
this.canvas.width = pixels.width;
this.canvas.height = pixels.height;
this.canvas.getContext('2d').drawImage(pixels, 0, 0, pixels.width, pixels.height);
vals = this.canvas.getContext('2d')
.getImageData(0, 0, pixels.width, pixels.height)
.data;
}
else {
throw new Error('pixels passed to tf.fromPixels() must be either an ' +
"HTMLVideoElement, HTMLImageElement, HTMLCanvasElement or " +
("ImageData, but was " + pixels.constructor.name));
}
var values;
if (numChannels === 4) {
values = new Int32Array(vals);
}
else {
var numPixels = pixels.width * pixels.height;
values = new Int32Array(numPixels * numChannels);
for (var i = 0; i < numPixels; i++) {
for (var channel = 0; channel < numChannels; ++channel) {
values[i * numChannels + channel] = vals[i * 4 + channel];
}
}
}
var outShape = [pixels.height, pixels.width, numChannels];
return ops_1.tensor3d(values, outShape, 'int32');
};
MathBackendCPU.prototype.read = function (dataId) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
return [2, this.readSync(dataId)];
});
});
};
MathBackendCPU.prototype.readSync = function (dataId) {
this.throwIfNoData(dataId);
return this.data.get(dataId);
};
MathBackendCPU.prototype.disposeData = function (dataId) {
if (this.data.has(dataId)) {
this.data.delete(dataId);
}
};
MathBackendCPU.prototype.time = function (f) {
return __awaiter(this, void 0, void 0, function () {
var start, kernelMs;
return __generator(this, function (_a) {
start = util_1.now();
f();
kernelMs = util_1.now() - start;
return [2, { kernelMs: kernelMs }];
});
});
};
MathBackendCPU.prototype.memory = function () {
return {
unreliable: true
};
};
MathBackendCPU.prototype.throwIfNoData = function (dataId) {
if (!this.data.has(dataId)) {
throw new Error("CPU backend: No data found for this tensor. " +
"Did you change your backend in the middle of the program? " +
"New backends can't use Tensors created with previous backends");
}
};
MathBackendCPU.prototype.slice = function (x, begin, size) {
var buffer = ops.buffer(size, x.dtype);
for (var i = 0; i < buffer.size; ++i) {
var loc = buffer.indexToLoc(i);
var xLoc = loc.map(function (idx, j) { return idx + begin[j]; });
buffer.set.apply(buffer, [x.get.apply(x, xLoc)].concat(loc));
}
return buffer.toTensor();
};
MathBackendCPU.prototype.stridedSlice = function (x, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask) {
var _a = slice_util_1.getStridedSlicedInfo(x.shape, begin, end, strides, beginMask, endMask, ellipsisMask, newAxisMask, shrinkAxisMask), beginIndex = _a[0], size = _a[1], shrinkAxis = _a[2];
var shape = size.filter(function (v, index) { return shrinkAxis.indexOf(index) === -1; });
if (shape.some(function (axis) { return axis === 0; })) {
return ops.tensor([], shape);
}
var buffer = ops.buffer(size, x.dtype);
for (var i = 0; i < buffer.size; i++) {
var loc = buffer.indexToLoc(i);
var newLoc = new Array(loc.length);
for (var j = 0; j < newLoc.length; j++) {
newLoc[j] = loc[j] * strides[j] + beginIndex[j];
}
buffer.set.apply(buffer, [x.get.apply(x, newLoc)].concat(loc));
}
return buffer.toTensor().reshape(shape);
};
MathBackendCPU.prototype.reverse = function (x, axis) {
var buffer = ops.buffer(x.shape, x.dtype);
var xBuffer = x.buffer();
var _loop_1 = function (i) {
var outLoc = buffer.indexToLoc(i);
var inLoc = outLoc.slice();
axis.forEach(function (ax) { return inLoc[ax] = x.shape[ax] - 1 - inLoc[ax]; });
buffer.set.apply(buffer, [xBuffer.get.apply(xBuffer, inLoc)].concat(outLoc));
};
for (var i = 0; i < buffer.size; i++) {
_loop_1(i);
}
return buffer.toTensor();
};
MathBackendCPU.prototype.concat = function (a, b) {
var outShape = concat_util.computeOutShape([a.shape, b.shape], 1);
var buffer = ops.buffer(outShape, a.dtype);
if (a.shape[0] === 1 && b.shape[0] === 1) {
var aVals = a.dataSync();
var bVals = b.dataSync();
var vals = buffer.values;
vals.set(aVals, 0);
vals.set(bVals, a.size);
return buffer.toTensor();
}
for (var i = 0; i < outShape[0]; ++i) {
for (var j = 0; j < a.shape[1]; ++j) {
buffer.set(a.get(i, j), i, j);
}
for (var j = 0; j < b.shape[1]; ++j) {
buffer.set(b.get(i, j), i, j + a.shape[1]);
}
}
return buffer.toTensor();
};
MathBackendCPU.prototype.neg = function (x) {
return this.multiply(ops.scalar(-1), x);
};
MathBackendCPU.prototype.add = function (a, b) {
return this.broadcastedBinaryOp(a, b, types_1.upcastType(a.dtype, b.dtype), function (aValue, bValue) { return aValue + bValue; });
};
MathBackendCPU.prototype.addN = function (tensors) {
var vals = tensors.map(function (t) { return t.dataSync(); });
var result = ops.buffer(tensors[0].shape, tensors[0].dtype);
var resultVals = result.values;
for (var i = 0; i < tensors.length; i++) {
var currVals = vals[i];
for (var j = 0; j < resultVals.length; j++) {
resultVals[j] += currVals[j];
}
}
return result.toTensor();
};
MathBackendCPU.prototype.subtract = function (a, b) {
return this.broadcastedBinaryOp(a, b, types_1.upcastType(a.dtype, b.dtype), function (aValue, bValue) { return aValue - bValue; });
};
MathBackendCPU.prototype.pow = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aValue, bValue) { return Math.pow(aValue, bValue); });
};
MathBackendCPU.prototype.matMul = function (a, b, transposeA, transposeB) {
var sharedDim = transposeA ? a.shape[0] : a.shape[1];
var leftDim = transposeA ? a.shape[1] : a.shape[0];
var rightDim = transposeB ? b.shape[0] : b.shape[1];
var aValues = a.dataSync();
var bValues = b.dataSync();
var _a = transposeA ? [1, a.strides[0]] : [a.strides[0], 1], aOuterStep = _a[0], aInnerStep = _a[1];
var _b = transposeB ? [b.strides[0], 1] : [1, b.strides[0]], bOuterStep = _b[0], bInnerStep = _b[1];
var aOuterEnd = leftDim * aOuterStep;
var bOuterEnd = rightDim * bOuterStep;
var result = new Float32Array(leftDim * rightDim);
var resultIndex = 0;
for (var aOuter = 0; aOuter < aOuterEnd; aOuter += aOuterStep) {
for (var bOuter = 0; bOuter < bOuterEnd; bOuter += bOuterStep) {
var aInner = aOuter;
var bInner = bOuter;
var sum = 0;
for (var k = 0; k < sharedDim; ++k) {
sum += aValues[aInner] * bValues[bInner];
aInner += aInnerStep;
bInner += bInnerStep;
}
result[resultIndex++] = sum;
}
}
return ops.tensor2d(result, [leftDim, rightDim]);
};
MathBackendCPU.prototype.multiply = function (a, b) {
return this.broadcastedBinaryOp(a, b, types_1.upcastType(a.dtype, b.dtype), function (aValue, bValue) { return aValue * bValue; });
};
MathBackendCPU.prototype.realDivide = function (a, b) {
var op = function (a, b) { return a / b; };
var outputDtype = 'float32';
return this.broadcastedBinaryOp(a, b, outputDtype, op);
};
MathBackendCPU.prototype.floorDiv = function (a, b) {
var op = function (a, b) { return Math.floor(a / b); };
var outputDtype = 'int32';
return this.broadcastedBinaryOp(a, b, outputDtype, op);
};
MathBackendCPU.prototype.sum = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('sum', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var resultDtype = types_1.upcastType(x.dtype, 'int32');
var result = ops.zeros(outShape, resultDtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var sum = 0;
for (var j = 0; j < reduceSize; ++j) {
sum += aVals[offset + j];
}
vals[i] = sum;
}
return result;
};
MathBackendCPU.prototype.unsortedSegmentSum = function (x, segmentIds, numSegments) {
var res = [];
var numIters = x.rank - segmentIds.rank;
for (var i = 0; i < numIters; ++i) {
segmentIds = segmentIds.expandDims(i + 1);
}
for (var i = 0; i < numSegments; ++i) {
var segmentId = ops.scalar(i, 'int32');
var mask = ops.equal(segmentId, segmentIds).asType('float32');
var sum = mask.mul(x).sum(0);
res.push(sum);
}
return ops.stack(res);
};
MathBackendCPU.prototype.argMin = function (x, axis) {
var axes = [axis];
axis_util.assertAxesAreInnerMostDims('argMin', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ops.zeros(outShape, 'int32');
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var min = aVals[offset];
var minIndex = 0;
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
if (value < min) {
min = value;
minIndex = j;
}
}
vals[i] = minIndex;
}
return result;
};
MathBackendCPU.prototype.argMax = function (x, axis) {
var axes = [axis];
axis_util.assertAxesAreInnerMostDims('argMax', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ops.zeros(outShape, 'int32');
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var max = aVals[offset];
var maxIndex = 0;
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
if (value > max) {
max = value;
maxIndex = j;
}
}
vals[i] = maxIndex;
}
return result;
};
MathBackendCPU.prototype.cumsum = function (x, axis, exclusive, reverse) {
if (axis !== x.rank - 1) {
throw new Error("backend.cumsum in CPU expects an inner-most axis=" + (x.rank - 1) + " " +
("but got axis=" + axis));
}
var resultDtype = types_1.upcastType(x.dtype, 'int32');
var result = ops.zeros(x.shape, resultDtype);
var vals = result.dataSync();
var aVals = x.dataSync();
var finalDim = x.shape[x.rank - 1];
var indexAdjuster = reverse ?
function (i, j) { return i + finalDim - j - 1; } :
function (i, j) { return i + j; };
for (var i = 0; i < aVals.length; i += finalDim) {
for (var j = 0; j < finalDim; j++) {
var idx = indexAdjuster(i, j);
if (j === 0) {
vals[idx] = exclusive ? 0 : aVals[idx];
}
else {
var prevIdx = indexAdjuster(i, j - 1);
vals[idx] = exclusive ? aVals[prevIdx] + vals[prevIdx] :
aVals[idx] + vals[prevIdx];
}
}
}
return result;
};
MathBackendCPU.prototype.equal = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return (aVal === bVal) ? 1 : 0;
});
};
MathBackendCPU.prototype.notEqual = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return (aVal !== bVal) ? 1 : 0;
});
};
MathBackendCPU.prototype.less = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return (aVal < bVal) ? 1 : 0;
});
};
MathBackendCPU.prototype.lessEqual = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return (aVal <= bVal) ? 1 : 0;
});
};
MathBackendCPU.prototype.greater = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return (aVal > bVal) ? 1 : 0;
});
};
MathBackendCPU.prototype.greaterEqual = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return (aVal >= bVal) ? 1 : 0;
});
};
MathBackendCPU.prototype.logicalNot = function (x) {
var values = x.dataSync();
var newValues = new Int32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = values[i] ? 0 : 1;
}
return tensor_1.Tensor.make(x.shape, { values: newValues }, 'bool');
};
MathBackendCPU.prototype.logicalAnd = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return aVal && bVal;
});
};
MathBackendCPU.prototype.logicalOr = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
return aVal || bVal;
});
};
MathBackendCPU.prototype.select = function (condition, a, b) {
var values = condition.dataSync();
var aValues = a.dataSync();
var bValues = b.dataSync();
var result = ops.zeros(a.shape, types_1.upcastType(a.dtype, b.dtype));
var newValues = result.dataSync();
var index = 0;
var offset = condition.rank === 0 || condition.rank > 1 || a.rank === 1 ?
1 :
a.shape[1];
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < offset; j++) {
if (values[i] === 1) {
newValues[index++] = aValues[i];
}
else {
newValues[index++] = bValues[i];
}
}
}
return result;
};
MathBackendCPU.prototype.where = function (condition) {
var condVals = condition.dataSync();
return where_impl_1.whereImpl(condition.shape, condVals);
};
MathBackendCPU.prototype.topk = function (x, k, sorted) {
var xVals = x.dataSync();
return topk_impl_1.topkImpl(xVals, x.shape, x.dtype, k, sorted);
};
MathBackendCPU.prototype.min = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('min', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ops.zeros(outShape, x.dtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var min = aVals[offset];
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
if (value < min) {
min = value;
}
}
vals[i] = min;
}
return result;
};
MathBackendCPU.prototype.minimum = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aVal, bVal) { return Math.min(aVal, bVal); });
};
MathBackendCPU.prototype.mod = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aVal, bVal) {
var rem = aVal % bVal;
if ((aVal < 0 && bVal < 0) || (aVal >= 0 && bVal >= 0)) {
return rem;
}
else {
return (rem + bVal) % bVal;
}
});
};
MathBackendCPU.prototype.max = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('max', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ops.zeros(outShape, x.dtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var max = aVals[offset];
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
if (value > max) {
max = value;
}
}
vals[i] = max;
}
return result;
};
MathBackendCPU.prototype.maximum = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aVal, bVal) { return Math.max(aVal, bVal); });
};
MathBackendCPU.prototype.all = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('all', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ops.zeros(outShape, x.dtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var all = aVals[offset];
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
all = all && value;
}
vals[i] = all;
}
return result;
};
MathBackendCPU.prototype.any = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('any', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ops.zeros(outShape, x.dtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.dataSync();
var aVals = x.dataSync();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var anyVal = aVals[offset];
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
anyVal = anyVal || value;
}
vals[i] = anyVal;
}
return result;
};
MathBackendCPU.prototype.squaredDifference = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aVal, bVal) {
var diff = aVal - bVal;
return diff * diff;
});
};
MathBackendCPU.prototype.ceil = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.ceil(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.floor = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.floor(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.sign = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
if (values[i] < 0) {
newValues[i] = -1;
}
else if (values[i] > 0) {
newValues[i] = 1;
}
else {
newValues[i] = 0;
}
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.round = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var base = Math.floor(values[i]);
if (values[i] - base < 0.5) {
newValues[i] = Math.floor(values[i]);
}
else if (values[i] - base > 0.5) {
newValues[i] = Math.ceil(values[i]);
}
else {
if (base % 2.0 === 0.0) {
newValues[i] = base;
}
else {
newValues[i] = base + 1.0;
}
}
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.exp = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.exp(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.expm1 = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.expm1(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.log = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = Math.log(value);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.log1p = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = Math.log1p(value);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.sqrt = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = Math.sqrt(value);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.rsqrt = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = 1 / Math.sqrt(value);
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.square = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = value * value;
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.reciprocal = function (x) {
var values = x.dataSync();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = 1 / values[i];
}
return tensor_1.Tensor.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.relu = function (x) {
var res = ops.zeros(x.shape, x.dtype);
var resVals = res.dataSync();
var inVals = x.dataSync();
for (var i = 0; i < inVals.length; ++i) {
resVals[i] = Math.max(0, inVals[i]);
}
return res;
};
MathBackendCPU.prototype.elu = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
var v = values[i];
if (v >= 0) {
resultValues[i] = v;
}
else {
resultValues[i] = (Math.exp(v) - 1);
}
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.eluDer = function (dy, y) {
var resultValues = new Float32Array(y.size);
var values = y.dataSync();
var dyValues = dy.dataSync();
for (var i = 0; i < values.length; ++i) {
var v = values[i];
if (v >= 1) {
resultValues[i] = dyValues[i];
}
else {
resultValues[i] = dyValues[i] * (v + 1);
}
}
return tensor_1.Tensor.make(y.shape, { values: resultValues });
};
MathBackendCPU.prototype.selu = function (x) {
var scaleAlpha = selu_util.SELU_SCALEALPHA;
var scale = selu_util.SELU_SCALE;
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
var v = values[i];
if (v >= 0) {
resultValues[i] = scale * v;
}
else {
resultValues[i] = scaleAlpha * (Math.exp(v) - 1);
}
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.clip = function (x, min, max) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
var v = values[i];
resultValues[i] = v > max ? max : (v < min ? min : v);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.abs = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.abs(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.int = function (x) {
var resultValues = new Int32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = values[i];
}
return tensor_1.Tensor.make(x.shape, { values: resultValues }, 'int32');
};
MathBackendCPU.prototype.sigmoid = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = 1 / (1 + Math.exp(-values[i]));
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.softplus = function (x) {
var epsilon = 1.1920928955078125e-7;
var threshold = Math.log(epsilon) + 2.0;
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
var tooLarge = values[i] > -threshold;
var tooSmall = values[i] < threshold;
var expX = Math.exp(values[i]);
var result = void 0;
if (tooSmall) {
result = expX;
}
else if (tooLarge) {
result = values[i];
}
else {
result = Math.log(1.0 + expX);
}
resultValues[i] = result;
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.sin = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.sin(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.cos = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.cos(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.tan = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.tan(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.asin = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.asin(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.acos = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.acos(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.atan = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.atan(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.atan2 = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aValue, bValue) { return Math.atan2(aValue, bValue); });
};
MathBackendCPU.prototype.sinh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.sinh(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.cosh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.cosh(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.tanh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = util.tanh(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.asinh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.asinh(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.acosh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.acosh(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.atanh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.atanh(values[i]);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.erf = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
var p = erf_util.ERF_P;
var a1 = erf_util.ERF_A1;
var a2 = erf_util.ERF_A2;
var a3 = erf_util.ERF_A3;
var a4 = erf_util.ERF_A4;
var a5 = erf_util.ERF_A5;
for (var i = 0; i < values.length; ++i) {
var v = values[i];
var t = 1.0 / (1.0 + p * v);
resultValues[i] = 1.0 -
(((((a5 * t + a4) * t) + a3) * t + a2) * t + a1) * t *
Math.exp(-v * v);
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.step = function (x, alpha) {
if (alpha === void 0) { alpha = 0; }
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
for (var i = 0; i < values.length; ++i) {
var value = values[i];
if (isNaN(value)) {
resultValues[i] = NaN;
}
else {
resultValues[i] = value > 0 ? 1 : alpha;
}
}
return tensor_1.Tensor.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.conv2d = function (x, filter, convInfo) {
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var dilationHeight = convInfo.dilationHeight;
var dilationWidth = convInfo.dilationWidth;
var padLeft = convInfo.padInfo.left;
var padTop = convInfo.padInfo.top;
var y = ops.buffer(convInfo.outShape, x.dtype);
var xVals = x.dataSync();
var wVals = filter.dataSync();
var yVals = y.values;
for (var b = 0; b < convInfo.batchSize; ++b) {
var xOffset1 = b * x.strides[0];
var yOffset1 = b * y.strides[0];
for (var yR = 0; yR < convInfo.outHeight; ++yR) {
var yOffset2 = yOffset1 + yR * y.strides[1];
var xRCorner = yR * convInfo.strideHeight - padLeft;
for (var wR = 0; wR < filterHeight; wR++) {
var xR = xRCorner + wR * dilationHeight;
if (xR < 0 || xR >= convInfo.inHeight) {
continue;
}
var wOffset1 = wR * filter.strides[0];
var xOffset2 = xOffset1 + xR * x.strides[1];
for (var yC = 0; yC < convInfo.outWidth; ++yC) {
var yOffset3 = yOffset2 + yC * convInfo.outChannels;
var xCCorner = yC * convInfo.strideWidth - padTop;
for (var wC = 0; wC < filterWidth; wC++) {
var xC = xCCorner + wC * dilationWidth;
if (xC < 0 || xC >= convInfo.inWidth) {
continue;
}
var wOffset2 = wOffset1 + wC * filter.strides[1];
var xOffset3 = xOffset2 + xC * convInfo.inChannels;
var wOffset3 = wOffset2;
for (var d1 = 0; d1 < convInfo.inChannels; ++d1) {
var xVal = xVals[xOffset3 + d1];
for (var d2 = 0; d2 < convInfo.outChannels; ++d2) {
yVals[yOffset3 + d2] += xVal * wVals[wOffset3 + d2];
}
wOffset3 += convInfo.outChannels;
}
}
}
}
}
}
return y.toTensor();
};
MathBackendCPU.prototype.conv2dDerInput = function (dy, filter, convInfo) {
var dx = ops.buffer(convInfo.inShape, 'float32');
var dxValues = dx.values;
var _a = dx.strides, dxS0 = _a[0], dxS1 = _a[1], dxS2 = _a[2];
var dyValues = dy.dataSync();
var _b = dy.strides, dyS0 = _b[0], dyS1 = _b[1], dyS2 = _b[2];
var fltValues = filter.dataSync();
var _c = filter.strides, fltS0 = _c[0], fltS1 = _c[1], fltS2 = _c[2];
var batchSize = convInfo.batchSize, filterHeight = convInfo.filterHeight, filterWidth = convInfo.filterWidth, inChannels = convInfo.inChannels, inHeight = convInfo.inHeight, inWidth = convInfo.inWidth, outChannels = convInfo.outChannels, outHeight = convInfo.outHeight, outWidth = convInfo.outWidth, strideHeight = convInfo.strideHeight, strideWidth = convInfo.strideWidth;
var topPad = filterHeight - 1 - convInfo.padInfo.top;
var leftPad = filterWidth - 1 - convInfo.padInfo.left;
for (var b = 0; b < batchSize; ++b) {
for (var d1 = 0; d1 < inChannels; ++d1) {
for (var xR = 0; xR < inHeight; ++xR) {
var xRCorner = xR - topPad;
var xRMin = Math.max(0, Math.ceil(xRCorner / strideHeight));
var yRMax = Math.min(outHeight, (filterHeight + xRCorner) / strideHeight);
for (var xC = 0; xC < inWidth; ++xC) {
var xCCorner = xC - leftPad;
var xCMin = Math.max(0, Math.ceil(xCCorner / strideWidth));
var yCMax = Math.min(outWidth, (filterWidth + xCCorner) / strideWidth);
var dotProd = 0;
for (var yR = xRMin; yR < yRMax; ++yR) {
var wR = yR * strideHeight - xRCorner;
for (var yC = xCMin; yC < yCMax; ++yC) {
var wC = yC * strideWidth - xCCorner;
var dyOffset = dyS0 * b + dyS1 * yR + dyS2 * yC;
var fltOffset = fltS0 * (filterHeight - 1 - wR) +
fltS1 * (filterWidth - 1 - wC) + fltS2 * d1;
for (var d2 = 0; d2 < outChannels; ++d2) {
var pixel = dyValues[dyOffset + d2];
var weight = fltValues[fltOffset + d2];
dotProd += pixel * weight;
}
}
}
dxValues[dxS0 * b + dxS1 * xR + dxS2 * xC + d1] = dotProd;
}
}
}
}
return dx.toTensor();
};
MathBackendCPU.prototype.conv2dDerFilter = function (x, dy, convInfo) {
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var dW = ops.buffer(convInfo.filterShape, 'float32');
var leftPad = convInfo.padInfo.left;
var topPad = convInfo.padInfo.top;
for (var wR = 0; wR < filterHeight; ++wR) {
var yRMin = Math.max(0, Math.ceil((topPad - wR) / strideHeight));
var yRMax = Math.min(convInfo.outHeight, (convInfo.inHeight + topPad - wR) / strideHeight);
for (var wC = 0; wC < filterWidth; ++wC) {
var yCMin = Math.max(0, Math.ceil((leftPad - wC) / strideWidth));
var yCMax = Math.min(convInfo.outWidth, (convInfo.inWidth + leftPad - wC) / strideWidth);
for (var d1 = 0; d1 < convInfo.inChannels; ++d1) {
for (var d2 = 0; d2 < convInfo.outChannels; ++d2) {
var dotProd = 0;
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var yR = yRMin; yR < yRMax; ++yR) {
var xR = wR + yR * strideHeight - topPad;
for (var yC = yCMin; yC < yCMax; ++yC) {
var xC = wC + yC * strideWidth - leftPad;
dotProd += x.get(b, xR, xC, d1) * dy.get(b, yR, yC, d2);
}
}
}
dW.set(dotProd, wR, wC, d1, d2);
}
}
}
}
return dW.toTensor();
};
MathBackendCPU.prototype.depthwiseConv2D = function (x, filter, convInfo) {
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var dilationHeight = convInfo.dilationHeight;
var dilationWidth = convInfo.dilationWidth;
var padLeft = convInfo.padInfo.left;
var padTop = convInfo.padInfo.top;
var chMul = convInfo.outChannels / convInfo.inChannels;
var y = ops.buffer(convInfo.outShape, x.dtype);
var xVals = x.dataSync();
var wVals = filter.dataSync();
var yVals = y.values;
for (var b = 0; b < convInfo.batchSize; ++b) {
var xOffset1 = b * x.strides[0];
var yOffset1 = b * y.strides[0];
for (var yR = 0; yR < convInfo.outHeight; ++yR) {
var yOffset2 = yOffset1 + yR * y.strides[1];
var xRCorner = yR * convInfo.strideHeight - padLeft;
for (var wR = 0; wR < filterHeight; ++wR) {
var xR = xRCorner + wR * dilationHeight;
if (xR < 0 || xR >= convInfo.inHeight) {
continue;
}
var wOffset1 = wR * filter.strides[0];
var xOffset2 = xOffset1 + xR * x.strides[1];
for (var yC = 0; yC < convInfo.outWidth; ++yC) {
var yOffset3 = yOffset2 + yC * y.strides[2];
var xCCorner = yC * convInfo.strideWidth - padTop;
for (var wC = 0; wC < filterWidth; ++wC) {
var xC = xCCorner + wC * dilationWidth;
if (xC < 0 || xC >= convInfo.inWidth) {
continue;
}
var wOffset2 = wOffset1 + wC * filter.strides[1];
var xOffset3 = xOffset2 + xC * convInfo.inChannels;
var yOffset4 = yOffset3;
var wOffset3 = wOffset2;
for (var d1 = 0; d1 < convInfo.inChannels; ++d1) {
var xVal = xVals[xOffset3 + d1];
for (var q = 0; q < chMul; ++q) {
yVals[yOffset4 + q] += xVal * wVals[wOffset3 + q];
}
yOffset4 += chMul;
wOffset3 += chMul;
}
}
}
}
}
}
return y.toTensor();
}