@tensorflow/tfjs-core
Version:
Hardware-accelerated JavaScript library for machine intelligence
1,230 lines (1,215 loc) • 1.01 MB
JavaScript
/**
* @license
* Copyright 2019 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 };
}
}
var contexts = {};
var WEBGL_ATTRIBUTES = {
alpha: false,
antialias: false,
premultipliedAlpha: false,
preserveDrawingBuffer: false,
depth: false,
stencil: false,
failIfMajorPerformanceCaveat: true
};
function getWebGLContext(webGLVersion) {
if (!(webGLVersion in contexts)) {
var canvas = document.createElement('canvas');
canvas.addEventListener('webglcontextlost', function (ev) {
ev.preventDefault();
delete contexts[webGLVersion];
}, false);
contexts[webGLVersion] = getWebGLRenderingContext(webGLVersion);
}
var gl = contexts[webGLVersion];
if (gl.isContextLost()) {
delete contexts[webGLVersion];
return getWebGLContext(webGLVersion);
}
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.STENCIL_TEST);
gl.disable(gl.BLEND);
gl.disable(gl.DITHER);
gl.disable(gl.POLYGON_OFFSET_FILL);
gl.disable(gl.SAMPLE_COVERAGE);
gl.enable(gl.SCISSOR_TEST);
gl.enable(gl.CULL_FACE);
gl.cullFace(gl.BACK);
return contexts[webGLVersion];
}
function getWebGLRenderingContext(webGLVersion) {
if (webGLVersion !== 1 && webGLVersion !== 2) {
throw new Error('Cannot get WebGL rendering context, WebGL is disabled.');
}
var canvas = document.createElement('canvas');
if (webGLVersion === 1) {
return (canvas.getContext('webgl', WEBGL_ATTRIBUTES) ||
canvas.getContext('experimental-webgl', WEBGL_ATTRIBUTES));
}
return canvas.getContext('webgl2', WEBGL_ATTRIBUTES);
}
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 nearestLargerEven(val) {
return val % 2 === 0 ? val : val + 1;
}
function sum(arr) {
var sum = 0;
for (var i = 0; i < arr.length; i++) {
sum += arr[i];
}
return sum;
}
function randUniform(a, b) {
var r = Math.random();
return (b * r) + (1 - r) * 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) || isTypedArray(arr)) {
for (var i = 0; i < arr.length; ++i) {
flatten(arr[i], ret);
}
}
else {
ret.push(arr);
}
return ret;
}
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 === n2) {
return true;
}
if (n1 == null || n2 == null) {
return false;
}
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 parseAxisParam(axis, shape) {
var rank = shape.length;
axis = axis == null ? shape.map(function (s, i) { return i; }) : [].concat(axis);
assert(axis.every(function (ax) { return ax >= -rank && ax < rank; }), "All values in axis param must be in range [-" + rank + ", " + rank + ") but " +
("got axis " + axis));
assert(axis.every(function (ax) { return isInt(ax); }), "All values in axis param must be integers but " +
("got axis " + axis));
return axis.map(function (a) { return a < 0 ? rank + a : a; });
}
function squeezeShape(shape, axis) {
var newShape = [];
var keptDims = [];
var axes = axis == null ? null : parseAxisParam(axis, shape).sort();
var j = 0;
for (var i = 0; i < shape.length; ++i) {
if (axes != null) {
if (axes[j] === i && shape[i] !== 1) {
throw new Error("Can't squeeze axis " + i + " since its dim '" + shape[i] + "' is not 1");
}
if ((axes[j] == null || axes[j] > i) && shape[i] === 1) {
newShape.push(shape[i]);
keptDims.push(i);
}
if (axes[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 getArrayFromDType(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 if (dtype === 'string') {
values = new Array(size);
}
else {
throw new Error("Unknown data type " + dtype);
}
return values;
}
function checkComputationForErrors(vals, dtype, name) {
if (dtype !== 'float32') {
return;
}
for (var i = 0; i < vals.length; i++) {
var num = vals[i];
if (isNaN(num) || !isFinite(num)) {
throw Error("The result of the '" + name + "' is " + num + ".");
}
}
}
function checkConversionForErrors(vals, dtype) {
for (var i = 0; i < vals.length; i++) {
var num = vals[i];
if (isNaN(num) || !isFinite(num)) {
throw Error("A tensor of type " + dtype + " being uploaded contains " + num + ".");
}
}
}
function hasEncodingLoss(oldType, newType) {
if (newType === 'complex64') {
return false;
}
if (newType === 'float32' && oldType !== 'complex64') {
return false;
}
if (newType === 'int32' && oldType !== 'float32' && oldType !== 'complex64') {
return false;
}
if (newType === 'bool' && oldType === 'bool') {
return false;
}
return true;
}
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 === 'complex64') {
return 8;
}
else if (dtype === 'bool') {
return 1;
}
else {
throw new Error("Unknown dtype " + dtype);
}
}
function bytesFromStringArray(arr) {
if (arr == null) {
return 0;
}
var bytes = 0;
arr.forEach(function (x) { return bytes += x.length * 2; });
return bytes;
}
function isString(value) {
return typeof value === 'string' || value instanceof String;
}
function isBoolean(value) {
return typeof value === 'boolean';
}
function isNumber(value) {
return typeof value === 'number';
}
function inferDtype(values) {
if (values instanceof Array) {
return inferDtype(values[0]);
}
if (values instanceof Float32Array) {
return 'float32';
}
else if (values instanceof Int32Array || values instanceof Uint8Array) {
return 'int32';
}
else if (isNumber(values)) {
return 'float32';
}
else if (isString(values)) {
return 'string';
}
else if (isBoolean(values)) {
return 'bool';
}
return 'float32';
}
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 (dtype === 'string') {
throw new Error('Cannot convert a string[] to a TypedArray');
}
if (Array.isArray(a)) {
a = flatten(a);
}
if (debugMode) {
checkConversionForErrors(a, dtype);
}
if (noConversionNeeded(a, dtype)) {
return a;
}
if (dtype == null || dtype === 'float32' || dtype === 'complex64') {
return new Float32Array(a);
}
else if (dtype === 'int32') {
return new Int32Array(a);
}
else if (dtype === 'bool') {
var bool = new Uint8Array(a.length);
for (var i = 0; i < bool.length; ++i) {
if (Math.round(a[i]) !== 0) {
bool[i] = 1;
}
}
return bool;
}
else {
throw new Error("Unknown data type " + dtype);
}
}
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' || dtype === 'complex64') {
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('Cannot 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,
nearestLargerEven: nearestLargerEven,
sum: sum,
randUniform: randUniform,
distSquared: distSquared,
assert: assert,
assertShapesMatch: assertShapesMatch,
assertNonNull: assertNonNull,
flatten: flatten,
sizeFromShape: sizeFromShape,
isScalarShape: isScalarShape,
arraysEqual: arraysEqual,
isInt: isInt,
tanh: tanh,
sizeToSquarishShape: sizeToSquarishShape,
createShuffledIndices: createShuffledIndices,
rightPad: rightPad,
repeatedTry: repeatedTry,
inferFromImplicitShape: inferFromImplicitShape,
parseAxisParam: parseAxisParam,
squeezeShape: squeezeShape,
getTypedArrayFromDType: getTypedArrayFromDType,
getArrayFromDType: getArrayFromDType,
checkComputationForErrors: checkComputationForErrors,
checkConversionForErrors: checkConversionForErrors,
hasEncodingLoss: hasEncodingLoss,
isTypedArray: isTypedArray,
bytesPerElement: bytesPerElement,
bytesFromStringArray: bytesFromStringArray,
isString: isString,
isBoolean: isBoolean,
isNumber: isNumber,
inferDtype: inferDtype,
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();
checkComputationForErrors(vals, r.dtype, name);
timer.then(function (timing) {
var extraInfo = '';
if (timing.getExtraProfileInfo != null) {
extraInfo = timing.getExtraProfileInfo();
}
_this.logger.logKernelProfile(name, r, vals, timing.kernelMs, extraInfo);
});
});
return result;
};
return Profiler;
}());
var Logger = (function () {
function Logger() {
}
Logger.prototype.logKernelProfile = function (name, result, vals, timeMs, extraInfo) {
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 + "\t%c" + extraInfo, 'font-weight:bold', 'color:red', 'color:blue', 'color: orange', 'color: green');
};
return Logger;
}());
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, dtype, strides);
var rank = shape.length;
var valsLines = subTensorToString(vals, shape, dtype, 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, dtype, strides) {
var n = sizeFromShape(shape);
var numCols = strides[strides.length - 1];
var padPerCol = new Array(numCols).fill(0);
var rank = shape.length;
var valuesOrTuples = dtype === 'complex64' ? createComplexTuples(vals) : vals;
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(valuesOrTuples[offset + j], 0).length);
}
}
}
return padPerCol;
}
function valToString(val, pad) {
var valStr;
if (Array.isArray(val)) {
valStr = parseFloat(val[0].toFixed(FORMAT_NUM_SIG_DIGITS)) + " + " +
(parseFloat(val[1].toFixed(FORMAT_NUM_SIG_DIGITS)) + "j");
}
else if (isString(val)) {
valStr = "'" + val + "'";
}
else {
valStr = parseFloat(val.toFixed(FORMAT_NUM_SIG_DIGITS)).toString();
}
return rightPad(valStr, pad);
}
function subTensorToString(vals, shape, dtype, strides, padPerCol, isLast) {
if (isLast === void 0) { isLast = true; }
var storagePerElement = dtype === 'complex64' ? 2 : 1;
var size = shape[0];
var rank = shape.length;
if (rank === 0) {
if (dtype === 'complex64') {
var complexTuple = createComplexTuples(vals);
return [valToString(complexTuple[0], 0)];
}
return [vals[0].toString()];
}
if (rank === 1) {
if (size > FORMAT_LIMIT_NUM_VALS) {
var firstValsSize = FORMAT_NUM_FIRST_LAST_VALS * storagePerElement;
var firstVals = Array.from(vals.slice(0, firstValsSize));
var lastVals = Array.from(vals.slice(size - FORMAT_NUM_FIRST_LAST_VALS * storagePerElement, size));
if (dtype === 'complex64') {
firstVals = createComplexTuples(firstVals);
lastVals = createComplexTuples(lastVals);
}
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(', ') +
']'
];
}
var displayVals = dtype === 'complex64' ? createComplexTuples(vals) :
Array.from(vals);
return [
'[' + displayVals.map(function (x, i) { return valToString(x, padPerCol[i]); }).join(', ') +
']'
];
}
var subshape = shape.slice(1);
var substrides = strides.slice(1);
var stride = strides[0] * storagePerElement;
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.slice(start, end), subshape, dtype, 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.slice(start, end), subshape, dtype, 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.slice(start, end), subshape, dtype, 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;
}
function createComplexTuples(vals) {
var complexTuples = [];
for (var i = 0; i < vals.length; i += 2) {
complexTuples.push([vals[i], vals[i + 1]]);
}
return complexTuples;
}
var TensorBuffer = (function () {
function TensorBuffer(shape, dtype, values) {
this.dtype = dtype;
this.shape = shape.slice();
this.size = sizeFromShape(shape);
if (values != null) {
var n = values.length;
assert(n === this.size, "Length of values '" + n + "' does not match the size " +
("inferred by the shape '" + this.size + "'."));
}
if (dtype === 'complex64') {
throw new Error("complex64 dtype TensorBuffers are not supported. Please create " +
"a TensorBuffer for the real and imaginary parts separately and " +
"call tf.complex(real, imag).");
}
this.values =
values || getArrayFromDType(dtype, sizeFromShape(this.shape));
this.strides = computeStrides(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.shape = shape.slice();
this.dtype = dtype || 'float32';
this.size = sizeFromShape(shape);
this.strides = computeStrides(shape);
this.dataId = dataId != null ? dataId : {};
this.id = trackerFn().nextTensorId();
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.as5D = function (rows, columns, depth, depth2, depth3) {
this.throwIfDisposed();
return this.reshape([rows, columns, depth, depth2, depth3]);
};
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');
assert(this.dtype !== 'complex64', 'Tensor.get() is not supported for complex64 tensors yet.');
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();
if (x instanceof Tensor) {
x = [x];
}
return opHandler.concat([this].concat(x), axis);
};
Tensor.prototype.split = function (numOrSizeSplits, axis) {
if (axis === void 0) { axis = 0; }
this.throwIfDisposed();
return opHandler.split(this, numOrSizeSplits, 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.prod = function (axis, keepDims) {
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
this.throwIfDisposed();
return opHandler.prod(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.atan2 = function (x) {
this.throwIfDisposed();
return opHandler.atan2(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.proto