@tensorflow/tfjs-core
Version:
Hardware-accelerated JavaScript library for machine intelligence
1,219 lines (1,204 loc) • 781 kB
JavaScript
/**
* @license
* Copyright 2018 Google LLC. All Rights Reserved.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* =============================================================================
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.tf = global.tf || {})));
}(this, (function (exports) { 'use strict';
/*! *****************************************************************************
Copyright (c) Microsoft Corporation. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
this file except in compliance with the License. You may obtain a copy of the
License at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions
and limitations under the License.
***************************************************************************** */
/* global Reflect, Promise */
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
function __extends(d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = Object.assign || function __assign(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
}
return t;
};
function __awaiter(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());
});
}
function __generator(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 };
}
}
function isMobile() {
var a = navigator.userAgent || navigator.vendor || window.opera;
return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i
.test(a) ||
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i
.test(a.substr(0, 4));
}
function shuffle(array) {
var counter = array.length;
var temp = 0;
var index = 0;
while (counter > 0) {
index = (Math.random() * counter) | 0;
counter--;
temp = array[counter];
array[counter] = array[index];
array[index] = temp;
}
}
function clamp(min, x, max) {
return Math.max(min, Math.min(x, max));
}
function randUniform(a, b) {
return Math.random() * (b - a) + a;
}
function distSquared(a, b) {
var result = 0;
for (var i = 0; i < a.length; i++) {
var diff = Number(a[i]) - Number(b[i]);
result += diff * diff;
}
return result;
}
function assert(expr, msg) {
if (!expr) {
throw new Error(typeof msg === 'string' ? msg : msg());
}
}
function assertShapesMatch(shapeA, shapeB, errorMessagePrefix) {
if (errorMessagePrefix === void 0) { errorMessagePrefix = ''; }
assert(arraysEqual(shapeA, shapeB), errorMessagePrefix + (" Shapes " + shapeA + " and " + shapeB + " must match"));
}
function assertNonNull(a) {
assert(a != null, "The input to the tensor constructor must be a non-null value.");
}
function flatten(arr, ret) {
if (ret === void 0) { ret = []; }
if (Array.isArray(arr)) {
for (var i = 0; i < arr.length; ++i) {
flatten(arr[i], ret);
}
}
else {
ret.push(arr);
}
return ret;
}
function inferShape(val) {
var firstElem = val;
if (isTypedArray(val)) {
return [val.length];
}
if (!Array.isArray(val)) {
return [];
}
var shape = [];
while (firstElem instanceof Array) {
shape.push(firstElem.length);
firstElem = firstElem[0];
}
if (val instanceof Array) {
deepAssertShapeConsistency(val, shape, []);
}
return shape;
}
function deepAssertShapeConsistency(val, shape, indices) {
indices = indices || [];
if (!(val instanceof Array)) {
assert(shape.length === 0, function () { return "Element arr[" + indices.join('][') + "] is a primitive, " +
("but should be an array of " + shape[0] + " elements"); });
return;
}
assert(shape.length > 0, function () { return "Element arr[" + indices.join('][') + "] should be a primitive, " +
("but is an array of " + val.length + " elements"); });
assert(val.length === shape[0], function () { return "Element arr[" + indices.join('][') + "] should have " + shape[0] + " " +
("elements, but has " + val.length + " elements"); });
var subShape = shape.slice(1);
for (var i = 0; i < val.length; ++i) {
deepAssertShapeConsistency(val[i], subShape, indices.concat(i));
}
}
function sizeFromShape(shape) {
if (shape.length === 0) {
return 1;
}
var size = shape[0];
for (var i = 1; i < shape.length; i++) {
size *= shape[i];
}
return size;
}
function isScalarShape(shape) {
return shape.length === 0;
}
function arraysEqual(n1, n2) {
if (n1.length !== n2.length) {
return false;
}
for (var i = 0; i < n1.length; i++) {
if (n1[i] !== n2[i]) {
return false;
}
}
return true;
}
function isInt(a) {
return a % 1 === 0;
}
function tanh(x) {
if (Math.tanh != null) {
return Math.tanh(x);
}
if (x === Infinity) {
return 1;
}
else if (x === -Infinity) {
return -1;
}
else {
var e2x = Math.exp(2 * x);
return (e2x - 1) / (e2x + 1);
}
}
function sizeToSquarishShape(size) {
for (var a = Math.floor(Math.sqrt(size)); a > 1; --a) {
if (size % a === 0) {
return [a, size / a];
}
}
return [1, size];
}
function createShuffledIndices(n) {
var shuffledIndices = new Uint32Array(n);
for (var i = 0; i < n; ++i) {
shuffledIndices[i] = i;
}
shuffle(shuffledIndices);
return shuffledIndices;
}
function rightPad(a, size) {
if (size <= a.length) {
return a;
}
return a + ' '.repeat(size - a.length);
}
function repeatedTry(checkFn, delayFn, maxCounter) {
if (delayFn === void 0) { delayFn = function (counter) { return 0; }; }
return new Promise(function (resolve, reject) {
var tryCount = 0;
var tryFn = function () {
if (checkFn()) {
resolve();
return;
}
tryCount++;
var nextBackoff = delayFn(tryCount);
if (maxCounter != null && tryCount >= maxCounter) {
reject();
return;
}
setTimeout(tryFn, nextBackoff);
};
tryFn();
});
}
function inferFromImplicitShape(shape, size) {
var shapeProd = 1;
var implicitIdx = -1;
for (var i = 0; i < shape.length; ++i) {
if (shape[i] >= 0) {
shapeProd *= shape[i];
}
else if (shape[i] === -1) {
if (implicitIdx !== -1) {
throw Error("Shapes can only have 1 implicit size. " +
("Found -1 at dim " + implicitIdx + " and dim " + i));
}
implicitIdx = i;
}
else if (shape[i] < 0) {
throw Error("Shapes can not be < 0. Found " + shape[i] + " at dim " + i);
}
}
if (implicitIdx === -1) {
if (size > 0 && size !== shapeProd) {
throw Error("Size(" + size + ") must match the product of shape " + shape);
}
return shape;
}
if (shapeProd === 0) {
throw Error("Cannot infer the missing size in [" + shape + "] when " +
"there are 0 elements");
}
if (size % shapeProd !== 0) {
throw Error("The implicit shape can't be a fractional number. " +
("Got " + size + " / " + shapeProd));
}
var newShape = shape.slice();
newShape[implicitIdx] = size / shapeProd;
return newShape;
}
function squeezeShape(shape, axis) {
var newShape = [];
var keptDims = [];
var j = 0;
for (var i = 0; i < shape.length; ++i) {
if (axis != null) {
if (axis[j] === i && shape[i] !== 1) {
throw new Error("Can't squeeze axis " + i + " since its dim '" + shape[i] + "' is not 1");
}
if ((axis[j] == null || axis[j] > i) && shape[i] === 1) {
newShape.push(shape[i]);
keptDims.push(i);
}
if (axis[j] <= i) {
j++;
}
}
if (shape[i] !== 1) {
newShape.push(shape[i]);
keptDims.push(i);
}
}
return { newShape: newShape, keptDims: keptDims };
}
function getTypedArrayFromDType(dtype, size) {
var values = null;
if (dtype == null || dtype === 'float32') {
values = new Float32Array(size);
}
else if (dtype === 'int32') {
values = new Int32Array(size);
}
else if (dtype === 'bool') {
values = new Uint8Array(size);
}
else {
throw new Error("Unknown data type " + dtype);
}
return values;
}
function checkComputationForNaN(vals, dtype, name) {
if (dtype !== 'float32') {
return;
}
for (var i = 0; i < vals.length; i++) {
if (isNaN(vals[i])) {
throw Error("The result of the '" + name + "' has NaNs.");
}
}
}
function checkConversionForNaN(vals, dtype) {
if (dtype === 'float32') {
return;
}
for (var i = 0; i < vals.length; i++) {
if (isNaN(vals[i])) {
throw Error("NaN is not a valid value for dtype: '" + dtype + "'.");
}
}
}
function hasEncodingLoss(oldType, newType) {
if (newType === 'float32') {
return false;
}
if (newType === 'int32' && oldType !== 'float32') {
return false;
}
if (newType === 'bool' && oldType === 'bool') {
return false;
}
return true;
}
function copyTypedArray(array, dtype, debugMode) {
if (dtype == null || dtype === 'float32') {
return new Float32Array(array);
}
else if (dtype === 'int32') {
if (debugMode) {
checkConversionForNaN(array, dtype);
}
return new Int32Array(array);
}
else if (dtype === 'bool') {
var bool = new Uint8Array(array.length);
for (var i = 0; i < bool.length; ++i) {
if (Math.round(array[i]) !== 0) {
bool[i] = 1;
}
}
return bool;
}
else {
throw new Error("Unknown data type " + dtype);
}
}
function isTypedArray(a) {
return a instanceof Float32Array || a instanceof Int32Array ||
a instanceof Uint8Array;
}
function bytesPerElement(dtype) {
if (dtype === 'float32' || dtype === 'int32') {
return 4;
}
else if (dtype === 'bool') {
return 1;
}
else {
throw new Error("Unknown dtype " + dtype);
}
}
function isFunction(f) {
return !!(f && f.constructor && f.call && f.apply);
}
function nearestDivisor(size, start) {
for (var i = start; i < size; ++i) {
if (size % i === 0) {
return i;
}
}
return size;
}
function computeStrides(shape) {
var rank = shape.length;
if (rank < 2) {
return [];
}
var strides = new Array(rank - 1);
strides[rank - 2] = shape[rank - 1];
for (var i = rank - 3; i >= 0; --i) {
strides[i] = strides[i + 1] * shape[i + 1];
}
return strides;
}
function toTypedArray(a, dtype, debugMode) {
if (noConversionNeeded(a, dtype)) {
return a;
}
if (Array.isArray(a)) {
a = flatten(a);
}
return copyTypedArray(a, dtype, debugMode);
}
function noConversionNeeded(a, dtype) {
return (a instanceof Float32Array && dtype === 'float32') ||
(a instanceof Int32Array && dtype === 'int32') ||
(a instanceof Uint8Array && dtype === 'bool');
}
function makeOnesTypedArray(size, dtype) {
var array = makeZerosTypedArray(size, dtype);
for (var i = 0; i < array.length; i++) {
array[i] = 1;
}
return array;
}
function makeZerosTypedArray(size, dtype) {
if (dtype == null || dtype === 'float32') {
return new Float32Array(size);
}
else if (dtype === 'int32') {
return new Int32Array(size);
}
else if (dtype === 'bool') {
return new Uint8Array(size);
}
else {
throw new Error("Unknown data type " + dtype);
}
}
function now() {
if (typeof performance !== 'undefined') {
return performance.now();
}
else if (typeof process !== 'undefined') {
var time = process.hrtime();
return time[0] * 1000 + time[1] / 1000000;
}
else {
throw new Error('Can not measure time in this environment. You should run tf.js ' +
'in the browser or in Node.js');
}
}
var util = /*#__PURE__*/Object.freeze({
shuffle: shuffle,
clamp: clamp,
randUniform: randUniform,
distSquared: distSquared,
assert: assert,
assertShapesMatch: assertShapesMatch,
assertNonNull: assertNonNull,
flatten: flatten,
inferShape: inferShape,
sizeFromShape: sizeFromShape,
isScalarShape: isScalarShape,
arraysEqual: arraysEqual,
isInt: isInt,
tanh: tanh,
sizeToSquarishShape: sizeToSquarishShape,
createShuffledIndices: createShuffledIndices,
rightPad: rightPad,
repeatedTry: repeatedTry,
inferFromImplicitShape: inferFromImplicitShape,
squeezeShape: squeezeShape,
getTypedArrayFromDType: getTypedArrayFromDType,
checkComputationForNaN: checkComputationForNaN,
checkConversionForNaN: checkConversionForNaN,
hasEncodingLoss: hasEncodingLoss,
isTypedArray: isTypedArray,
bytesPerElement: bytesPerElement,
isFunction: isFunction,
nearestDivisor: nearestDivisor,
computeStrides: computeStrides,
toTypedArray: toTypedArray,
makeOnesTypedArray: makeOnesTypedArray,
makeZerosTypedArray: makeZerosTypedArray,
now: now
});
var Profiler = (function () {
function Profiler(backendTimer, logger) {
this.backendTimer = backendTimer;
this.logger = logger;
if (logger == null) {
this.logger = new Logger();
}
}
Profiler.prototype.profileKernel = function (name, f) {
var _this = this;
var result;
var holdResultWrapperFn = function () {
result = f();
};
var timer = this.backendTimer.time(holdResultWrapperFn);
var results = Array.isArray(result) ? result : [result];
results.forEach(function (r) {
var vals = r.dataSync();
checkComputationForNaN(vals, r.dtype, name);
timer.then(function (timing) {
_this.logger.logKernelProfile(name, r, vals, timing.kernelMs);
});
});
return result;
};
return Profiler;
}());
var Logger = (function () {
function Logger() {
}
Logger.prototype.logKernelProfile = function (name, result, vals, timeMs) {
var time = rightPad(timeMs + "ms", 9);
var paddedName = rightPad(name, 25);
var rank = result.rank;
var size = result.size;
var shape = rightPad(result.shape.toString(), 14);
console.log("%c" + paddedName + "\t%c" + time + "\t%c" + rank + "D " + shape + "\t%c" + size, 'font-weight:bold', 'color:red', 'color:blue', 'color: orange');
};
return Logger;
}());
function getFilteredNodesXToY(tape, xs, y) {
var tensorsFromX = {};
var nodesFromX = {};
for (var i = 0; i < xs.length; i++) {
tensorsFromX[xs[i].id] = true;
}
for (var i = 0; i < tape.length; i++) {
var node = tape[i];
var nodeInputs = node.inputs;
for (var inputName in nodeInputs) {
var input = nodeInputs[inputName];
var anyInputFromX = false;
for (var j = 0; j < xs.length; j++) {
if (tensorsFromX[input.id]) {
tensorsFromX[node.output.id] = true;
anyInputFromX = true;
nodesFromX[node.id] = true;
break;
}
}
if (anyInputFromX) {
break;
}
}
}
var tensorsLeadToY = {};
tensorsLeadToY[y.id] = true;
var nodesToY = {};
for (var i = tape.length - 1; i >= 0; i--) {
var node = tape[i];
var nodeInputs = node.inputs;
var outputs = [];
outputs.push(node.output);
for (var j = 0; j < outputs.length; j++) {
if (tensorsLeadToY[outputs[j].id]) {
for (var inputName in nodeInputs) {
tensorsLeadToY[nodeInputs[inputName].id] = true;
nodesToY[node.id] = true;
}
break;
}
}
}
var filteredTape = [];
for (var i = 0; i < tape.length; i++) {
var node = tape[i];
if (nodesFromX[node.id] && nodesToY[node.id]) {
var prunedInputs = {};
for (var inputName in node.inputs) {
var nodeInput = node.inputs[inputName];
if (tensorsFromX[nodeInput.id]) {
prunedInputs[inputName] = nodeInput;
}
}
var prunedNode = Object.assign({}, node);
prunedNode.inputs = prunedInputs;
prunedNode.output = node.output;
filteredTape.push(prunedNode);
}
}
return filteredTape;
}
function backpropagateGradients(tensorAccumulatedGradientMap, filteredTape) {
for (var i = filteredTape.length - 1; i >= 0; i--) {
var node = filteredTape[i];
var dy = tensorAccumulatedGradientMap[node.output.id];
if (node.gradient == null) {
throw new Error("Cannot compute gradient: gradient function not found " +
("for " + node.name + "."));
}
var inputGradients = node.gradient(dy);
for (var inputName in node.inputs) {
if (!(inputName in inputGradients)) {
throw new Error("Cannot backprop through input " + inputName + ". " +
("Available gradients found: " + Object.keys(inputGradients) + "."));
}
var dx = inputGradients[inputName]();
var x = node.inputs[inputName];
if (!arraysEqual(dx.shape, x.shape)) {
throw new Error("Error in gradient for op " + node.name + ". The gradient of input " +
("'" + inputName + "' has shape '" + dx.shape + "', which does not match ") +
("the shape of the input '" + x.shape + "'"));
}
if (tensorAccumulatedGradientMap[x.id] == null) {
tensorAccumulatedGradientMap[x.id] = dx;
}
else {
var curGradient = tensorAccumulatedGradientMap[x.id];
tensorAccumulatedGradientMap[x.id] = curGradient.add(dx);
curGradient.dispose();
}
}
}
}
var FORMAT_LIMIT_NUM_VALS = 20;
var FORMAT_NUM_FIRST_LAST_VALS = 3;
var FORMAT_NUM_SIG_DIGITS = 7;
function tensorToString(vals, shape, dtype, verbose) {
var strides = computeStrides(shape);
var padPerCol = computeMaxSizePerColumn(vals, shape, strides);
var rank = shape.length;
var valsLines = subTensorToString(vals, shape, strides, padPerCol);
var lines = ['Tensor'];
if (verbose) {
lines.push(" dtype: " + dtype);
lines.push(" rank: " + rank);
lines.push(" shape: [" + shape + "]");
lines.push(" values:");
}
lines.push(valsLines.map(function (l) { return ' ' + l; }).join('\n'));
return lines.join('\n');
}
function computeMaxSizePerColumn(vals, shape, strides) {
var n = sizeFromShape(shape);
var numCols = strides[strides.length - 1];
var padPerCol = new Array(numCols).fill(0);
var rank = shape.length;
if (rank > 1) {
for (var row = 0; row < n / numCols; row++) {
var offset = row * numCols;
for (var j = 0; j < numCols; j++) {
padPerCol[j] =
Math.max(padPerCol[j], valToString(vals[offset + j], 0).length);
}
}
}
return padPerCol;
}
function valToString(val, pad) {
return rightPad(parseFloat(val.toFixed(FORMAT_NUM_SIG_DIGITS)).toString(), pad);
}
function subTensorToString(vals, shape, strides, padPerCol, isLast) {
if (isLast === void 0) { isLast = true; }
var size = shape[0];
var rank = shape.length;
if (rank === 0) {
return [vals[0].toString()];
}
if (rank === 1) {
if (size > FORMAT_LIMIT_NUM_VALS) {
var firstVals = Array.from(vals.subarray(0, FORMAT_NUM_FIRST_LAST_VALS));
var lastVals = Array.from(vals.subarray(size - FORMAT_NUM_FIRST_LAST_VALS, size));
return [
'[' + firstVals.map(function (x, i) { return valToString(x, padPerCol[i]); }).join(', ') +
', ..., ' +
lastVals
.map(function (x, i) { return valToString(x, padPerCol[size - FORMAT_NUM_FIRST_LAST_VALS + i]); })
.join(', ') +
']'
];
}
return [
'[' +
Array.from(vals).map(function (x, i) { return valToString(x, padPerCol[i]); }).join(', ') +
']'
];
}
var subshape = shape.slice(1);
var substrides = strides.slice(1);
var stride = strides[0];
var lines = [];
if (size > FORMAT_LIMIT_NUM_VALS) {
for (var i = 0; i < FORMAT_NUM_FIRST_LAST_VALS; i++) {
var start = i * stride;
var end = start + stride;
lines.push.apply(lines, subTensorToString(vals.subarray(start, end), subshape, substrides, padPerCol, false));
}
lines.push('...');
for (var i = size - FORMAT_NUM_FIRST_LAST_VALS; i < size; i++) {
var start = i * stride;
var end = start + stride;
lines.push.apply(lines, subTensorToString(vals.subarray(start, end), subshape, substrides, padPerCol, i === size - 1));
}
}
else {
for (var i = 0; i < size; i++) {
var start = i * stride;
var end = start + stride;
lines.push.apply(lines, subTensorToString(vals.subarray(start, end), subshape, substrides, padPerCol, i === size - 1));
}
}
var sep = rank === 2 ? ',' : '';
lines[0] = '[' + lines[0] + sep;
for (var i = 1; i < lines.length - 1; i++) {
lines[i] = ' ' + lines[i] + sep;
}
var newLineSep = ',\n';
for (var i = 2; i < rank; i++) {
newLineSep += '\n';
}
lines[lines.length - 1] =
' ' + lines[lines.length - 1] + ']' + (isLast ? '' : newLineSep);
return lines;
}
var TensorBuffer = (function () {
function TensorBuffer(shape, dtype, values) {
this.dtype = dtype;
if (values != null) {
var n = values.length;
var size = sizeFromShape(shape);
assert(n === size, "Length of values '" + n + "' does not match the size " +
("inferred by the shape '" + size + "'"));
}
this.shape = shape.slice();
this.values =
values || getTypedArrayFromDType(dtype, sizeFromShape(shape));
this.strides = computeStrides(shape);
this.size = sizeFromShape(shape);
}
TensorBuffer.prototype.set = function (value) {
var locs = [];
for (var _i = 1; _i < arguments.length; _i++) {
locs[_i - 1] = arguments[_i];
}
if (locs.length === 0) {
locs = [0];
}
assert(locs.length === this.rank, "The number of provided coordinates (" + locs.length + ") must " +
("match the rank (" + this.rank + ")"));
var index = this.locToIndex(locs);
this.values[index] = value;
};
TensorBuffer.prototype.get = function () {
var locs = [];
for (var _i = 0; _i < arguments.length; _i++) {
locs[_i] = arguments[_i];
}
if (locs.length === 0) {
locs = [0];
}
var index = locs[locs.length - 1];
for (var i = 0; i < locs.length - 1; ++i) {
index += this.strides[i] * locs[i];
}
return this.values[index];
};
TensorBuffer.prototype.locToIndex = function (locs) {
if (this.rank === 0) {
return 0;
}
else if (this.rank === 1) {
return locs[0];
}
var index = locs[locs.length - 1];
for (var i = 0; i < locs.length - 1; ++i) {
index += this.strides[i] * locs[i];
}
return index;
};
TensorBuffer.prototype.indexToLoc = function (index) {
if (this.rank === 0) {
return [];
}
else if (this.rank === 1) {
return [index];
}
var locs = new Array(this.shape.length);
for (var i = 0; i < locs.length - 1; ++i) {
locs[i] = Math.floor(index / this.strides[i]);
index -= locs[i] * this.strides[i];
}
locs[locs.length - 1] = index;
return locs;
};
Object.defineProperty(TensorBuffer.prototype, "rank", {
get: function () {
return this.shape.length;
},
enumerable: true,
configurable: true
});
TensorBuffer.prototype.toTensor = function () {
return Tensor.make(this.shape, { values: this.values }, this.dtype);
};
return TensorBuffer;
}());
var trackerFn = null;
var opHandler = null;
function setTensorTracker(fn) {
trackerFn = fn;
}
function setOpHandler(handler) {
opHandler = handler;
}
var Tensor = (function () {
function Tensor(shape, dtype, values, dataId) {
this.isDisposedInternal = false;
this.size = sizeFromShape(shape);
if (values != null) {
assert(this.size === values.length, "Based on the provided shape, [" + shape + "], the tensor should have " +
(this.size + " values but has " + values.length));
}
this.shape = shape.slice();
this.dtype = dtype || 'float32';
this.strides = computeStrides(shape);
this.dataId = dataId != null ? dataId : {};
this.id = Tensor.nextId++;
this.rankType = (this.rank < 5 ? this.rank.toString() : 'higher');
trackerFn().registerTensor(this);
if (values != null) {
trackerFn().write(this.dataId, values);
}
}
Tensor.make = function (shape, data, dtype) {
return new Tensor(shape, dtype, data.values, data.dataId);
};
Tensor.prototype.flatten = function () {
this.throwIfDisposed();
return this.as1D();
};
Tensor.prototype.asScalar = function () {
this.throwIfDisposed();
assert(this.size === 1, 'The array must have only 1 element.');
return this.reshape([]);
};
Tensor.prototype.as1D = function () {
this.throwIfDisposed();
return this.reshape([this.size]);
};
Tensor.prototype.as2D = function (rows, columns) {
this.throwIfDisposed();
return this.reshape([rows, columns]);
};
Tensor.prototype.as3D = function (rows, columns, depth) {
this.throwIfDisposed();
return this.reshape([rows, columns, depth]);
};
Tensor.prototype.as4D = function (rows, columns, depth, depth2) {
this.throwIfDisposed();
return this.reshape([rows, columns, depth, depth2]);
};
Tensor.prototype.asType = function (dtype) {
this.throwIfDisposed();
return opHandler.cast(this, dtype);
};
Object.defineProperty(Tensor.prototype, "rank", {
get: function () {
return this.shape.length;
},
enumerable: true,
configurable: true
});
Tensor.prototype.get = function () {
var locs = [];
for (var _i = 0; _i < arguments.length; _i++) {
locs[_i] = arguments[_i];
}
assert(locs.length === this.rank, 'Number of coordinates in get() must match the rank of the tensor');
this.throwIfDisposed();
if (locs.length === 0) {
locs = [0];
}
var index = locs[locs.length - 1];
for (var i = 0; i < locs.length - 1; ++i) {
index += this.strides[i] * locs[i];
}
return this.dataSync()[index];
};
Tensor.prototype.buffer = function () {
return opHandler.buffer(this.shape, this.dtype, this.dataSync());
};
Tensor.prototype.data = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
this.throwIfDisposed();
return [2, trackerFn().read(this.dataId)];
});
});
};
Tensor.prototype.dataSync = function () {
this.throwIfDisposed();
return trackerFn().readSync(this.dataId);
};
Tensor.prototype.dispose = function () {
if (this.isDisposed) {
return;
}
trackerFn().disposeTensor(this);
this.isDisposedInternal = true;
};
Object.defineProperty(Tensor.prototype, "isDisposed", {
get: function () {
return this.isDisposedInternal;
},
enumerable: true,
configurable: true
});
Tensor.prototype.throwIfDisposed = function () {
if (this.isDisposed) {
throw new Error("Tensor is disposed.");
}
};
Tensor.prototype.toFloat = function () {
return this.asType('float32');
};
Tensor.prototype.toInt = function () {
return this.asType('int32');
};
Tensor.prototype.toBool = function () {
return this.asType('bool');
};
Tensor.prototype.print = function (verbose) {
if (verbose === void 0) { verbose = false; }
return opHandler.print(this, verbose);
};
Tensor.prototype.reshape = function (newShape) {
this.throwIfDisposed();
return opHandler.reshape(this, newShape);
};
Tensor.prototype.reshapeAs = function (x) {
this.throwIfDisposed();
return this.reshape(x.shape);
};
Tensor.prototype.expandDims = function (axis) {
if (axis === void 0) { axis = 0; }
return opHandler.expandDims(this, axis);
};
Tensor.prototype.cumsum = function (axis, exclusive, reverse) {
if (axis === void 0) { axis = 0; }
if (exclusive === void 0) { exclusive = false; }
if (reverse === void 0) { reverse = false; }
return opHandler.cumsum(this, axis, exclusive, reverse);
};
Tensor.prototype.squeeze = function (axis) {
this.throwIfDisposed();
return opHandler.squeeze(this, axis);
};
Tensor.prototype.clone = function () {
this.throwIfDisposed();
return opHandler.clone(this);
};
Tensor.prototype.toString = function (verbose) {
if (verbose === void 0) { verbose = false; }
var vals = this.dataSync();
return tensorToString(vals, this.shape, this.dtype, verbose);
};
Tensor.prototype.tile = function (reps) {
this.throwIfDisposed();
return opHandler.tile(this, reps);
};
Tensor.prototype.gather = function (indices, axis) {
if (axis === void 0) { axis = 0; }
this.throwIfDisposed();
return opHandler.gather(this, indices, axis);
};
Tensor.prototype.matMul = function (b, transposeA, transposeB) {
if (transposeA === void 0) { transposeA = false; }
if (transposeB === void 0) { transposeB = false; }
this.throwIfDisposed();
return opHandler.matMul(this, b, transposeA, transposeB);
};
Tensor.prototype.dot = function (b) {
this.throwIfDisposed();
return opHandler.dot(this, b);
};
Tensor.prototype.norm = function (ord, axis, keepDims) {
if (ord === void 0) { ord = 'euclidean'; }
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.norm(this, ord, axis, keepDims);
};
Tensor.prototype.slice = function (begin, size) {
this.throwIfDisposed();
return opHandler.slice(this, begin, size);
};
Tensor.prototype.reverse = function (axis) {
this.throwIfDisposed();
return opHandler.reverse(this, axis);
};
Tensor.prototype.concat = function (x, axis) {
if (axis === void 0) { axis = 0; }
this.throwIfDisposed();
return opHandler.concat([this, x], axis);
};
Tensor.prototype.stack = function (x, axis) {
if (axis === void 0) { axis = 0; }
return opHandler.stack([this, x], axis);
};
Tensor.prototype.unstack = function (x, axis) {
if (axis === void 0) { axis = 0; }
return opHandler.unstack(this, axis);
};
Tensor.prototype.pad = function (paddings, constantValue) {
if (constantValue === void 0) { constantValue = 0; }
return opHandler.pad(this, paddings, constantValue);
};
Tensor.prototype.batchNormalization = function (mean, variance, varianceEpsilon, scale, offset) {
if (varianceEpsilon === void 0) { varianceEpsilon = .001; }
this.throwIfDisposed();
return opHandler.batchNormalization(this, mean, variance, varianceEpsilon, scale, offset);
};
Tensor.prototype.all = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.all(this, axis, keepDims);
};
Tensor.prototype.any = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.any(this, axis, keepDims);
};
Tensor.prototype.logSumExp = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.logSumExp(this, axis, keepDims);
};
Tensor.prototype.sum = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.sum(this, axis, keepDims);
};
Tensor.prototype.mean = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.mean(this, axis, keepDims);
};
Tensor.prototype.min = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.min(this, axis, keepDims);
};
Tensor.prototype.max = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.max(this, axis, keepDims);
};
Tensor.prototype.argMin = function (axis) {
if (axis === void 0) { axis = null; }
this.throwIfDisposed();
return opHandler.argMin(this, axis);
};
Tensor.prototype.argMax = function (axis) {
if (axis === void 0) { axis = null; }
this.throwIfDisposed();
return opHandler.argMax(this, axis);
};
Tensor.prototype.cast = function (dtype) {
this.throwIfDisposed();
return opHandler.cast(this, dtype);
};
Tensor.prototype.add = function (x) {
this.throwIfDisposed();
return opHandler.add(this, x);
};
Tensor.prototype.addStrict = function (x) {
this.throwIfDisposed();
return opHandler.addStrict(this, x);
};
Tensor.prototype.sub = function (x) {
this.throwIfDisposed();
return opHandler.sub(this, x);
};
Tensor.prototype.subStrict = function (x) {
this.throwIfDisposed();
return opHandler.subStrict(this, x);
};
Tensor.prototype.pow = function (exp) {
this.throwIfDisposed();
return opHandler.pow(this, exp);
};
Tensor.prototype.powStrict = function (exp) {
this.throwIfDisposed();
return opHandler.powStrict(this, exp);
};
Tensor.prototype.mul = function (x) {
this.throwIfDisposed();
return opHandler.mul(this, x);
};
Tensor.prototype.mulStrict = function (x) {
this.throwIfDisposed();
return opHandler.mulStrict(this, x);
};
Tensor.prototype.div = function (x) {
this.throwIfDisposed();
return opHandler.div(this, x);
};
Tensor.prototype.floorDiv = function (x) {
this.throwIfDisposed();
return opHandler.floorDiv(this, x);
};
Tensor.prototype.divStrict = function (x) {
this.throwIfDisposed();
return opHandler.divStrict(this, x);
};
Tensor.prototype.minimum = function (x) {
this.throwIfDisposed();
return opHandler.minimum(this, x);
};
Tensor.prototype.minimumStrict = function (x) {
this.throwIfDisposed();
return opHandler.minimumStrict(this, x);
};
Tensor.prototype.maximum = function (x) {
this.throwIfDisposed();
return opHandler.maximum(this, x);
};
Tensor.prototype.maximumStrict = function (x) {
this.throwIfDisposed();
return opHandler.maximumStrict(this, x);
};
Tensor.prototype.mod = function (x) {
this.throwIfDisposed();
return opHandler.mod(this, x);
};
Tensor.prototype.modStrict = function (x) {
this.throwIfDisposed();
return opHandler.modStrict(this, x);
};
Tensor.prototype.squaredDifference = function (x) {
this.throwIfDisposed();
return opHandler.squaredDifference(this, x);
};
Tensor.prototype.squaredDifferenceStrict = function (x) {
this.throwIfDisposed();
return opHandler.squaredDifferenceStrict(this, x);
};
Tensor.prototype.transpose = function (perm) {
this.throwIfDisposed();
return opHandler.transpose(this, perm);
};
Tensor.prototype.notEqual = function (x) {
this.throwIfDisposed();
return opHandler.notEqual(this, x);
};
Tensor.prototype.notEqualStrict = function (x) {
this.throwIfDisposed();
return opHandler.notEqualStrict(this, x);
};
Tensor.prototype.less = function (x) {
this.throwIfDisposed();
return opHandler.less(this, x);
};
Tensor.prototype.lessStrict = function (x) {
this.throwIfDisposed();
return opHandler.lessStrict(this, x);
};
Tensor.prototype.equal = function (x) {
this.throwIfDisposed();
return opHandler.equal(this, x);
};
Tensor.prototype.equalStrict = function (x) {
this.throwIfDisposed();
return opHandler.equalStrict(this, x);
};
Tensor.protot