You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

12901 lines
572 KiB

(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.deeplearn = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
},{}],2:[function(require,module,exports){
// A library of seedable RNGs implemented in Javascript.
//
// Usage:
//
// var seedrandom = require('seedrandom');
// var random = seedrandom(1); // or any seed.
// var x = random(); // 0 <= x < 1. Every bit is random.
// var x = random.quick(); // 0 <= x < 1. 32 bits of randomness.
// alea, a 53-bit multiply-with-carry generator by Johannes Baagøe.
// Period: ~2^116
// Reported to pass all BigCrush tests.
var alea = require('./lib/alea');
// xor128, a pure xor-shift generator by George Marsaglia.
// Period: 2^128-1.
// Reported to fail: MatrixRank and LinearComp.
var xor128 = require('./lib/xor128');
// xorwow, George Marsaglia's 160-bit xor-shift combined plus weyl.
// Period: 2^192-2^32
// Reported to fail: CollisionOver, SimpPoker, and LinearComp.
var xorwow = require('./lib/xorwow');
// xorshift7, by François Panneton and Pierre L'ecuyer, takes
// a different approach: it adds robustness by allowing more shifts
// than Marsaglia's original three. It is a 7-shift generator
// with 256 bits, that passes BigCrush with no systmatic failures.
// Period 2^256-1.
// No systematic BigCrush failures reported.
var xorshift7 = require('./lib/xorshift7');
// xor4096, by Richard Brent, is a 4096-bit xor-shift with a
// very long period that also adds a Weyl generator. It also passes
// BigCrush with no systematic failures. Its long period may
// be useful if you have many generators and need to avoid
// collisions.
// Period: 2^4128-2^32.
// No systematic BigCrush failures reported.
var xor4096 = require('./lib/xor4096');
// Tyche-i, by Samuel Neves and Filipe Araujo, is a bit-shifting random
// number generator derived from ChaCha, a modern stream cipher.
// https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf
// Period: ~2^127
// No systematic BigCrush failures reported.
var tychei = require('./lib/tychei');
// The original ARC4-based prng included in this library.
// Period: ~2^1600
var sr = require('./seedrandom');
sr.alea = alea;
sr.xor128 = xor128;
sr.xorwow = xorwow;
sr.xorshift7 = xorshift7;
sr.xor4096 = xor4096;
sr.tychei = tychei;
module.exports = sr;
},{"./lib/alea":3,"./lib/tychei":4,"./lib/xor128":5,"./lib/xor4096":6,"./lib/xorshift7":7,"./lib/xorwow":8,"./seedrandom":9}],3:[function(require,module,exports){
// A port of an algorithm by Johannes Baagøe <baagoe@baagoe.com>, 2010
// http://baagoe.com/en/RandomMusings/javascript/
// https://github.com/nquinlan/better-random-numbers-for-javascript-mirror
// Original work is under MIT license -
// Copyright (C) 2010 by Johannes Baagøe <baagoe@baagoe.org>
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
(function(global, module, define) {
function Alea(seed) {
var me = this, mash = Mash();
me.next = function() {
var t = 2091639 * me.s0 + me.c * 2.3283064365386963e-10; // 2^-32
me.s0 = me.s1;
me.s1 = me.s2;
return me.s2 = t - (me.c = t | 0);
};
// Apply the seeding algorithm from Baagoe.
me.c = 1;
me.s0 = mash(' ');
me.s1 = mash(' ');
me.s2 = mash(' ');
me.s0 -= mash(seed);
if (me.s0 < 0) { me.s0 += 1; }
me.s1 -= mash(seed);
if (me.s1 < 0) { me.s1 += 1; }
me.s2 -= mash(seed);
if (me.s2 < 0) { me.s2 += 1; }
mash = null;
}
function copy(f, t) {
t.c = f.c;
t.s0 = f.s0;
t.s1 = f.s1;
t.s2 = f.s2;
return t;
}
function impl(seed, opts) {
var xg = new Alea(seed),
state = opts && opts.state,
prng = xg.next;
prng.int32 = function() { return (xg.next() * 0x100000000) | 0; }
prng.double = function() {
return prng() + (prng() * 0x200000 | 0) * 1.1102230246251565e-16; // 2^-53
};
prng.quick = prng;
if (state) {
if (typeof(state) == 'object') copy(state, xg);
prng.state = function() { return copy(xg, {}); }
}
return prng;
}
function Mash() {
var n = 0xefc8249d;
var mash = function(data) {
data = data.toString();
for (var i = 0; i < data.length; i++) {
n += data.charCodeAt(i);
var h = 0.02519603282416938 * n;
n = h >>> 0;
h -= n;
h *= n;
n = h >>> 0;
h -= n;
n += h * 0x100000000; // 2^32
}
return (n >>> 0) * 2.3283064365386963e-10; // 2^-32
};
return mash;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.alea = impl;
}
})(
this,
(typeof module) == 'object' && module, // present in node.js
(typeof define) == 'function' && define // present with an AMD loader
);
},{}],4:[function(require,module,exports){
// A Javascript implementaion of the "Tyche-i" prng algorithm by
// Samuel Neves and Filipe Araujo.
// See https://eden.dei.uc.pt/~sneves/pubs/2011-snfa2.pdf
(function(global, module, define) {
function XorGen(seed) {
var me = this, strseed = '';
// Set up generator function.
me.next = function() {
var b = me.b, c = me.c, d = me.d, a = me.a;
b = (b << 25) ^ (b >>> 7) ^ c;
c = (c - d) | 0;
d = (d << 24) ^ (d >>> 8) ^ a;
a = (a - b) | 0;
me.b = b = (b << 20) ^ (b >>> 12) ^ c;
me.c = c = (c - d) | 0;
me.d = (d << 16) ^ (c >>> 16) ^ a;
return me.a = (a - b) | 0;
};
/* The following is non-inverted tyche, which has better internal
* bit diffusion, but which is about 25% slower than tyche-i in JS.
me.next = function() {
var a = me.a, b = me.b, c = me.c, d = me.d;
a = (me.a + me.b | 0) >>> 0;
d = me.d ^ a; d = d << 16 ^ d >>> 16;
c = me.c + d | 0;
b = me.b ^ c; b = b << 12 ^ d >>> 20;
me.a = a = a + b | 0;
d = d ^ a; me.d = d = d << 8 ^ d >>> 24;
me.c = c = c + d | 0;
b = b ^ c;
return me.b = (b << 7 ^ b >>> 25);
}
*/
me.a = 0;
me.b = 0;
me.c = 2654435769 | 0;
me.d = 1367130551;
if (seed === Math.floor(seed)) {
// Integer seed.
me.a = (seed / 0x100000000) | 0;
me.b = seed | 0;
} else {
// String seed.
strseed += seed;
}
// Mix in string seed, then discard an initial batch of 64 values.
for (var k = 0; k < strseed.length + 20; k++) {
me.b ^= strseed.charCodeAt(k) | 0;
me.next();
}
}
function copy(f, t) {
t.a = f.a;
t.b = f.b;
t.c = f.c;
t.d = f.d;
return t;
};
function impl(seed, opts) {
var xg = new XorGen(seed),
state = opts && opts.state,
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
prng.double = function() {
do {
var top = xg.next() >>> 11,
bot = (xg.next() >>> 0) / 0x100000000,
result = (top + bot) / (1 << 21);
} while (result === 0);
return result;
};
prng.int32 = xg.next;
prng.quick = prng;
if (state) {
if (typeof(state) == 'object') copy(state, xg);
prng.state = function() { return copy(xg, {}); }
}
return prng;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.tychei = impl;
}
})(
this,
(typeof module) == 'object' && module, // present in node.js
(typeof define) == 'function' && define // present with an AMD loader
);
},{}],5:[function(require,module,exports){
// A Javascript implementaion of the "xor128" prng algorithm by
// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper
(function(global, module, define) {
function XorGen(seed) {
var me = this, strseed = '';
me.x = 0;
me.y = 0;
me.z = 0;
me.w = 0;
// Set up generator function.
me.next = function() {
var t = me.x ^ (me.x << 11);
me.x = me.y;
me.y = me.z;
me.z = me.w;
return me.w ^= (me.w >>> 19) ^ t ^ (t >>> 8);
};
if (seed === (seed | 0)) {
// Integer seed.
me.x = seed;
} else {
// String seed.
strseed += seed;
}
// Mix in string seed, then discard an initial batch of 64 values.
for (var k = 0; k < strseed.length + 64; k++) {
me.x ^= strseed.charCodeAt(k) | 0;
me.next();
}
}
function copy(f, t) {
t.x = f.x;
t.y = f.y;
t.z = f.z;
t.w = f.w;
return t;
}
function impl(seed, opts) {
var xg = new XorGen(seed),
state = opts && opts.state,
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
prng.double = function() {
do {
var top = xg.next() >>> 11,
bot = (xg.next() >>> 0) / 0x100000000,
result = (top + bot) / (1 << 21);
} while (result === 0);
return result;
};
prng.int32 = xg.next;
prng.quick = prng;
if (state) {
if (typeof(state) == 'object') copy(state, xg);
prng.state = function() { return copy(xg, {}); }
}
return prng;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.xor128 = impl;
}
})(
this,
(typeof module) == 'object' && module, // present in node.js
(typeof define) == 'function' && define // present with an AMD loader
);
},{}],6:[function(require,module,exports){
// A Javascript implementaion of Richard Brent's Xorgens xor4096 algorithm.
//
// This fast non-cryptographic random number generator is designed for
// use in Monte-Carlo algorithms. It combines a long-period xorshift
// generator with a Weyl generator, and it passes all common batteries
// of stasticial tests for randomness while consuming only a few nanoseconds
// for each prng generated. For background on the generator, see Brent's
// paper: "Some long-period random number generators using shifts and xors."
// http://arxiv.org/pdf/1004.3115v1.pdf
//
// Usage:
//
// var xor4096 = require('xor4096');
// random = xor4096(1); // Seed with int32 or string.
// assert.equal(random(), 0.1520436450538547); // (0, 1) range, 53 bits.
// assert.equal(random.int32(), 1806534897); // signed int32, 32 bits.
//
// For nonzero numeric keys, this impelementation provides a sequence
// identical to that by Brent's xorgens 3 implementaion in C. This
// implementation also provides for initalizing the generator with
// string seeds, or for saving and restoring the state of the generator.
//
// On Chrome, this prng benchmarks about 2.1 times slower than
// Javascript's built-in Math.random().
(function(global, module, define) {
function XorGen(seed) {
var me = this;
// Set up generator function.
me.next = function() {
var w = me.w,
X = me.X, i = me.i, t, v;
// Update Weyl generator.
me.w = w = (w + 0x61c88647) | 0;
// Update xor generator.
v = X[(i + 34) & 127];
t = X[i = ((i + 1) & 127)];
v ^= v << 13;
t ^= t << 17;
v ^= v >>> 15;
t ^= t >>> 12;
// Update Xor generator array state.
v = X[i] = v ^ t;
me.i = i;
// Result is the combination.
return (v + (w ^ (w >>> 16))) | 0;
};
function init(me, seed) {
var t, v, i, j, w, X = [], limit = 128;
if (seed === (seed | 0)) {
// Numeric seeds initialize v, which is used to generates X.
v = seed;
seed = null;
} else {
// String seeds are mixed into v and X one character at a time.
seed = seed + '\0';
v = 0;
limit = Math.max(limit, seed.length);
}
// Initialize circular array and weyl value.
for (i = 0, j = -32; j < limit; ++j) {
// Put the unicode characters into the array, and shuffle them.
if (seed) v ^= seed.charCodeAt((j + 32) % seed.length);
// After 32 shuffles, take v as the starting w value.
if (j === 0) w = v;
v ^= v << 10;
v ^= v >>> 15;
v ^= v << 4;
v ^= v >>> 13;
if (j >= 0) {
w = (w + 0x61c88647) | 0; // Weyl.
t = (X[j & 127] ^= (v + w)); // Combine xor and weyl to init array.
i = (0 == t) ? i + 1 : 0; // Count zeroes.
}
}
// We have detected all zeroes; make the key nonzero.
if (i >= 128) {
X[(seed && seed.length || 0) & 127] = -1;
}
// Run the generator 512 times to further mix the state before using it.
// Factoring this as a function slows the main generator, so it is just
// unrolled here. The weyl generator is not advanced while warming up.
i = 127;
for (j = 4 * 128; j > 0; --j) {
v = X[(i + 34) & 127];
t = X[i = ((i + 1) & 127)];
v ^= v << 13;
t ^= t << 17;
v ^= v >>> 15;
t ^= t >>> 12;
X[i] = v ^ t;
}
// Storing state as object members is faster than using closure variables.
me.w = w;
me.X = X;
me.i = i;
}
init(me, seed);
}
function copy(f, t) {
t.i = f.i;
t.w = f.w;
t.X = f.X.slice();
return t;
};
function impl(seed, opts) {
if (seed == null) seed = +(new Date);
var xg = new XorGen(seed),
state = opts && opts.state,
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
prng.double = function() {
do {
var top = xg.next() >>> 11,
bot = (xg.next() >>> 0) / 0x100000000,
result = (top + bot) / (1 << 21);
} while (result === 0);
return result;
};
prng.int32 = xg.next;
prng.quick = prng;
if (state) {
if (state.X) copy(state, xg);
prng.state = function() { return copy(xg, {}); }
}
return prng;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.xor4096 = impl;
}
})(
this, // window object or global
(typeof module) == 'object' && module, // present in node.js
(typeof define) == 'function' && define // present with an AMD loader
);
},{}],7:[function(require,module,exports){
// A Javascript implementaion of the "xorshift7" algorithm by
// François Panneton and Pierre L'ecuyer:
// "On the Xorgshift Random Number Generators"
// http://saluc.engr.uconn.edu/refs/crypto/rng/panneton05onthexorshift.pdf
(function(global, module, define) {
function XorGen(seed) {
var me = this;
// Set up generator function.
me.next = function() {
// Update xor generator.
var X = me.x, i = me.i, t, v, w;
t = X[i]; t ^= (t >>> 7); v = t ^ (t << 24);
t = X[(i + 1) & 7]; v ^= t ^ (t >>> 10);
t = X[(i + 3) & 7]; v ^= t ^ (t >>> 3);
t = X[(i + 4) & 7]; v ^= t ^ (t << 7);
t = X[(i + 7) & 7]; t = t ^ (t << 13); v ^= t ^ (t << 9);
X[i] = v;
me.i = (i + 1) & 7;
return v;
};
function init(me, seed) {
var j, w, X = [];
if (seed === (seed | 0)) {
// Seed state array using a 32-bit integer.
w = X[0] = seed;
} else {
// Seed state using a string.
seed = '' + seed;
for (j = 0; j < seed.length; ++j) {
X[j & 7] = (X[j & 7] << 15) ^
(seed.charCodeAt(j) + X[(j + 1) & 7] << 13);
}
}
// Enforce an array length of 8, not all zeroes.
while (X.length < 8) X.push(0);
for (j = 0; j < 8 && X[j] === 0; ++j);
if (j == 8) w = X[7] = -1; else w = X[j];
me.x = X;
me.i = 0;
// Discard an initial 256 values.
for (j = 256; j > 0; --j) {
me.next();
}
}
init(me, seed);
}
function copy(f, t) {
t.x = f.x.slice();
t.i = f.i;
return t;
}
function impl(seed, opts) {
if (seed == null) seed = +(new Date);
var xg = new XorGen(seed),
state = opts && opts.state,
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
prng.double = function() {
do {
var top = xg.next() >>> 11,
bot = (xg.next() >>> 0) / 0x100000000,
result = (top + bot) / (1 << 21);
} while (result === 0);
return result;
};
prng.int32 = xg.next;
prng.quick = prng;
if (state) {
if (state.x) copy(state, xg);
prng.state = function() { return copy(xg, {}); }
}
return prng;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.xorshift7 = impl;
}
})(
this,
(typeof module) == 'object' && module, // present in node.js
(typeof define) == 'function' && define // present with an AMD loader
);
},{}],8:[function(require,module,exports){
// A Javascript implementaion of the "xorwow" prng algorithm by
// George Marsaglia. See http://www.jstatsoft.org/v08/i14/paper
(function(global, module, define) {
function XorGen(seed) {
var me = this, strseed = '';
// Set up generator function.
me.next = function() {
var t = (me.x ^ (me.x >>> 2));
me.x = me.y; me.y = me.z; me.z = me.w; me.w = me.v;
return (me.d = (me.d + 362437 | 0)) +
(me.v = (me.v ^ (me.v << 4)) ^ (t ^ (t << 1))) | 0;
};
me.x = 0;
me.y = 0;
me.z = 0;
me.w = 0;
me.v = 0;
if (seed === (seed | 0)) {
// Integer seed.
me.x = seed;
} else {
// String seed.
strseed += seed;
}
// Mix in string seed, then discard an initial batch of 64 values.
for (var k = 0; k < strseed.length + 64; k++) {
me.x ^= strseed.charCodeAt(k) | 0;
if (k == strseed.length) {
me.d = me.x << 10 ^ me.x >>> 4;
}
me.next();
}
}
function copy(f, t) {
t.x = f.x;
t.y = f.y;
t.z = f.z;
t.w = f.w;
t.v = f.v;
t.d = f.d;
return t;
}
function impl(seed, opts) {
var xg = new XorGen(seed),
state = opts && opts.state,
prng = function() { return (xg.next() >>> 0) / 0x100000000; };
prng.double = function() {
do {
var top = xg.next() >>> 11,
bot = (xg.next() >>> 0) / 0x100000000,
result = (top + bot) / (1 << 21);
} while (result === 0);
return result;
};
prng.int32 = xg.next;
prng.quick = prng;
if (state) {
if (typeof(state) == 'object') copy(state, xg);
prng.state = function() { return copy(xg, {}); }
}
return prng;
}
if (module && module.exports) {
module.exports = impl;
} else if (define && define.amd) {
define(function() { return impl; });
} else {
this.xorwow = impl;
}
})(
this,
(typeof module) == 'object' && module, // present in node.js
(typeof define) == 'function' && define // present with an AMD loader
);
},{}],9:[function(require,module,exports){
/*
Copyright 2014 David Bau.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
(function (pool, math) {
//
// The following constants are related to IEEE 754 limits.
//
var global = this,
width = 256, // each RC4 output is 0 <= x < 256
chunks = 6, // at least six RC4 outputs for each double
digits = 52, // there are 52 significant digits in a double
rngname = 'random', // rngname: name for Math.random and Math.seedrandom
startdenom = math.pow(width, chunks),
significance = math.pow(2, digits),
overflow = significance * 2,
mask = width - 1,
nodecrypto; // node.js crypto module, initialized at the bottom.
//
// seedrandom()
// This is the seedrandom function described above.
//
function seedrandom(seed, options, callback) {
var key = [];
options = (options == true) ? { entropy: true } : (options || {});
// Flatten the seed string or build one from local entropy if needed.
var shortseed = mixkey(flatten(
options.entropy ? [seed, tostring(pool)] :
(seed == null) ? autoseed() : seed, 3), key);
// Use the seed to initialize an ARC4 generator.
var arc4 = new ARC4(key);
// This function returns a random double in [0, 1) that contains
// randomness in every bit of the mantissa of the IEEE 754 value.
var prng = function() {
var n = arc4.g(chunks), // Start with a numerator n < 2 ^ 48
d = startdenom, // and denominator d = 2 ^ 48.
x = 0; // and no 'extra last byte'.
while (n < significance) { // Fill up all significant digits by
n = (n + x) * width; // shifting numerator and
d *= width; // denominator and generating a
x = arc4.g(1); // new least-significant-byte.
}
while (n >= overflow) { // To avoid rounding up, before adding
n /= 2; // last byte, shift everything
d /= 2; // right using integer math until
x >>>= 1; // we have exactly the desired bits.
}
return (n + x) / d; // Form the number within [0, 1).
};
prng.int32 = function() { return arc4.g(4) | 0; }
prng.quick = function() { return arc4.g(4) / 0x100000000; }
prng.double = prng;
// Mix the randomness into accumulated entropy.
mixkey(tostring(arc4.S), pool);
// Calling convention: what to return as a function of prng, seed, is_math.
return (options.pass || callback ||
function(prng, seed, is_math_call, state) {
if (state) {
// Load the arc4 state from the given state if it has an S array.
if (state.S) { copy(state, arc4); }
// Only provide the .state method if requested via options.state.
prng.state = function() { return copy(arc4, {}); }
}
// If called as a method of Math (Math.seedrandom()), mutate
// Math.random because that is how seedrandom.js has worked since v1.0.
if (is_math_call) { math[rngname] = prng; return seed; }
// Otherwise, it is a newer calling convention, so return the
// prng directly.
else return prng;
})(
prng,
shortseed,
'global' in options ? options.global : (this == math),
options.state);
}
math['seed' + rngname] = seedrandom;
//
// ARC4
//
// An ARC4 implementation. The constructor takes a key in the form of
// an array of at most (width) integers that should be 0 <= x < (width).
//
// The g(count) method returns a pseudorandom integer that concatenates
// the next (count) outputs from ARC4. Its return value is a number x
// that is in the range 0 <= x < (width ^ count).
//
function ARC4(key) {
var t, keylen = key.length,
me = this, i = 0, j = me.i = me.j = 0, s = me.S = [];
// The empty key [] is treated as [0].
if (!keylen) { key = [keylen++]; }
// Set up S using the standard key scheduling algorithm.
while (i < width) {
s[i] = i++;
}
for (i = 0; i < width; i++) {
s[i] = s[j = mask & (j + key[i % keylen] + (t = s[i]))];
s[j] = t;
}
// The "g" method returns the next (count) outputs as one number.
(me.g = function(count) {
// Using instance members instead of closure state nearly doubles speed.
var t, r = 0,
i = me.i, j = me.j, s = me.S;
while (count--) {
t = s[i = mask & (i + 1)];
r = r * width + s[mask & ((s[i] = s[j = mask & (j + t)]) + (s[j] = t))];
}
me.i = i; me.j = j;
return r;
// For robust unpredictability, the function call below automatically
// discards an initial batch of values. This is called RC4-drop[256].
// See http://google.com/search?q=rsa+fluhrer+response&btnI
})(width);
}
//
// copy()
// Copies internal state of ARC4 to or from a plain object.
//
function copy(f, t) {
t.i = f.i;
t.j = f.j;
t.S = f.S.slice();
return t;
};
//
// flatten()
// Converts an object tree to nested arrays of strings.
//
function flatten(obj, depth) {
var result = [], typ = (typeof obj), prop;
if (depth && typ == 'object') {
for (prop in obj) {
try { result.push(flatten(obj[prop], depth - 1)); } catch (e) {}
}
}
return (result.length ? result : typ == 'string' ? obj : obj + '\0');
}
//
// mixkey()
// Mixes a string seed into a key that is an array of integers, and
// returns a shortened string seed that is equivalent to the result key.
//
function mixkey(seed, key) {
var stringseed = seed + '', smear, j = 0;
while (j < stringseed.length) {
key[mask & j] =
mask & ((smear ^= key[mask & j] * 19) + stringseed.charCodeAt(j++));
}
return tostring(key);
}
//
// autoseed()
// Returns an object for autoseeding, using window.crypto and Node crypto
// module if available.
//
function autoseed() {
try {
var out;
if (nodecrypto && (out = nodecrypto.randomBytes)) {
// The use of 'out' to remember randomBytes makes tight minified code.
out = out(width);
} else {
out = new Uint8Array(width);
(global.crypto || global.msCrypto).getRandomValues(out);
}
return tostring(out);
} catch (e) {
var browser = global.navigator,
plugins = browser && browser.plugins;
return [+new Date, global, plugins, global.screen, tostring(pool)];
}
}
//
// tostring()
// Converts an array of charcodes to a string
//
function tostring(a) {
return String.fromCharCode.apply(0, a);
}
//
// When seedrandom.js is loaded, we immediately mix a few bits
// from the built-in RNG into the entropy pool. Because we do
// not want to interfere with deterministic PRNG state later,
// seedrandom will not call math.random on its own again after
// initialization.
//
mixkey(math.random(), pool);
//
// Nodejs and AMD support: export the implementation as a module using
// either convention.
//
if ((typeof module) == 'object' && module.exports) {
module.exports = seedrandom;
// When in node.js, try using crypto package for autoseeding.
try {
nodecrypto = require('crypto');
} catch (ex) {}
} else if ((typeof define) == 'function' && define.amd) {
define(function() { return seedrandom; });
}
// End anonymous scope, and pass initial values.
})(
[], // pool: entropy pool starts empty
Math // math: package containing random, pow, and seedrandom
);
},{"crypto":1}],10:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../math/ndarray");
var MANIFEST_FILE = 'manifest.json';
var CheckpointLoader = (function () {
function CheckpointLoader(urlPath) {
this.urlPath = urlPath;
if (this.urlPath.charAt(this.urlPath.length - 1) !== '/') {
this.urlPath += '/';
}
}
CheckpointLoader.prototype.loadManifest = function () {
var _this = this;
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', _this.urlPath + MANIFEST_FILE);
xhr.onload = function () {
_this.checkpointManifest = JSON.parse(xhr.responseText);
resolve();
};
xhr.onerror = function (error) {
throw new Error(MANIFEST_FILE + " not found at " + _this.urlPath + ". " + error);
};
xhr.send();
});
};
CheckpointLoader.prototype.getCheckpointManifest = function () {
var _this = this;
if (this.checkpointManifest == null) {
return new Promise(function (resolve, reject) {
_this.loadManifest().then(function () {
resolve(_this.checkpointManifest);
});
});
}
return new Promise(function (resolve, reject) {
resolve(_this.checkpointManifest);
});
};
CheckpointLoader.prototype.getAllVariables = function () {
var _this = this;
if (this.variables != null) {
return new Promise(function (resolve, reject) {
resolve(_this.variables);
});
}
return new Promise(function (resolve, reject) {
_this.getCheckpointManifest().then(function (checkpointDefinition) {
var variableNames = Object.keys(_this.checkpointManifest);
var variablePromises = [];
for (var i = 0; i < variableNames.length; i++) {
variablePromises.push(_this.getVariable(variableNames[i]));
}
Promise.all(variablePromises).then(function (variables) {
_this.variables = {};
for (var i = 0; i < variables.length; i++) {
_this.variables[variableNames[i]] = variables[i];
}
resolve(_this.variables);
});
});
});
};
CheckpointLoader.prototype.getVariable = function (varName) {
var _this = this;
if (!(varName in this.checkpointManifest)) {
throw new Error('Cannot load non-existant variable ' + varName);
}
var variableRequestPromiseMethod = function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.responseType = 'arraybuffer';
var fname = _this.checkpointManifest[varName].filename;
xhr.open('GET', _this.urlPath + fname);
xhr.onload = function () {
if (xhr.status === 404) {
throw new Error("Not found variable " + varName);
}
var values = new Float32Array(xhr.response);
var ndarray = ndarray_1.NDArray.make(_this.checkpointManifest[varName].shape, { values: values });
resolve(ndarray);
};
xhr.onerror = function (error) {
throw new Error("Could not fetch variable " + varName + ": " + error);
};
xhr.send();
};
if (this.checkpointManifest == null) {
return new Promise(function (resolve, reject) {
_this.loadManifest().then(function () {
new Promise(variableRequestPromiseMethod).then(resolve);
});
});
}
return new Promise(variableRequestPromiseMethod);
};
return CheckpointLoader;
}());
exports.CheckpointLoader = CheckpointLoader;
},{"../math/ndarray":95}],11:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../math/ndarray");
var util = require("../util");
var STATS_SAMPLE_PERCENTAGE = 0.1;
var InMemoryDataset = (function () {
function InMemoryDataset(dataShapes, math) {
this.dataShapes = dataShapes;
this.math = math;
this.normalizationInfo = {};
}
InMemoryDataset.prototype.getDataShape = function (dataIndex) {
return this.dataShapes[dataIndex];
};
InMemoryDataset.prototype.getData = function () {
return this.dataset;
};
InMemoryDataset.prototype.getStats = function () {
var _this = this;
if (this.dataset == null) {
throw new Error('Data is null.');
}
return this.dataset.map(function (d) { return _this.getStatsForData(d); });
};
InMemoryDataset.prototype.getStatsForData = function (data) {
var inputMin = Number.POSITIVE_INFINITY;
var inputMax = Number.NEGATIVE_INFINITY;
var exampleIndices = data.map(function (example, i) { return i; });
util.shuffle(exampleIndices);
exampleIndices =
exampleIndices.slice(exampleIndices.length * STATS_SAMPLE_PERCENTAGE);
for (var i = 0; i < exampleIndices.length; i++) {
var inputValues = data[exampleIndices[i]].getValues();
for (var j = 0; j < inputValues.length; j++) {
inputMin = Math.min(inputMin, inputValues[j]);
inputMax = Math.max(inputMax, inputValues[j]);
}
}
return {
inputMin: inputMin,
inputMax: inputMax,
exampleCount: data.length,
shape: data[0].shape,
};
};
InMemoryDataset.prototype.normalizeExamplesToRange = function (examples, curLowerBounds, curUpperBounds, newLowerBounds, newUpperBounds) {
var _this = this;
var curBoundsIsPerDimension = (curUpperBounds instanceof Float32Array &&
curLowerBounds instanceof Float32Array);
var newBoundsIsPerDimension = (newLowerBounds instanceof Float32Array &&
newUpperBounds instanceof Float32Array);
var inputSize = util.sizeFromShape(examples[0].shape);
var newExamples = [];
examples.forEach(function (example) {
var inputValues = example.getValues();
var normalizedValues = new Float32Array(inputSize);
for (var j = 0; j < inputSize; j++) {
var curLowerBound = curBoundsIsPerDimension ?
curLowerBounds[j] :
curLowerBounds;
var curUpperBound = curBoundsIsPerDimension ?
curUpperBounds[j] :
curUpperBounds;
var curRange = curUpperBound - curLowerBound;
var newLowerBound = newBoundsIsPerDimension ?
newLowerBounds[j] :
newLowerBounds;
var newUpperBound = newBoundsIsPerDimension ?
newUpperBounds[j] :
newUpperBounds;
var newRange = newUpperBound - newLowerBound;
if (curRange === 0) {
normalizedValues[j] = newLowerBound;
}
else {
normalizedValues[j] = newLowerBound +
newRange * (inputValues[j] - curLowerBound) / curRange;
}
}
newExamples.push(ndarray_1.NDArray.make(example.shape, { values: normalizedValues }, 'float32', _this.math));
});
return newExamples;
};
InMemoryDataset.prototype.computeBounds = function (dataIndex) {
var _this = this;
if (this.dataset == null) {
throw new Error('Data is null.');
}
var size = util.sizeFromShape(this.dataset[dataIndex][0].shape);
this.normalizationInfo[dataIndex] = {
isNormalized: false,
minValues: new Float32Array(size),
maxValues: new Float32Array(size)
};
for (var i = 0; i < size; i++) {
this.normalizationInfo[dataIndex].minValues[i] = Number.POSITIVE_INFINITY;
this.normalizationInfo[dataIndex].maxValues[i] = Number.NEGATIVE_INFINITY;
}
this.dataset[dataIndex].forEach(function (example) {
var inputValues = example.getValues();
for (var k = 0; k < size; k++) {
_this.normalizationInfo[dataIndex].minValues[k] = Math.min(_this.normalizationInfo[dataIndex].minValues[k], inputValues[k]);
_this.normalizationInfo[dataIndex].maxValues[k] = Math.max(_this.normalizationInfo[dataIndex].maxValues[k], inputValues[k]);
}
});
};
InMemoryDataset.prototype.normalizeWithinBounds = function (dataIndex, lowerBound, upperBound) {
if (this.dataset == null) {
throw new Error('Data is null.');
}
if (dataIndex >= this.dataset.length) {
throw new Error('dataIndex out of bounds.');
}
if (this.normalizationInfo[dataIndex] == null) {
this.computeBounds(dataIndex);
}
var curLowerBounds;
var curUpperBounds;
if (this.normalizationInfo[dataIndex].isNormalized) {
curLowerBounds = this.normalizationInfo[dataIndex].lowerBound;
curUpperBounds = this.normalizationInfo[dataIndex].upperBound;
}
else {
curLowerBounds = this.normalizationInfo[dataIndex].minValues;
curUpperBounds = this.normalizationInfo[dataIndex].maxValues;
}
this.dataset[dataIndex] = this.normalizeExamplesToRange(this.dataset[dataIndex], curLowerBounds, curUpperBounds, lowerBound, upperBound);
this.normalizationInfo[dataIndex].isNormalized = true;
this.normalizationInfo[dataIndex].lowerBound = lowerBound;
this.normalizationInfo[dataIndex].upperBound = upperBound;
};
InMemoryDataset.prototype.isNormalized = function (dataIndex) {
return this.normalizationInfo != null &&
this.normalizationInfo[dataIndex].isNormalized;
};
InMemoryDataset.prototype.removeNormalization = function (dataIndex) {
if (this.dataset == null) {
throw new Error('Training or test data is null.');
}
if (!this.isNormalized(dataIndex)) {
return;
}
this.dataset[dataIndex] = this.normalizeExamplesToRange(this.dataset[dataIndex], this.normalizationInfo[dataIndex].lowerBound, this.normalizationInfo[dataIndex].upperBound, this.normalizationInfo[dataIndex].minValues, this.normalizationInfo[dataIndex].maxValues);
this.normalizationInfo[dataIndex].isNormalized = false;
};
InMemoryDataset.prototype.unnormalizeExamples = function (examples, dataIndex) {
if (!this.isNormalized(dataIndex)) {
return examples;
}
return this.normalizeExamplesToRange(examples, this.normalizationInfo[dataIndex].lowerBound, this.normalizationInfo[dataIndex].upperBound, this.normalizationInfo[dataIndex].minValues, this.normalizationInfo[dataIndex].maxValues);
};
InMemoryDataset.prototype.dispose = function () {
if (this.dataset == null) {
return;
}
for (var i = 0; i < this.dataset.length; i++) {
for (var j = 0; j < this.dataset[i].length; j++) {
this.dataset[i][j].dispose();
}
}
this.dataset = [];
};
return InMemoryDataset;
}());
exports.InMemoryDataset = InMemoryDataset;
},{"../math/ndarray":95,"../util":101}],12:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../math/ndarray");
var util = require("../util");
var InMemoryShuffledInputProviderBuilder = (function () {
function InMemoryShuffledInputProviderBuilder(inputs) {
this.inputs = inputs;
this.idx = 0;
this.inputCounter = 0;
this.epoch = 0;
this.shuffledIndices = util.createShuffledIndices(inputs[0].length);
this.numInputs = inputs.length;
var numExamples = this.inputs[0].length;
for (var i = 0; i < this.numInputs; i++) {
util.assert(this.inputs[i].length === numExamples, 'Number of examples must match across different inputs.');
}
for (var i = 0; i < this.numInputs; i++) {
var inputShape = this.inputs[i][0].shape;
for (var j = 0; j < this.inputs[i].length; j++) {
util.assertShapesMatch(inputShape, this.inputs[i][j].shape);
}
}
}
InMemoryShuffledInputProviderBuilder.prototype.getCurrentExampleIndex = function () {
var returnIdx = this.idx;
this.inputCounter++;
if (this.inputCounter >= this.numInputs) {
this.idx++;
this.inputCounter = 0;
if (this.idx >= this.inputs[0].length) {
this.idx = 0;
this.epoch++;
}
}
return returnIdx;
};
InMemoryShuffledInputProviderBuilder.prototype.getNextInput = function (inputId) {
var currentExampleIndex = this.getCurrentExampleIndex();
return this.inputs[inputId][this.shuffledIndices[currentExampleIndex]];
};
InMemoryShuffledInputProviderBuilder.prototype.getEpoch = function () {
return this.epoch;
};
InMemoryShuffledInputProviderBuilder.prototype.getInputProviders = function () {
var inputProviders = [];
for (var i = 0; i < this.numInputs; i++) {
inputProviders.push(this.getInputProvider(i));
}
return inputProviders;
};
return InMemoryShuffledInputProviderBuilder;
}());
exports.InMemoryShuffledInputProviderBuilder = InMemoryShuffledInputProviderBuilder;
var InCPUMemoryShuffledInputProviderBuilder = (function (_super) {
__extends(InCPUMemoryShuffledInputProviderBuilder, _super);
function InCPUMemoryShuffledInputProviderBuilder() {
return _super !== null && _super.apply(this, arguments) || this;
}
InCPUMemoryShuffledInputProviderBuilder.prototype.getInputProvider = function (inputId) {
var shuffledInputProvider = this;
return {
getNextCopy: function (math) {
return ndarray_1.NDArray.like(shuffledInputProvider.getNextInput(inputId));
},
disposeCopy: function (math, copy) {
copy.dispose();
}
};
};
return InCPUMemoryShuffledInputProviderBuilder;
}(InMemoryShuffledInputProviderBuilder));
exports.InCPUMemoryShuffledInputProviderBuilder = InCPUMemoryShuffledInputProviderBuilder;
var InGPUMemoryShuffledInputProviderBuilder = (function (_super) {
__extends(InGPUMemoryShuffledInputProviderBuilder, _super);
function InGPUMemoryShuffledInputProviderBuilder() {
return _super !== null && _super.apply(this, arguments) || this;
}
InGPUMemoryShuffledInputProviderBuilder.prototype.getInputProvider = function (inputId) {
var shuffledInputProvider = this;
return {
getNextCopy: function (math) {
return math.clone(shuffledInputProvider.getNextInput(inputId));
},
disposeCopy: function (math, copy) {
copy.dispose();
}
};
};
return InGPUMemoryShuffledInputProviderBuilder;
}(InMemoryShuffledInputProviderBuilder));
exports.InGPUMemoryShuffledInputProviderBuilder = InGPUMemoryShuffledInputProviderBuilder;
},{"../math/ndarray":95,"../util":101}],13:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var math_1 = require("../math/math");
var ndarray_1 = require("../math/ndarray");
var util = require("../util");
var dataset_1 = require("./dataset");
var PARSING_IMAGE_CANVAS_HEIGHT_PX = 1000;
function getXhrDatasetConfig(jsonConfigPath) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', jsonConfigPath);
xhr.onload = function () {
resolve(JSON.parse(xhr.responseText));
};
xhr.onerror = function (error) {
reject(error);
};
xhr.send();
});
}
exports.getXhrDatasetConfig = getXhrDatasetConfig;
var XhrDataset = (function (_super) {
__extends(XhrDataset, _super);
function XhrDataset(xhrDatasetConfig) {
var _this = this;
var safeMode = false;
_this = _super.call(this, xhrDatasetConfig.data.map(function (x) { return x.shape; }), new math_1.NDArrayMath('cpu', safeMode)) || this;
_this.xhrDatasetConfig = xhrDatasetConfig;
return _this;
}
XhrDataset.prototype.getNDArray = function (info) {
var _this = this;
var dataPromise = info.dataType === 'png' ?
parseTypedArrayFromPng(info, info.shape) :
parseTypedArrayFromBinary(info);
var inputSize = util.sizeFromShape(info.shape);
return dataPromise.then(function (data) {
var ndarrays = [];
for (var i = 0; i < data.length / inputSize; i++) {
var values = data.subarray(i * inputSize, (i + 1) * inputSize);
var ndarray = ndarray_1.NDArray.make(info.shape, { values: new Float32Array(values) }, 'float32', _this.math);
ndarrays.push(ndarray);
}
return ndarrays;
});
};
XhrDataset.prototype.fetchData = function () {
var _this = this;
return new Promise(function (resolve, reject) {
var promises = _this.xhrDatasetConfig.data.map(function (x) { return _this.getNDArray(x); });
Promise.all(promises).then(function (data) {
_this.dataset = data;
resolve();
});
});
};
return XhrDataset;
}(dataset_1.InMemoryDataset));
exports.XhrDataset = XhrDataset;
function parseTypedArrayFromBinary(info) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', info.path);
xhr.responseType = 'arraybuffer';
xhr.onload = function (event) {
var data = (info.dataType === 'float32') ?
new Float32Array(xhr.response) :
new Uint8Array(xhr.response);
resolve(data);
};
xhr.onerror = function (err) { return reject(err); };
xhr.send();
});
}
function parseGrayscaleImageData(data, result, resultOffset) {
var idx = resultOffset;
for (var i = 0; i < data.length; i += 4) {
result[idx++] = data[i];
}
}
function parseRGBImageData(data, result, resultOffset) {
var idx = resultOffset;
for (var i = 0; i < data.length; i += 4) {
result[idx] = data[i];
result[idx + 1] = data[i + 1];
result[idx + 2] = data[i + 2];
idx += 3;
}
}
function parseImage(img, shape) {
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
var N = img.height;
var inputSize = util.sizeFromShape(shape);
var result = new Uint8Array(N * inputSize);
if (img.width !== shape[0] * shape[1]) {
throw new Error("Image width (" + img.width + ") must be multiple of " +
("rows*columns (" + shape[0] + "*" + shape[1] + ") of the ndarray"));
}
canvas.width = img.width;
canvas.height = PARSING_IMAGE_CANVAS_HEIGHT_PX;
var sx = 0;
var sWidth = canvas.width;
var sHeight = canvas.height;
var dx = 0;
var dy = 0;
var dWidth = sWidth;
var dHeight = sHeight;
var depth = shape[2];
var offset = 0;
var numPasses = Math.ceil(N / canvas.height);
for (var pass = 0; pass < numPasses; ++pass) {
var sy = pass * canvas.height;
if ((pass === numPasses - 1) && (N % canvas.height > 0)) {
canvas.height = N % canvas.height;
sHeight = canvas.height;
dHeight = sHeight;
}
ctx.drawImage(img, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;
(depth === 1) ? parseGrayscaleImageData(data, result, offset) :
parseRGBImageData(data, result, offset);
offset += canvas.height * inputSize;
}
return result;
}
function parseTypedArrayFromPng(info, shape) {
return new Promise(function (resolve, reject) {
var img = new Image();
img.setAttribute('crossOrigin', '');
img.onload = function () {
var result = parseImage(img, shape);
img.src = '';
img = null;
resolve(result);
};
img.src = info.path;
});
}
},{"../math/math":94,"../math/ndarray":95,"../util":101,"./dataset":11}],14:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: 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));
}
exports.isMobile = isMobile;
},{}],15:[function(require,module,exports){
(function (global){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var device_util = require("./device_util");
var math_1 = require("./math/math");
var util = require("./util");
var Type;
(function (Type) {
Type[Type["NUMBER"] = 0] = "NUMBER";
Type[Type["BOOLEAN"] = 1] = "BOOLEAN";
})(Type = exports.Type || (exports.Type = {}));
exports.URL_PROPERTIES = [
{ name: 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED', type: Type.BOOLEAN },
{ name: 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE', type: Type.BOOLEAN },
{ name: 'WEBGL_VERSION', type: Type.NUMBER },
{ name: 'WEBGL_FLOAT_TEXTURE_ENABLED', type: Type.BOOLEAN }, {
name: 'WEBGL_GET_BUFFER_SUB_DATA_ASYNC_EXTENSION_ENABLED',
type: Type.BOOLEAN
}
];
function getWebGLRenderingContext(webGLVersion) {
if (webGLVersion === 0) {
throw new Error('Cannot get WebGL rendering context, WebGL is disabled.');
}
var tempCanvas = document.createElement('canvas');
if (webGLVersion === 1) {
return (tempCanvas.getContext('webgl') ||
tempCanvas.getContext('experimental-webgl'));
}
return tempCanvas.getContext('webgl2');
}
function loseContext(gl) {
if (gl != null) {
var loseContextExtension = gl.getExtension('WEBGL_lose_context');
if (loseContextExtension == null) {
throw new Error('Extension WEBGL_lose_context not supported on this browser.');
}
loseContextExtension.loseContext();
}
}
function isWebGLVersionEnabled(webGLVersion) {
var gl = getWebGLRenderingContext(webGLVersion);
if (gl != null) {
loseContext(gl);
return true;
}
return false;
}
function isWebGLDisjointQueryTimerEnabled(webGLVersion) {
var gl = getWebGLRenderingContext(webGLVersion);
var extensionName = webGLVersion === 1 ? 'EXT_disjoint_timer_query' :
'EXT_disjoint_timer_query_webgl2';
var ext = gl.getExtension(extensionName);
var isExtEnabled = ext != null;
if (gl != null) {
loseContext(gl);
}
return isExtEnabled;
}
function isFloatTextureReadPixelsEnabled(webGLVersion) {
if (webGLVersion === 0) {
return false;
}
var gl = getWebGLRenderingContext(webGLVersion);
if (webGLVersion === 1) {
if (gl.getExtension('OES_texture_float') == null) {
return false;
}
}
else {
if (gl.getExtension('EXT_color_buffer_float') == null) {
return false;
}
}
var frameBuffer = gl.createFramebuffer();
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var internalFormat = webGLVersion === 2 ? gl.RGBA32F : gl.RGBA;
gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, gl.RGBA, gl.FLOAT, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
var frameBufferComplete = (gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE);
gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, new Float32Array(4));
var readPixelsNoError = gl.getError() === gl.NO_ERROR;
loseContext(gl);
return frameBufferComplete && readPixelsNoError;
}
function isWebGLGetBufferSubDataAsyncExtensionEnabled(webGLVersion) {
if (webGLVersion !== 2) {
return false;
}
var gl = getWebGLRenderingContext(webGLVersion);
var ext = gl.getExtension('WEBGL_get_buffer_sub_data_async');
var isEnabled = ext != null;
loseContext(gl);
return isEnabled;
}
var Environment = (function () {
function Environment(features) {
this.features = {};
this.globalMath = null;
this.backendRegistry = {};
this.prevBackendRegistry = this.backendRegistry;
if (features != null) {
this.features = features;
}
}
Environment.prototype.get = function (feature) {
if (feature in this.features) {
return this.features[feature];
}
this.features[feature] = this.evaluateFeature(feature);
return this.features[feature];
};
Environment.prototype.getBestBackend = function () {
var orderedBackends = ['webgl', 'cpu'];
for (var i = 0; i < orderedBackends.length; ++i) {
var backendId = orderedBackends[i];
if (backendId in this.backendRegistry) {
return this.backendRegistry[backendId];
}
}
throw new Error('No backend found in registry.');
};
Environment.prototype.evaluateFeature = function (feature) {
if (feature === 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED') {
var webGLVersion = this.get('WEBGL_VERSION');
if (webGLVersion === 0) {
return false;
}
return isWebGLDisjointQueryTimerEnabled(webGLVersion);
}
else if (feature === 'WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE') {
return this.get('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED') &&
!device_util.isMobile();
}
else if (feature === 'WEBGL_VERSION') {
if (isWebGLVersionEnabled(2)) {
return 2;
}
else if (isWebGLVersionEnabled(1)) {
return 1;
}
return 0;
}
else if (feature === 'WEBGL_FLOAT_TEXTURE_ENABLED') {
return isFloatTextureReadPixelsEnabled(this.get('WEBGL_VERSION'));
}
else if (feature === 'WEBGL_GET_BUFFER_SUB_DATA_ASYNC_EXTENSION_ENABLED') {
return isWebGLGetBufferSubDataAsyncExtensionEnabled(this.get('WEBGL_VERSION'));
}
throw new Error("Unknown feature " + feature + ".");
};
Environment.prototype.setFeatures = function (features) {
this.empty();
this.features = features;
};
Environment.prototype.reset = function () {
this.globalMath = null;
this.backendRegistry = this.prevBackendRegistry;
this.features = getFeaturesFromURL();
};
Environment.prototype.setMath = function (math) {
this.globalMath = math;
};
Environment.prototype.getBackend = function (name) {
return this.backendRegistry[name];
};
Environment.prototype.registerBackend = function (name, factory) {
if (name in this.backendRegistry) {
throw new Error(name + " backend was already registered");
}
try {
var backend = factory();
this.backendRegistry[name] = backend;
return true;
}
catch (err) {
return false;
}
};
Object.defineProperty(Environment.prototype, "math", {
get: function () {
if (this.globalMath == null) {
var bestBackend = this.getBestBackend();
var safeMode = false;
this.globalMath = new math_1.NDArrayMath(bestBackend, safeMode);
}
return this.globalMath;
},
enumerable: true,
configurable: true
});
Environment.prototype.empty = function () {
this.globalMath = null;
this.prevBackendRegistry = this.backendRegistry;
this.backendRegistry = {};
this.features = null;
};
return Environment;
}());
exports.Environment = Environment;
var DEEPLEARNJS_FLAGS_PREFIX = 'dljsflags';
function getFeaturesFromURL() {
var features = {};
if (typeof window === 'undefined') {
return features;
}
var urlParams = util.getQueryParams(window.location.search);
if (DEEPLEARNJS_FLAGS_PREFIX in urlParams) {
var urlFlags_1 = {};
var keyValues = urlParams[DEEPLEARNJS_FLAGS_PREFIX].split(',');
keyValues.forEach(function (keyValue) {
var _a = keyValue.split(':'), key = _a[0], value = _a[1];
urlFlags_1[key] = value;
});
exports.URL_PROPERTIES.forEach(function (urlProperty) {
if (urlProperty.name in urlFlags_1) {
console.log("Setting feature override from URL " + urlProperty.name + ": " +
("" + urlFlags_1[urlProperty.name]));
if (urlProperty.type === Type.NUMBER) {
features[urlProperty.name] = +urlFlags_1[urlProperty.name];
}
else if (urlProperty.type === Type.BOOLEAN) {
features[urlProperty.name] = urlFlags_1[urlProperty.name] === 'true';
}
else {
console.warn("Unknown URL param: " + urlProperty.name + ".");
}
}
});
}
return features;
}
function getGlobalNamespace() {
var ns;
if (typeof (window) !== 'undefined') {
ns = window;
}
else if (typeof (global) !== 'undefined') {
ns = global;
}
else {
throw new Error('Could not find a global object');
}
return ns;
}
function getOrMakeEnvironment() {
var ns = getGlobalNamespace();
ns.ENV = ns.ENV || new Environment(getFeaturesFromURL());
return ns.ENV;
}
exports.ENV = getOrMakeEnvironment();
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
},{"./device_util":14,"./math/math":94,"./util":101}],16:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var initializers_1 = require("../initializers");
var concat_util = require("../math/concat_util");
var conv_util = require("../math/conv_util");
var ndarray_1 = require("../math/ndarray");
var util = require("../util");
var GraphLayers = (function () {
function GraphLayers(g) {
this.g = g;
}
GraphLayers.prototype.dense = function (name, x, units, activation, useBias, kernelInitializer, biasInitializer) {
if (activation === void 0) { activation = null; }
if (useBias === void 0) { useBias = true; }
if (kernelInitializer === void 0) { kernelInitializer = new initializers_1.VarianceScalingInitializer(); }
if (biasInitializer === void 0) { biasInitializer = new initializers_1.ZerosInitializer(); }
var weights = this.g.variable(name + '-weights', kernelInitializer.initialize([x.shape[0], units], x.shape[0], units));
var out = this.g.matmul(x, weights);
if (useBias) {
var bias = this.g.variable(name + '-bias', biasInitializer.initialize([units], x.shape[0], units));
out = this.g.add(out, bias);
}
if (activation != null) {
out = activation(out);
}
return out;
};
return GraphLayers;
}());
exports.GraphLayers = GraphLayers;
var Graph = (function () {
function Graph() {
this.nodes = [];
this.layers = new GraphLayers(this);
}
Graph.prototype.variable = function (name, data) {
return this.addNodeAndReturnOutput(new VariableNode(this, name, data));
};
Graph.prototype.placeholder = function (name, shape) {
return this.addNodeAndReturnOutput(new PlaceholderNode(this, name, shape));
};
Graph.prototype.constant = function (value) {
var finalValue;
if (typeof value === 'number') {
finalValue = ndarray_1.Scalar.new(value);
}
else if (value instanceof ndarray_1.NDArray) {
finalValue = value;
}
else if (value instanceof Array) {
var flatValues = util.flatten(value);
var vals = new Float32Array(flatValues);
finalValue = ndarray_1.NDArray.make(util.inferShape(value), { values: vals });
}
else {
throw new Error('unimplemented constant type.');
}
return this.addNodeAndReturnOutput(new ConstantNode(this, finalValue));
};
Graph.prototype.reshape = function (x, shape) {
return this.addNodeAndReturnOutput(new ReshapeNode(this, 'Reshape', x, shape));
};
Graph.prototype.fusedLinearCombination = function (x1, x2, c1, c2) {
return this.addNodeAndReturnOutput(new FusedLinearCombinationNode(this, x1, x2, c1, c2));
};
Graph.prototype.add = function (x1, x2) {
return this.addNodeAndReturnOutput(new AddNode(this, x1, x2));
};
Graph.prototype.subtract = function (x1, x2) {
return this.addNodeAndReturnOutput(new SubtractNode(this, x1, x2));
};
Graph.prototype.multiply = function (x1, x2) {
return this.addNodeAndReturnOutput(new MultiplyNode(this, x1, x2));
};
Graph.prototype.divide = function (x1, x2) {
return this.addNodeAndReturnOutput(new DivideNode(this, x1, x2));
};
Graph.prototype.reduceSum = function (x) {
return this.addNodeAndReturnOutput(new ReduceSumNode(this, x));
};
Graph.prototype.concat3d = function (x1, x2, axis) {
return this.addNodeAndReturnOutput(new Concat3DNode(this, x1, x2, axis));
};
Graph.prototype.matmul = function (x1, x2) {
return this.addNodeAndReturnOutput(new MatMulNode(this, x1, x2));
};
Graph.prototype.conv2d = function (x, w, b, fieldSize, outputDepth, stride, zeroPad) {
if (stride === void 0) { stride = 1; }
return this.addNodeAndReturnOutput(new Convolution2DNode(this, x, w, b, fieldSize, outputDepth, stride, zeroPad));
};
Graph.prototype.maxPool = function (x, fieldSize, stride, zeroPad) {
if (stride === void 0) { stride = 1; }
return this.addNodeAndReturnOutput(new MaxPoolNode(this, x, fieldSize, stride, zeroPad));
};
Graph.prototype.exp = function (x) {
return this.addNodeAndReturnOutput(new ExpNode(this, x));
};
Graph.prototype.log = function (x) {
return this.addNodeAndReturnOutput(new LogNode(this, x));
};
Graph.prototype.relu = function (x) {
return this.addNodeAndReturnOutput(new ReLUNode(this, x));
};
Graph.prototype.leakyRelu = function (x, alpha) {
return this.addNodeAndReturnOutput(new LeakyReLUNode(this, x, alpha));
};
Graph.prototype.prelu = function (x, alpha) {
return this.addNodeAndReturnOutput(new PReLUNode(this, x, alpha));
};
Graph.prototype.elu = function (x) {
return this.addNodeAndReturnOutput(new EluNode(this, x));
};
Graph.prototype.tanh = function (x) {
return this.addNodeAndReturnOutput(new TanHNode(this, x));
};
Graph.prototype.sigmoid = function (x) {
return this.addNodeAndReturnOutput(new SigmoidNode(this, x));
};
Graph.prototype.square = function (x) {
return this.addNodeAndReturnOutput(new SquareNode(this, x));
};
Graph.prototype.softmax = function (x) {
return this.addNodeAndReturnOutput(new SoftmaxNode(this, x));
};
Graph.prototype.softmaxCrossEntropyCost = function (x, target) {
return this.addNodeAndReturnOutput(new SoftmaxCrossEntropyCostNode(this, x, target));
};
Graph.prototype.meanSquaredCost = function (label, prediction) {
return this.addNodeAndReturnOutput(new MeanSquaredCostNode(this, label, prediction));
};
Graph.prototype.argmax = function (x) {
return this.addNodeAndReturnOutput(new ArgMaxNode(this, x));
};
Graph.prototype.argmaxEquals = function (x1, x2) {
return this.addNodeAndReturnOutput(new ArgMaxEqualsNode(this, x1, x2));
};
Graph.prototype.addNodeAndReturnOutput = function (node) {
this.nodes.push(node);
node.validate();
return node.output;
};
Graph.prototype.getNodes = function () {
return this.nodes;
};
return Graph;
}());
exports.Graph = Graph;
var Tensor = (function () {
function Tensor(shape) {
this.shape = shape;
this.id = Tensor.nextID++;
}
Tensor.nextID = 0;
return Tensor;
}());
exports.Tensor = Tensor;
var Node = (function () {
function Node(graph, name, inputs, output) {
this.graph = graph;
this.name = name;
this.inputs = inputs;
this.output = output;
this.id = Node.nextID++;
output.node = this;
}
Node.nextID = 0;
return Node;
}());
exports.Node = Node;
var VariableNode = (function (_super) {
__extends(VariableNode, _super);
function VariableNode(graph, name, data) {
var _this = _super.call(this, graph, name, {}, new Tensor(data.shape)) || this;
_this.data = data;
return _this;
}
VariableNode.prototype.validate = function () {
util.assert(this.data != null, 'Error adding variable op: Data for variable \'' + this.name +
'\' is null or undefined');
};
return VariableNode;
}(Node));
exports.VariableNode = VariableNode;
var PlaceholderNode = (function (_super) {
__extends(PlaceholderNode, _super);
function PlaceholderNode(graph, name, shape) {
return _super.call(this, graph, name, {}, new Tensor(shape)) || this;
}
PlaceholderNode.prototype.validate = function () { };
return PlaceholderNode;
}(Node));
exports.PlaceholderNode = PlaceholderNode;
var ConstantNode = (function (_super) {
__extends(ConstantNode, _super);
function ConstantNode(graph, data) {
var _this = _super.call(this, graph, 'Constant', {}, new Tensor(data.shape)) || this;
_this.data = data;
return _this;
}
ConstantNode.prototype.validate = function () {
util.assert(this.data != null, 'Error adding constant: data for placeholder \'' + this.name +
'\' is null or undefined');
};
return ConstantNode;
}(Node));
exports.ConstantNode = ConstantNode;
var ReshapeNode = (function (_super) {
__extends(ReshapeNode, _super);
function ReshapeNode(graph, name, x, shape) {
var _this = _super.call(this, graph, name, { x: x }, new Tensor(shape)) || this;
_this.name = name;
_this.x = x;
_this.shape = shape;
return _this;
}
ReshapeNode.prototype.validate = function () {
var xSize = util.sizeFromShape(this.x.shape);
var shapeSize = util.sizeFromShape(this.shape);
util.assert(xSize === shapeSize, "Error making reshape operation: input to reshape '" + this.name + "'" +
(" of shape (" + this.x.shape + ") does not match size of ") +
("requested shape " + this.shape + "."));
};
ReshapeNode.X = 'x';
return ReshapeNode;
}(Node));
exports.ReshapeNode = ReshapeNode;
var FusedLinearCombinationNode = (function (_super) {
__extends(FusedLinearCombinationNode, _super);
function FusedLinearCombinationNode(graph, t1, t2, c1, c2) {
var _this = _super.call(this, graph, 'Linear Combination', { t1: t1, t2: t2, c1: c1, c2: c2 }, new Tensor(t1.shape)) || this;
_this.t1 = t1;
_this.t2 = t2;
_this.c1 = c1;
_this.c2 = c2;
return _this;
}
FusedLinearCombinationNode.prototype.validate = function () {
util.assertShapesMatch(this.t1.shape, this.t2.shape);
if (!util.isScalarShape(this.c1.shape)) {
throw new Error('Error adding fusedLinearCombination: c1 is not a scalar, got ' +
("shape: " + this.c1.shape));
}
if (!util.isScalarShape(this.c2.shape)) {
throw new Error('Error adding fusedLinearCombination: c2 is not a scalar, got ' +
("shape: " + this.c2.shape));
}
};
FusedLinearCombinationNode.T1 = 't1';
FusedLinearCombinationNode.T2 = 't2';
FusedLinearCombinationNode.C1 = 'c1';
FusedLinearCombinationNode.C2 = 'c2';
return FusedLinearCombinationNode;
}(Node));
exports.FusedLinearCombinationNode = FusedLinearCombinationNode;
var AddNode = (function (_super) {
__extends(AddNode, _super);
function AddNode(graph, t1, t2) {
var _this = _super.call(this, graph, 'Add', { t1: t1, t2: t2 }, new Tensor(util.sizeFromShape(t1.shape) === 1
? t2.shape
: (t1.shape.length < t2.shape.length ? t2.shape : t1.shape))) || this;
_this.t1 = t1;
_this.t2 = t2;
return _this;
}
AddNode.prototype.validate = function () {
util.assert(util.sizeFromShape(this.t1.shape) === 1 ||
util.sizeFromShape(this.t2.shape) === 1 ||
util.arraysEqual(this.t1.shape, this.t2.shape) ||
(this.t1.shape.length === 2 && this.t2.shape.length === 1 &&
this.t1.shape[1] === this.t2.shape[0]) ||
(this.t1.shape.length === 1 && this.t2.shape.length === 2 &&
this.t1.shape[0] === this.t2.shape[1]), 'Error adding add operation op: one of inputs must be scalar, ' +
("shapes " + this.t1.shape + " and " + this.t2.shape + " must match,") +
'or one of them can be broadcasted (2D and 1D).');
};
AddNode.T1 = 't1';
AddNode.T2 = 't2';
return AddNode;
}(Node));
exports.AddNode = AddNode;
var SubtractNode = (function (_super) {
__extends(SubtractNode, _super);
function SubtractNode(graph, t1, t2) {
var _this = _super.call(this, graph, 'Subtract', { t1: t1, t2: t2 }, new Tensor(util.sizeFromShape(t1.shape) === 1 ? t2.shape : t1.shape)) || this;
_this.t1 = t1;
_this.t2 = t2;
return _this;
}
SubtractNode.prototype.validate = function () {
util.assert(util.sizeFromShape(this.t1.shape) === 1 ||
util.sizeFromShape(this.t2.shape) === 1 ||
util.arraysEqual(this.t1.shape, this.t2.shape), 'Error adding subtract op: one of inputs must be scalar or the ' +
("shapes " + this.t1.shape + " and " + this.t2.shape + " must match."));
};
SubtractNode.T1 = 't1';
SubtractNode.T2 = 't2';
return SubtractNode;
}(Node));
exports.SubtractNode = SubtractNode;
var MultiplyNode = (function (_super) {
__extends(MultiplyNode, _super);
function MultiplyNode(graph, t1, t2) {
var _this = _super.call(this, graph, 'Multiply', { t1: t1, t2: t2 }, new Tensor(util.sizeFromShape(t1.shape) === 1 ? t2.shape : t1.shape)) || this;
_this.t1 = t1;
_this.t2 = t2;
return _this;
}
MultiplyNode.prototype.validate = function () {
util.assert(util.sizeFromShape(this.t1.shape) === 1 ||
util.sizeFromShape(this.t2.shape) === 1 ||
util.arraysEqual(this.t1.shape, this.t2.shape), 'Error adding multiply op: one of inputs must be scalar or the ' +
("shapes " + this.t1.shape + " and " + this.t2.shape + " must match."));
};
MultiplyNode.T1 = 't1';
MultiplyNode.T2 = 't2';
return MultiplyNode;
}(Node));
exports.MultiplyNode = MultiplyNode;
var DivideNode = (function (_super) {
__extends(DivideNode, _super);
function DivideNode(graph, t1, t2) {
var _this = _super.call(this, graph, 'Divide', { t1: t1, t2: t2 }, new Tensor(util.sizeFromShape(t1.shape) === 1 ? t2.shape : t1.shape)) || this;
_this.t1 = t1;
_this.t2 = t2;
return _this;
}
DivideNode.prototype.validate = function () {
util.assert(util.sizeFromShape(this.t1.shape) === 1 ||
util.sizeFromShape(this.t2.shape) === 1 ||
util.arraysEqual(this.t1.shape, this.t2.shape), 'Error adding divide op: one of inputs must be scalar or the ' +
("shapes " + this.t1.shape + " and " + this.t2.shape + " must match."));
};
DivideNode.T1 = 't1';
DivideNode.T2 = 't2';
return DivideNode;
}(Node));
exports.DivideNode = DivideNode;
var ReduceSumNode = (function (_super) {
__extends(ReduceSumNode, _super);
function ReduceSumNode(graph, x) {
return _super.call(this, graph, 'ReduceSum', { x: x }, new Tensor([])) || this;
}
ReduceSumNode.prototype.validate = function () { };
ReduceSumNode.X = 'x';
return ReduceSumNode;
}(Node));
exports.ReduceSumNode = ReduceSumNode;
var Concat3DNode = (function (_super) {
__extends(Concat3DNode, _super);
function Concat3DNode(graph, x1, x2, axis) {
var _this = _super.call(this, graph, 'Concat3D', { x1: x1, x2: x2 }, new Tensor(concat_util.computeOutShape(x1.shape, x2.shape, axis))) || this;
_this.x1 = x1;
_this.x2 = x2;
_this.axis = axis;
return _this;
}
Concat3DNode.prototype.validate = function () {
concat_util.assertParams(this.x1.shape, this.x2.shape, this.axis);
};
Concat3DNode.X1 = 'x1';
Concat3DNode.X2 = 'x2';
Concat3DNode.AXIS = 'axis';
return Concat3DNode;
}(Node));
exports.Concat3DNode = Concat3DNode;
function getMatMulOutputShape(x1Shape, x2Shape) {
if (x1Shape.length === 1 && x2Shape.length === 1) {
return [1];
}
else if (x1Shape.length === 1 && x2Shape.length === 2) {
return [x2Shape[1]];
}
else if (x1Shape.length === 2 && x2Shape.length === 1) {
return [x1Shape[0]];
}
return [x1Shape[0], x2Shape[1]];
}
var MatMulNode = (function (_super) {
__extends(MatMulNode, _super);
function MatMulNode(graph, x1, x2) {
var _this = _super.call(this, graph, 'MatMul', { x1: x1, x2: x2 }, new Tensor(getMatMulOutputShape(x1.shape, x2.shape))) || this;
_this.x1 = x1;
_this.x2 = x2;
return _this;
}
MatMulNode.prototype.validate = function () {
if (this.x1.shape.length === 2 && this.x2.shape.length === 2) {
util.assert(this.x1.shape[1] === this.x2.shape[0], 'Error adding matmul op: inner shapes of matrices with shapes ' +
(this.x1.shape + " and " + this.x2.shape + " must match."));
}
else if (this.x1.shape.length === 2 && this.x2.shape.length === 1) {
util.assert(this.x1.shape[1] === this.x2.shape[0], 'Error adding matmul op: second dimension of matrix with shape ' +
this.x1.shape.toString() +
(" must match size of vector with shape " + this.x2.shape + "."));
}
else if (this.x1.shape.length === 1 && this.x2.shape.length === 2) {
util.assert(this.x1.shape[0] === this.x2.shape[0], "Error adding matmul op: size of vector with shape " + this.x1.shape +
" must match first dimension of matrix with " +
("shape " + this.x2.shape + "."));
}
else {
throw new Error('Error adding matmul op: inputs must be vectors or matrices.');
}
};
MatMulNode.X1 = 'x1';
MatMulNode.X2 = 'x2';
return MatMulNode;
}(Node));
exports.MatMulNode = MatMulNode;
var Convolution2DNode = (function (_super) {
__extends(Convolution2DNode, _super);
function Convolution2DNode(graph, x, w, b, fieldSize, outputDepth, stride, zeroPad) {
if (stride === void 0) { stride = 1; }
var _this = _super.call(this, graph, 'Convolution 2D', { x: x, w: w, b: b }, new Tensor(conv_util.computeOutputShape3D(x.shape, fieldSize, outputDepth, stride, zeroPad))) || this;
_this.x = x;
_this.w = w;
_this.b = b;
_this.fieldSize = fieldSize;
_this.outputDepth = outputDepth;
_this.stride = stride;
_this.zeroPad = zeroPad;
return _this;
}
Convolution2DNode.prototype.validate = function () {
util.assert(this.x.shape.length === 3, 'Error adding conv2d op: input must be of rank 3, but got shape: ' +
(this.x.shape + "."));
util.assert(this.w.shape.length === 4, 'Error adding conv2d op: weights must be of rank 4, but got shape: ' +
(this.w.shape + "."));
util.assert(this.b.shape.length === 1, 'Error adding conv2d op: biases must be of rank 1, but got shape: ' +
(this.b.shape + "."));
util.assert(this.x.shape[2] === this.w.shape[2], "Error adding conv2d op: depth of input (" + this.x.shape[2] + ") " +
("must match input depth for weights (" + this.w.shape[2] + ")."));
};
Convolution2DNode.X = 'x';
Convolution2DNode.W = 'w';
Convolution2DNode.B = 'b';
return Convolution2DNode;
}(Node));
exports.Convolution2DNode = Convolution2DNode;
var MaxPoolNode = (function (_super) {
__extends(MaxPoolNode, _super);
function MaxPoolNode(graph, x, fieldSize, stride, zeroPad) {
if (stride === void 0) { stride = 1; }
var _this = _super.call(this, graph, 'Max pool', { x: x }, new Tensor(conv_util.computeOutputShape3D(x.shape, fieldSize, x.shape[2], stride, zeroPad))) || this;
_this.x = x;
_this.fieldSize = fieldSize;
_this.stride = stride;
_this.zeroPad = zeroPad;
return _this;
}
MaxPoolNode.prototype.validate = function () {
util.assert(this.x.shape.length === 3, 'Error adding maxPool op: input must be of rank 3, but got shape: ' +
(this.x.shape + "."));
};
MaxPoolNode.X = 'x';
return MaxPoolNode;
}(Node));
exports.MaxPoolNode = MaxPoolNode;
var ReLUNode = (function (_super) {
__extends(ReLUNode, _super);
function ReLUNode(graph, x) {
return _super.call(this, graph, 'ReLU', { x: x }, new Tensor(x.shape)) || this;
}
ReLUNode.prototype.validate = function () { };
ReLUNode.X = 'x';
return ReLUNode;
}(Node));
exports.ReLUNode = ReLUNode;
var LeakyReLUNode = (function (_super) {
__extends(LeakyReLUNode, _super);
function LeakyReLUNode(graph, x, alpha) {
var _this = _super.call(this, graph, 'LeakyReLU', { x: x }, new Tensor(x.shape)) || this;
_this.alpha = alpha;
return _this;
}
LeakyReLUNode.prototype.validate = function () { };
LeakyReLUNode.X = 'x';
return LeakyReLUNode;
}(Node));
exports.LeakyReLUNode = LeakyReLUNode;
var PReLUNode = (function (_super) {
__extends(PReLUNode, _super);
function PReLUNode(graph, x, alpha) {
var _this = _super.call(this, graph, 'PReLU', { x: x, alpha: alpha }, new Tensor(x.shape)) || this;
_this.x = x;
_this.alpha = alpha;
return _this;
}
PReLUNode.prototype.validate = function () {
util.assert(util.arraysEqual(this.x.shape, this.alpha.shape), 'Error adding pRelu op: the ' +
("shapes x: " + this.x.shape + " and alpha: " + this.alpha.shape + " must match."));
};
PReLUNode.X = 'x';
PReLUNode.ALPHA = 'alpha';
return PReLUNode;
}(Node));
exports.PReLUNode = PReLUNode;
var EluNode = (function (_super) {
__extends(EluNode, _super);
function EluNode(graph, x) {
return _super.call(this, graph, 'Elu', { x: x }, new Tensor(x.shape)) || this;
}
EluNode.prototype.validate = function () { };
EluNode.X = 'x';
return EluNode;
}(Node));
exports.EluNode = EluNode;
var ExpNode = (function (_super) {
__extends(ExpNode, _super);
function ExpNode(graph, x) {
return _super.call(this, graph, 'Exp', { x: x }, new Tensor(x.shape)) || this;
}
ExpNode.prototype.validate = function () { };
ExpNode.X = 'x';
return ExpNode;
}(Node));
exports.ExpNode = ExpNode;
var LogNode = (function (_super) {
__extends(LogNode, _super);
function LogNode(graph, x) {
return _super.call(this, graph, 'Log', { x: x }, new Tensor(x.shape)) || this;
}
LogNode.prototype.validate = function () { };
LogNode.X = 'x';
return LogNode;
}(Node));
exports.LogNode = LogNode;
var TanHNode = (function (_super) {
__extends(TanHNode, _super);
function TanHNode(graph, x) {
return _super.call(this, graph, 'TanH', { x: x }, new Tensor(x.shape)) || this;
}
TanHNode.prototype.validate = function () { };
TanHNode.X = 'x';
return TanHNode;
}(Node));
exports.TanHNode = TanHNode;
var SigmoidNode = (function (_super) {
__extends(SigmoidNode, _super);
function SigmoidNode(graph, x) {
return _super.call(this, graph, 'Sigmoid', { x: x }, new Tensor(x.shape)) || this;
}
SigmoidNode.prototype.validate = function () { };
SigmoidNode.X = 'x';
return SigmoidNode;
}(Node));
exports.SigmoidNode = SigmoidNode;
var SquareNode = (function (_super) {
__extends(SquareNode, _super);
function SquareNode(graph, x) {
return _super.call(this, graph, 'Square', { x: x }, new Tensor(x.shape)) || this;
}
SquareNode.prototype.validate = function () { };
SquareNode.X = 'x';
return SquareNode;
}(Node));
exports.SquareNode = SquareNode;
var SoftmaxCrossEntropyCostNode = (function (_super) {
__extends(SoftmaxCrossEntropyCostNode, _super);
function SoftmaxCrossEntropyCostNode(graph, x, target) {
var _this = _super.call(this, graph, 'SoftmaxCrossEntropyCost', { x: x, target: target }, new Tensor([])) || this;
_this.x = x;
_this.target = target;
return _this;
}
SoftmaxCrossEntropyCostNode.prototype.validate = function () {
util.assert(util.arraysEqual(this.x.shape, this.target.shape), "Error adding softmaxCrossEntropyCost op: x shape (" + this.x.shape + ") " +
("must match target shape (" + this.target.shape + ")."));
};
SoftmaxCrossEntropyCostNode.X = 'x';
SoftmaxCrossEntropyCostNode.TARGET = 'target';
return SoftmaxCrossEntropyCostNode;
}(Node));
exports.SoftmaxCrossEntropyCostNode = SoftmaxCrossEntropyCostNode;
var SoftmaxNode = (function (_super) {
__extends(SoftmaxNode, _super);
function SoftmaxNode(graph, x) {
var _this = _super.call(this, graph, 'Softmax', { x: x }, new Tensor(x.shape)) || this;
_this.x = x;
return _this;
}
SoftmaxNode.prototype.validate = function () {
util.assert(this.x.shape.length === 1, 'The input to a softmax must be a 1-D tensor');
util.assert(this.x.shape[0] >= 2, 'The input to a softmax must have at least 2 values');
};
SoftmaxNode.X = 'x';
return SoftmaxNode;
}(Node));
exports.SoftmaxNode = SoftmaxNode;
var MeanSquaredCostNode = (function (_super) {
__extends(MeanSquaredCostNode, _super);
function MeanSquaredCostNode(graph, label, prediction) {
var _this = _super.call(this, graph, 'Mean Squared Cost', { label: label, prediction: prediction }, new Tensor([])) || this;
_this.label = label;
_this.prediction = prediction;
return _this;
}
MeanSquaredCostNode.prototype.validate = function () {
util.assert(util.arraysEqual(this.label.shape, this.prediction.shape), "Error adding meanSquaredCost op: label shape (" + this.label.shape + ") " +
("must match prediction shape (" + this.prediction.shape + ")."));
};
MeanSquaredCostNode.LABEL = 'label';
MeanSquaredCostNode.PREDICTION = 'prediction';
return MeanSquaredCostNode;
}(Node));
exports.MeanSquaredCostNode = MeanSquaredCostNode;
var ArgMaxNode = (function (_super) {
__extends(ArgMaxNode, _super);
function ArgMaxNode(graph, x) {
var _this = _super.call(this, graph, 'ArgMax', { x: x }, new Tensor([1])) || this;
_this.x = x;
return _this;
}
ArgMaxNode.prototype.validate = function () {
util.assert(util.sizeFromShape(this.x.shape) > 0, 'Error adding argmax op: input tensor must have at least one entry.');
};
ArgMaxNode.X = 'x';
return ArgMaxNode;
}(Node));
exports.ArgMaxNode = ArgMaxNode;
var ArgMaxEqualsNode = (function (_super) {
__extends(ArgMaxEqualsNode, _super);
function ArgMaxEqualsNode(graph, x1, x2) {
var _this = _super.call(this, graph, 'ArgMaxEquals', { x1: x1, x2: x2 }, new Tensor([1])) || this;
_this.x1 = x1;
_this.x2 = x2;
return _this;
}
ArgMaxEqualsNode.prototype.validate = function () {
util.assert(util.arraysEqual(this.x1.shape, this.x2.shape), "Error adding ArgMaxEquals op: x1 shape (" + this.x1.shape + ") " +
("must match x2 shape (" + this.x2.shape + ")."));
};
ArgMaxEqualsNode.X1 = 'x1';
ArgMaxEqualsNode.X2 = 'x2';
return ArgMaxEqualsNode;
}(Node));
exports.ArgMaxEqualsNode = ArgMaxEqualsNode;
},{"../initializers":52,"../math/concat_util":91,"../math/conv_util":92,"../math/ndarray":95,"../util":101}],17:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var graph_1 = require("./graph");
var priority_queue = require("./priority_queue");
var priority_queue_1 = require("./priority_queue");
function getUnorderedEvaluationSet(nodes, terminatingNodes) {
var terminatingNodeMap = {};
var seen = {};
var set = [];
var visit = nodes.slice();
terminatingNodes.forEach(function (node) { return terminatingNodeMap[node.id] = node; });
var _loop_1 = function () {
var cur = visit.pop();
if (seen[cur.id] == null) {
if (terminatingNodeMap[cur.id] == null) {
Object.keys(cur.inputs)
.map(function (inputName) { return cur.inputs[inputName]; })
.forEach(function (input) { return visit.push(input.node); });
}
set.push(cur);
seen[cur.id] = cur;
}
};
while (visit.length !== 0) {
_loop_1();
}
return set;
}
exports.getUnorderedEvaluationSet = getUnorderedEvaluationSet;
function getOrderedEvaluationSet(unorderedEvaluationSet) {
var set = [];
var nodeIndices = {};
var pendingDependencies = {};
var nodeQueue = new priority_queue_1.PriorityQueue(function (a, b) { return priority_queue.defaultCompare(pendingDependencies[a.id], pendingDependencies[b.id]); }, function (node, newIndex) { return nodeIndices[node.id] = newIndex; });
unorderedEvaluationSet.forEach(function (node) { return pendingDependencies[node.id] = 0; });
unorderedEvaluationSet.forEach(function (node) { return Object.keys(node.inputs)
.map(function (key) { return node.inputs[key]; })
.forEach(function (input) {
if (unorderedEvaluationSet.indexOf(input.node) !== -1) {
pendingDependencies[input.node.id]++;
}
}); });
unorderedEvaluationSet.forEach(function (node) { return nodeQueue.enqueue(node); });
while (!nodeQueue.empty()) {
set.unshift(nodeQueue.dequeue());
Object.keys(set[0].inputs).map(function (key) { return set[0].inputs[key]; }).forEach(function (input) {
if (unorderedEvaluationSet.indexOf(input.node) === -1) {
return;
}
pendingDependencies[input.node.id]--;
nodeQueue.update(input.node, nodeIndices[input.node.id]);
});
}
return set;
}
exports.getOrderedEvaluationSet = getOrderedEvaluationSet;
function isInputNode(node) {
return Object.keys(node.inputs).length === 0;
}
exports.isInputNode = isInputNode;
function shouldBackProp(t) {
return !(t.node instanceof graph_1.ConstantNode);
}
exports.shouldBackProp = shouldBackProp;
function isPassthroughNode(node, map) {
var keys = Object.keys(node.inputs);
for (var i = 0; i < keys.length; i++) {
var input = node.inputs[keys[i]];
if (map.get(input, true) === map.get(node.output, true)) {
return true;
}
}
return false;
}
exports.isPassthroughNode = isPassthroughNode;
},{"./graph":16,"./priority_queue":46}],18:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var graph_1 = require("./graph");
var graph_util = require("./graph_util");
var add_1 = require("./ops/add");
var argmax_1 = require("./ops/argmax");
var argmaxequals_1 = require("./ops/argmaxequals");
var concat3d_1 = require("./ops/concat3d");
var convolution_1 = require("./ops/convolution");
var divide_1 = require("./ops/divide");
var element_wise_activation_1 = require("./ops/element_wise_activation");
var element_wise_cost_1 = require("./ops/element_wise_cost");
var exp_1 = require("./ops/exp");
var linear_combination_1 = require("./ops/linear_combination");
var log_1 = require("./ops/log");
var matmul_1 = require("./ops/matmul");
var max_pool_1 = require("./ops/max_pool");
var multiply_1 = require("./ops/multiply");
var reduce_sum_1 = require("./ops/reduce_sum");
var reshape_1 = require("./ops/reshape");
var softmax_1 = require("./ops/softmax");
var subtract_1 = require("./ops/subtract");
function emitFromGraphNodes(nodes) {
var ops = [];
nodes.forEach(function (node) { return Array.prototype.push.apply(ops, emitOpFromNode(node)); });
return ops;
}
exports.emitFromGraphNodes = emitFromGraphNodes;
function emitOpFromNode(node) {
if (node instanceof graph_1.ReshapeNode) {
return [new reshape_1.Reshape(node.inputs[graph_1.ReshapeNode.X], node.output)];
}
else if (node instanceof graph_1.MatMulNode) {
var x1 = node.inputs[graph_1.MatMulNode.X1];
var x2 = node.inputs[graph_1.MatMulNode.X2];
return [new matmul_1.MatMul(x1, x2, node.output)];
}
else if (node instanceof graph_1.Convolution2DNode) {
var w = node.inputs[graph_1.Convolution2DNode.W];
var x = node.inputs[graph_1.Convolution2DNode.X];
var b = node.inputs[graph_1.Convolution2DNode.B];
return [new convolution_1.Convolution2D(w, x, b, node.output, node.fieldSize, node.outputDepth, node.stride, node.zeroPad)];
}
else if (node instanceof graph_1.MaxPoolNode) {
var x = node.inputs[graph_1.MaxPoolNode.X];
return [new max_pool_1.MaxPool(x, node.output, node.fieldSize, node.stride, node.zeroPad)];
}
else if (node instanceof graph_1.ExpNode) {
return [new exp_1.Exp(node.inputs[graph_1.ExpNode.X], node.output)];
}
else if (node instanceof graph_1.LogNode) {
return [new log_1.Log(node.inputs[graph_1.LogNode.X], node.output)];
}
else if (node instanceof graph_1.ReLUNode) {
return [new element_wise_activation_1.ReLU(node.inputs[graph_1.ReLUNode.X], node.output)];
}
else if (node instanceof graph_1.LeakyReLUNode) {
return [new element_wise_activation_1.LeakyReLU(node.inputs[graph_1.LeakyReLUNode.X], node.output, node.alpha)];
}
else if (node instanceof graph_1.PReLUNode) {
return [new element_wise_activation_1.PReLU(node.inputs[graph_1.PReLUNode.X], node.inputs[graph_1.PReLUNode.ALPHA], node.output)];
}
else if (node instanceof graph_1.EluNode) {
return [new element_wise_activation_1.Elu(node.inputs[graph_1.EluNode.X], node.output)];
}
else if (node instanceof graph_1.TanHNode) {
return [new element_wise_activation_1.TanH(node.inputs[graph_1.TanHNode.X], node.output)];
}
else if (node instanceof graph_1.SigmoidNode) {
return [new element_wise_activation_1.Sigmoid(node.inputs[graph_1.SigmoidNode.X], node.output)];
}
else if (node instanceof graph_1.SoftmaxCrossEntropyCostNode) {
var x = node.inputs[graph_1.SoftmaxCrossEntropyCostNode.X];
var target = node.inputs[graph_1.SoftmaxCrossEntropyCostNode.TARGET];
return [new softmax_1.SoftmaxCrossEntropyCost(x, target, node.output)];
}
else if (node instanceof graph_1.SoftmaxNode) {
return [new softmax_1.Softmax(node.inputs[graph_1.SoftmaxNode.X], node.output)];
}
else if (node instanceof graph_1.MeanSquaredCostNode) {
var label = node.inputs[graph_1.MeanSquaredCostNode.LABEL];
var prediction = node.inputs[graph_1.MeanSquaredCostNode.PREDICTION];
return [new element_wise_cost_1.MeanSquaredCost(label, prediction, node.output)];
}
else if (node instanceof graph_1.ArgMaxEqualsNode) {
return [new argmaxequals_1.ArgMaxEquals(node.inputs[graph_1.ArgMaxEqualsNode.X1], node.inputs[graph_1.ArgMaxEqualsNode.X2], node.output)];
}
else if (node instanceof graph_1.ArgMaxNode) {
return [new argmax_1.ArgMax(node.x, node.output)];
}
else if (node instanceof graph_1.FusedLinearCombinationNode) {
return [new linear_combination_1.LinearCombination(node.inputs[graph_1.FusedLinearCombinationNode.T1], node.inputs[graph_1.FusedLinearCombinationNode.T2], node.inputs[graph_1.FusedLinearCombinationNode.C1], node.inputs[graph_1.FusedLinearCombinationNode.C2], node.output)];
}
else if (node instanceof graph_1.Concat3DNode) {
return [new concat3d_1.Concat3D(node.inputs[graph_1.Concat3DNode.X1], node.inputs[graph_1.Concat3DNode.X2], node.axis, node.output)];
}
else if (node instanceof graph_1.SquareNode) {
return [new element_wise_activation_1.Square(node.inputs[graph_1.SquareNode.X], node.output)];
}
else if (node instanceof graph_1.AddNode) {
return [new add_1.Add(node.inputs[graph_1.AddNode.T1], node.inputs[graph_1.AddNode.T2], node.output)];
}
else if (node instanceof graph_1.SubtractNode) {
return [new subtract_1.Subtract(node.inputs[graph_1.SubtractNode.T1], node.inputs[graph_1.SubtractNode.T2], node.output)];
}
else if (node instanceof graph_1.MultiplyNode) {
return [new multiply_1.Multiply(node.inputs[graph_1.MultiplyNode.T1], node.inputs[graph_1.MultiplyNode.T2], node.output)];
}
else if (node instanceof graph_1.DivideNode) {
return [new divide_1.Divide(node.inputs[graph_1.DivideNode.T1], node.inputs[graph_1.DivideNode.T2], node.output)];
}
else if (node instanceof graph_1.ReduceSumNode) {
return [new reduce_sum_1.ReduceSum(node.inputs[graph_1.ReduceSumNode.X], node.output)];
}
else if (graph_util.isInputNode(node)) {
return [];
}
else {
throw Error("Unsupported node type: " + node.constructor.name);
}
}
},{"./graph":16,"./graph_util":17,"./ops/add":19,"./ops/argmax":20,"./ops/argmaxequals":21,"./ops/concat3d":22,"./ops/convolution":23,"./ops/divide":24,"./ops/element_wise_activation":25,"./ops/element_wise_cost":26,"./ops/exp":27,"./ops/linear_combination":28,"./ops/log":29,"./ops/matmul":30,"./ops/max_pool":31,"./ops/multiply":32,"./ops/reduce_sum":34,"./ops/reshape":35,"./ops/softmax":36,"./ops/subtract":37}],19:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../../util");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var Add = (function (_super) {
__extends(Add, _super);
function Add(x1Tensor, x2Tensor, yTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.yTensor = yTensor;
util.assert(util.sizeFromShape(x1Tensor.shape) === 1 ||
util.sizeFromShape(x2Tensor.shape) === 1 ||
util.arraysEqual(x1Tensor.shape, x2Tensor.shape) ||
(x1Tensor.shape.length === 2 && x2Tensor.shape.length === 1 &&
x1Tensor.shape[1] === x2Tensor.shape[0]) ||
(x1Tensor.shape.length === 1 && x2Tensor.shape.length === 2 &&
x1Tensor.shape[0] === x2Tensor.shape[1]), 'One of t1 or t2 must be a scalar, or t1 and t2 must have ' +
'the same shape, ' +
'or one of them can be broadcasted (2D and 1D).');
return _this;
}
Add.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
var result;
if (util.isScalarShape(x1.shape)) {
result = math.scalarPlusArray(x1, x2);
}
else if (util.isScalarShape(x2.shape)) {
result = math.scalarPlusArray(x2, x1);
}
else {
result = math.add(x1, x2);
}
inferenceArrays.set(_this.yTensor, keep(result));
});
};
Add.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.x1Tensor)) {
if (_this.x1Tensor.shape.length === 1 &&
_this.x2Tensor.shape.length === 2 &&
_this.x1Tensor.shape[0] === _this.x2Tensor.shape[1]) {
var sum = math.sum(dy, 0);
gradientArrays.add(_this.x1Tensor, sum);
}
else if (util.isScalarShape(_this.x1Tensor.shape)) {
var sum = math.sum(dy);
gradientArrays.add(_this.x1Tensor, sum);
}
else {
gradientArrays.add(_this.x1Tensor, math.clone(dy));
}
}
if (graph_util.shouldBackProp(_this.x2Tensor)) {
if (_this.x1Tensor.shape.length === 2 &&
_this.x2Tensor.shape.length === 1 &&
_this.x1Tensor.shape[1] === _this.x2Tensor.shape[0]) {
var sum = math.sum(dy, 0);
gradientArrays.add(_this.x2Tensor, sum);
}
else if (util.isScalarShape(_this.x2Tensor.shape)) {
var sum = math.sum(dy);
gradientArrays.add(_this.x2Tensor, sum);
}
else {
gradientArrays.add(_this.x2Tensor, math.clone(dy));
}
}
});
};
Add.prototype.dispose = function () {
if (this.dySizeScalar != null) {
this.dySizeScalar.dispose();
}
};
return Add;
}(op_1.Operation));
exports.Add = Add;
},{"../../util":101,"../graph_util":17,"./op":33}],20:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var op_1 = require("./op");
var ArgMax = (function (_super) {
__extends(ArgMax, _super);
function ArgMax(xTensor, yTensor) {
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.yTensor = yTensor;
return _this;
}
ArgMax.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.argMax(x)));
});
};
ArgMax.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
throw new Error('ArgMax backprop unimplemented');
};
return ArgMax;
}(op_1.Operation));
exports.ArgMax = ArgMax;
},{"./op":33}],21:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var op_1 = require("./op");
var ArgMaxEquals = (function (_super) {
__extends(ArgMaxEquals, _super);
function ArgMaxEquals(x1Tensor, x2Tensor, yTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.yTensor = yTensor;
return _this;
}
ArgMaxEquals.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.argMaxEquals(x1, x2)));
});
};
ArgMaxEquals.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
throw new Error('ArgMaxEquals backprop unimplemented');
};
return ArgMaxEquals;
}(op_1.Operation));
exports.ArgMaxEquals = ArgMaxEquals;
},{"./op":33}],22:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var concat_util = require("../../math/concat_util");
var op_1 = require("./op");
var Concat3D = (function (_super) {
__extends(Concat3D, _super);
function Concat3D(x1Tensor, x2Tensor, axis, yTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.axis = axis;
_this.yTensor = yTensor;
concat_util.assertParams(x1Tensor.shape, x2Tensor.shape, axis);
return _this;
}
Concat3D.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
var concatResult = math.concat3D(x1, x2, _this.axis);
inferenceArrays.set(_this.yTensor, keep(concatResult));
});
};
Concat3D.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
throw new Error('Concat3D backprop not implemented.');
};
return Concat3D;
}(op_1.Operation));
exports.Concat3D = Concat3D;
},{"../../math/concat_util":91,"./op":33}],23:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var conv_util = require("../../math/conv_util");
var util = require("../../util");
var op_1 = require("./op");
var Convolution2D = (function (_super) {
__extends(Convolution2D, _super);
function Convolution2D(wTensor, xTensor, bTensor, yTensor, fieldSize, outputDepth, stride, zeroPad) {
if (stride === void 0) { stride = 1; }
var _this = _super.call(this) || this;
_this.wTensor = wTensor;
_this.xTensor = xTensor;
_this.bTensor = bTensor;
_this.yTensor = yTensor;
_this.fieldSize = fieldSize;
_this.outputDepth = outputDepth;
_this.stride = stride;
_this.assertWeightsShape(wTensor.shape);
_this.zeroPad = zeroPad != null ?
zeroPad :
conv_util.computeDefaultPad(_this.xTensor.shape, _this.fieldSize, _this.stride);
util.assert(util.isInt(_this.zeroPad), "The zero padding (" + _this.zeroPad + ") must be an integer. Change the " +
"stride and/or zero pad parameters");
return _this;
}
Convolution2D.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var weights = inferenceArrays.get(this.wTensor);
var biases = inferenceArrays.get(this.bTensor);
var x = inferenceArrays.get(this.xTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.conv2d(x, weights, biases, _this.stride, _this.zeroPad)));
});
};
Convolution2D.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var filter = inferenceArrays.get(this.wTensor);
var x = inferenceArrays.get(this.xTensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
var dw = math.conv2dDerFilter(x, dy, filter.shape, _this.stride, _this.zeroPad);
var db = math.conv2dDerBias(dy);
var dx = math.conv2dDerInput(x.shape, dy, filter, _this.stride, _this.zeroPad);
gradientArrays.add(_this.wTensor, dw);
gradientArrays.add(_this.bTensor, db);
gradientArrays.add(_this.xTensor, dx);
});
};
Convolution2D.prototype.assertWeightsShape = function (weightsShape) {
util.assert(weightsShape[0] === this.fieldSize &&
weightsShape[1] === this.fieldSize &&
weightsShape[2] === this.xTensor.shape[2] &&
weightsShape[3] === this.outputDepth, "weights must be of shape [" + this.fieldSize + "," + this.fieldSize + "," +
(this.xTensor.shape[2] + "," + this.outputDepth + "] but they are of") +
("shape [" + weightsShape + "]"));
};
return Convolution2D;
}(op_1.Operation));
exports.Convolution2D = Convolution2D;
},{"../../math/conv_util":92,"../../util":101,"./op":33}],24:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../../util");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var Divide = (function (_super) {
__extends(Divide, _super);
function Divide(x1Tensor, x2Tensor, yTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.yTensor = yTensor;
util.assert(util.sizeFromShape(x1Tensor.shape) === 1 ||
util.sizeFromShape(x2Tensor.shape) === 1 ||
util.arraysEqual(x1Tensor.shape, x2Tensor.shape), 'One of t1 or t2 must be a scalar, or t1 and t2 must have ' +
'the same shape');
return _this;
}
Divide.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var t1 = inferenceArrays.get(this.x1Tensor);
var t2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
var result;
if (util.isScalarShape(t1.shape)) {
result = math.scalarDividedByArray(t1, t2);
}
else if (util.isScalarShape(t2.shape)) {
result = math.arrayDividedByScalar(t1, t2);
}
else {
result = math.divide(t1, t2);
}
inferenceArrays.set(_this.yTensor, keep(result));
});
};
Divide.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
var dy = gradientArrays.get(this.yTensor);
var x1IsScalar = util.isScalarShape(x1.shape);
var x2IsScalar = util.isScalarShape(x2.shape);
math.scope(function () {
if (graph_util.shouldBackProp(_this.x1Tensor)) {
if (x1IsScalar) {
var div = math.divide(dy, x2);
gradientArrays.add(_this.x1Tensor, math.sum(div));
div.dispose();
}
else if (x2IsScalar) {
gradientArrays.add(_this.x1Tensor, math.arrayDividedByScalar(dy, x2));
}
else {
gradientArrays.add(_this.x1Tensor, math.divide(dy, x2));
}
}
if (graph_util.shouldBackProp(_this.x2Tensor)) {
var x2Squared = math.elementWiseMul(x2, x2);
var x1OverX2Squared = void 0;
if (x2IsScalar) {
x1OverX2Squared = math.arrayDividedByScalar(x1, x2Squared);
}
else if (x1IsScalar) {
x1OverX2Squared = math.scalarDividedByArray(x1, x2Squared);
}
else {
x1OverX2Squared = math.divide(x1, x2Squared);
}
var dx2 = math.neg(x1OverX2Squared);
var dyTimesDerivative = math.elementWiseMul(dy, dx2);
if (x2IsScalar) {
gradientArrays.add(_this.x2Tensor, math.sum(dyTimesDerivative));
}
else {
gradientArrays.add(_this.x2Tensor, dyTimesDerivative);
}
}
});
};
return Divide;
}(op_1.Operation));
exports.Divide = Divide;
},{"../../util":101,"../graph_util":17,"./op":33}],25:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var activation_functions_1 = require("../../math/activation_functions");
var op_1 = require("./op");
var ElementWiseActivation = (function (_super) {
__extends(ElementWiseActivation, _super);
function ElementWiseActivation(xTensor, yTensor, func) {
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.yTensor = yTensor;
_this.func = func;
return _this;
}
ElementWiseActivation.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(_this.func.output(math, x)));
});
};
ElementWiseActivation.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
var y = inferenceArrays.get(this.yTensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
var dydx = _this.func.der(math, x, y);
gradientArrays.add(_this.xTensor, math.elementWiseMul(dy, dydx));
dydx.dispose();
});
};
ElementWiseActivation.prototype.dispose = function () {
this.func.dispose();
};
return ElementWiseActivation;
}(op_1.Operation));
exports.ElementWiseActivation = ElementWiseActivation;
var ReLU = (function (_super) {
__extends(ReLU, _super);
function ReLU(xTensor, yTensor) {
return _super.call(this, xTensor, yTensor, new activation_functions_1.ReLUFunc()) || this;
}
return ReLU;
}(ElementWiseActivation));
exports.ReLU = ReLU;
var LeakyReLU = (function (_super) {
__extends(LeakyReLU, _super);
function LeakyReLU(xTensor, yTensor, alpha) {
return _super.call(this, xTensor, yTensor, new activation_functions_1.LeakyReluFunc(alpha)) || this;
}
return LeakyReLU;
}(ElementWiseActivation));
exports.LeakyReLU = LeakyReLU;
var TanH = (function (_super) {
__extends(TanH, _super);
function TanH(xTensor, yTensor) {
return _super.call(this, xTensor, yTensor, new activation_functions_1.TanHFunc()) || this;
}
return TanH;
}(ElementWiseActivation));
exports.TanH = TanH;
var Sigmoid = (function (_super) {
__extends(Sigmoid, _super);
function Sigmoid(xTensor, yTensor) {
return _super.call(this, xTensor, yTensor, new activation_functions_1.SigmoidFunc()) || this;
}
return Sigmoid;
}(ElementWiseActivation));
exports.Sigmoid = Sigmoid;
var Square = (function (_super) {
__extends(Square, _super);
function Square(xTensor, yTensor) {
return _super.call(this, xTensor, yTensor, new activation_functions_1.SquareFunc()) || this;
}
return Square;
}(ElementWiseActivation));
exports.Square = Square;
var Elu = (function (_super) {
__extends(Elu, _super);
function Elu(xTensor, yTensor) {
return _super.call(this, xTensor, yTensor, new activation_functions_1.EluFunc()) || this;
}
return Elu;
}(ElementWiseActivation));
exports.Elu = Elu;
var PReLU = (function (_super) {
__extends(PReLU, _super);
function PReLU(xTensor, alphaTensor, yTensor) {
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.alphaTensor = alphaTensor;
_this.yTensor = yTensor;
return _this;
}
PReLU.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
var alpha = inferenceArrays.get(this.alphaTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.prelu(x, alpha)));
});
};
PReLU.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
var alpha = inferenceArrays.get(this.alphaTensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
var dydx = math.preluDer(x, alpha);
gradientArrays.add(_this.xTensor, math.elementWiseMul(dy, dydx));
});
};
return PReLU;
}(op_1.Operation));
exports.PReLU = PReLU;
},{"../../math/activation_functions":53,"./op":33}],26:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../environment");
var cost_functions_1 = require("../../math/cost_functions");
var ndarray_1 = require("../../math/ndarray");
var util = require("../../util");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var ElementWiseCost = (function (_super) {
__extends(ElementWiseCost, _super);
function ElementWiseCost(x1Tensor, x2Tensor, yTensor, func) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.yTensor = yTensor;
_this.func = func;
_this.oneOverNScalar =
environment_1.ENV.math.keep(ndarray_1.Scalar.new(1 / util.sizeFromShape(x1Tensor.shape)));
return _this;
}
ElementWiseCost.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
var elementWiseCost = _this.func.cost(math, x1, x2);
var sum = math.sum(elementWiseCost);
var result = math.scalarTimesArray(_this.oneOverNScalar, sum);
inferenceArrays.set(_this.yTensor, keep(result));
});
};
ElementWiseCost.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.x1Tensor)) {
gradientArrays.add(_this.x1Tensor, _this.func.der(math, x1, x2));
}
if (graph_util.shouldBackProp(_this.x2Tensor)) {
gradientArrays.add(_this.x2Tensor, _this.func.der(math, x2, x1));
}
});
};
ElementWiseCost.prototype.dispose = function () {
this.func.dispose();
this.oneOverNScalar.dispose();
};
return ElementWiseCost;
}(op_1.Operation));
exports.ElementWiseCost = ElementWiseCost;
var MeanSquaredCost = (function (_super) {
__extends(MeanSquaredCost, _super);
function MeanSquaredCost(x1Tensor, x2Tensor, yTensor) {
return _super.call(this, x1Tensor, x2Tensor, yTensor, new cost_functions_1.SquareCostFunc()) || this;
}
return MeanSquaredCost;
}(ElementWiseCost));
exports.MeanSquaredCost = MeanSquaredCost;
},{"../../environment":15,"../../math/cost_functions":93,"../../math/ndarray":95,"../../util":101,"../graph_util":17,"./op":33}],27:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var graph_util = require("../graph_util");
var op_1 = require("./op");
var Exp = (function (_super) {
__extends(Exp, _super);
function Exp(xTensor, yTensor) {
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.yTensor = yTensor;
return _this;
}
Exp.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.exp(x)));
});
};
Exp.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var y = inferenceArrays.get(this.yTensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.xTensor)) {
gradientArrays.add(_this.xTensor, math.elementWiseMul(y, dy));
}
});
};
return Exp;
}(op_1.Operation));
exports.Exp = Exp;
},{"../graph_util":17,"./op":33}],28:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var graph_util = require("../graph_util");
var op_1 = require("./op");
var LinearCombination = (function (_super) {
__extends(LinearCombination, _super);
function LinearCombination(x1Tensor, x2Tensor, c1Tensor, c2Tensor, outTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.c1Tensor = c1Tensor;
_this.c2Tensor = c2Tensor;
_this.outTensor = outTensor;
return _this;
}
LinearCombination.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
var c1 = inferenceArrays.get(this.c1Tensor).asScalar();
var c2 = inferenceArrays.get(this.c2Tensor).asScalar();
math.scope(function (keep) {
inferenceArrays.set(_this.outTensor, keep(math.scaledArrayAdd(c1, x1, c2, x2)));
});
};
LinearCombination.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
var c1 = inferenceArrays.get(this.c1Tensor);
var c2 = inferenceArrays.get(this.c2Tensor);
var dy = gradientArrays.get(this.outTensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.x1Tensor)) {
gradientArrays.add(_this.x1Tensor, math.scalarTimesArray(c1, dy));
}
if (graph_util.shouldBackProp(_this.x2Tensor)) {
gradientArrays.add(_this.x2Tensor, math.scalarTimesArray(c2, dy));
}
if (graph_util.shouldBackProp(_this.c1Tensor)) {
var dotProduct1 = math.elementWiseMul(x1, dy);
gradientArrays.add(_this.c1Tensor, math.sum(dotProduct1));
}
if (graph_util.shouldBackProp(_this.c2Tensor)) {
var dotProduct2 = math.elementWiseMul(x2, dy);
gradientArrays.add(_this.c2Tensor, math.sum(dotProduct2));
}
});
};
return LinearCombination;
}(op_1.Operation));
exports.LinearCombination = LinearCombination;
},{"../graph_util":17,"./op":33}],29:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var graph_util = require("../graph_util");
var op_1 = require("./op");
var Log = (function (_super) {
__extends(Log, _super);
function Log(xTensor, yTensor) {
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.yTensor = yTensor;
return _this;
}
Log.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.log(x)));
});
};
Log.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.xTensor)) {
gradientArrays.add(_this.xTensor, math.divide(dy, x));
}
});
};
return Log;
}(op_1.Operation));
exports.Log = Log;
},{"../graph_util":17,"./op":33}],30:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var matmul_1 = require("../../math/backends/types/matmul");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var MatMul = (function (_super) {
__extends(MatMul, _super);
function MatMul(x1Tensor, x2Tensor, yTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.yTensor = yTensor;
return _this;
}
MatMul.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
if (x1.shape.length === 2 && x2.shape.length === 2) {
inferenceArrays.set(_this.yTensor, keep(math.matMul(x1, x2)));
}
else if (x1.shape.length === 2 && x2.shape.length === 1) {
inferenceArrays.set(_this.yTensor, keep(math.matrixTimesVector(x1, x2)));
}
else if (x1.shape.length === 1 && x2.shape.length === 2) {
inferenceArrays.set(_this.yTensor, keep(math.vectorTimesMatrix(x1, x2)));
}
});
};
MatMul.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
var dy = gradientArrays.get(this.yTensor);
if (x1.shape.length === 1) {
x1 = x1.reshape([1, x1.size]);
dy = dy.reshape([1, dy.size]);
}
if (x2.shape.length === 1) {
x2 = x2.reshape([x2.size, 1]);
dy = dy.reshape([dy.size, 1]);
}
math.scope(function () {
if (graph_util.shouldBackProp(_this.x1Tensor)) {
var dx1 = math.matMul(dy, x2, matmul_1.MatrixOrientation.REGULAR, matmul_1.MatrixOrientation.TRANSPOSED);
gradientArrays.add(_this.x1Tensor, _this.x1Tensor.shape.length === 1 ? dx1.as1D() : dx1);
}
if (graph_util.shouldBackProp(_this.x2Tensor)) {
var dx2 = math.matMul(x1, dy, matmul_1.MatrixOrientation.TRANSPOSED, matmul_1.MatrixOrientation.REGULAR);
gradientArrays.add(_this.x2Tensor, _this.x2Tensor.shape.length === 1 ? dx2.as1D() : dx2);
}
});
};
return MatMul;
}(op_1.Operation));
exports.MatMul = MatMul;
},{"../../math/backends/types/matmul":61,"../graph_util":17,"./op":33}],31:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var conv_util = require("../../math/conv_util");
var util = require("../../util");
var op_1 = require("./op");
var MaxPool = (function (_super) {
__extends(MaxPool, _super);
function MaxPool(xTensor, yTensor, fieldSize, stride, pad) {
if (stride === void 0) { stride = 1; }
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.yTensor = yTensor;
_this.fieldSize = fieldSize;
_this.stride = stride;
if (pad != null) {
_this.pad = pad;
}
else {
_this.pad = conv_util.computeDefaultPad(xTensor.shape, _this.fieldSize, _this.stride);
}
util.assert(util.isInt(_this.pad), "The zero padding (" + _this.pad + ") must be an integer. Change the " +
"stride and/or zero pad parameters");
return _this;
}
MaxPool.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(math.maxPool(x, _this.fieldSize, _this.stride, _this.pad)));
});
};
MaxPool.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
gradientArrays.add(_this.xTensor, math.maxPoolBackprop(dy, x, _this.fieldSize, _this.stride, _this.pad));
});
};
return MaxPool;
}(op_1.Operation));
exports.MaxPool = MaxPool;
},{"../../math/conv_util":92,"../../util":101,"./op":33}],32:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../../util");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var Multiply = (function (_super) {
__extends(Multiply, _super);
function Multiply(x1Tensor, x2Tensor, yTensor) {
var _this = _super.call(this) || this;
_this.x1Tensor = x1Tensor;
_this.x2Tensor = x2Tensor;
_this.yTensor = yTensor;
util.assert(util.sizeFromShape(x1Tensor.shape) === 1 ||
util.sizeFromShape(x2Tensor.shape) === 1 ||
util.arraysEqual(x1Tensor.shape, x2Tensor.shape), 'One of t1 or t2 must be a scalar, or t1 and t2 must have ' +
'the same shape');
return _this;
}
Multiply.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var t1 = inferenceArrays.get(this.x1Tensor);
var t2 = inferenceArrays.get(this.x2Tensor);
math.scope(function (keep) {
var result;
if (util.isScalarShape(t1.shape)) {
result = math.scalarTimesArray(t1, t2);
}
else if (util.isScalarShape(t2.shape)) {
result = math.scalarTimesArray(t2, t1);
}
else {
result = math.elementWiseMul(t1, t2);
}
inferenceArrays.set(_this.yTensor, keep(result));
});
};
Multiply.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var x1 = inferenceArrays.get(this.x1Tensor);
var x2 = inferenceArrays.get(this.x2Tensor);
var dy = gradientArrays.get(this.yTensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.x1Tensor)) {
if (util.isScalarShape(_this.x1Tensor.shape)) {
var mul = math.elementWiseMul(dy, x2);
gradientArrays.add(_this.x1Tensor, math.sum(mul));
}
else if (util.isScalarShape(x2.shape)) {
gradientArrays.add(_this.x1Tensor, math.scalarTimesArray(x2, dy));
}
else {
gradientArrays.add(_this.x1Tensor, math.elementWiseMul(x2, dy));
}
}
if (graph_util.shouldBackProp(_this.x2Tensor)) {
if (util.isScalarShape(_this.x2Tensor.shape)) {
var mul = math.elementWiseMul(dy, x1);
gradientArrays.add(_this.x2Tensor, math.sum(mul));
}
else if (util.isScalarShape(x1.shape)) {
gradientArrays.add(_this.x2Tensor, math.scalarTimesArray(x1, dy));
}
else {
gradientArrays.add(_this.x2Tensor, math.elementWiseMul(x1, dy));
}
}
});
};
return Multiply;
}(op_1.Operation));
exports.Multiply = Multiply;
},{"../../util":101,"../graph_util":17,"./op":33}],33:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Operation = (function () {
function Operation() {
}
Operation.prototype.disposeTransientArrays = function (inferenceArrays, gradientArrays) { };
Operation.prototype.dispose = function () { };
return Operation;
}());
exports.Operation = Operation;
},{}],34:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../environment");
var ndarray_1 = require("../../math/ndarray");
var util = require("../../util");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var ReduceSum = (function (_super) {
__extends(ReduceSum, _super);
function ReduceSum(x, outTensor) {
var _this = _super.call(this) || this;
_this.x = x;
_this.outTensor = outTensor;
util.assertShapesMatch(outTensor.shape, []);
_this.ones = environment_1.ENV.math.keep(ndarray_1.NDArray.ones(x.shape));
return _this;
}
ReduceSum.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.x);
math.scope(function (keep) {
inferenceArrays.set(_this.outTensor, keep(math.sum(x)));
});
};
ReduceSum.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
if (!graph_util.shouldBackProp(this.x)) {
return;
}
math.scope(function () {
var dy = gradientArrays.get(_this.outTensor);
gradientArrays.add(_this.x, math.scalarTimesArray(dy, _this.ones));
});
};
ReduceSum.prototype.dispose = function () {
this.ones.dispose();
};
return ReduceSum;
}(op_1.Operation));
exports.ReduceSum = ReduceSum;
},{"../../environment":15,"../../math/ndarray":95,"../../util":101,"../graph_util":17,"./op":33}],35:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../../util");
var op_1 = require("./op");
var Reshape = (function (_super) {
__extends(Reshape, _super);
function Reshape(xTensor, yTensor) {
var _this = _super.call(this) || this;
_this.xTensor = xTensor;
_this.yTensor = yTensor;
var xSize = util.sizeFromShape(xTensor.shape);
var ySize = util.sizeFromShape(yTensor.shape);
util.assert(xSize === ySize, "The input size (" + xSize + ") and output size (" + ySize + ") must match");
return _this;
}
Reshape.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var x = inferenceArrays.get(this.xTensor);
var clone = math.clone(x);
math.scope(function (keep) {
inferenceArrays.set(_this.yTensor, keep(clone.reshape(_this.yTensor.shape)));
});
};
Reshape.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var dy = gradientArrays.get(this.yTensor);
var clone = math.clone(dy);
math.scope(function () {
gradientArrays.add(_this.xTensor, clone.reshape(_this.xTensor.shape));
});
};
return Reshape;
}(op_1.Operation));
exports.Reshape = Reshape;
},{"../../util":101,"./op":33}],36:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../environment");
var ndarray_1 = require("../../math/ndarray");
var util = require("../../util");
var graph_1 = require("../graph");
var op_1 = require("./op");
var Softmax = (function (_super) {
__extends(Softmax, _super);
function Softmax(logitsTensor, output) {
var _this = _super.call(this) || this;
_this.logitsTensor = logitsTensor;
_this.output = output;
return _this;
}
Softmax.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var logits = inferenceArrays.get(this.logitsTensor);
return math.scope(function (keep) {
inferenceArrays.set(_this.output, keep(math.softmax(logits)));
});
};
Softmax.prototype.backProp = function () {
throw Error('Softmax backprop is not yet implemented');
};
return Softmax;
}(op_1.Operation));
exports.Softmax = Softmax;
var SoftmaxCrossEntropyCost = (function (_super) {
__extends(SoftmaxCrossEntropyCost, _super);
function SoftmaxCrossEntropyCost(logitsTensor, labelTensor, yTensor) {
var _this = _super.call(this) || this;
_this.logitsTensor = logitsTensor;
_this.labelTensor = labelTensor;
_this.yTensor = yTensor;
_this.softmaxTensor = new graph_1.Tensor(logitsTensor.shape);
_this.epsilon = environment_1.ENV.math.keep(ndarray_1.Scalar.new(1e-5));
return _this;
}
SoftmaxCrossEntropyCost.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var logits = inferenceArrays.get(this.logitsTensor);
var label = inferenceArrays.get(this.labelTensor);
math.scope(function (keep) {
var softmaxResult = math.softmax(logits);
inferenceArrays.set(_this.softmaxTensor, keep(softmaxResult));
inferenceArrays.set(_this.yTensor, keep(crossEntropyCost(math, softmaxResult, label, _this.epsilon)));
});
};
SoftmaxCrossEntropyCost.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var softmax = inferenceArrays.get(this.softmaxTensor);
var label = inferenceArrays.get(this.labelTensor);
math.scope(function () {
gradientArrays.add(_this.logitsTensor, math.subtract(softmax, label));
});
};
SoftmaxCrossEntropyCost.prototype.disposeTransientArrays = function (inferenceArrays, gradientArrays) {
inferenceArrays.disposeArray(this.softmaxTensor);
};
SoftmaxCrossEntropyCost.prototype.dispose = function () {
this.epsilon.dispose();
};
return SoftmaxCrossEntropyCost;
}(op_1.Operation));
exports.SoftmaxCrossEntropyCost = SoftmaxCrossEntropyCost;
function crossEntropyCost(math, y, target, epsilon) {
util.assert(y.size === target.size, 'The output and target must be the same size');
return math.scope(function () {
var yPlusEps = math.scalarPlusArray(epsilon, y);
var logOutput = math.log(yPlusEps);
var tarLogOutput = math.elementWiseMul(target, logOutput);
var costVector = math.neg(tarLogOutput);
return math.sum(costVector);
});
}
exports.crossEntropyCost = crossEntropyCost;
},{"../../environment":15,"../../math/ndarray":95,"../../util":101,"../graph":16,"./op":33}],37:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../../util");
var graph_util = require("../graph_util");
var op_1 = require("./op");
var Subtract = (function (_super) {
__extends(Subtract, _super);
function Subtract(t1, t2, outTensor) {
var _this = _super.call(this) || this;
_this.t1 = t1;
_this.t2 = t2;
_this.outTensor = outTensor;
util.assert(util.sizeFromShape(t1.shape) === 1 ||
util.sizeFromShape(t2.shape) === 1 ||
util.arraysEqual(t1.shape, t2.shape), 'One of t1 or t2 must be a scalar, or t1 and t2 must have ' +
'the same shape');
return _this;
}
Subtract.prototype.feedForward = function (math, inferenceArrays) {
var _this = this;
var t1 = inferenceArrays.get(this.t1);
var t2 = inferenceArrays.get(this.t2);
math.scope(function (keep) {
var result;
if (util.isScalarShape(t1.shape)) {
result = math.scalarMinusArray(t1, t2);
}
else if (util.isScalarShape(t2.shape)) {
result = math.arrayMinusScalar(t1, t2);
}
else {
result = math.subtract(t1, t2);
}
inferenceArrays.set(_this.outTensor, keep(result));
});
};
Subtract.prototype.backProp = function (math, inferenceArrays, gradientArrays) {
var _this = this;
var dy = gradientArrays.get(this.outTensor);
math.scope(function () {
if (graph_util.shouldBackProp(_this.t1)) {
if (util.isScalarShape(_this.t1.shape)) {
var sum = math.sum(dy);
gradientArrays.add(_this.t1, sum);
}
else {
gradientArrays.add(_this.t1, math.clone(dy));
}
}
if (graph_util.shouldBackProp(_this.t2)) {
if (util.isScalarShape(_this.t2.shape)) {
var sum = math.sum(dy);
var negSum = math.neg(sum);
gradientArrays.add(_this.t2, negSum);
}
else {
gradientArrays.add(_this.t2, math.neg(dy));
}
}
});
};
Subtract.prototype.dispose = function () {
if (this.dySizeScalar != null) {
this.dySizeScalar.dispose();
}
};
return Subtract;
}(op_1.Operation));
exports.Subtract = Subtract;
},{"../../util":101,"../graph_util":17,"./op":33}],38:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../../math/ndarray");
var tensor_array_map_1 = require("../tensor_array_map");
var optimizer_1 = require("./optimizer");
var AdadeltaOptimizer = (function (_super) {
__extends(AdadeltaOptimizer, _super);
function AdadeltaOptimizer(learningRate, gamma, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
_this.gamma = gamma;
_this.accumulatedSquaredGradients = new tensor_array_map_1.TensorArrayMap();
_this.accumulatedUpdates = new tensor_array_map_1.TensorArrayMap();
_this.eps = ndarray_1.Scalar.new(1e-6);
_this.g = ndarray_1.Scalar.new(_this.gamma);
return _this;
}
AdadeltaOptimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
_super.prototype.beforeBatch.call(this, math, batchSize, runtime, activationArrayMap, gradientArrayMap);
if (this.accumulatedSquaredGradients.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.accumulatedSquaredGradients.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
_this.accumulatedUpdates.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
};
AdadeltaOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var oldCache = _this.accumulatedSquaredGradients.get(node.output);
var oldUpdates = _this.accumulatedUpdates.get(node.output);
var gradientSquare = math.multiply(gradient, gradient);
var cache = math.scaledArrayAdd(_this.g, oldCache, math.subtract(_this.one, _this.g), gradientSquare);
var updates = math.multiply(math.divide(math.sqrt(math.add(oldUpdates, _this.eps)), math.sqrt(math.add(oldCache, _this.eps))), gradient);
var variable = math.scaledArrayAdd(_this.c, updates, _this.one, oldVariable);
var updateSquare = math.multiply(updates, updates);
var newUpdates = math.scaledArrayAdd(_this.g, oldUpdates, math.subtract(_this.one, _this.g), updateSquare);
_this.accumulatedSquaredGradients.set(node.output, keep(cache));
_this.accumulatedUpdates.set(node.output, keep(newUpdates));
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
oldVariable.dispose();
oldCache.dispose();
oldUpdates.dispose();
});
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
AdadeltaOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this.eps.dispose();
this.g.dispose();
this.accumulatedSquaredGradients.dispose();
this.accumulatedUpdates.dispose();
};
return AdadeltaOptimizer;
}(optimizer_1.Optimizer));
exports.AdadeltaOptimizer = AdadeltaOptimizer;
},{"../../math/ndarray":95,"../tensor_array_map":49,"./optimizer":43}],39:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../../math/ndarray");
var tensor_array_map_1 = require("../tensor_array_map");
var optimizer_1 = require("./optimizer");
var AdagradOptimizer = (function (_super) {
__extends(AdagradOptimizer, _super);
function AdagradOptimizer(learningRate, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
_this.accumulatedSquaredGradients = new tensor_array_map_1.TensorArrayMap();
_this.eps = ndarray_1.Scalar.new(1e-6);
return _this;
}
AdagradOptimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
_super.prototype.beforeBatch.call(this, math, batchSize, runtime, activationArrayMap, gradientArrayMap);
if (this.accumulatedSquaredGradients.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.accumulatedSquaredGradients.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
};
AdagradOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var oldCache = _this.accumulatedSquaredGradients.get(node.output);
var gradientSquare = math.multiply(gradient, gradient);
var cache = math.add(oldCache, gradientSquare);
var variable = math.scaledArrayAdd(_this.c, math.divide(gradient, math.add(math.sqrt(cache), _this.eps)), _this.one, oldVariable);
_this.accumulatedSquaredGradients.set(node.output, keep(cache));
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
oldVariable.dispose();
oldCache.dispose();
});
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
AdagradOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this.eps.dispose();
this.accumulatedSquaredGradients.dispose();
};
return AdagradOptimizer;
}(optimizer_1.Optimizer));
exports.AdagradOptimizer = AdagradOptimizer;
},{"../../math/ndarray":95,"../tensor_array_map":49,"./optimizer":43}],40:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../../math/ndarray");
var tensor_array_map_1 = require("../tensor_array_map");
var optimizer_1 = require("./optimizer");
var AdamOptimizer = (function (_super) {
__extends(AdamOptimizer, _super);
function AdamOptimizer(learningRate, beta1, beta2, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
_this.beta1 = beta1;
_this.beta2 = beta2;
_this.firstMoment = new tensor_array_map_1.TensorArrayMap();
_this.secondMoment = new tensor_array_map_1.TensorArrayMap();
_this.eps = ndarray_1.Scalar.new(1e-8);
_this.b1 = ndarray_1.Scalar.new(_this.beta1);
_this.b2 = ndarray_1.Scalar.new(_this.beta2);
_this.accB1 = ndarray_1.Scalar.new(_this.beta1);
_this.accB2 = ndarray_1.Scalar.new(_this.beta2);
return _this;
}
AdamOptimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
_super.prototype.beforeBatch.call(this, math, batchSize, runtime, activationArrayMap, gradientArrayMap);
if (this.firstMoment.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.firstMoment.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
if (this.secondMoment.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.secondMoment.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
};
AdamOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var oldFirstMoment = _this.firstMoment.get(node.output);
var oldSecondMoment = _this.secondMoment.get(node.output);
var newFirstMoment = math.scaledArrayAdd(_this.b1, oldFirstMoment, math.subtract(_this.one, _this.b1), gradient);
var gradientSquare = math.multiply(gradient, gradient);
var newSecondMoment = math.scaledArrayAdd(_this.b2, oldSecondMoment, math.subtract(_this.one, _this.b2), gradientSquare);
var biasCorrectedFirstMoment = math.divide(newFirstMoment, math.subtract(_this.one, _this.accB1));
var biasCorrectedSecondMoment = math.divide(newSecondMoment, math.subtract(_this.one, _this.accB2));
var variable = math.scaledArrayAdd(_this.c, math.divide(biasCorrectedFirstMoment, math.add(math.sqrt(biasCorrectedSecondMoment), _this.eps)), _this.one, oldVariable);
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
_this.firstMoment.set(node.output, keep(newFirstMoment));
_this.secondMoment.set(node.output, keep(newSecondMoment));
oldVariable.dispose();
gradient.dispose();
oldFirstMoment.dispose();
oldSecondMoment.dispose();
});
var oldAccB1 = _this.accB1;
var oldAccB2 = _this.accB2;
_this.accB1 = keep(math.multiply(_this.accB1, _this.b1));
_this.accB2 = keep(math.multiply(_this.accB2, _this.b2));
oldAccB1.dispose();
oldAccB2.dispose();
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
AdamOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this.firstMoment.dispose();
this.secondMoment.dispose();
this.eps.dispose();
this.b1.dispose();
this.b2.dispose();
this.accB1.dispose();
this.accB2.dispose();
};
return AdamOptimizer;
}(optimizer_1.Optimizer));
exports.AdamOptimizer = AdamOptimizer;
},{"../../math/ndarray":95,"../tensor_array_map":49,"./optimizer":43}],41:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../../math/ndarray");
var tensor_array_map_1 = require("../tensor_array_map");
var optimizer_1 = require("./optimizer");
var AdamaxOptimizer = (function (_super) {
__extends(AdamaxOptimizer, _super);
function AdamaxOptimizer(learningRate, beta1, beta2, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
_this.beta1 = beta1;
_this.beta2 = beta2;
_this.firstMoment = new tensor_array_map_1.TensorArrayMap();
_this.weightedInfNorm = new tensor_array_map_1.TensorArrayMap();
_this.eps = ndarray_1.Scalar.new(1e-8);
_this.b1 = ndarray_1.Scalar.new(_this.beta1);
_this.b2 = ndarray_1.Scalar.new(_this.beta2);
_this.accB1 = ndarray_1.Scalar.new(_this.beta1);
return _this;
}
AdamaxOptimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
_super.prototype.beforeBatch.call(this, math, batchSize, runtime, activationArrayMap, gradientArrayMap);
if (this.firstMoment.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.firstMoment.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
if (this.weightedInfNorm.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.weightedInfNorm.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
};
AdamaxOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var oldFirstMoment = _this.firstMoment.get(node.output);
var oldWeightedInfNorm = _this.weightedInfNorm.get(node.output);
var newFirstMoment = math.scaledArrayAdd(_this.b1, oldFirstMoment, math.subtract(_this.one, _this.b1), gradient);
var ut0 = math.multiply(_this.b2, oldWeightedInfNorm);
var ut1 = math.abs(gradient);
var newWeightedInfNorm = math.add(math.relu(math.subtract(ut0, ut1)), ut1);
var variable = math.scaledArrayAdd(_this.one, oldVariable, math.divide(_this.c, math.subtract(_this.one, _this.accB1)), math.divide(newFirstMoment, math.add(_this.eps, newWeightedInfNorm)));
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
_this.firstMoment.set(node.output, keep(newFirstMoment));
_this.weightedInfNorm.set(node.output, keep(newWeightedInfNorm));
oldVariable.dispose();
gradient.dispose();
oldFirstMoment.dispose();
oldWeightedInfNorm.dispose();
});
var oldAccB1 = _this.accB1;
_this.accB1 = keep(math.multiply(_this.accB1, _this.b1));
oldAccB1.dispose();
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
AdamaxOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this.firstMoment.dispose();
this.weightedInfNorm.dispose();
this.eps.dispose();
this.accB1.dispose();
this.b1.dispose();
this.b2.dispose();
};
return AdamaxOptimizer;
}(optimizer_1.Optimizer));
exports.AdamaxOptimizer = AdamaxOptimizer;
},{"../../math/ndarray":95,"../tensor_array_map":49,"./optimizer":43}],42:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../../math/ndarray");
var tensor_array_map_1 = require("../tensor_array_map");
var sgd_optimizer_1 = require("./sgd_optimizer");
var MomentumOptimizer = (function (_super) {
__extends(MomentumOptimizer, _super);
function MomentumOptimizer(learningRate, momentum, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
_this.momentum = momentum;
_this.variableVelocities = new tensor_array_map_1.TensorArrayMap();
_this.m = ndarray_1.Scalar.new(_this.momentum);
return _this;
}
MomentumOptimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
_super.prototype.beforeBatch.call(this, math, batchSize, runtime, activationArrayMap, gradientArrayMap);
if (this.variableVelocities.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.variableVelocities.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
};
MomentumOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var oldVelocity = _this.variableVelocities.get(node.output);
var velocity = math.scaledArrayAdd(_this.m, oldVelocity, _this.one, gradient);
var variable = math.scaledArrayAdd(_this.c, velocity, _this.one, oldVariable);
_this.variableVelocities.set(node.output, keep(velocity));
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
oldVariable.dispose();
oldVelocity.dispose();
});
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
MomentumOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this.m.dispose();
this.variableVelocities.dispose();
};
MomentumOptimizer.prototype.setMomentum = function (momentum) {
this.momentum = momentum;
};
return MomentumOptimizer;
}(sgd_optimizer_1.SGDOptimizer));
exports.MomentumOptimizer = MomentumOptimizer;
},{"../../math/ndarray":95,"../tensor_array_map":49,"./sgd_optimizer":45}],43:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../environment");
var ndarray_1 = require("../../math/ndarray");
var session_util = require("../session_util");
var tensor_array_map_1 = require("../tensor_array_map");
var Optimizer = (function () {
function Optimizer(learningRate, specifiedVariableList) {
this.learningRate = learningRate;
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
if (specifiedVariableList != null) {
this.specifiedVariableNodes = specifiedVariableList;
}
this.one = environment_1.ENV.math.keep(ndarray_1.Scalar.new(1));
}
Optimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
this.variableNodes = this.specifiedVariableNodes == null ?
session_util.getVariableNodesFromEvaluationSet(runtime.nodes) :
this.specifiedVariableNodes;
if (batchSize !== this.prevBatchSize) {
if (this.c != null) {
this.c.dispose();
}
this.prevBatchSize = batchSize;
this.c = math.keep(ndarray_1.Scalar.new(-this.learningRate / batchSize));
}
this.variableNodes.forEach(function (node) { return _this.variableGradients.set(node.output, math.keep(ndarray_1.NDArray.zeros(node.output.shape))); });
};
Optimizer.prototype.afterExample = function (math, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var gradient = gradientArrayMap.get(node.output);
var accumulatedGradient = _this.variableGradients.get(node.output);
_this.variableGradients.set(node.output, keep(math.add(gradient, accumulatedGradient)));
accumulatedGradient.dispose();
});
});
};
Optimizer.prototype.dispose = function () {
if (this.c != null) {
this.c.dispose();
}
this.one.dispose();
this.variableNodes.forEach(function (node) {
node.data.dispose();
});
this.specifiedVariableNodes.forEach(function (node) {
node.data.dispose();
});
};
return Optimizer;
}());
exports.Optimizer = Optimizer;
},{"../../environment":15,"../../math/ndarray":95,"../session_util":48,"../tensor_array_map":49}],44:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../../math/ndarray");
var tensor_array_map_1 = require("../tensor_array_map");
var optimizer_1 = require("./optimizer");
var RMSPropOptimizer = (function (_super) {
__extends(RMSPropOptimizer, _super);
function RMSPropOptimizer(learningRate, gamma, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
_this.gamma = gamma;
_this.accumulatedSquaredGradients = new tensor_array_map_1.TensorArrayMap();
_this.eps = ndarray_1.Scalar.new(1e-6);
_this.g = ndarray_1.Scalar.new(_this.gamma);
return _this;
}
RMSPropOptimizer.prototype.beforeBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
_super.prototype.beforeBatch.call(this, math, batchSize, runtime, activationArrayMap, gradientArrayMap);
if (this.accumulatedSquaredGradients.size() === 0) {
this.variableNodes.forEach(function (node) {
_this.accumulatedSquaredGradients.set(node.output, ndarray_1.NDArray.zeros(node.output.shape));
});
}
};
RMSPropOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var oldCache = _this.accumulatedSquaredGradients.get(node.output);
var gradientSquare = math.multiply(gradient, gradient);
var cache = math.scaledArrayAdd(_this.g, oldCache, math.subtract(_this.one, _this.g), gradientSquare);
var variable = math.scaledArrayAdd(_this.c, math.divide(gradient, math.add(math.sqrt(cache), _this.eps)), _this.one, oldVariable);
_this.accumulatedSquaredGradients.set(node.output, keep(cache));
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
oldVariable.dispose();
oldCache.dispose();
});
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
RMSPropOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
this.eps.dispose();
this.g.dispose();
this.accumulatedSquaredGradients.dispose();
};
return RMSPropOptimizer;
}(optimizer_1.Optimizer));
exports.RMSPropOptimizer = RMSPropOptimizer;
},{"../../math/ndarray":95,"../tensor_array_map":49,"./optimizer":43}],45:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var tensor_array_map_1 = require("../tensor_array_map");
var optimizer_1 = require("./optimizer");
var SGDOptimizer = (function (_super) {
__extends(SGDOptimizer, _super);
function SGDOptimizer(learningRate, specifiedVariableList) {
var _this = _super.call(this, learningRate, specifiedVariableList) || this;
_this.learningRate = learningRate;
return _this;
}
SGDOptimizer.prototype.afterBatch = function (math, batchSize, runtime, activationArrayMap, gradientArrayMap) {
var _this = this;
math.scope(function (keep) {
_this.variableNodes.forEach(function (node) {
var oldVariable = activationArrayMap.get(node.output);
var gradient = _this.variableGradients.get(node.output);
var variable = math.scaledArrayAdd(_this.c, gradient, _this.one, oldVariable);
activationArrayMap.set(node.output, keep(variable));
node.data = variable;
oldVariable.dispose();
});
});
this.variableGradients.dispose();
this.variableGradients = new tensor_array_map_1.TensorArrayMap();
};
SGDOptimizer.prototype.dispose = function () {
_super.prototype.dispose.call(this);
};
SGDOptimizer.prototype.setLearningRate = function (learningRate) {
this.learningRate = learningRate;
};
return SGDOptimizer;
}(optimizer_1.Optimizer));
exports.SGDOptimizer = SGDOptimizer;
},{"../tensor_array_map":49,"./optimizer":43}],46:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function defaultCompare(a, b) {
if (a === b) {
return 0;
}
else if (a < b) {
return -1;
}
else {
return 1;
}
}
exports.defaultCompare = defaultCompare;
var PriorityQueue = (function () {
function PriorityQueue(comparator, indexObserver) {
this.comparator = comparator;
this.indexObserver = indexObserver;
this.heap = [];
}
PriorityQueue.prototype.enqueue = function (t) {
this.heap.push(t);
this.onIndexChanged(t, this.heap.length - 1);
this.siftUp(this.heap.length - 1);
};
PriorityQueue.prototype.dequeue = function () {
if (this.empty()) {
throw new Error('dequeue called on empty priority queue.');
}
var t = this.heap[0];
this.swap(0, this.heap.length - 1);
this.heap.pop();
this.siftDown(0);
return t;
};
PriorityQueue.prototype.update = function (newT, index) {
var last = (index === this.heap.length - 1);
if (!last) {
this.swap(index, this.heap.length - 1);
}
this.heap.pop();
if (!last) {
if (this.siftUpIndex(index) !== -1) {
this.siftUp(index);
}
else if (this.siftDownIndex(index) !== -1) {
this.siftDown(index);
}
}
this.enqueue(newT);
};
PriorityQueue.prototype.empty = function () {
return this.heap.length === 0;
};
PriorityQueue.prototype.onIndexChanged = function (t, newIndex) {
if (this.indexObserver) {
this.indexObserver(t, newIndex);
}
};
PriorityQueue.prototype.getParentIndex = function (index) {
if (index === 0) {
return -1;
}
return Math.floor((index - 1) / 2);
};
PriorityQueue.prototype.getLeftChildIndex = function (index) {
var candidate = index * 2 + 1;
return candidate < this.heap.length ? candidate : -1;
};
PriorityQueue.prototype.getRightChildIndex = function (index) {
var candidate = index * 2 + 2;
return candidate < this.heap.length ? candidate : -1;
};
PriorityQueue.prototype.siftUpIndex = function (index) {
var parentIndex = this.getParentIndex(index);
if (parentIndex === -1) {
return -1;
}
if (this.compare(parentIndex, index) > 0) {
return parentIndex;
}
return -1;
};
PriorityQueue.prototype.siftUp = function (index) {
var siftIndex = this.siftUpIndex(index);
while (siftIndex !== -1) {
this.swap(index, siftIndex);
index = siftIndex;
siftIndex = this.siftUpIndex(index);
}
};
PriorityQueue.prototype.siftDownIndex = function (index) {
if (index >= this.heap.length) {
return -1;
}
var largestChildIndex = index;
var leftChildIndex = this.getLeftChildIndex(index);
if ((leftChildIndex !== -1) &&
(this.compare(leftChildIndex, largestChildIndex) < 0)) {
largestChildIndex = leftChildIndex;
}
var rightChildIndex = this.getRightChildIndex(index);
if ((rightChildIndex !== -1) &&
(this.compare(rightChildIndex, largestChildIndex) < 0)) {
largestChildIndex = rightChildIndex;
}
return (largestChildIndex === index) ? -1 : largestChildIndex;
};
PriorityQueue.prototype.siftDown = function (index) {
var siftIndex = this.siftDownIndex(index);
while (siftIndex !== -1) {
this.swap(index, siftIndex);
index = siftIndex;
siftIndex = this.siftDownIndex(index);
}
};
PriorityQueue.prototype.compare = function (aIndex, bIndex) {
return this.comparator(this.heap[aIndex], this.heap[bIndex]);
};
PriorityQueue.prototype.swap = function (a, b) {
var temp = this.heap[a];
this.heap[a] = this.heap[b];
this.heap[b] = temp;
this.onIndexChanged(this.heap[a], a);
this.onIndexChanged(this.heap[b], b);
};
return PriorityQueue;
}());
exports.PriorityQueue = PriorityQueue;
},{}],47:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../math/ndarray");
var util = require("../util");
var operation_emitter = require("./operation_emitter");
var session_util = require("./session_util");
var tensor_array_map_1 = require("./tensor_array_map");
var FeedDictionary = (function () {
function FeedDictionary(feedEntries) {
var _this = this;
this.dict = {};
if (feedEntries) {
feedEntries.forEach(function (entry) { return _this.dict[entry.tensor.id] = entry; });
}
}
return FeedDictionary;
}());
exports.FeedDictionary = FeedDictionary;
var CostReduction;
(function (CostReduction) {
CostReduction[CostReduction["NONE"] = 0] = "NONE";
CostReduction[CostReduction["SUM"] = 1] = "SUM";
CostReduction[CostReduction["MEAN"] = 2] = "MEAN";
})(CostReduction = exports.CostReduction || (exports.CostReduction = {}));
var Session = (function () {
function Session(graph, math) {
this.math = math;
this.activationArrayMap = new tensor_array_map_1.TensorArrayMap();
this.runtimeCache = {};
this.oneScalar = ndarray_1.Scalar.new(1);
this.gradientArrayMap = new tensor_array_map_1.SummedTensorArrayMap(this.math);
}
Session.prototype.dispose = function () {
var _this = this;
this.activationArrayMap.dispose();
Object.keys(this.runtimeCache).forEach(function (key) {
var runtime = _this.runtimeCache[key];
if (runtime.operations) {
runtime.operations.forEach(function (op) { return op.dispose(); });
}
});
this.runtimeCache = {};
if (this.batchSizeScalar != null) {
this.batchSizeScalar.dispose();
}
this.oneScalar.dispose();
};
Session.prototype.evalAll = function (tensors, feedEntries) {
var _this = this;
return this.math.scope(function () {
var feed = new FeedDictionary(feedEntries);
var runtime = _this.getOrCreateRuntime(tensors, feed);
var activations = _this.activationArrayMap;
session_util.disposeAndInitializeOperationOutputs(runtime.nodes, activations);
session_util.disposeTransientOperationArrays(runtime.operations, _this.activationArrayMap, _this.gradientArrayMap);
session_util.addPersistentArraysToTensorArrayMap(runtime.nodes, activations);
session_util.loadInputsFromFeedDictionaryToTensorArrayMap(feed, activations, _this.math);
runtime.operations.forEach(function (op) { return op.feedForward(_this.math, activations); });
var results = tensors.map(function (x) { return activations.get(x); });
tensors.forEach(function (x) { return activations.delete(x); });
session_util.releaseFeedDictionaryInputsFromTensorArrayMap(feed, activations, _this.math);
return results;
});
};
Session.prototype.eval = function (tensor, feedEntries) {
return this.evalAll([tensor], feedEntries)[0];
};
Session.prototype.train = function (costTensor, feedEntries, batchSize, optimizer, costReduction) {
var _this = this;
if (costReduction === void 0) { costReduction = CostReduction.NONE; }
util.assert(util.isScalarShape(costTensor.shape), 'Cost tensor for training must be a scalar value.');
if (this.prevBatchSize !== batchSize) {
this.prevBatchSize = batchSize;
if (this.batchSizeScalar != null) {
this.batchSizeScalar.dispose();
}
this.batchSizeScalar = this.math.keep(ndarray_1.Scalar.new(batchSize));
}
var feed = new FeedDictionary(feedEntries);
session_util.throwIfFeedDictionaryContainsNDArrays(feed);
var runtime = this.getOrCreateRuntime([costTensor], feed);
var inferenceOperations = runtime.operations;
var backPropOperations = runtime.operations.slice().reverse();
var activations = this.activationArrayMap;
var gradients = this.gradientArrayMap;
gradients.nullify(costTensor);
gradients.add(costTensor, this.oneScalar);
session_util.addPersistentArraysToTensorArrayMap(runtime.nodes, activations);
optimizer.beforeBatch(this.math, batchSize, runtime, activations, gradients);
return this.math.scope(function () {
var cost = ndarray_1.Scalar.new(0);
for (var i = 0; i < batchSize; ++i) {
session_util.disposeAndInitializeOperationOutputs(runtime.nodes, activations);
session_util.disposeAndInitializeOperationInputGradients(runtime.nodes, gradients);
session_util.disposeTransientOperationArrays(runtime.operations, activations, gradients);
session_util.loadInputsFromFeedDictionaryToTensorArrayMap(feed, activations, _this.math);
inferenceOperations.forEach(function (op) { return op.feedForward(_this.math, activations); });
backPropOperations.forEach(function (op) { return op.backProp(_this.math, activations, gradients); });
optimizer.afterExample(_this.math, runtime, activations, gradients);
session_util.releaseFeedDictionaryInputsFromTensorArrayMap(feed, activations, _this.math);
cost = _this.updateCostForExample(cost, activations.get(costTensor), costReduction);
}
optimizer.afterBatch(_this.math, batchSize, runtime, activations, gradients);
return _this.updateCostForBatch(cost, costReduction);
});
};
Session.prototype.updateCostForExample = function (totalCost, currCost, costReduction) {
if (costReduction === CostReduction.MEAN ||
costReduction === CostReduction.SUM) {
return this.math.add(totalCost, currCost);
}
return totalCost;
};
Session.prototype.updateCostForBatch = function (totalCost, costReduction) {
if (costReduction === CostReduction.MEAN) {
return this.math.divide(totalCost, this.batchSizeScalar);
}
return totalCost;
};
Session.prototype.getOrCreateRuntime = function (tensors, feed) {
var key = this.makeRuntimeCacheKey(tensors, feed);
var runtime = this.runtimeCache[key];
if (runtime === undefined) {
var nodes = session_util.getOrderedEvaluationSetFromEvalTensor(tensors, feed);
session_util.removeFeedDictionaryNodesFromEvaluationSet(feed, nodes);
session_util.throwErrorIfEvaluationSetContainsPlaceholderNodes(nodes);
var operations = operation_emitter.emitFromGraphNodes(nodes);
runtime = { nodes: nodes, operations: operations };
this.runtimeCache[key] = runtime;
}
return runtime;
};
Session.prototype.makeRuntimeCacheKey = function (tensors, feed) {
return tensors.map(function (x) { return x.id; }).sort().join('_') + '__' +
Object.keys(feed.dict).sort().join('_');
};
return Session;
}());
exports.Session = Session;
},{"../math/ndarray":95,"../util":101,"./operation_emitter":18,"./session_util":48,"./tensor_array_map":49}],48:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../math/ndarray");
var util = require("../util");
var graph_1 = require("./graph");
var graph_util = require("./graph_util");
function getTerminatingNodesFromFeedDictionary(feedDictionary) {
return Object.keys(feedDictionary.dict)
.map(function (tensorID) { return feedDictionary.dict[+tensorID].tensor.node; });
}
exports.getTerminatingNodesFromFeedDictionary = getTerminatingNodesFromFeedDictionary;
function getOrderedEvaluationSetFromEvalTensor(evalTensors, feedDictionary) {
var terminatingNodes = getTerminatingNodesFromFeedDictionary(feedDictionary);
var evalNodes = evalTensors.map(function (x) { return x.node; });
var unorderedEvaluationSet = graph_util.getUnorderedEvaluationSet(evalNodes, terminatingNodes);
var orderedEvaluationSet = graph_util.getOrderedEvaluationSet(unorderedEvaluationSet);
return orderedEvaluationSet;
}
exports.getOrderedEvaluationSetFromEvalTensor = getOrderedEvaluationSetFromEvalTensor;
function addPersistentArraysToTensorArrayMap(evaluationSet, tensorArrayMap) {
evaluationSet.forEach(function (node) {
if (node instanceof graph_1.VariableNode || node instanceof graph_1.ConstantNode) {
tensorArrayMap.set(node.output, node.data);
}
});
}
exports.addPersistentArraysToTensorArrayMap = addPersistentArraysToTensorArrayMap;
function getVariableNodesFromEvaluationSet(evaluationSet) {
var nodes = [];
evaluationSet.forEach(function (node) {
if (node instanceof graph_1.VariableNode) {
nodes.push(node);
}
});
return nodes;
}
exports.getVariableNodesFromEvaluationSet = getVariableNodesFromEvaluationSet;
function throwIfFeedDictionaryContainsNDArrays(feedDictionary) {
Object.keys(feedDictionary.dict).forEach(function (tensorID) {
if (feedDictionary.dict[+tensorID].data instanceof ndarray_1.NDArray) {
throw new Error('training requires FeedDictionary entries to be InputProviders' +
'and not NDArrays.');
}
});
}
exports.throwIfFeedDictionaryContainsNDArrays = throwIfFeedDictionaryContainsNDArrays;
function loadInputsFromFeedDictionaryToTensorArrayMap(batchFeed, activations, math) {
Object.keys(batchFeed.dict).forEach(function (tensorID) {
var feedEntry = batchFeed.dict[+tensorID];
var data;
if (feedEntry.data instanceof ndarray_1.NDArray) {
data = feedEntry.data;
}
else {
var provider = feedEntry.data;
data = provider.getNextCopy(math);
}
util.assert(util.arraysEqual(feedEntry.tensor.shape, data.shape), "Error loading FeedEntry: feeding NDArray of shape " + data.shape + " " +
("does not match Tensor (id: " + feedEntry.tensor.id + ") shape: ") +
(feedEntry.tensor.shape + "."));
activations.set(feedEntry.tensor, data);
});
}
exports.loadInputsFromFeedDictionaryToTensorArrayMap = loadInputsFromFeedDictionaryToTensorArrayMap;
function releaseFeedDictionaryInputsFromTensorArrayMap(batchFeed, activations, math) {
Object.keys(batchFeed.dict).forEach(function (tensorID) {
var feedEntry = batchFeed.dict[+tensorID];
if (!(feedEntry.data instanceof ndarray_1.NDArray)) {
var provider = feedEntry.data;
var feedEntryArray = activations.get(feedEntry.tensor);
provider.disposeCopy(math, feedEntryArray);
}
activations.delete(feedEntry.tensor);
});
}
exports.releaseFeedDictionaryInputsFromTensorArrayMap = releaseFeedDictionaryInputsFromTensorArrayMap;
function removeFeedDictionaryNodesFromEvaluationSet(feedDictionary, evaluationSet) {
var i = 0;
while (i < evaluationSet.length) {
var node = evaluationSet[i];
if (feedDictionary.dict[node.output.id] != null) {
evaluationSet.splice(i, 1);
}
else {
++i;
}
}
}
exports.removeFeedDictionaryNodesFromEvaluationSet = removeFeedDictionaryNodesFromEvaluationSet;
function disposeAndInitializeOperationOutputs(evaluationSet, tensorArrayMap) {
evaluationSet.forEach(function (node) {
if (!graph_util.isInputNode(node)) {
if (!graph_util.isPassthroughNode(node, tensorArrayMap)) {
tensorArrayMap.disposeArray(node.output);
}
tensorArrayMap.set(node.output, null);
}
});
}
exports.disposeAndInitializeOperationOutputs = disposeAndInitializeOperationOutputs;
function disposeAndInitializeOperationInputGradients(evaluationSet, gradients) {
evaluationSet.forEach(function (node) {
Object.keys(node.inputs).forEach(function (inputName) {
var input = node.inputs[inputName];
if (gradients.get(input, true) !== gradients.get(node.output, true)) {
gradients.disposeArray(input);
}
gradients.nullify(input);
});
});
}
exports.disposeAndInitializeOperationInputGradients = disposeAndInitializeOperationInputGradients;
function disposeTransientOperationArrays(operations, activations, gradients) {
operations.forEach(function (op) { return op.disposeTransientArrays(activations, gradients); });
}
exports.disposeTransientOperationArrays = disposeTransientOperationArrays;
function throwErrorIfEvaluationSetContainsPlaceholderNodes(evaluationSet) {
evaluationSet.forEach(function (node) {
if (node instanceof graph_1.PlaceholderNode) {
var shape = '[' + node.output.shape.join(', ') + ']';
throw new Error('Placeholder node "' + node.name + '" ' + shape +
' not present in feed dictionary.');
}
});
}
exports.throwErrorIfEvaluationSetContainsPlaceholderNodes = throwErrorIfEvaluationSetContainsPlaceholderNodes;
},{"../math/ndarray":95,"../util":101,"./graph":16,"./graph_util":17}],49:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var TensorArrayMapBase = (function () {
function TensorArrayMapBase() {
this.dict = {};
}
TensorArrayMapBase.prototype.get = function (tensor, skipChecks) {
if (skipChecks === void 0) { skipChecks = false; }
if (!skipChecks && this.dict[tensor.id] === undefined) {
throw new Error("tensor " + tensor.id + " not in array map.");
}
var nda = this.dict[tensor.id];
if (!skipChecks && nda === null) {
throw new Error("tensor " + tensor.id + " has null array.");
}
return nda;
};
TensorArrayMapBase.prototype.delete = function (tensor) {
delete this.dict[tensor.id];
};
TensorArrayMapBase.prototype.nullify = function (tensor) {
this.dict[tensor.id] = null;
};
TensorArrayMapBase.prototype.disposeArray = function (tensor) {
if (this.dict[tensor.id] === undefined) {
return;
}
var nda = this.dict[tensor.id];
if (nda === null) {
return;
}
nda.dispose();
this.dict[tensor.id] = null;
};
TensorArrayMapBase.prototype.size = function () {
return Object.keys(this.dict).length;
};
TensorArrayMapBase.prototype.dispose = function () {
var _this = this;
Object.keys(this.dict).forEach(function (tensorID) {
var nda = _this.dict[+tensorID];
if (nda) {
nda.dispose();
}
});
this.dict = {};
};
TensorArrayMapBase.prototype.hasNullArray = function (tensor) {
if (this.dict[tensor.id] === undefined) {
throw new Error("tensor " + tensor.id + " not in array map.");
}
return this.dict[tensor.id] === null;
};
return TensorArrayMapBase;
}());
exports.TensorArrayMapBase = TensorArrayMapBase;
var TensorArrayMap = (function (_super) {
__extends(TensorArrayMap, _super);
function TensorArrayMap() {
return _super !== null && _super.apply(this, arguments) || this;
}
TensorArrayMap.prototype.set = function (tensor, array) {
this.dict[tensor.id] = array;
};
return TensorArrayMap;
}(TensorArrayMapBase));
exports.TensorArrayMap = TensorArrayMap;
var SummedTensorArrayMap = (function (_super) {
__extends(SummedTensorArrayMap, _super);
function SummedTensorArrayMap(math) {
var _this = _super.call(this) || this;
_this.math = math;
return _this;
}
SummedTensorArrayMap.prototype.add = function (tensor, array) {
if (this.dict[tensor.id] == null) {
this.dict[tensor.id] = this.math.keep(array);
}
else {
var oldValue = this.get(tensor);
var newValue = this.math.keep(this.math.addStrict(oldValue, array));
this.dict[tensor.id] = newValue;
oldValue.dispose();
}
};
return SummedTensorArrayMap;
}(TensorArrayMapBase));
exports.SummedTensorArrayMap = SummedTensorArrayMap;
},{}],50:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var session_1 = require("./graph/session");
var ndarray_1 = require("./math/ndarray");
var DEFAULT_EVAL_INTERVAL_MS = 1500;
var DEFAULT_COST_INTERVAL_MS = 500;
var DEFAULT_INFERENCE_EXAMPLE_INTERVAL_MS = 3000;
var MetricReduction;
(function (MetricReduction) {
MetricReduction[MetricReduction["SUM"] = 0] = "SUM";
MetricReduction[MetricReduction["MEAN"] = 1] = "MEAN";
})(MetricReduction = exports.MetricReduction || (exports.MetricReduction = {}));
var GraphRunner = (function () {
function GraphRunner(math, session, eventObserver) {
this.math = math;
this.session = session;
this.eventObserver = eventObserver;
this.lastCostTimestamp = 0;
this.lastEvalTimestamp = 0;
this.resetStatistics();
this.zeroScalar = ndarray_1.Scalar.new(0);
}
GraphRunner.prototype.resetStatistics = function () {
this.totalBatchesTrained = 0;
};
GraphRunner.prototype.train = function (costTensor, trainFeedEntries, batchSize, optimizer, numBatches, metricTensor, metricFeedEntries, metricBatchSize, metricReduction, evalIntervalMs, costIntervalMs) {
if (metricReduction === void 0) { metricReduction = MetricReduction.MEAN; }
if (evalIntervalMs === void 0) { evalIntervalMs = DEFAULT_EVAL_INTERVAL_MS; }
if (costIntervalMs === void 0) { costIntervalMs = DEFAULT_COST_INTERVAL_MS; }
this.costTensor = costTensor;
this.trainFeedEntries = trainFeedEntries;
this.metricTensor = metricTensor;
this.metricFeedEntries = metricFeedEntries;
if (metricBatchSize != null && this.metricBatchSize !== metricBatchSize) {
if (this.metricBatchSizeScalar != null) {
this.metricBatchSizeScalar.dispose();
}
this.metricBatchSizeScalar = ndarray_1.Scalar.new(metricBatchSize);
}
this.metricBatchSize = metricBatchSize;
this.metricReduction = metricReduction;
this.batchSize = batchSize;
this.optimizer = optimizer;
this.metricIntervalMs = evalIntervalMs;
this.costIntervalMs = costIntervalMs;
this.currentTrainLoopNumBatches = numBatches;
this.batchesTrainedThisRun = 0;
this.isTraining = true;
this.trainStartTimestamp = performance.now();
this.trainNetwork();
};
GraphRunner.prototype.stopTraining = function () {
this.isTraining = false;
};
GraphRunner.prototype.resumeTraining = function () {
this.isTraining = true;
this.trainNetwork();
};
GraphRunner.prototype.trainNetwork = function () {
var _this = this;
if (this.batchesTrainedThisRun === this.currentTrainLoopNumBatches) {
this.stopTraining();
}
if (!this.isTraining) {
if (this.eventObserver.doneTrainingCallback != null) {
this.eventObserver.doneTrainingCallback();
}
return;
}
var start = performance.now();
var shouldComputeCost = this.eventObserver.avgCostCallback != null &&
(start - this.lastCostTimestamp > this.costIntervalMs);
if (shouldComputeCost) {
this.lastCostTimestamp = start;
}
var costReduction = shouldComputeCost ? session_1.CostReduction.MEAN : session_1.CostReduction.NONE;
this.math.scope(function (keep) {
var avgCost = _this.session.train(_this.costTensor, _this.trainFeedEntries, _this.batchSize, _this.optimizer, costReduction);
if (shouldComputeCost) {
var trainTime = performance.now() - start;
_this.eventObserver.avgCostCallback(avgCost);
if (_this.eventObserver.trainExamplesPerSecCallback != null) {
var examplesPerSec = (_this.batchSize * 1000 / trainTime);
_this.eventObserver.trainExamplesPerSecCallback(examplesPerSec);
}
}
if (_this.eventObserver.metricCallback != null &&
_this.metricFeedEntries != null &&
start - _this.lastEvalTimestamp > _this.metricIntervalMs) {
_this.lastEvalTimestamp = start;
if (_this.lastComputedMetric != null) {
_this.lastComputedMetric.dispose();
}
_this.lastComputedMetric = _this.computeMetric();
_this.eventObserver.metricCallback(_this.lastComputedMetric);
}
if (_this.eventObserver.totalTimeCallback != null) {
_this.eventObserver.totalTimeCallback((start - _this.trainStartTimestamp) / 1000);
}
_this.batchesTrainedThisRun++;
_this.totalBatchesTrained++;
if (_this.eventObserver.batchesTrainedCallback != null) {
_this.eventObserver.batchesTrainedCallback(_this.totalBatchesTrained);
}
});
requestAnimationFrame(function () { return _this.trainNetwork(); });
};
GraphRunner.prototype.infer = function (inferenceTensor, inferenceFeedEntries, inferenceExampleIntervalMs, inferenceExampleCount, numPasses) {
var _this = this;
if (inferenceExampleIntervalMs === void 0) { inferenceExampleIntervalMs = DEFAULT_INFERENCE_EXAMPLE_INTERVAL_MS; }
if (inferenceExampleCount === void 0) { inferenceExampleCount = 5; }
if (this.eventObserver.inferenceExamplesCallback == null &&
this.eventObserver.inferenceExamplesPerSecCallback == null) {
throw new Error('Cannot start inference loop, no inference example or ' +
'examples/sec observer provided.');
}
for (var i = 0; i < inferenceFeedEntries.length; i++) {
var feedEntry = inferenceFeedEntries[i];
if (feedEntry.data instanceof ndarray_1.NDArray) {
throw new Error('Cannot start inference on the model runner with feed entries of ' +
'type NDArray. Please use InputProviders.');
}
}
this.inferenceExampleIntervalMs = inferenceExampleIntervalMs;
this.inferenceTensor = inferenceTensor;
this.inferenceFeedEntries = inferenceFeedEntries;
this.inferenceExampleCount = inferenceExampleCount;
this.currentInferenceLoopNumPasses = numPasses;
if (!this.isInferring) {
this.inferencePassesThisRun = 0;
requestAnimationFrame(function () { return _this.inferNetwork(); });
}
this.isInferring = true;
};
GraphRunner.prototype.inferNetwork = function () {
var _this = this;
if (!this.isInferring ||
this.inferencePassesThisRun === this.currentInferenceLoopNumPasses) {
return;
}
this.math.scope(function (keep) {
var feeds = [];
var inferenceValues = [];
var start = performance.now();
for (var i = 0; i < _this.inferenceExampleCount; i++) {
var ndarrayFeedEntries = [];
for (var j = 0; j < _this.inferenceFeedEntries.length; j++) {
var feedEntry = _this.inferenceFeedEntries[j];
var nextCopy = feedEntry.data.getNextCopy(_this.math);
ndarrayFeedEntries.push({ tensor: feedEntry.tensor, data: nextCopy });
}
feeds.push(ndarrayFeedEntries);
inferenceValues.push(_this.session.eval(_this.inferenceTensor, ndarrayFeedEntries));
}
if (_this.eventObserver.inferenceExamplesPerSecCallback != null) {
inferenceValues[inferenceValues.length - 1].getValues();
var inferenceExamplesPerSecTime = performance.now() - start;
var examplesPerSec = (_this.inferenceExampleCount * 1000 / inferenceExamplesPerSecTime);
_this.eventObserver.inferenceExamplesPerSecCallback(examplesPerSec);
}
if (_this.eventObserver.inferenceExamplesCallback != null) {
_this.eventObserver.inferenceExamplesCallback(feeds, inferenceValues);
}
_this.inferencePassesThisRun++;
});
this.lastInferTimeoutID = window.setTimeout(function () { return _this.inferNetwork(); }, this.inferenceExampleIntervalMs);
};
GraphRunner.prototype.stopInferring = function () {
this.isInferring = false;
window.clearTimeout(this.lastInferTimeoutID);
};
GraphRunner.prototype.isInferenceRunning = function () {
return this.isInferring;
};
GraphRunner.prototype.computeMetric = function () {
var _this = this;
if (this.metricFeedEntries == null) {
throw new Error('Cannot compute metric, no metric FeedEntries provided.');
}
var metric = this.zeroScalar;
return this.math.scope(function (keep) {
for (var i = 0; i < _this.metricBatchSize; i++) {
var metricValue = _this.session.eval(_this.metricTensor, _this.metricFeedEntries);
metric = _this.math.add(metric, metricValue);
}
if (_this.metricReduction === MetricReduction.MEAN) {
metric = _this.math.divide(metric, _this.metricBatchSizeScalar);
}
return metric;
});
};
GraphRunner.prototype.getTotalBatchesTrained = function () {
return this.totalBatchesTrained;
};
GraphRunner.prototype.getLastComputedMetric = function () {
return this.lastComputedMetric;
};
GraphRunner.prototype.setMath = function (math) {
this.math = math;
};
GraphRunner.prototype.setSession = function (session) {
this.session = session;
};
GraphRunner.prototype.setInferenceTensor = function (inferenceTensor) {
this.inferenceTensor = inferenceTensor;
};
GraphRunner.prototype.setInferenceExampleCount = function (inferenceExampleCount) {
this.inferenceExampleCount = inferenceExampleCount;
};
return GraphRunner;
}());
exports.GraphRunner = GraphRunner;
},{"./graph/session":47,"./math/ndarray":95}],51:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var xhr_dataset = require("./data/xhr-dataset");
exports.xhr_dataset = xhr_dataset;
var environment = require("./environment");
exports.environment = environment;
var gpgpu_util = require("./math/backends/webgl/gpgpu_util");
exports.gpgpu_util = gpgpu_util;
var render_ndarray_gpu_util = require("./math/backends/webgl/render_ndarray_gpu_util");
exports.render_ndarray_gpu_util = render_ndarray_gpu_util;
var webgl_util = require("./math/backends/webgl/webgl_util");
exports.webgl_util = webgl_util;
var conv_util = require("./math/conv_util");
exports.conv_util = conv_util;
var test_util = require("./test_util");
exports.test_util = test_util;
var util = require("./util");
exports.util = util;
var version_1 = require("./version");
exports.version = version_1.version;
var checkpoint_loader_1 = require("./data/checkpoint_loader");
exports.CheckpointLoader = checkpoint_loader_1.CheckpointLoader;
var dataset_1 = require("./data/dataset");
exports.InMemoryDataset = dataset_1.InMemoryDataset;
var input_provider_1 = require("./data/input_provider");
exports.InCPUMemoryShuffledInputProviderBuilder = input_provider_1.InCPUMemoryShuffledInputProviderBuilder;
exports.InGPUMemoryShuffledInputProviderBuilder = input_provider_1.InGPUMemoryShuffledInputProviderBuilder;
var xhr_dataset_1 = require("./data/xhr-dataset");
exports.XhrDataset = xhr_dataset_1.XhrDataset;
var environment_1 = require("./environment");
exports.ENV = environment_1.ENV;
exports.Environment = environment_1.Environment;
var graph_1 = require("./graph/graph");
exports.Graph = graph_1.Graph;
exports.Tensor = graph_1.Tensor;
var adadelta_optimizer_1 = require("./graph/optimizers/adadelta_optimizer");
exports.AdadeltaOptimizer = adadelta_optimizer_1.AdadeltaOptimizer;
var adagrad_optimizer_1 = require("./graph/optimizers/adagrad_optimizer");
exports.AdagradOptimizer = adagrad_optimizer_1.AdagradOptimizer;
var adam_optimizer_1 = require("./graph/optimizers/adam_optimizer");
exports.AdamOptimizer = adam_optimizer_1.AdamOptimizer;
var adamax_optimizer_1 = require("./graph/optimizers/adamax_optimizer");
exports.AdamaxOptimizer = adamax_optimizer_1.AdamaxOptimizer;
var momentum_optimizer_1 = require("./graph/optimizers/momentum_optimizer");
exports.MomentumOptimizer = momentum_optimizer_1.MomentumOptimizer;
var optimizer_1 = require("./graph/optimizers/optimizer");
exports.Optimizer = optimizer_1.Optimizer;
var rmsprop_optimizer_1 = require("./graph/optimizers/rmsprop_optimizer");
exports.RMSPropOptimizer = rmsprop_optimizer_1.RMSPropOptimizer;
var sgd_optimizer_1 = require("./graph/optimizers/sgd_optimizer");
exports.SGDOptimizer = sgd_optimizer_1.SGDOptimizer;
var session_1 = require("./graph/session");
exports.CostReduction = session_1.CostReduction;
exports.Session = session_1.Session;
var graph_runner_1 = require("./graph_runner");
exports.GraphRunner = graph_runner_1.GraphRunner;
exports.MetricReduction = graph_runner_1.MetricReduction;
var initializers_1 = require("./initializers");
exports.ConstantInitializer = initializers_1.ConstantInitializer;
exports.NDArrayInitializer = initializers_1.NDArrayInitializer;
exports.OnesInitializer = initializers_1.OnesInitializer;
exports.RandomNormalInitializer = initializers_1.RandomNormalInitializer;
exports.RandomTruncatedNormalInitializer = initializers_1.RandomTruncatedNormalInitializer;
exports.RandomUniformInitializer = initializers_1.RandomUniformInitializer;
exports.VarianceScalingInitializer = initializers_1.VarianceScalingInitializer;
exports.ZerosInitializer = initializers_1.ZerosInitializer;
var backend_cpu_1 = require("./math/backends/backend_cpu");
exports.MathBackendCPU = backend_cpu_1.MathBackendCPU;
exports.NDArrayMathCPU = backend_cpu_1.NDArrayMathCPU;
var backend_webgl_1 = require("./math/backends/backend_webgl");
exports.MathBackendWebGL = backend_webgl_1.MathBackendWebGL;
exports.NDArrayMathGPU = backend_webgl_1.NDArrayMathGPU;
var matmul_1 = require("./math/backends/types/matmul");
exports.MatrixOrientation = matmul_1.MatrixOrientation;
var gpgpu_context_1 = require("./math/backends/webgl/gpgpu_context");
exports.GPGPUContext = gpgpu_context_1.GPGPUContext;
var math_1 = require("./math/math");
exports.NDArrayMath = math_1.NDArrayMath;
var ndarray_1 = require("./math/ndarray");
exports.Array1D = ndarray_1.Array1D;
exports.Array2D = ndarray_1.Array2D;
exports.Array3D = ndarray_1.Array3D;
exports.Array4D = ndarray_1.Array4D;
exports.NDArray = ndarray_1.NDArray;
exports.Scalar = ndarray_1.Scalar;
},{"./data/checkpoint_loader":10,"./data/dataset":11,"./data/input_provider":12,"./data/xhr-dataset":13,"./environment":15,"./graph/graph":16,"./graph/optimizers/adadelta_optimizer":38,"./graph/optimizers/adagrad_optimizer":39,"./graph/optimizers/adam_optimizer":40,"./graph/optimizers/adamax_optimizer":41,"./graph/optimizers/momentum_optimizer":42,"./graph/optimizers/optimizer":43,"./graph/optimizers/rmsprop_optimizer":44,"./graph/optimizers/sgd_optimizer":45,"./graph/session":47,"./graph_runner":50,"./initializers":52,"./math/backends/backend_cpu":55,"./math/backends/backend_webgl":57,"./math/backends/types/matmul":61,"./math/backends/webgl/gpgpu_context":71,"./math/backends/webgl/gpgpu_util":73,"./math/backends/webgl/render_ndarray_gpu_util":80,"./math/backends/webgl/webgl_util":89,"./math/conv_util":92,"./math/math":94,"./math/ndarray":95,"./test_util":100,"./util":101,"./version":102}],52:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("./math/ndarray");
var VarianceScalingInitializer = (function () {
function VarianceScalingInitializer(scale, mode, distribution) {
if (scale === void 0) { scale = 1.0; }
if (mode === void 0) { mode = 'fan_in'; }
if (distribution === void 0) { distribution = 'normal'; }
this.scale = scale;
this.mode = mode;
this.distribution = distribution;
}
VarianceScalingInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
var n = 0;
if (this.mode === 'fan_in') {
n = inputUnits;
}
else if (this.mode === 'fan_out') {
n = outputUnits;
}
else if (this.mode === 'fan_avg') {
n = (inputUnits + outputUnits) / 2;
}
else {
throw new Error("Unexpected mode for variance scaling initializer: " + this.mode);
}
if (this.distribution === 'normal') {
return ndarray_1.NDArray.randTruncatedNormal(weightsShape, 0.0, Math.sqrt(this.scale / n));
}
else if (this.distribution === 'uniform') {
return ndarray_1.NDArray.randUniform(weightsShape, 0.0, Math.sqrt(3 * this.scale / n));
}
else {
throw new Error("Unexpected distribution for variance scaling initializer: " +
("" + this.distribution));
}
};
return VarianceScalingInitializer;
}());
exports.VarianceScalingInitializer = VarianceScalingInitializer;
var ZerosInitializer = (function () {
function ZerosInitializer() {
}
ZerosInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
return ndarray_1.NDArray.zeros(weightsShape);
};
return ZerosInitializer;
}());
exports.ZerosInitializer = ZerosInitializer;
var OnesInitializer = (function () {
function OnesInitializer() {
}
OnesInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
var values = ndarray_1.NDArray.zeros(weightsShape);
values.fill(1);
return values;
};
return OnesInitializer;
}());
exports.OnesInitializer = OnesInitializer;
var ConstantInitializer = (function () {
function ConstantInitializer(value) {
if (value === void 0) { value = 0; }
this.value = value;
}
ConstantInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
var values = ndarray_1.NDArray.zeros(weightsShape);
values.fill(this.value);
return values;
};
return ConstantInitializer;
}());
exports.ConstantInitializer = ConstantInitializer;
var NDArrayInitializer = (function () {
function NDArrayInitializer(ndarray) {
this.ndarray = ndarray;
}
NDArrayInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
return this.ndarray;
};
return NDArrayInitializer;
}());
exports.NDArrayInitializer = NDArrayInitializer;
var RandomNormalInitializer = (function () {
function RandomNormalInitializer(mean, stdev) {
if (mean === void 0) { mean = 0; }
if (stdev === void 0) { stdev = .05; }
this.mean = mean;
this.stdev = stdev;
}
RandomNormalInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
return ndarray_1.NDArray.randNormal(weightsShape, this.mean, this.stdev);
};
return RandomNormalInitializer;
}());
exports.RandomNormalInitializer = RandomNormalInitializer;
var RandomTruncatedNormalInitializer = (function () {
function RandomTruncatedNormalInitializer(mean, stdev) {
if (mean === void 0) { mean = 0; }
if (stdev === void 0) { stdev = .05; }
this.mean = mean;
this.stdev = stdev;
}
RandomTruncatedNormalInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
return ndarray_1.NDArray.randTruncatedNormal(weightsShape, this.mean, this.stdev);
};
return RandomTruncatedNormalInitializer;
}());
exports.RandomTruncatedNormalInitializer = RandomTruncatedNormalInitializer;
var RandomUniformInitializer = (function () {
function RandomUniformInitializer(minval, maxval) {
if (minval === void 0) { minval = -.05; }
if (maxval === void 0) { maxval = .05; }
this.minval = minval;
this.maxval = maxval;
}
RandomUniformInitializer.prototype.initialize = function (weightsShape, inputUnits, outputUnits) {
return ndarray_1.NDArray.randUniform(weightsShape, this.minval, this.maxval);
};
return RandomUniformInitializer;
}());
exports.RandomUniformInitializer = RandomUniformInitializer;
},{"./math/ndarray":95}],53:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("./ndarray");
var TanHFunc = (function () {
function TanHFunc() {
this.one = ndarray_1.Scalar.new(1);
}
TanHFunc.prototype.output = function (math, x) {
return math.tanh(x);
};
TanHFunc.prototype.der = function (math, x, y) {
var _this = this;
return math.scope(function () {
var ySquared = math.elementWiseMul(y, y);
return math.scalarMinusArray(_this.one, ySquared);
});
};
TanHFunc.prototype.dispose = function () {
this.one.dispose();
};
return TanHFunc;
}());
exports.TanHFunc = TanHFunc;
var ReLUFunc = (function () {
function ReLUFunc() {
}
ReLUFunc.prototype.output = function (math, x) {
return math.relu(x);
};
ReLUFunc.prototype.der = function (math, x, y) {
return math.step(x);
};
ReLUFunc.prototype.dispose = function () { };
return ReLUFunc;
}());
exports.ReLUFunc = ReLUFunc;
var LeakyReluFunc = (function () {
function LeakyReluFunc(alpha) {
this.alpha = alpha;
}
LeakyReluFunc.prototype.output = function (math, x) {
return math.leakyRelu(x, this.alpha);
};
LeakyReluFunc.prototype.der = function (math, x, y) {
return math.step(x, this.alpha);
};
LeakyReluFunc.prototype.dispose = function () { };
return LeakyReluFunc;
}());
exports.LeakyReluFunc = LeakyReluFunc;
var SigmoidFunc = (function () {
function SigmoidFunc() {
}
SigmoidFunc.prototype.output = function (math, x) {
return math.sigmoid(x);
};
SigmoidFunc.prototype.der = function (math, x, y) {
return math.scope(function () {
var ySquared = math.elementWiseMul(y, y);
return math.subStrict(y, ySquared);
});
};
SigmoidFunc.prototype.dispose = function () { };
return SigmoidFunc;
}());
exports.SigmoidFunc = SigmoidFunc;
var SquareFunc = (function () {
function SquareFunc() {
this.two = ndarray_1.Scalar.new(2);
}
SquareFunc.prototype.output = function (math, x) {
return math.elementWiseMul(x, x);
};
SquareFunc.prototype.der = function (math, x, y) {
return math.scalarTimesArray(this.two, x);
};
SquareFunc.prototype.dispose = function () {
this.two.dispose();
};
return SquareFunc;
}());
exports.SquareFunc = SquareFunc;
var EluFunc = (function () {
function EluFunc() {
}
EluFunc.prototype.output = function (math, x) {
return math.elu(x);
};
EluFunc.prototype.der = function (math, x, y) {
return math.eluDer(x);
};
EluFunc.prototype.dispose = function () { };
return EluFunc;
}());
exports.EluFunc = EluFunc;
},{"./ndarray":95}],54:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function axesAreInnerMostDims(axes, rank) {
for (var i = 0; i < axes.length; ++i) {
if (axes[axes.length - i - 1] !== rank - 1 - i) {
return false;
}
}
return true;
}
exports.axesAreInnerMostDims = axesAreInnerMostDims;
function combineLocations(outputLoc, reduceLoc, axes) {
var rank = outputLoc.length + reduceLoc.length;
var loc = [];
var outIdx = 0;
var reduceIdx = 0;
for (var dim = 0; dim < rank; dim++) {
if (axes.indexOf(dim) === -1) {
loc.push(outputLoc[outIdx++]);
}
else {
loc.push(reduceLoc[reduceIdx++]);
}
}
return loc;
}
exports.combineLocations = combineLocations;
function computeOutAndReduceShapes(aShape, axes) {
var outShape = [];
var rank = aShape.length;
for (var dim = 0; dim < rank; dim++) {
if (axes.indexOf(dim) === -1) {
outShape.push(aShape[dim]);
}
}
var reduceShape = axes.map(function (dim) { return aShape[dim]; });
return [outShape, reduceShape];
}
exports.computeOutAndReduceShapes = computeOutAndReduceShapes;
function expandShapeToKeepDim(shape, axes) {
var reduceSubShape = axes.map(function (x) { return 1; });
return combineLocations(shape, reduceSubShape, axes);
}
exports.expandShapeToKeepDim = expandShapeToKeepDim;
function parseAxisParam(axis, shape) {
if (axis == null) {
axis = shape.map(function (s, i) { return i; });
}
else if (typeof (axis) === 'number') {
axis = [axis];
}
return axis;
}
exports.parseAxisParam = parseAxisParam;
function assertAxesAreInnerMostDims(msg, axes, rank) {
if (!axesAreInnerMostDims(axes, rank)) {
throw new Error(msg + " supports only inner-most axes for now. " +
("Got axes " + axes + " and rank-" + rank + " input."));
}
}
exports.assertAxesAreInnerMostDims = assertAxesAreInnerMostDims;
function getPermutedAxes(axes, rank) {
if (axesAreInnerMostDims(axes, rank)) {
return null;
}
var result = [];
for (var i = 0; i < rank; ++i) {
if (axes.indexOf(i) === -1) {
result.push(i);
}
}
axes.forEach(function (axis) { return result.push(axis); });
return result;
}
exports.getPermutedAxes = getPermutedAxes;
function getInnerMostAxes(numAxes, rank) {
var res = [];
for (var i = rank - numAxes; i < rank; ++i) {
res.push(i);
}
return res;
}
exports.getInnerMostAxes = getInnerMostAxes;
},{}],55:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, 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 util = require("../../util");
var broadcast_util = require("../broadcast_util");
var concat_util = require("../concat_util");
var math_1 = require("../math");
var ndarray_1 = require("../ndarray");
var types = require("../types");
var types_1 = require("../types");
var axis_util = require("./../axis_util");
var matmul_1 = require("./types/matmul");
var MathBackendCPU = (function () {
function MathBackendCPU() {
this.data = {};
}
MathBackendCPU.prototype.dispose = function () { };
MathBackendCPU.prototype.write = function (id, values, dtype, shape) {
this.data[id] = values;
};
MathBackendCPU.prototype.writePixels = function (id, pixels, numChannels) {
var vals;
if (pixels instanceof ImageData) {
vals = pixels.data;
}
else if (pixels instanceof HTMLCanvasElement) {
vals = pixels.getContext('2d')
.getImageData(0, 0, pixels.width, pixels.height)
.data;
}
else if (pixels instanceof HTMLImageElement ||
pixels instanceof HTMLVideoElement) {
var canvas = document.createElement('canvas');
canvas.width = pixels.width;
canvas.height = pixels.height;
canvas.getContext('2d').drawImage(pixels, 0, 0, canvas.width, canvas.height);
vals = canvas.getContext('2d')
.getImageData(0, 0, canvas.width, canvas.height)
.data;
}
else {
throw new Error("pixels is of unknown type: " + 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];
}
}
}
this.data[id] = values;
};
MathBackendCPU.prototype.read = function (id) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
this.throwIfNoData(id);
return [2, this.data[id]];
});
});
};
MathBackendCPU.prototype.readSync = function (id) {
this.throwIfNoData(id);
return this.data[id];
};
MathBackendCPU.prototype.disposeData = function (id) {
delete this.data[id];
};
MathBackendCPU.prototype.time = function (query) {
return __awaiter(this, void 0, void 0, function () {
var start;
return __generator(this, function (_a) {
start = performance.now();
query();
return [2, performance.now() - start];
});
});
};
MathBackendCPU.prototype.throwIfNoData = function (id) {
if (!(id in this.data)) {
throw new Error("No data found for NDArray with id " + id + ". " +
"Use dl.ENV.math instead of constructing your own NDArrayMath. " +
"If you need to construct your own math, make sure this array is " +
"allocated after the math construction");
}
};
MathBackendCPU.prototype.clone = function (x) {
return ndarray_1.NDArray.make(x.shape, { values: new Float32Array(x.getValues()) });
};
MathBackendCPU.prototype.slice1D = function (x, begin, size) {
var newVals = x.getValues().slice(begin, begin + size);
return ndarray_1.Array1D.new(newVals);
};
MathBackendCPU.prototype.slice2D = function (x, begin, size) {
var result = ndarray_1.Array2D.zeros(size);
var startI = begin[0], startJ = begin[1];
for (var i = 0; i < size[0]; ++i) {
for (var j = 0; j < size[1]; ++j) {
var val = x.get(i + startI, j + startJ);
result.set(val, i, j);
}
}
return result;
};
MathBackendCPU.prototype.slice3D = function (x, begin, size) {
var result = ndarray_1.Array3D.zeros(size);
var startI = begin[0], startJ = begin[1], startK = begin[2];
for (var i = 0; i < size[0]; ++i) {
for (var j = 0; j < size[1]; ++j) {
for (var k = 0; k < size[2]; ++k) {
var val = x.get(i + startI, j + startJ, k + startK);
result.set(val, i, j, k);
}
}
}
return result;
};
MathBackendCPU.prototype.slice4D = function (x, begin, size) {
var result = ndarray_1.Array4D.zeros(size);
var startI = begin[0], startJ = begin[1], startK = begin[2], startL = begin[3];
for (var i = 0; i < size[0]; ++i) {
for (var j = 0; j < size[1]; ++j) {
for (var k = 0; k < size[2]; ++k) {
for (var l = 0; l < size[3]; ++l) {
var val = x.get(i + startI, j + startJ, k + startK, l + startL);
result.set(val, i, j, k, l);
}
}
}
}
return result;
};
MathBackendCPU.prototype.concat1D = function (a, b) {
var outShape = concat_util.computeOutShape(a.shape, b.shape, 0);
var result = ndarray_1.Array1D.zeros(outShape);
var aVals = a.getValues();
var bVals = b.getValues();
var vals = result.getValues();
vals.set(aVals, 0);
vals.set(bVals, a.size);
return result;
};
MathBackendCPU.prototype.concat2D = function (a, b, axis) {
var outShape = concat_util.computeOutShape(a.shape, b.shape, axis);
var result = ndarray_1.Array2D.zeros(outShape);
if (axis === 0) {
var aVals = a.getValues();
var bVals = b.getValues();
var vals = result.getValues();
vals.set(aVals, 0);
vals.set(bVals, a.size);
return result;
}
for (var i = 0; i < outShape[0]; ++i) {
for (var j = 0; j < outShape[1]; ++j) {
var index = [i, j];
var value = void 0;
if (index[axis] < a.shape[axis]) {
value = a.get(i, j);
}
else {
index[axis] -= a.shape[axis];
var i2 = index[0], j2 = index[1];
value = b.get(i2, j2);
}
result.set(value, i, j);
}
}
return result;
};
MathBackendCPU.prototype.concat3D = function (a, b, axis) {
var outShape = concat_util.computeOutShape(a.shape, b.shape, axis);
var result = ndarray_1.Array3D.zeros(outShape);
if (axis === 0) {
var aVals = a.getValues();
var bVals = b.getValues();
var vals = result.getValues();
vals.set(aVals, 0);
vals.set(bVals, a.size);
return result;
}
for (var i = 0; i < outShape[0]; ++i) {
for (var j = 0; j < outShape[1]; ++j) {
for (var k = 0; k < outShape[2]; ++k) {
var index = [i, j, k];
var value = void 0;
if (index[axis] < a.shape[axis]) {
value = a.get(i, j, k);
}
else {
index[axis] -= a.shape[axis];
var i2 = index[0], j2 = index[1], k2 = index[2];
value = b.get(i2, j2, k2);
}
result.set(value, i, j, k);
}
}
}
return result;
};
MathBackendCPU.prototype.concat4D = function (a, b, axis) {
var outShape = concat_util.computeOutShape(a.shape, b.shape, axis);
var result = ndarray_1.Array4D.zeros(outShape);
if (axis === 0) {
var aVals = a.getValues();
var bVals = b.getValues();
var vals = result.getValues();
vals.set(aVals, 0);
vals.set(bVals, a.size);
return result;
}
for (var i = 0; i < outShape[0]; ++i) {
for (var j = 0; j < outShape[1]; ++j) {
for (var k = 0; k < outShape[2]; ++k) {
for (var l = 0; l < outShape[3]; ++l) {
var index = [i, j, k, l];
var value = void 0;
if (index[axis] < a.shape[axis]) {
value = a.get(i, j, k, l);
}
else {
index[axis] -= a.shape[axis];
var i2 = index[0], j2 = index[1], k2 = index[2], l2 = index[3];
value = b.get(i2, j2, k2, l2);
}
result.set(value, i, j, k, l);
}
}
}
}
return result;
};
MathBackendCPU.prototype.neg = function (x) {
return this.multiply(ndarray_1.Scalar.new(-1), x);
};
MathBackendCPU.prototype.add = function (a, b) {
return this.broadcastedBinaryOp(a, b, types.upcastType(a.dtype, b.dtype), function (aValue, bValue) { return aValue + bValue; });
};
MathBackendCPU.prototype.subtract = function (a, b) {
return this.broadcastedBinaryOp(a, b, types.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, aOrientation, bOrientation) {
if (aOrientation === void 0) { aOrientation = matmul_1.MatrixOrientation.REGULAR; }
if (bOrientation === void 0) { bOrientation = matmul_1.MatrixOrientation.REGULAR; }
var sharedDim = (aOrientation === matmul_1.MatrixOrientation.REGULAR) ? a.shape[1] : a.shape[0];
var leftDim = (aOrientation === matmul_1.MatrixOrientation.REGULAR) ? a.shape[0] : a.shape[1];
var rightDim = (bOrientation === matmul_1.MatrixOrientation.REGULAR) ? b.shape[1] : b.shape[0];
var normalGetter = function (matrix, i, j) {
return matrix.get(i, j);
};
var transposedGetter = function (matrix, i, j) {
return matrix.get(j, i);
};
var aGetter = (aOrientation === matmul_1.MatrixOrientation.REGULAR) ?
normalGetter :
transposedGetter;
var bGetter = (bOrientation === matmul_1.MatrixOrientation.REGULAR) ?
normalGetter :
transposedGetter;
var values = new Float32Array(leftDim * rightDim);
var index = 0;
for (var i = 0; i < leftDim; ++i) {
for (var j = 0; j < rightDim; ++j) {
var sum = 0;
for (var k = 0; k < sharedDim; ++k) {
sum += aGetter(a, i, k) * bGetter(b, k, j);
}
values[index++] = sum;
}
}
return ndarray_1.Array2D.new([leftDim, rightDim], values);
};
MathBackendCPU.prototype.multiply = function (a, b) {
return this.broadcastedBinaryOp(a, b, a.dtype, function (aValue, bValue) { return aValue * bValue; });
};
MathBackendCPU.prototype.divide = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'float32', function (aValue, bValue) { return aValue / bValue; });
};
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.SumTypesMap[x.dtype];
var result = ndarray_1.NDArray.zeros(outShape, resultDtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.getValues();
var aVals = x.getValues();
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.argMin = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('argMin', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ndarray_1.NDArray.zeros(outShape, 'int32');
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.getValues();
var aVals = x.getValues();
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 (isNaN(value)) {
minIndex = util.NAN_INT32;
break;
}
if (value < min) {
min = value;
minIndex = j;
}
}
vals[i] = minIndex;
}
return result;
};
MathBackendCPU.prototype.argMax = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('argMax', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var result = ndarray_1.NDArray.zeros(outShape, 'int32');
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.getValues();
var aVals = x.getValues();
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 (isNaN(value)) {
maxIndex = util.NAN_INT32;
break;
}
if (value > max) {
max = value;
maxIndex = j;
}
}
vals[i] = maxIndex;
}
return result;
};
MathBackendCPU.prototype.equal = function (a, b) {
return this.broadcastedBinaryOp(a, b, 'bool', function (aVal, bVal) {
if (util.isValNaN(aVal, a.dtype) || util.isValNaN(bVal, b.dtype)) {
return util.getNaN('bool');
}
else {
return (aVal === bVal) ? 1 : 0;
}
});
};
MathBackendCPU.prototype.topKValues = function (x, k) {
return this.topK(x, k).values;
};
MathBackendCPU.prototype.topKIndices = function (x, k) {
return this.topK(x, k).indices;
};
MathBackendCPU.prototype.topK = function (x, k) {
var values = x.getValues();
var valuesAndIndices = [];
for (var i = 0; i < values.length; i++) {
valuesAndIndices.push({ value: values[i], index: i });
}
valuesAndIndices.sort(function (a, b) {
return b.value - a.value;
});
var topkValues = util.getTypedArrayFromDType(x.dtype, k);
var topkIndices = new Int32Array(k);
for (var i = 0; i < k; i++) {
topkValues[i] = valuesAndIndices[i].value;
topkIndices[i] = valuesAndIndices[i].index;
}
return {
values: ndarray_1.Array1D.new(topkValues),
indices: ndarray_1.Array1D.new(topkIndices)
};
};
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 = ndarray_1.NDArray.zeros(outShape, x.dtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.getValues();
var aVals = x.getValues();
for (var i = 0; i < vals.length; ++i) {
var offset = i * reduceSize;
var min = aVals[0];
for (var j = 0; j < reduceSize; ++j) {
var value = aVals[offset + j];
if (isNaN(value)) {
min = Number.NaN;
break;
}
if (value < min) {
min = value;
}
}
vals[i] = min;
}
return result;
};
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 = ndarray_1.NDArray.zeros(outShape, x.dtype);
var reduceSize = util.sizeFromShape(reduceShape);
var vals = result.getValues();
var aVals = x.getValues();
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 (isNaN(value)) {
max = Number.NaN;
break;
}
if (value > max) {
max = value;
}
}
vals[i] = max;
}
return result;
};
MathBackendCPU.prototype.ceil = function (x) {
var values = x.getValues();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.ceil(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.floor = function (x) {
var values = x.getValues();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.floor(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.exp = function (x) {
var values = x.getValues();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
newValues[i] = Math.exp(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.log = function (x) {
var values = x.getValues();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = Math.log(value);
}
return ndarray_1.NDArray.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.sqrt = function (x) {
var values = x.getValues();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = Math.sqrt(value);
}
return ndarray_1.NDArray.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.square = function (x) {
var values = x.getValues();
var newValues = new Float32Array(values.length);
for (var i = 0; i < values.length; ++i) {
var value = values[i];
newValues[i] = value * value;
}
return ndarray_1.NDArray.make(x.shape, { values: newValues });
};
MathBackendCPU.prototype.relu = function (x) {
var res = ndarray_1.NDArray.zeros(x.shape, x.dtype);
var resVals = res.getValues();
var inVals = x.getValues();
for (var i = 0; i < inVals.length; ++i) {
var val = inVals[i];
if (util.isValNaN(val, x.dtype)) {
resVals[i] = util.getNaN(res.dtype);
}
else {
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 ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.eluDer = 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] = 1;
}
else {
resultValues[i] = Math.exp(v);
}
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.selu = function (x) {
var scaleAlpha = 1.7580993408473768599402175208123;
var scale = 1.0507009873554804934193349852946;
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 ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.leakyRelu = function (x, alpha) {
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] = alpha * v;
}
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.prelu = function (x, alpha) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
var alphas = alpha.dataSync();
for (var i = 0; i < values.length; i++) {
var v = values[i];
if (v >= 0) {
resultValues[i] = v;
}
else {
resultValues[i] = alphas[i] * v;
}
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.preluDer = function (x, alpha) {
var resultValues = new Float32Array(x.size);
var values = x.dataSync();
var alphas = alpha.dataSync();
for (var i = 0; i < values.length; i++) {
var v = values[i];
if (v > 0) {
resultValues[i] = 1;
}
else if (v < 0) {
resultValues[i] = alphas[i];
}
else {
resultValues[i] = v;
}
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.clip = function (x, min, max) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.min(max, Math.max(min, values[i]));
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.abs = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.abs(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.sigmoid = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = 1 / (1 + Math.exp(-values[i]));
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.sin = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.sin(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.cos = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.cos(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.tan = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.tan(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.asin = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.asin(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.acos = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.acos(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.atan = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.atan(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.sinh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.sinh(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.cosh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = Math.cosh(values[i]);
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.tanh = function (x) {
var resultValues = new Float32Array(x.size);
var values = x.getValues();
for (var i = 0; i < values.length; ++i) {
resultValues[i] = util.tanh(values[i]);
}
return ndarray_1.NDArray.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.getValues();
for (var i = 0; i < values.length; ++i) {
var value = values[i];
if (util.isValNaN(value, x.dtype)) {
resultValues[i] = util.getNaN(x.dtype);
}
else {
resultValues[i] = value > 0 ? 1 : alpha;
}
}
return ndarray_1.NDArray.make(x.shape, { values: resultValues });
};
MathBackendCPU.prototype.conv2d = function (x, filter, bias, convInfo) {
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var padLeft = convInfo.padInfo.left;
var padTop = convInfo.padInfo.top;
var y = ndarray_1.Array4D.zeros(convInfo.outShape);
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var d2 = 0; d2 < convInfo.outChannels; ++d2) {
for (var yR = 0; yR < convInfo.outHeight; ++yR) {
var xRCorner = yR * convInfo.strideHeight - padLeft;
var xRMin = Math.max(0, xRCorner);
var xRMax = Math.min(convInfo.inHeight, filterHeight + xRCorner);
for (var yC = 0; yC < convInfo.outWidth; ++yC) {
var xCCorner = yC * convInfo.strideWidth - padTop;
var xCMin = Math.max(0, xCCorner);
var xCMax = Math.min(convInfo.inWidth, filterWidth + xCCorner);
var dotProd = 0;
for (var xR = xRMin; xR < xRMax; ++xR) {
var wR = xR - xRCorner;
for (var xC = xCMin; xC < xCMax; ++xC) {
var wC = xC - xCCorner;
for (var d1 = 0; d1 < convInfo.inChannels; ++d1) {
var pixel = x.get(b, xR, xC, d1);
var weight = filter.get(wR, wC, d1, d2);
dotProd += pixel * weight;
}
}
}
var biasVal = (bias != null) ? bias.get(d2) : 0;
y.set(dotProd + biasVal, b, yR, yC, d2);
}
}
}
}
return y;
};
MathBackendCPU.prototype.conv2dDerInput = function (dy, filter, convInfo) {
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var topPad = filterHeight - 1 - convInfo.padInfo.top;
var leftPad = filterWidth - 1 - convInfo.padInfo.left;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var dx = ndarray_1.Array4D.zeros(convInfo.inShape);
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var d1 = 0; d1 < convInfo.inChannels; ++d1) {
for (var xR = 0; xR < convInfo.inHeight; ++xR) {
var xRCorner = xR - leftPad;
var xRMin = Math.max(0, Math.ceil(xRCorner / strideHeight));
var yRMax = Math.min(convInfo.outHeight, (filterHeight + xRCorner) / strideHeight);
for (var xC = 0; xC < convInfo.inWidth; ++xC) {
var xCCorner = xC - topPad;
var xCMin = Math.max(0, Math.ceil(xCCorner / strideWidth));
var yCMax = Math.min(convInfo.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;
for (var d2 = 0; d2 < convInfo.outChannels; ++d2) {
var pixel = dy.get(b, yR, yC, d2);
var weight = filter.get(filterHeight - 1 - wR, filterWidth - 1 - wC, d1, d2);
dotProd += pixel * weight;
}
}
}
dx.set(dotProd, b, xR, xC, d1);
}
}
}
}
return dx;
};
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 = ndarray_1.Array4D.zeros(convInfo.filterShape);
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;
};
MathBackendCPU.prototype.conv2dDerBias = function (dy) {
var _a = dy.shape, batchSize = _a[0], numRows = _a[1], numCols = _a[2], outDepth = _a[3];
var values = new Float32Array(outDepth);
for (var d2 = 0; d2 < outDepth; ++d2) {
var sum = 0;
for (var b = 0; b < batchSize; ++b) {
for (var r = 0; r < numRows; ++r) {
for (var c = 0; c < numCols; ++c) {
sum += dy.get(b, r, c, d2);
}
}
}
values[d2] = sum;
}
return ndarray_1.Array1D.new(values);
};
MathBackendCPU.prototype.depthwiseConv2D = function (x, filter, convInfo) {
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var padLeft = convInfo.padInfo.left;
var padTop = convInfo.padInfo.top;
var chMul = convInfo.outChannels / convInfo.inChannels;
var y = ndarray_1.Array4D.zeros(convInfo.outShape);
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var d1 = 0; d1 < convInfo.inChannels; ++d1) {
for (var yR = 0; yR < convInfo.outHeight; ++yR) {
var xRCorner = yR * convInfo.strideHeight - padLeft;
var xRMin = Math.max(0, xRCorner);
var xRMax = Math.min(convInfo.inHeight, filterHeight + xRCorner);
for (var yC = 0; yC < convInfo.outWidth; ++yC) {
var xCCorner = yC * convInfo.strideWidth - padTop;
var xCMin = Math.max(0, xCCorner);
var xCMax = Math.min(convInfo.inWidth, filterWidth + xCCorner);
for (var q = 0; q < chMul; ++q) {
var dotProd = 0;
for (var xR = xRMin; xR < xRMax; ++xR) {
var wR = xR - xRCorner;
for (var xC = xCMin; xC < xCMax; ++xC) {
var wC = xC - xCCorner;
var pixel = x.get(b, xR, xC, d1);
var weight = filter.get(wR, wC, d1, q);
dotProd += pixel * weight;
}
}
y.set(dotProd, b, yR, yC, d1 * chMul + q);
}
}
}
}
}
return y;
};
MathBackendCPU.prototype.tile = function (x, reps) {
var newShape = new Array(x.rank);
for (var i = 0; i < newShape.length; i++) {
newShape[i] = x.shape[i] * reps[i];
}
var dtype;
if (x.dtype === 'float32') {
dtype = Float32Array;
}
else if (x.dtype === 'int32') {
dtype = Int32Array;
}
else if (x.dtype === 'bool') {
dtype = Uint8Array;
}
else {
throw new Error("Dtype " + x.dtype + " not supported for tile");
}
var resultValues = new dtype(util.sizeFromShape(newShape));
var result = ndarray_1.NDArray.make(newShape, { values: resultValues }, x.dtype);
var values = x.getValues();
for (var i = 0; i < result.size; ++i) {
var newLoc = result.indexToLoc(i);
var originalLoc = new Array(x.rank);
for (var i_1 = 0; i_1 < originalLoc.length; i_1++) {
originalLoc[i_1] = newLoc[i_1] % x.shape[i_1];
}
var originalIndex = x.locToIndex(originalLoc);
resultValues[i] = values[originalIndex];
}
return result;
};
MathBackendCPU.prototype.transpose = function (x, perm) {
var newShape = new Array(x.rank);
for (var i = 0; i < newShape.length; i++) {
newShape[i] = x.shape[perm[i]];
}
var resultValues = new Float32Array(x.size);
var values = x.getValues();
var result = ndarray_1.NDArray.make(newShape, { values: resultValues });
for (var i = 0; i < x.size; ++i) {
var loc = x.indexToLoc(i);
var newLoc = new Array(loc.length);
for (var i_2 = 0; i_2 < newLoc.length; i_2++) {
newLoc[i_2] = loc[perm[i_2]];
}
var newIndex = result.locToIndex(newLoc);
resultValues[newIndex] = values[i];
}
return result;
};
MathBackendCPU.prototype.pool = function (x, convInfo, poolType) {
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var y = ndarray_1.Array4D.zeros(convInfo.outShape);
var padTop = convInfo.padInfo.top;
var padLeft = convInfo.padInfo.left;
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var d = 0; d < convInfo.inChannels; ++d) {
for (var yR = 0; yR < convInfo.outHeight; ++yR) {
var xRCorner = yR * strideHeight - padTop;
var xRMin = Math.max(0, xRCorner);
var xRMax = Math.min(convInfo.inHeight, filterHeight + xRCorner);
for (var yC = 0; yC < convInfo.outWidth; ++yC) {
var xCCorner = yC * strideWidth - padLeft;
var xCMin = Math.max(0, xCCorner);
var xCMax = Math.min(convInfo.inWidth, filterWidth + xCCorner);
var minMaxValue = (poolType === 'max' ? Number.NEGATIVE_INFINITY :
Number.POSITIVE_INFINITY);
var avgValue = 0;
for (var xR = xRMin; xR < xRMax; ++xR) {
for (var xC = xCMin; xC < xCMax; ++xC) {
var pixel = x.get(b, xR, xC, d);
if (isNaN(pixel)) {
minMaxValue = NaN;
avgValue = NaN;
break;
}
if ((poolType === 'max' && pixel > minMaxValue) ||
(poolType === 'min' && pixel < minMaxValue)) {
minMaxValue = pixel;
}
else if (poolType === 'avg') {
avgValue += pixel / (filterHeight * filterWidth);
}
}
if (isNaN(minMaxValue)) {
break;
}
}
y.set(poolType === 'avg' ? avgValue : minMaxValue, b, yR, yC, d);
}
}
}
}
return y;
};
MathBackendCPU.prototype.maxPool = function (x, convInfo) {
return this.pool(x, convInfo, 'max');
};
MathBackendCPU.prototype.maxPoolPositions = function (x, convInfo) {
var maxPositions = ndarray_1.Array4D.zeros(convInfo.outShape);
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var padTop = convInfo.padInfo.top;
var padLeft = convInfo.padInfo.left;
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var d = 0; d < convInfo.inChannels; ++d) {
for (var yR = 0; yR < convInfo.outHeight; ++yR) {
var xRCorner = yR * strideHeight - padTop;
var xRMin = Math.max(0, xRCorner);
var xRMax = Math.min(convInfo.inHeight, filterHeight + xRCorner);
for (var yC = 0; yC < convInfo.outWidth; ++yC) {
var xCCorner = yC * strideWidth - padLeft;
var xCMin = Math.max(0, xCCorner);
var xCMax = Math.min(convInfo.inWidth, filterWidth + xCCorner);
var maxValue = Number.NEGATIVE_INFINITY;
var maxPosition = -1;
for (var xR = xRMin; xR < xRMax; ++xR) {
var wR = xR - xRCorner;
for (var xC = xCMin; xC < xCMax; ++xC) {
var wC = xC - xCCorner;
var pixel = x.get(b, xR, xC, d);
if (pixel > maxValue) {
maxValue = pixel;
maxPosition = wR * filterWidth + wC;
}
}
}
maxPositions.set(maxPosition, b, yR, yC, d);
}
}
}
}
return maxPositions;
};
MathBackendCPU.prototype.maxPoolBackprop = function (dy, x, convInfo) {
var maxPositions = this.maxPoolPositions(x, convInfo);
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var padLeft = filterWidth - 1 - convInfo.padInfo.left;
var padTop = filterHeight - 1 - convInfo.padInfo.top;
var dx = ndarray_1.Array4D.zeros(x.shape);
for (var b = 0; b < convInfo.batchSize; ++b) {
for (var d = 0; d < convInfo.inChannels; ++d) {
for (var dxR = 0; dxR < convInfo.inHeight; ++dxR) {
for (var dxC = 0; dxC < convInfo.inWidth; ++dxC) {
var dyRCorner = dxR - padTop;
var dyCCorner = dxC - padLeft;
var dotProd = 0;
for (var wR = 0; wR < filterHeight; ++wR) {
var dyR = (dyRCorner + wR) / strideHeight;
if (dyR < 0 || dyR >= convInfo.outHeight ||
Math.floor(dyR) !== dyR) {
continue;
}
for (var wC = 0; wC < filterWidth; ++wC) {
var dyC = (dyCCorner + wC) / strideWidth;
if (dyC < 0 || dyC >= convInfo.outWidth ||
Math.floor(dyC) !== dyC) {
continue;
}
var maxPos = filterHeight * filterWidth - 1 -
maxPositions.get(b, dyR, dyC, d);
var curPos = wR * filterWidth + wC;
var mask = maxPos === curPos ? 1 : 0;
if (mask === 0) {
continue;
}
var pixel = dy.get(b, dyR, dyC, d);
dotProd += pixel * mask;
}
}
dx.set(dotProd, b, dxR, dxC, d);
}
}
}
}
return dx;
};
MathBackendCPU.prototype.minPool = function (x, convInfo) {
return this.pool(x, convInfo, 'min');
};
MathBackendCPU.prototype.avgPool = function (x, convInfo) {
return this.pool(x, convInfo, 'avg');
};
MathBackendCPU.prototype.resizeBilinear3D = function (x, newShape2D, alignCorners) {
var output = ndarray_1.Array3D.zeros([newShape2D[0], newShape2D[1], x.shape[2]]);
var effectiveInputSize = alignCorners ? [x.shape[0] - 1, x.shape[1] - 1, x.shape[2]] : x.shape;
var effectiveOutputSize = alignCorners ?
[output.shape[0] - 1, output.shape[1] - 1, output.shape[2]] :
output.shape;
for (var r = 0; r < output.shape[0]; r++) {
for (var c = 0; c < output.shape[1]; c++) {
for (var d = 0; d < output.shape[2]; d++) {
var sourceFracRow = (effectiveInputSize[0]) * r / (effectiveOutputSize[0]);
var sourceFracCol = (effectiveInputSize[1]) * c / (effectiveOutputSize[1]);
var sourceRowFloor = Math.floor(sourceFracRow);
var sourceRowCeil = Math.min(x.shape[0] - 1, Math.ceil(sourceFracRow));
var sourceColFloor = Math.floor(sourceFracCol);
var sourceColCeil = Math.min(x.shape[1] - 1, Math.ceil(sourceFracCol));
var topLeft = x.get(sourceRowFloor, sourceColFloor, d);
var bottomLeft = x.get(sourceRowCeil, sourceColFloor, d);
var topRight = x.get(sourceRowFloor, sourceColCeil, d);
var bottomRight = x.get(sourceRowCeil, sourceColCeil, d);
var rowFrac = sourceFracRow - sourceRowFloor;
var colFrac = sourceFracCol - sourceColFloor;
var top_1 = topLeft + (topRight - topLeft) * colFrac;
var bottom = bottomLeft + (bottomRight - bottomLeft) * colFrac;
var newValue = top_1 + (bottom - top_1) * rowFrac;
output.set(newValue, r, c, d);
}
}
}
return output;
};
MathBackendCPU.prototype.batchNormalization2D = function (x, mean, variance, varianceEpsilon, scale, offset) {
var xValues = x.getValues();
var meanValues = mean.getValues();
var varianceValues = variance.getValues();
var scaleValues = scale ? scale.getValues() : new Float32Array([1]);
var offsetValues = offset ? offset.getValues() : new Float32Array([0]);
var outValues = new Float32Array(xValues.length);
for (var i = 0; i < xValues.length; i++) {
outValues[i] = offsetValues[i % offsetValues.length] +
(xValues[i] - meanValues[i % meanValues.length]) *
scaleValues[i % scaleValues.length] /
Math.sqrt(varianceValues[i % varianceValues.length] + varianceEpsilon);
}
return ndarray_1.Array2D.new(x.shape, outValues);
};
MathBackendCPU.prototype.batchNormalization3D = function (x, mean, variance, varianceEpsilon, scale, offset) {
var xValues = x.getValues();
var meanValues = mean.getValues();
var varianceValues = variance.getValues();
var scaleValues = scale ? scale.getValues() : new Float32Array([1]);
var offsetValues = offset ? offset.getValues() : new Float32Array([0]);
var outValues = new Float32Array(xValues.length);
for (var i = 0; i < xValues.length; i++) {
outValues[i] = offsetValues[i % offsetValues.length] +
(xValues[i] - meanValues[i % meanValues.length]) *
scaleValues[i % scaleValues.length] /
Math.sqrt(varianceValues[i % varianceValues.length] + varianceEpsilon);
}
return ndarray_1.Array3D.new(x.shape, outValues);
};
MathBackendCPU.prototype.multinomial = function (probabilities, numSamples, seed) {
var batchSize = probabilities.shape[0];
var numEvents = probabilities.shape[1];
var res = ndarray_1.Array2D.zeros([batchSize, numSamples], 'int32');
var resVals = res.getValues();
var probVals = probabilities.getValues();
for (var b = 0; b < batchSize; ++b) {
var offset = b * numEvents;
var cdf = new Float32Array(numEvents - 1);
cdf[0] = probVals[offset];
for (var event_1 = 1; event_1 < cdf.length; ++event_1) {
cdf[event_1] = cdf[event_1 - 1] + probVals[offset + event_1];
}
var random = seedrandom.alea(seed.toString());
var outOffset = b * numSamples;
for (var sampleId = 0; sampleId < numSamples; ++sampleId) {
var r = random();
resVals[outOffset + sampleId] = cdf.length;
for (var event_2 = 0; event_2 < cdf.length; event_2++) {
if (r < cdf[event_2]) {
resVals[outOffset + sampleId] = event_2;
break;
}
}
}
}
return res;
};
MathBackendCPU.prototype.oneHot = function (indices, depth, onValue, offValue) {
var res = new Float32Array(indices.size * depth);
res.fill(offValue);
for (var event_3 = 0; event_3 < indices.size; ++event_3) {
res[event_3 * depth + indices.get(event_3)] = onValue;
}
return ndarray_1.Array2D.new([indices.size, depth], res);
};
MathBackendCPU.prototype.broadcastedBinaryOp = function (a, b, dtype, op) {
var newShape = broadcast_util.assertAndGetBroadcastShape(a.shape, b.shape);
var result = ndarray_1.NDArray.zeros(newShape, dtype);
var newValues = result.getValues();
var aValues = a.getValues();
var bValues = b.getValues();
var aBroadcastDims = broadcast_util.getBroadcastDims(a.shape, newShape);
var bBroadcastDims = broadcast_util.getBroadcastDims(b.shape, newShape);
var _loop_1 = function (i) {
var loc = result.indexToLoc(i);
var aLoc = loc.slice(-a.rank);
aBroadcastDims.forEach(function (d) { return aLoc[d] = 0; });
var aIndex = a.locToIndex(aLoc);
var bLoc = loc.slice(-b.rank);
bBroadcastDims.forEach(function (d) { return bLoc[d] = 0; });
var bIndex = b.locToIndex(bLoc);
newValues[i] = op(aValues[aIndex], bValues[bIndex]);
};
for (var i = 0; i < newValues.length; ++i) {
_loop_1(i);
}
return result;
};
return MathBackendCPU;
}());
exports.MathBackendCPU = MathBackendCPU;
environment_1.ENV.registerBackend('cpu', function () { return new MathBackendCPU(); });
var NDArrayMathCPU = (function (_super) {
__extends(NDArrayMathCPU, _super);
function NDArrayMathCPU(safeMode) {
if (safeMode === void 0) { safeMode = false; }
var _this = this;
console.warn('new NDArrayMathCPU() is deprecated. Please use the global ' +
'dl.ENV.math. In rare cases, to construct your own NDArrayMath ' +
'that runs on CPU, use math = new NDArrayMath(\'cpu\', safeMode); ' +
'and make sure to set it as global: dl.ENV.setMath(math);');
_this = _super.call(this, 'cpu', safeMode) || this;
environment_1.ENV.setMath(_this);
return _this;
}
return NDArrayMathCPU;
}(math_1.NDArrayMath));
exports.NDArrayMathCPU = NDArrayMathCPU;
},{"../../environment":15,"../../util":101,"../broadcast_util":90,"../concat_util":91,"../math":94,"../ndarray":95,"../types":99,"./../axis_util":54,"./types/matmul":61,"seedrandom":2}],56:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../../util");
var kernel_registry = require("./kernel_registry");
var tape_1 = require("./tape");
var BackendEngine = (function () {
function BackendEngine(backend) {
this.backend = backend;
this.debugMode = false;
this.masterTape = new tape_1.Tape(backend);
}
BackendEngine.prototype.enableDebugMode = function () {
this.debugMode = true;
};
BackendEngine.prototype.executeKernel = function (kernelName, config, grad) {
var _this = this;
var kernelFn = function () {
return kernel_registry.executeKernel(_this.backend, kernelName, config);
};
var start;
if (this.debugMode) {
start = performance.now();
}
var result = kernelFn();
if (this.debugMode) {
var vals = result.getValues();
var time = util.rightPad(performance.now() - start + "ms", 9);
var paddedName = util.rightPad(name, 25);
var rank = result.rank;
var size = result.size;
var shape = util.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');
this.checkForNaN(vals, result.dtype, name);
}
var evaluatedNode = {
name: "kernel: " + kernelName,
kernel: kernelName,
inputAndArgs: config,
output: result,
gradient: grad
};
this.masterTape.addEvaluatedKernelNode(evaluatedNode);
return result;
};
BackendEngine.prototype.gradientWrt = function (y, xs) {
return this.masterTape.gradientWrt(y, xs);
};
BackendEngine.prototype.checkForNaN = function (vals, dtype, name) {
for (var i = 0; i < vals.length; i++) {
if (util.isValNaN(vals[i], dtype)) {
throw Error("The result of the last math." + name + " has NaNs.");
}
}
};
BackendEngine.prototype.getBackend = function () {
return this.backend;
};
return BackendEngine;
}());
exports.BackendEngine = BackendEngine;
},{"../../util":101,"./kernel_registry":58,"./tape":59}],57:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, 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 environment_1 = require("../../environment");
var util = require("../../util");
var axis_util = require("../axis_util");
var math_1 = require("../math");
var ndarray_1 = require("../ndarray");
var reduce_util = require("../reduce_util");
var types_1 = require("../types");
var argminmax_gpu_1 = require("./webgl/argminmax_gpu");
var batchnorm_gpu_1 = require("./webgl/batchnorm_gpu");
var binaryop_gpu = require("./webgl/binaryop_gpu");
var binaryop_gpu_1 = require("./webgl/binaryop_gpu");
var clip_gpu_1 = require("./webgl/clip_gpu");
var concat_gpu_1 = require("./webgl/concat_gpu");
var conv_backprop_gpu_1 = require("./webgl/conv_backprop_gpu");
var conv_gpu_1 = require("./webgl/conv_gpu");
var conv_gpu_depthwise_1 = require("./webgl/conv_gpu_depthwise");
var copy_gpu_1 = require("./webgl/copy_gpu");
var gpgpu_context_1 = require("./webgl/gpgpu_context");
var gpgpu_math = require("./webgl/gpgpu_math");
var gpgpu_util = require("./webgl/gpgpu_util");
var max_pool_backprop_gpu_1 = require("./webgl/max_pool_backprop_gpu");
var mulmat_gpu_1 = require("./webgl/mulmat_gpu");
var multinomial_gpu_1 = require("./webgl/multinomial_gpu");
var onehot_gpu_1 = require("./webgl/onehot_gpu");
var pool_gpu_1 = require("./webgl/pool_gpu");
var reduce_gpu_1 = require("./webgl/reduce_gpu");
var resize_bilinear_gpu_1 = require("./webgl/resize_bilinear_gpu");
var slice_gpu_1 = require("./webgl/slice_gpu");
var tex_util_1 = require("./webgl/tex_util");
var texture_manager_1 = require("./webgl/texture_manager");
var tile_gpu_1 = require("./webgl/tile_gpu");
var transpose_gpu_1 = require("./webgl/transpose_gpu");
var unary_op = require("./webgl/unaryop_gpu");
var unaryop_gpu_1 = require("./webgl/unaryop_gpu");
var webgl_util = require("./webgl/webgl_util");
var MathBackendWebGL = (function () {
function MathBackendWebGL(gpgpu) {
this.texData = {};
this.binaryCache = {};
if (environment_1.ENV.get('WEBGL_VERSION') < 1) {
throw new Error('WebGL is not supported on this device');
}
if (gpgpu == null) {
var gl = gpgpu_util.createWebGLContext();
this.gpgpu = new gpgpu_context_1.GPGPUContext(gl);
this.gpgpuCreatedLocally = true;
}
else {
this.gpgpu = gpgpu;
this.gpgpuCreatedLocally = false;
}
this.textureManager = new texture_manager_1.TextureManager(this.gpgpu);
}
MathBackendWebGL.prototype.writePixels = function (id, pixels, numChannels) {
var shape = [pixels.height, pixels.width, numChannels];
var texShape = [shape[0], shape[1]];
var texture = this.textureManager.acquireTexture(texShape);
this.gpgpu.uploadPixelDataToTexture(texture, pixels);
this.texData[id] = {
texture: texture,
textureType: tex_util_1.TextureType.RGBA_COLOR,
texShape: texShape,
numChannels: numChannels,
dtype: 'int32'
};
};
MathBackendWebGL.prototype.write = function (id, values, dtype, shape) {
var texShape = webgl_util.getTextureShapeFromLogicalShape(this.gpgpu.gl, shape);
var texture = this.textureManager.acquireTexture(texShape);
var textureType = tex_util_1.TextureType.DEFAULT;
this.texData[id] = { texture: texture, textureType: textureType, texShape: texShape, dtype: dtype };
if (values != null) {
this.gpgpu.uploadMatrixToTexture(texture, texShape[0], texShape[1], typedArrayToFloat32(values, dtype));
}
};
MathBackendWebGL.prototype.readSync = function (id) {
this.throwIfNoData(id);
var values;
var _a = this.texData[id], texture = _a.texture, textureType = _a.textureType, texShape = _a.texShape, numChannels = _a.numChannels, dtype = _a.dtype;
if (textureType === tex_util_1.TextureType.DEFAULT) {
values = this.gpgpu.downloadMatrixFromTexture(texture, texShape[0], texShape[1]);
}
else {
values = this.gpgpu.downloadMatrixFromRGBAColorTexture(texture, texShape[0], texShape[1], numChannels);
}
return float32ToTypedArray(values, dtype);
};
MathBackendWebGL.prototype.read = function (id) {
return __awaiter(this, void 0, void 0, function () {
var _a, texture, textureType, texShape;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
this.throwIfNoData(id);
_a = this.texData[id], texture = _a.texture, textureType = _a.textureType, texShape = _a.texShape;
if (environment_1.ENV.get('WEBGL_GET_BUFFER_SUB_DATA_ASYNC_EXTENSION_ENABLED') &&
textureType === tex_util_1.TextureType.DEFAULT) {
return [2, this.gpgpu.downloadMatrixFromTextureAsync(texture, texShape[0], texShape[1])];
}
if (!environment_1.ENV.get('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED')) {
return [2, this.readSync(id)];
}
return [4, this.gpgpu.runQuery(function () { })];
case 1:
_b.sent();
return [2, this.readSync(id)];
}
});
});
};
MathBackendWebGL.prototype.time = function (query) {
return __awaiter(this, void 0, void 0, function () {
var start, a;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
if (!!environment_1.ENV.get('WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_ENABLED')) return [3, 2];
start = performance.now();
a = query();
return [4, a.data()];
case 1:
_a.sent();
return [2, performance.now() - start];
case 2: return [2, this.gpgpu.runQuery(query)];
}
});
});
};
MathBackendWebGL.prototype.disposeData = function (id) {
if (id in this.texData) {
var _a = this.texData[id], texture = _a.texture, texShape = _a.texShape;
this.textureManager.releaseTexture(texture, texShape);
delete this.texData[id];
}
};
MathBackendWebGL.prototype.getTexture = function (id) {
this.throwIfNoData(id);
return this.texData[id].texture;
};
MathBackendWebGL.prototype.getTextureData = function (id) {
this.throwIfNoData(id);
return this.texData[id];
};
MathBackendWebGL.prototype.getGPGPUContext = function () {
return this.gpgpu;
};
MathBackendWebGL.prototype.clone = function (x) {
this.throwIfNoData(x.id);
var texShape = this.texData[x.id].texShape;
var source = x.as2D(texShape[0], texShape[1]);
var output = this.makeOutputArray(texShape, x.dtype);
this.copy2D(source, [0, 0], texShape, output, [0, 0], texShape);
return output.reshape(x.shape);
};
MathBackendWebGL.prototype.slice1D = function (x, begin, size) {
var program = new slice_gpu_1.SliceProgram([size]);
var customSetup = program.getCustomSetupFunc([begin]);
return this.compileAndRun(program, [x], null, customSetup);
};
MathBackendWebGL.prototype.slice2D = function (x, begin, size) {
var program = new slice_gpu_1.SliceProgram(size);
var customSetup = program.getCustomSetupFunc(begin);
return this.compileAndRun(program, [x], null, customSetup);
};
MathBackendWebGL.prototype.slice3D = function (x, begin, size) {
var program = new slice_gpu_1.SliceProgram(size);
var customSetup = program.getCustomSetupFunc(begin);
return this.compileAndRun(program, [x], null, customSetup);
};
MathBackendWebGL.prototype.slice4D = function (x, begin, size) {
var program = new slice_gpu_1.SliceProgram(size);
var customSetup = program.getCustomSetupFunc(begin);
return this.compileAndRun(program, [x], null, customSetup);
};
MathBackendWebGL.prototype.copy2D = function (source, sourceBeginRowCol, sourceSizeRowCol, dest, destBeginRowCol, destSizeRowCol) {
var program = new copy_gpu_1.Copy2DProgram(sourceSizeRowCol[1], destSizeRowCol[1]);
var customSetup = program.getCustomSetupFunc(sourceBeginRowCol, destBeginRowCol, destSizeRowCol);
this.compileAndRun(program, [source], dest, customSetup);
};
MathBackendWebGL.prototype.concat1D = function (a, b) {
var program = new concat_gpu_1.ConcatProgram(a.shape, b.shape, 0);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.concat2D = function (a, b, axis) {
var program = new concat_gpu_1.ConcatProgram(a.shape, b.shape, axis);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.concat3D = function (a, b, axis) {
var program = new concat_gpu_1.ConcatProgram(a.shape, b.shape, axis);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.concat4D = function (a, b, axis) {
var program = new concat_gpu_1.ConcatProgram(a.shape, b.shape, axis);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.neg = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.NEG);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.matMul = function (a, b, aOrientation, bOrientation) {
var program = new mulmat_gpu_1.MatMulProgram(a.shape, b.shape, aOrientation, bOrientation);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.multiply = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.MUL, a.shape, b.shape);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.batchNormalization2D = function (x, mean, variance, varianceEpsilon, scale, offset) {
var inputs = [x, mean, variance];
var offsetShape = null;
if (offset != null) {
offsetShape = offset.shape;
inputs.push(offset);
}
var scaleShape = null;
if (scale != null) {
scaleShape = scale.shape;
inputs.push(scale);
}
var program = new batchnorm_gpu_1.BatchNormProgram(x.shape, mean.shape, variance.shape, offsetShape, scaleShape, varianceEpsilon);
return this.compileAndRun(program, inputs);
};
MathBackendWebGL.prototype.batchNormalization3D = function (x, mean, variance, varianceEpsilon, scale, offset) {
var inputs = [x, mean, variance];
var offsetShape = null;
if (offset != null) {
offsetShape = offset.shape;
inputs.push(offset);
}
var scaleShape = null;
if (scale != null) {
scaleShape = scale.shape;
inputs.push(scale);
}
var program = new batchnorm_gpu_1.BatchNormProgram(x.shape, mean.shape, variance.shape, offsetShape, scaleShape, varianceEpsilon);
return this.compileAndRun(program, inputs);
};
MathBackendWebGL.prototype.tile = function (x, reps) {
var program = new tile_gpu_1.TileProgram(x.shape, reps);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.transpose = function (x, perm) {
var program = new transpose_gpu_1.TransposeProgram(x.shape, perm);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.reduce = function (x, reduceType, dtype) {
var batchSize = x.shape[0];
var inSize = x.shape[1];
var windowSize = reduce_util.computeOptimalWindowSize(inSize);
var reduceInfo = { windowSize: windowSize, inSize: inSize, batchSize: batchSize };
var program = new reduce_gpu_1.ReduceProgram(reduceInfo, reduceType);
var _a = program.outputShape, rows = _a[0], cols = _a[1];
var output = this.makeOutputArray(program.outputShape, dtype).as2D(rows, cols);
this.compileAndRun(program, [x], output);
if (output.shape[1] === 1) {
return output;
}
return this.reduce(output, reduceType, dtype);
};
MathBackendWebGL.prototype.argReduce = function (x, reduceType, bestIndicesA) {
if (bestIndicesA === void 0) { bestIndicesA = null; }
var batchSize = x.shape[0];
var inSize = x.shape[1];
if (bestIndicesA != null) {
batchSize = bestIndicesA.shape[0];
inSize = bestIndicesA.shape[1];
}
var windowSize = reduce_util.computeOptimalWindowSize(inSize);
var reduceInfo = { windowSize: windowSize, inSize: inSize, batchSize: batchSize };
var program = new argminmax_gpu_1.ArgMinMaxProgram(reduceInfo, reduceType, bestIndicesA == null);
var _a = program.outputShape, rows = _a[0], cols = _a[1];
var output = this.makeOutputArray(program.outputShape, 'int32').as2D(rows, cols);
var inputs = [x];
if (bestIndicesA != null) {
inputs.push(bestIndicesA);
}
this.compileAndRun(program, inputs, output);
if (output.shape[1] === 1) {
return output;
}
return this.argReduce(x, reduceType, output);
};
MathBackendWebGL.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 inSize = util.sizeFromShape(reduceShape);
var a2D = x.as2D(-1, inSize);
var outputDType = types_1.SumTypesMap[x.dtype];
return this.reduce(a2D, 'sum', outputDType).reshape(outShape);
};
MathBackendWebGL.prototype.argMin = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('argMin', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var inSize = util.sizeFromShape(reduceShape);
var a2D = x.as2D(-1, inSize);
return this.argReduce(a2D, 'min').reshape(outShape);
};
MathBackendWebGL.prototype.argMax = function (x, axes) {
axis_util.assertAxesAreInnerMostDims('argMax', axes, x.rank);
var _a = axis_util.computeOutAndReduceShapes(x.shape, axes), outShape = _a[0], reduceShape = _a[1];
var inSize = util.sizeFromShape(reduceShape);
var a2D = x.as2D(-1, inSize);
return this.argReduce(a2D, 'max').reshape(outShape);
};
MathBackendWebGL.prototype.equal = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.EQUAL, a.shape, b.shape);
var output = this.makeOutputArray(program.outputShape, 'bool');
return this.compileAndRun(program, [a, b], output);
};
MathBackendWebGL.prototype.topKValues = function (x, k) {
throw new Error('topKValues GPU not yet implemented!');
};
MathBackendWebGL.prototype.topKIndices = function (x, k) {
throw new Error('topKIndices GPU not yet implemented!');
};
MathBackendWebGL.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 inSize = util.sizeFromShape(reduceShape);
var a2D = x.as2D(-1, inSize);
return this.reduce(a2D, 'min', a2D.dtype).reshape(outShape);
};
MathBackendWebGL.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 inSize = util.sizeFromShape(reduceShape);
var a2D = x.as2D(-1, inSize);
return this.reduce(a2D, 'max', a2D.dtype).reshape(outShape);
};
MathBackendWebGL.prototype.divide = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.DIV, a.shape, b.shape);
var output = this.makeOutputArray(program.outputShape, 'float32');
return this.compileAndRun(program, [a, b], output);
};
MathBackendWebGL.prototype.add = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.ADD, a.shape, b.shape);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.subtract = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.SUB, a.shape, b.shape);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.pow = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.POW, a.shape, b.shape);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.ceil = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.CEIL);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.floor = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.FLOOR);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.exp = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.EXP);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.log = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.LOG);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.sqrt = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.SQRT);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.square = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.SQUARE);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.relu = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.RELU);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.elu = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.ELU);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.eluDer = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.ELU_DER);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.selu = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.SELU);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.leakyRelu = function (x, alpha) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.LEAKY_RELU(alpha));
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.prelu = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.PRELU, a.shape, b.shape);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.preluDer = function (a, b) {
var program = new binaryop_gpu_1.BinaryOpProgram(binaryop_gpu.PRELU_DER, a.shape, b.shape);
return this.compileAndRun(program, [a, b]);
};
MathBackendWebGL.prototype.clip = function (x, min, max) {
var program = new clip_gpu_1.ClipProgram(x.shape, min, max);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.abs = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.ABS);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.sigmoid = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.SIGMOID);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.sin = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.SIN);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.cos = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.COS);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.tan = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.TAN);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.asin = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.ASIN);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.acos = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.ACOS);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.atan = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.ATAN);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.sinh = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.SINH);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.cosh = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.COSH);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.tanh = function (x) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.TANH);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.step = function (x, alpha) {
var program = new unaryop_gpu_1.UnaryOpProgram(x.shape, unary_op.STEP(alpha));
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.conv2d = function (x, filter, bias, convInfo) {
var program = new conv_gpu_1.Conv2DProgram(convInfo, bias != null);
var inputs = bias != null ? [x, filter, bias] : [x, filter];
return this.compileAndRun(program, inputs);
};
MathBackendWebGL.prototype.conv2dDerInput = function (dy, filter, convInfo) {
var program = new conv_backprop_gpu_1.Conv2DDerInputProgram(convInfo);
return this.compileAndRun(program, [dy, filter]);
};
MathBackendWebGL.prototype.conv2dDerFilter = function (x, dy, convInfo) {
var program = new conv_backprop_gpu_1.Conv2DDerFilterProgram(convInfo);
return this.compileAndRun(program, [x, dy]);
};
MathBackendWebGL.prototype.conv2dDerBias = function (dy) {
var program = new conv_backprop_gpu_1.Conv2DDerBiasProgram(dy.shape);
return this.compileAndRun(program, [dy]);
};
MathBackendWebGL.prototype.depthwiseConv2D = function (x, filter, convInfo) {
var program = new conv_gpu_depthwise_1.DepthwiseConv2DProgram(convInfo);
return this.compileAndRun(program, [x, filter]);
};
MathBackendWebGL.prototype.maxPool = function (x, convInfo) {
var program = new pool_gpu_1.Pool2DProgram(convInfo, 'max', false);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.minPool = function (x, convInfo) {
var program = new pool_gpu_1.Pool2DProgram(convInfo, 'min', false);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.avgPool = function (x, convInfo) {
var program = new pool_gpu_1.Pool2DProgram(convInfo, 'avg', false);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.maxPoolBackprop = function (dy, x, convInfo) {
var getPositions = true;
var maxPoolPositionsProgram = new pool_gpu_1.Pool2DProgram(convInfo, 'max', getPositions);
var maxPoolPositions = this.compileAndRun(maxPoolPositionsProgram, [x]);
var maxPoolBackPropProgram = new max_pool_backprop_gpu_1.MaxPool2DBackpropProgram(convInfo);
var result = this.compileAndRun(maxPoolBackPropProgram, [dy, maxPoolPositions]);
maxPoolPositions.dispose();
return result;
};
MathBackendWebGL.prototype.resizeBilinear3D = function (x, newShape2D, alignCorners) {
var program = new resize_bilinear_gpu_1.ResizeBilinear3DProgram(x.shape, newShape2D, alignCorners);
return this.compileAndRun(program, [x]);
};
MathBackendWebGL.prototype.multinomial = function (probs, numSamples, seed) {
var batchSize = probs.shape[0];
var numOutcomes = probs.shape[1];
var program = new multinomial_gpu_1.MultinomialProgram(batchSize, numOutcomes, numSamples);
var output = this.makeOutputArray(program.outputShape, 'int32');
var customSetup = program.getCustomSetupFunc(seed);
return this.compileAndRun(program, [probs], output, customSetup);
};
MathBackendWebGL.prototype.oneHot = function (indices, depth, onValue, offValue) {
var program = new onehot_gpu_1.OneHotProgram(indices.size, depth, onValue, offValue);
return this.compileAndRun(program, [indices]);
};
MathBackendWebGL.prototype.makeOutputArray = function (shape, dtype) {
return ndarray_1.NDArray.make(shape, {}, dtype);
};
MathBackendWebGL.prototype.compileAndRun = function (program, inputs, output, customSetup) {
var _this = this;
if (output == null) {
output = this.makeOutputArray(program.outputShape, inputs[0].dtype);
}
var inputsData = inputs.map(function (input) {
_this.throwIfNoData(input.id);
return { array: input, texData: _this.texData[input.id] };
});
this.throwIfNoData(output.id);
var outputData = { array: output, texData: this.texData[output.id] };
var key = gpgpu_math.makeShaderKey(program, inputsData, outputData);
var binary = this.getAndSaveBinary(key, function () {
return gpgpu_math.compileProgram(_this.gpgpu, program, inputsData, outputData);
});
gpgpu_math.runProgram(binary, inputsData, outputData, customSetup);
return output;
};
MathBackendWebGL.prototype.getAndSaveBinary = function (key, getBinary) {
if (!(key in this.binaryCache)) {
this.binaryCache[key] = getBinary();
}
return this.binaryCache[key];
};
MathBackendWebGL.prototype.getTextureManager = function () {
return this.textureManager;
};
MathBackendWebGL.prototype.dispose = function () {
for (var key in this.binaryCache) {
this.gpgpu.deleteProgram(this.binaryCache[key].webGLProgram);
}
this.textureManager.dispose();
if (this.gpgpuCreatedLocally) {
this.gpgpu.dispose();
}
};
MathBackendWebGL.prototype.throwIfNoData = function (id) {
if (!(id in this.texData)) {
throw new Error("No data found for NDArray with id " + id + ". " +
"Use dl.ENV.math instead of constructing your own NDArrayMath. " +
"If you need to construct your own math, make sure this array is " +
"allocated after the math construction");
}
};
return MathBackendWebGL;
}());
exports.MathBackendWebGL = MathBackendWebGL;
environment_1.ENV.registerBackend('webgl', function () { return new MathBackendWebGL(); });
var NDArrayMathGPU = (function (_super) {
__extends(NDArrayMathGPU, _super);
function NDArrayMathGPU(gpgpu, safeMode) {
if (safeMode === void 0) { safeMode = false; }
var _this = this;
console.warn('new NDArrayMathGPU() is deprecated. Please use the global ' +
'dl.ENV.math. In rare cases, to construct your own NDArrayMath ' +
'that runs on GPU, use math = new NDArrayMath(\'webgl\', safeMode); ' +
'and make sure to set it as global: dl.ENV.setMath(math);');
_this = _super.call(this, new MathBackendWebGL(gpgpu), safeMode) || this;
environment_1.ENV.setMath(_this);
return _this;
}
NDArrayMathGPU.prototype.getGPGPUContext = function () {
return this.backendEngine.getBackend()
.getGPGPUContext();
};
NDArrayMathGPU.prototype.getTextureManager = function () {
return this.backendEngine.getBackend()
.getTextureManager();
};
return NDArrayMathGPU;
}(math_1.NDArrayMath));
exports.NDArrayMathGPU = NDArrayMathGPU;
function float32ToTypedArray(a, dtype) {
if (dtype === 'float32') {
return a;
}
else if (dtype === 'int32' || dtype === 'bool') {
var result = (dtype === 'int32') ? new Int32Array(a.length) :
new Uint8Array(a.length);
for (var i = 0; i < result.length; ++i) {
var val = a[i];
val = isNaN(val) ? util.getNaN(dtype) : Math.round(val);
result[i] = val;
}
return result;
}
else {
throw new Error("Unknown dtype " + dtype);
}
}
function typedArrayToFloat32(a, dtype) {
if (a instanceof Float32Array) {
return a;
}
else {
var res = new Float32Array(a.length);
for (var i = 0; i < res.length; i++) {
var val = a[i];
res[i] = util.isValNaN(val, dtype) ? NaN : val;
}
return res;
}
}
},{"../../environment":15,"../../util":101,"../axis_util":54,"../math":94,"../ndarray":95,"../reduce_util":97,"../types":99,"./webgl/argminmax_gpu":62,"./webgl/batchnorm_gpu":63,"./webgl/binaryop_gpu":64,"./webgl/clip_gpu":65,"./webgl/concat_gpu":66,"./webgl/conv_backprop_gpu":67,"./webgl/conv_gpu":68,"./webgl/conv_gpu_depthwise":69,"./webgl/copy_gpu":70,"./webgl/gpgpu_context":71,"./webgl/gpgpu_math":72,"./webgl/gpgpu_util":73,"./webgl/max_pool_backprop_gpu":74,"./webgl/mulmat_gpu":75,"./webgl/multinomial_gpu":76,"./webgl/onehot_gpu":77,"./webgl/pool_gpu":78,"./webgl/reduce_gpu":79,"./webgl/resize_bilinear_gpu":81,"./webgl/slice_gpu":83,"./webgl/tex_util":84,"./webgl/texture_manager":85,"./webgl/tile_gpu":86,"./webgl/transpose_gpu":87,"./webgl/unaryop_gpu":88,"./webgl/webgl_util":89}],58:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var KERNEL_METHODS = {
MatMul: function (backend, config) {
return backend.matMul(config.inputs.a, config.inputs.b, config.args.aOrientation, config.args.bOrientation);
},
Clone: function (backend, config) {
return backend.clone(config.inputs.x);
},
Slice1D: function (backend, config) {
return backend.slice1D(config.inputs.x, config.args.begin, config.args.size);
},
Slice2D: function (backend, config) {
return backend.slice2D(config.inputs.x, config.args.begin, config.args.size);
},
Slice3D: function (backend, config) {
return backend.slice3D(config.inputs.x, config.args.begin, config.args.size);
},
Slice4D: function (backend, config) {
return backend.slice4D(config.inputs.x, config.args.begin, config.args.size);
},
Concat1D: function (backend, config) {
return backend.concat1D(config.inputs.a, config.inputs.b);
},
Concat2D: function (backend, config) {
return backend.concat2D(config.inputs.a, config.inputs.b, config.args.axis);
},
Concat3D: function (backend, config) {
return backend.concat3D(config.inputs.a, config.inputs.b, config.args.axis);
},
Concat4D: function (backend, config) {
return backend.concat4D(config.inputs.a, config.inputs.b, config.args.axis);
},
Neg: function (backend, config) {
return backend.neg(config.inputs.x);
},
Add: function (backend, config) {
return backend.add(config.inputs.a, config.inputs.b);
},
Sub: function (backend, config) {
return backend.subtract(config.inputs.a, config.inputs.b);
},
Mul: function (backend, config) {
return backend.multiply(config.inputs.a, config.inputs.b);
},
Div: function (backend, config) {
return backend.divide(config.inputs.a, config.inputs.b);
},
Sum: function (backend, config) {
return backend.sum(config.inputs.x, config.args.axes);
},
ArgMax: function (backend, config) {
return backend.argMax(config.inputs.x, config.args.axes);
},
ArgMin: function (backend, config) {
return backend.argMin(config.inputs.x, config.args.axes);
},
Equal: function (backend, config) {
return backend.equal(config.inputs.a, config.inputs.b);
},
TopKValues: function (backend, config) {
return backend.topKValues(config.inputs.x, config.args.k);
},
TopKIndices: function (backend, config) {
return backend.topKIndices(config.inputs.x, config.args.k);
},
Min: function (backend, config) {
return backend.min(config.inputs.x, config.args.axes);
},
Max: function (backend, config) {
return backend.max(config.inputs.x, config.args.axes);
},
Ceil: function (backend, config) {
return backend.ceil(config.inputs.x);
},
Floor: function (backend, config) {
return backend.floor(config.inputs.x);
},
Pow: function (backend, config) {
return backend.pow(config.inputs.a, config.inputs.b);
},
Exp: function (backend, config) {
return backend.exp(config.inputs.x);
},
Log: function (backend, config) {
return backend.log(config.inputs.x);
},
Sqrt: function (backend, config) {
return backend.sqrt(config.inputs.x);
},
Square: function (backend, config) {
return backend.square(config.inputs.x);
},
Relu: function (backend, config) {
return backend.relu(config.inputs.x);
},
LeakyRelu: function (backend, config) {
return backend.leakyRelu(config.inputs.x, config.args.alpha);
},
PReLU: function (backend, config) {
return backend.prelu(config.inputs.x, config.inputs.alpha);
},
PReLUDer: function (backend, config) {
return backend.preluDer(config.inputs.x, config.inputs.alpha);
},
Elu: function (backend, config) {
return backend.elu(config.inputs.x);
},
EluDer: function (backend, config) {
return backend.eluDer(config.inputs.x);
},
Selu: function (backend, config) {
return backend.selu(config.inputs.x);
},
Abs: function (backend, config) {
return backend.abs(config.inputs.x);
},
Sigmoid: function (backend, config) {
return backend.sigmoid(config.inputs.x);
},
Step: function (backend, config) {
return backend.step(config.inputs.x, config.args.alpha);
},
Sin: function (backend, config) {
return backend.sin(config.inputs.x);
},
Cos: function (backend, config) {
return backend.cos(config.inputs.x);
},
Tan: function (backend, config) {
return backend.tan(config.inputs.x);
},
Asin: function (backend, config) {
return backend.asin(config.inputs.x);
},
Acos: function (backend, config) {
return backend.acos(config.inputs.x);
},
Atan: function (backend, config) {
return backend.atan(config.inputs.x);
},
Sinh: function (backend, config) {
return backend.sinh(config.inputs.x);
},
Cosh: function (backend, config) {
return backend.cosh(config.inputs.x);
},
Tanh: function (backend, config) {
return backend.tanh(config.inputs.x);
},
Clip: function (backend, config) {
return backend.clip(config.inputs.x, config.args.min, config.args.max);
},
Transpose: function (backend, config) {
return backend.transpose(config.inputs.x, config.args.perm);
},
Tile: function (backend, config) {
return backend.tile(config.inputs.x, config.args.reps);
},
Conv2D: function (backend, config) {
return backend.conv2d(config.inputs.x, config.inputs.filter, config.inputs.bias, config.args.convInfo);
},
Conv2DDerInput: function (backend, config) {
return backend.conv2dDerInput(config.inputs.dy, config.inputs.filter, config.args.convInfo);
},
Conv2DDerFilter: function (backend, config) {
return backend.conv2dDerFilter(config.inputs.x, config.inputs.dy, config.args.convInfo);
},
Conv2DDerBias: function (backend, config) {
return backend.conv2dDerBias(config.inputs.dy);
},
DepthwiseConv2D: function (backend, config) {
return backend.depthwiseConv2D(config.inputs.x, config.inputs.filter, config.args.convInfo);
},
MaxPool: function (backend, config) {
return backend.maxPool(config.inputs.x, config.args.convInfo);
},
MaxPoolBackprop: function (backend, config) {
return backend.maxPoolBackprop(config.inputs.dy, config.inputs.x, config.args.convInfo);
},
AvgPool: function (backend, config) {
return backend.avgPool(config.inputs.x, config.args.convInfo);
},
MinPool: function (backend, config) {
return backend.minPool(config.inputs.x, config.args.convInfo);
},
ResizeBilinear3D: function (backend, config) {
return backend.resizeBilinear3D(config.inputs.x, config.args.newShape2D, config.args.alignCorners);
},
BatchNorm3D: function (backend, config) {
return backend.batchNormalization3D(config.inputs.x, config.inputs.mean, config.inputs.variance, config.args.varianceEpsilon, config.inputs.scale, config.inputs.offset);
},
BatchNorm2D: function (backend, config) {
return backend.batchNormalization2D(config.inputs.x, config.inputs.mean, config.inputs.variance, config.args.varianceEpsilon, config.inputs.scale, config.inputs.offset);
},
Multinomial: function (backend, config) {
return backend.multinomial(config.inputs.probs, config.args.numSamples, config.args.seed);
},
OneHot: function (backend, config) {
return backend.oneHot(config.inputs.indices, config.args.depth, config.args.onValue, config.args.offValue);
}
};
function executeKernel(backend, kernelName, config) {
return KERNEL_METHODS[kernelName](backend, config);
}
exports.executeKernel = executeKernel;
},{}],59:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ndarray_1 = require("../ndarray");
var tape_util = require("./tape_util");
var Tape = (function () {
function Tape(backend) {
this.backend = backend;
this.evaluatedTapeNodes = [];
this.outputNodeMap = {};
}
Tape.prototype.addEvaluatedKernelNode = function (node) {
this.outputNodeMap[node.output.id] = node;
this.evaluatedTapeNodes.push(node);
};
Tape.prototype.gradientWrt = function (y, xs) {
if (this.outputNodeMap[y.id] == null) {
throw new Error("Cannot compute gradient: y is not part of this tape.");
}
var filteredNodes = tape_util.getFilteredNodesXToY(this.evaluatedTapeNodes, xs, y);
var arrayAccumulatedGradientMap = {};
arrayAccumulatedGradientMap[y.id] = ndarray_1.Scalar.new(1);
tape_util.backpropagateGradients(this.backend, arrayAccumulatedGradientMap, filteredNodes);
var gradients = [];
for (var i = 0; i < xs.length; i++) {
gradients.push(arrayAccumulatedGradientMap[xs[i].id]);
}
return gradients;
};
return Tape;
}());
exports.Tape = Tape;
},{"../ndarray":95,"./tape_util":60}],60:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getFilteredNodesXToY(tapeNodes, xs, y) {
var arraysFromX = {};
for (var i = 0; i < xs.length; i++) {
arraysFromX[xs[i].id] = true;
}
for (var i = 0; i < tapeNodes.length; i++) {
var node = tapeNodes[i];
var nodeInputs = node.inputAndArgs.inputs;
for (var inputName in nodeInputs) {
var input = nodeInputs[inputName];
for (var j = 0; j < xs.length; j++) {
if (arraysFromX[input.id]) {
arraysFromX[node.output.id] = true;
break;
}
}
if (arraysFromX[node.output.id]) {
break;
}
}
}
var arraysLeadToY = {};
arraysLeadToY[y.id] = true;
for (var i = tapeNodes.length - 1; i >= 0; i--) {
var node = tapeNodes[i];
var nodeInputs = node.inputAndArgs.inputs;
if (arraysLeadToY[node.output.id]) {
for (var inputName in nodeInputs) {
arraysLeadToY[nodeInputs[inputName].id] = true;
}
}
}
var filteredTapeNodes = [];
for (var i = 0; i < tapeNodes.length; i++) {
var node = tapeNodes[i];
if (arraysFromX[node.output.id] && arraysLeadToY[node.output.id]) {
var prunedInputs = {};
for (var inputName in node.inputAndArgs.inputs) {
var nodeInput = node.inputAndArgs.inputs[inputName];
if (arraysFromX[nodeInput.id]) {
prunedInputs[inputName] = nodeInput;
}
}
var prunedNode = Object.assign({}, node);
prunedNode.inputAndArgs = { inputs: prunedInputs };
filteredTapeNodes.push(prunedNode);
}
}
return filteredTapeNodes;
}
exports.getFilteredNodesXToY = getFilteredNodesXToY;
function backpropagateGradients(backend, arrayAccumulatedGradientMap, filteredNodes) {
for (var i = filteredNodes.length - 1; i >= 0; i--) {
var node = filteredNodes[i];
var dy = arrayAccumulatedGradientMap[node.output.id];
if (node.gradient == null) {
throw new Error("Cannot compute gradient: gradient function not found for\n " + node.name + ".");
}
var inputGradients = node.gradient(dy, node.output);
for (var inputName in node.inputAndArgs.inputs) {
if (!(inputName in inputGradients)) {
throw new Error("Cannot backprop through input " +
(node.name + "." + inputName + ". Gradients found: ") +
(Object.keys(inputGradients) + "."));
}
var grad = inputGradients[inputName]();
var activation = node.inputAndArgs.inputs[inputName];
if (arrayAccumulatedGradientMap[activation.id] == null) {
arrayAccumulatedGradientMap[activation.id] = grad;
}
else {
var curGradient = arrayAccumulatedGradientMap[activation.id];
arrayAccumulatedGradientMap[activation.id] =
backend.add(curGradient, grad);
curGradient.dispose();
}
}
}
}
exports.backpropagateGradients = backpropagateGradients;
},{}],61:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var MatrixOrientation;
(function (MatrixOrientation) {
MatrixOrientation[MatrixOrientation["REGULAR"] = 0] = "REGULAR";
MatrixOrientation[MatrixOrientation["TRANSPOSED"] = 1] = "TRANSPOSED";
})(MatrixOrientation = exports.MatrixOrientation || (exports.MatrixOrientation = {}));
},{}],62:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ArgMinMaxProgram = (function () {
function ArgMinMaxProgram(reduceInfo, op, firstPass) {
this.variableNames = ['A'];
var windowSize = reduceInfo.windowSize;
var batchSize = reduceInfo.batchSize;
var inSize = reduceInfo.inSize;
var outSize = Math.ceil(inSize / windowSize);
if (!firstPass) {
this.variableNames.push('bestIndicesA');
}
this.outputShape = [batchSize, outSize];
var compOp = (op === 'max') ? '>' : '<';
var indexSnippet = firstPass ?
'inOffset + i;' :
'round(getBestIndicesA(batch, inOffset + i));';
this.userCode = "\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = outIdx * " + windowSize + ";\n\n int bestIndex = 0;\n float bestValue = getA(batch, inOffset);\n\n for (int i = 0; i < " + windowSize + "; i++) {\n int inIdx = " + indexSnippet + ";\n float candidate = getA(batch, inIdx);\n if (isNaN(candidate)) {\n setOutput(candidate);\n return;\n }\n if (candidate " + compOp + " bestValue) {\n bestValue = candidate;\n bestIndex = inIdx;\n }\n }\n setOutput(float(bestIndex));\n }\n ";
}
return ArgMinMaxProgram;
}());
exports.ArgMinMaxProgram = ArgMinMaxProgram;
},{}],63:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var broadcast_util = require("../../broadcast_util");
var BatchNormProgram = (function () {
function BatchNormProgram(xShape, meanShape, varianceShape, offsetShape, scaleShape, varianceEpsilon) {
this.outputShape = [];
this.supportsBroadcasting = true;
this.variableNames = ['x', 'mean', 'variance'];
broadcast_util.assertAndGetBroadcastShape(xShape, meanShape);
broadcast_util.assertAndGetBroadcastShape(xShape, varianceShape);
var offsetSnippet = '0.0';
if (offsetShape != null) {
broadcast_util.assertAndGetBroadcastShape(xShape, offsetShape);
this.variableNames.push('offset');
offsetSnippet = 'getOffsetAtOutCoords()';
}
var scaleSnippet = '1.0';
if (scaleShape != null) {
broadcast_util.assertAndGetBroadcastShape(xShape, scaleShape);
this.variableNames.push('scale');
scaleSnippet = 'getScaleAtOutCoords()';
}
this.outputShape = xShape;
this.userCode = "\n void main() {\n float x = getXAtOutCoords();\n float mean = getMeanAtOutCoords();\n float variance = getVarianceAtOutCoords();\n float offset = " + offsetSnippet + ";\n float scale = " + scaleSnippet + ";\n float inv = scale / sqrt(variance + float(" + varianceEpsilon + "));\n setOutput((x - mean) * inv + offset);\n }\n ";
}
return BatchNormProgram;
}());
exports.BatchNormProgram = BatchNormProgram;
},{"../../broadcast_util":90}],64:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var broadcast_util = require("../../broadcast_util");
exports.ADD = 'return a + b;';
exports.SUB = 'return a - b;';
exports.MUL = 'return a * b;';
exports.DIV = 'return a / b;';
exports.POW = "\n return (round(mod(b, 2.0)) == 0 || round(mod(b, 2.0)) == 2) ?\n pow(abs(a), b) : sign(a) * pow(abs(a), b);\n";
exports.EQUAL = "\n if (isNaN(a)) return a;\n if (isNaN(b)) return b;\n return float(a == b);\n";
exports.PRELU = "\n return (a >= 0.0) ? a : b * a;\n";
exports.PRELU_DER = "\n return (a > 0.0) ? 1.0 : ((a < 0.0) ? b : a);\n";
var BinaryOpProgram = (function () {
function BinaryOpProgram(op, aShape, bShape) {
this.variableNames = ['A', 'B'];
this.supportsBroadcasting = true;
this.outputShape =
broadcast_util.assertAndGetBroadcastShape(aShape, bShape);
this.userCode = "\n float binaryOperation(float a, float b) {\n " + op + "\n }\n\n void main() {\n float a = getAAtOutCoords();\n float b = getBAtOutCoords();\n setOutput(binaryOperation(a, b));\n }\n ";
}
return BinaryOpProgram;
}());
exports.BinaryOpProgram = BinaryOpProgram;
},{"../../broadcast_util":90}],65:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ClipProgram = (function () {
function ClipProgram(aShape, min, max) {
this.variableNames = ['A'];
this.outputShape = aShape;
var minFixed = min.toFixed(20);
var maxFixed = max.toFixed(20);
this.userCode = "\n void main() {\n float value = getAAtOutCoords();\n if (isNaN(value)) {\n setOutput(value);\n return;\n }\n\n setOutput(clamp(value, " + minFixed + ", " + maxFixed + "));\n }\n ";
}
return ClipProgram;
}());
exports.ClipProgram = ClipProgram;
},{}],66:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var concat_util = require("../../concat_util");
var shader_compiler_1 = require("./shader_compiler");
var ConcatProgram = (function () {
function ConcatProgram(aShape, bShape, axis) {
this.variableNames = ['A', 'B'];
this.outputShape = [];
var yAxes = ['yR', 'yC', 'yD', 'yW'];
var concatAxis = yAxes[axis];
this.outputShape = concat_util.computeOutShape(aShape, bShape, axis);
var dType = shader_compiler_1.getCoordsDataType(aShape.length);
var unpackSnippet = getUnpack(aShape.length);
var sampleCoords = getSampleCoords(aShape.length);
this.userCode = "\n void main() {\n " + dType + " coords = getOutputCoords();\n " + unpackSnippet + "\n\n float value = 0.0;\n if (" + concatAxis + " < " + aShape[axis] + ") {\n value = getA(" + sampleCoords + ");\n } else {\n " + concatAxis + " -= " + aShape[axis] + ";\n value = getB(" + sampleCoords + ");\n }\n\n setOutput(value);\n }\n ";
}
return ConcatProgram;
}());
exports.ConcatProgram = ConcatProgram;
function getSampleCoords(rank) {
if (rank === 1) {
return 'yR';
}
else if (rank === 2) {
return 'yR, yC';
}
else if (rank === 3) {
return 'yR, yC, yD';
}
else if (rank === 4) {
return 'yR, yC, yD, yW';
}
else {
throw Error("Concat for rank " + rank + " is not yet supported");
}
}
function getUnpack(rank) {
var res = rank === 1 ? 'int yR = coords;' : 'int yR = coords.x;';
if (rank > 1) {
res += '\nint yC = coords.y;';
}
if (rank > 2) {
res += '\nint yD = coords.z;';
}
if (rank > 3) {
res += '\nint yW = coords.w;';
}
if (rank > 4) {
throw Error("Concat for rank " + rank + " is not yet supported");
}
return res;
}
},{"../../concat_util":91,"./shader_compiler":82}],67:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Conv2DDerFilterProgram = (function () {
function Conv2DDerFilterProgram(convInfo) {
this.variableNames = ['x', 'dy'];
this.outputShape = convInfo.filterShape;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var padTop = convInfo.padInfo.top;
var padLeft = convInfo.padInfo.left;
this.userCode = "\n void main() {\n ivec4 coords = getOutputCoords();\n int wR = coords.x;\n int wC = coords.y;\n int d1 = coords.z;\n int d2 = coords.w;\n\n // Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n\n for (int b = 0; b < " + convInfo.batchSize + "; b++) {\n for (int yR = 0; yR < " + convInfo.outHeight + "; yR++) {\n int xR = wR + yR * " + strideHeight + " - " + padTop + ";\n\n if (xR < 0 || xR >= " + convInfo.inHeight + ") {\n continue;\n }\n\n for (int yC = 0; yC < " + convInfo.outWidth + "; yC++) {\n int xC = wC + yC * " + strideWidth + " - " + padLeft + ";\n\n if (xC < 0 || xC >= " + convInfo.inWidth + ") {\n continue;\n }\n\n float dyValue = getDy(b, yR, yC, d2);\n float xValue = getX(b, xR, xC, d1);\n dotProd += (xValue * dyValue);\n }\n }\n }\n setOutput(dotProd);\n }\n ";
}
return Conv2DDerFilterProgram;
}());
exports.Conv2DDerFilterProgram = Conv2DDerFilterProgram;
var Conv2DDerInputProgram = (function () {
function Conv2DDerInputProgram(convInfo) {
this.variableNames = ['dy', 'W'];
this.outputShape = convInfo.inShape;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var padTop = filterHeight - 1 - convInfo.padInfo.top;
var padLeft = filterWidth - 1 - convInfo.padInfo.left;
this.userCode = "\n const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d1 = coords[3];\n\n ivec2 dyCorner = coords.yz - pads;\n int dyRCorner = dyCorner.x;\n int dyCCorner = dyCorner.y;\n\n // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < " + filterHeight + "; wR++) {\n float dyR = float(dyRCorner + wR) / " + strideHeight + ".0;\n\n if (dyR < 0.0 || dyR >= " + convInfo.outHeight + ".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n int wRPerm = " + filterHeight + " - 1 - wR;\n\n for (int wC = 0; wC < " + filterWidth + "; wC++) {\n float dyC = float(dyCCorner + wC) / " + strideWidth + ".0;\n\n if (dyC < 0.0 || dyC >= " + convInfo.outWidth + ".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n int wCPerm = " + filterWidth + " - 1 - wC;\n\n for (int d2 = 0; d2 < " + convInfo.outChannels + "; d2++) {\n float xValue = getDy(batch, idyR, idyC, d2);\n float wValue = getW(wRPerm, wCPerm, d1, d2);\n dotProd += xValue * wValue;\n }\n }\n }\n setOutput(dotProd);\n }\n ";
}
return Conv2DDerInputProgram;
}());
exports.Conv2DDerInputProgram = Conv2DDerInputProgram;
var Conv2DDerBiasProgram = (function () {
function Conv2DDerBiasProgram(yShape) {
this.variableNames = ['dy'];
var batchSize = yShape[0], yNumRows = yShape[1], yNumCols = yShape[2], outputDepth = yShape[3];
this.outputShape = [outputDepth];
this.userCode = "\n void main() {\n int d2 = getOutputCoords();\n\n float derBias = 0.0;\n for (int b = 0; b < " + batchSize + "; b++) {\n for (int yR = 0; yR < " + yNumRows + "; yR++) {\n for (int yC = 0; yC < " + yNumCols + "; yC++) {\n derBias += getDy(b, yR, yC, d2);\n }\n }\n }\n setOutput(derBias);\n }\n ";
}
return Conv2DDerBiasProgram;
}());
exports.Conv2DDerBiasProgram = Conv2DDerBiasProgram;
},{}],68:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Conv2DProgram = (function () {
function Conv2DProgram(convInfo, hasBias) {
this.variableNames = ['x', 'W'];
if (hasBias) {
this.variableNames.push('bias');
}
this.outputShape = convInfo.outShape;
var biasSnippet = hasBias ? 'dotProd += getBias(d2);' : '';
var padTop = convInfo.padInfo.top;
var padLeft = convInfo.padInfo.left;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var inputDepthNearestVec4 = Math.floor(convInfo.inChannels / 4) * 4;
var inputDepthVec4Remainder = convInfo.inChannels % 4;
this.userCode = "\n const ivec2 strides = ivec2(" + strideHeight + ", " + strideWidth + ");\n const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d2 = coords[3];\n\n ivec2 xRCCorner = coords.yz * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < " + filterHeight + "; wR++) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= " + convInfo.inHeight + ") {\n continue;\n }\n\n for (int wC = 0; wC < " + filterWidth + "; wC++) {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= " + convInfo.inWidth + ") {\n continue;\n }\n\n for (int d1 = 0; d1 < " + inputDepthNearestVec4 + "; d1 += 4) {\n vec4 xValues = vec4(\n getX(batch, xR, xC, d1),\n getX(batch, xR, xC, d1 + 1),\n getX(batch, xR, xC, d1 + 2),\n getX(batch, xR, xC, d1 + 3)\n );\n vec4 wValues = vec4(\n getW(wR, wC, d1, d2),\n getW(wR, wC, d1 + 1, d2),\n getW(wR, wC, d1 + 2, d2),\n getW(wR, wC, d1 + 3, d2)\n );\n\n dotProd += dot(xValues, wValues);\n }\n\n if (" + (inputDepthVec4Remainder === 1) + ") {\n dotProd +=\n getX(batch, xR, xC, " + inputDepthNearestVec4 + ") *\n getW(wR, wC, " + inputDepthNearestVec4 + ", d2);\n } else if (" + (inputDepthVec4Remainder === 2) + ") {\n vec2 xValues = vec2(\n getX(batch, xR, xC, " + inputDepthNearestVec4 + "),\n getX(batch, xR, xC, " + inputDepthNearestVec4 + " + 1)\n );\n vec2 wValues = vec2(\n getW(wR, wC, " + inputDepthNearestVec4 + ", d2),\n getW(wR, wC, " + inputDepthNearestVec4 + " + 1, d2)\n );\n dotProd += dot(xValues, wValues);\n } else if (" + (inputDepthVec4Remainder === 3) + ") {\n vec3 xValues = vec3(\n getX(batch, xR, xC, " + inputDepthNearestVec4 + "),\n getX(batch, xR, xC, " + inputDepthNearestVec4 + " + 1),\n getX(batch, xR, xC, " + inputDepthNearestVec4 + " + 2)\n );\n vec3 wValues = vec3(\n getW(wR, wC, " + inputDepthNearestVec4 + ", d2),\n getW(wR, wC, " + inputDepthNearestVec4 + " + 1, d2),\n getW(wR, wC, " + inputDepthNearestVec4 + " + 2, d2)\n );\n dotProd += dot(xValues, wValues);\n }\n }\n }\n " + biasSnippet + "\n setOutput(dotProd);\n }\n ";
}
return Conv2DProgram;
}());
exports.Conv2DProgram = Conv2DProgram;
},{}],69:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var DepthwiseConv2DProgram = (function () {
function DepthwiseConv2DProgram(convInfo) {
this.variableNames = ['x', 'W'];
this.outputShape = convInfo.outShape;
var xNumRows = convInfo.inHeight;
var xNumCols = convInfo.inWidth;
var padTop = convInfo.padInfo.top;
var padLeft = convInfo.padInfo.left;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var channelMul = convInfo.outChannels / convInfo.inChannels;
this.userCode = "\n const ivec2 strides = ivec2(" + strideHeight + ", " + strideWidth + ");\n const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords.x;\n ivec2 xRCCorner = coords.yz * strides - pads;\n int d2 = coords.w;\n int d1 = d2 / " + channelMul + ";\n int q = d2 - d1 * " + channelMul + ";\n\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n // TODO(dsmilkov): Flatten the two for loops and vec4 the operations.\n for (int wR = 0; wR < " + filterHeight + "; wR++) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= " + xNumRows + ") {\n continue;\n }\n\n for (int wC = 0; wC < " + filterWidth + "; wC++) {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= " + xNumCols + ") {\n continue;\n }\n\n float xVal = getX(batch, xR, xC, d1);\n float wVal = getW(wR, wC, d1, q);\n dotProd += xVal * wVal;\n }\n }\n setOutput(dotProd);\n }\n ";
}
return DepthwiseConv2DProgram;
}());
exports.DepthwiseConv2DProgram = DepthwiseConv2DProgram;
},{}],70:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Copy2DProgram = (function () {
function Copy2DProgram(srcNumCols, destNumCols) {
this.variableNames = ['source'];
this.outputShape = null;
this.userCode = "\n uniform ivec2 sourceStart;\n uniform ivec2 destStart;\n\n void main() {\n ivec2 destCoords = getOutputCoords() - destStart;\n int index = destCoords.x * " + destNumCols + " + destCoords.y;\n int r = index / " + srcNumCols + ";\n ivec2 sourceCoords = sourceStart + ivec2(r, index - r * " + srcNumCols + ");\n setOutput(getSource(sourceCoords.x, sourceCoords.y));\n }\n ";
}
Copy2DProgram.prototype.getCustomSetupFunc = function (sourceStart, destStart, destSize) {
return function (gpgpu, webGLProgram) {
gpgpu.setOutputMatrixWriteRegion(destStart[0], destSize[0], destStart[1], destSize[1]);
var sourceStartCRLoc = gpgpu.getUniformLocation(webGLProgram, 'sourceStart');
gpgpu.gl.uniform2i(sourceStartCRLoc, sourceStart[0], sourceStart[1]);
var destStartCRLoc = gpgpu.getUniformLocation(webGLProgram, 'destStart');
gpgpu.gl.uniform2i(destStartCRLoc, destStart[0], destStart[1]);
};
};
return Copy2DProgram;
}());
exports.Copy2DProgram = Copy2DProgram;
},{}],71:[function(require,module,exports){
"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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, 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 environment_1 = require("../../../environment");
var util = require("../../../util");
var gpgpu_util = require("./gpgpu_util");
var tex_util = require("./tex_util");
var webgl_util = require("./webgl_util");
var GPGPUContext = (function () {
function GPGPUContext(gl) {
this.outputTexture = null;
this.program = null;
this.disposed = false;
this.autoDebugValidate = false;
if (gl != null) {
this.gl = gl;
}
else {
this.gl = gpgpu_util.createWebGLContext();
}
if (environment_1.ENV.get('WEBGL_VERSION') === 1) {
this.textureFloatExtension =
webgl_util.getExtensionOrThrow(this.gl, 'OES_texture_float');
this.colorBufferFloatExtension =
this.gl.getExtension('WEBGL_color_buffer_float');
}
else {
this.colorBufferFloatExtension =
webgl_util.getExtensionOrThrow(this.gl, 'EXT_color_buffer_float');
}
this.loseContextExtension =
webgl_util.getExtensionOrThrow(this.gl, 'WEBGL_lose_context');
if (environment_1.ENV.get('WEBGL_GET_BUFFER_SUB_DATA_ASYNC_EXTENSION_ENABLED')) {
this.getBufferSubDataAsyncExtension =
this.gl.getExtension('WEBGL_get_buffer_sub_data_async');
}
this.vertexBuffer = gpgpu_util.createVertexBuffer(this.gl);
this.indexBuffer = gpgpu_util.createIndexBuffer(this.gl);
this.framebuffer = webgl_util.createFramebuffer(this.gl);
}
GPGPUContext.prototype.dispose = function () {
var _this = this;
this.throwIfDisposed();
if (this.program != null) {
console.warn('Disposing a GPGPUContext that still has a bound WebGLProgram.' +
' This is probably a resource leak, delete the program with ' +
'GPGPUContext.deleteProgram before disposing.');
}
if (this.outputTexture != null) {
console.warn('Disposing a GPGPUContext that still has a bound output matrix ' +
'texture. This is probably a resource leak, delete the output ' +
'matrix texture with GPGPUContext.deleteMatrixTexture before ' +
'disposing.');
}
var gl = this.gl;
webgl_util.callAndCheck(gl, function () { return gl.finish(); });
webgl_util.callAndCheck(gl, function () { return gl.bindFramebuffer(gl.FRAMEBUFFER, null); });
webgl_util.callAndCheck(gl, function () { return gl.deleteFramebuffer(_this.framebuffer); });
webgl_util.callAndCheck(gl, function () { return gl.bindBuffer(gl.ARRAY_BUFFER, null); });
webgl_util.callAndCheck(gl, function () { return gl.deleteBuffer(_this.vertexBuffer); });
webgl_util.callAndCheck(gl, function () { return gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, null); });
webgl_util.callAndCheck(gl, function () { return gl.deleteBuffer(_this.indexBuffer); });
this.loseContextExtension.loseContext();
this.disposed = true;
};
GPGPUContext.prototype.enableAutomaticDebugValidation = function (enabled) {
this.autoDebugValidate = enabled;
webgl_util.enableDebugWebGLErrorChecking(enabled);
};
GPGPUContext.prototype.createMatrixTexture = function (rows, columns) {
this.throwIfDisposed();
return gpgpu_util.createMatrixTexture(this.gl, rows, columns);
};
GPGPUContext.prototype.uploadPixelDataToTexture = function (texture, pixels) {
this.throwIfDisposed();
gpgpu_util.uploadPixelDataToTexture(this.gl, texture, pixels);
};
GPGPUContext.prototype.createPackedMatrixTexture = function (rows, columns) {
this.throwIfDisposed();
return gpgpu_util.createPackedMatrixTexture(this.gl, rows, columns);
};
GPGPUContext.prototype.deleteMatrixTexture = function (texture) {
var _this = this;
this.throwIfDisposed();
if (this.outputTexture === texture) {
webgl_util.unbindColorTextureFromFramebuffer(this.gl, this.framebuffer);
this.outputTexture = null;
}
webgl_util.callAndCheck(this.gl, function () { return _this.gl.deleteTexture(texture); });
};
GPGPUContext.prototype.uploadMatrixToTexture = function (texture, rows, columns, matrix) {
this.throwIfDisposed();
var numChannels = 1;
return gpgpu_util.uploadMatrixToTexture(this.gl, texture, rows, columns, matrix, numChannels);
};
GPGPUContext.prototype.uploadMatrixToPackedTexture = function (texture, rows, columns, matrix) {
this.throwIfDisposed();
return gpgpu_util.uploadMatrixToPackedTexture(this.gl, texture, rows, columns, matrix);
};
GPGPUContext.prototype.downloadMatrixFromTexture = function (texture, rows, columns) {
var _this = this;
return this.downloadMatrixDriver(texture, function () {
return gpgpu_util.downloadMatrixFromOutputTexture(_this.gl, rows, columns);
});
};
GPGPUContext.prototype.downloadMatrixFromTextureAsync = function (texture, rows, columns) {
return __awaiter(this, void 0, void 0, function () {
var _this = this;
return __generator(this, function (_a) {
if (this.getBufferSubDataAsyncExtension == null) {
throw new Error("Cannot download matrix from output texture asynchronously, " +
"WEBGL_get_buffer_sub_data_async is not enabled.");
}
return [2, this.downloadMatrixDriverAsync(texture, function () { return gpgpu_util.downloadMatrixFromOutputTextureAsync(_this.gl, _this.getBufferSubDataAsyncExtension, rows, columns); })];
});
});
};
GPGPUContext.prototype.downloadMatrixFromRGBAColorTexture = function (texture, rows, columns, channels) {
var _this = this;
return this.downloadMatrixDriver(texture, function () { return gpgpu_util.downloadMatrixFromRGBAColorTexture(_this.gl, rows, columns, channels); });
};
GPGPUContext.prototype.downloadMatrixFromPackedTexture = function (texture, rows, columns) {
var _this = this;
return this.downloadMatrixDriver(texture, function () { return gpgpu_util.downloadMatrixFromPackedOutputTexture(_this.gl, rows, columns); });
};
GPGPUContext.prototype.createProgram = function (fragmentShaderSource) {
this.throwIfDisposed();
var gl = this.gl;
var fragmentShader = webgl_util.createFragmentShader(gl, fragmentShaderSource);
var vertexShader = gpgpu_util.createVertexShader(gl);
var program = webgl_util.createProgram(gl);
webgl_util.callAndCheck(gl, function () { return gl.attachShader(program, vertexShader); });
webgl_util.callAndCheck(gl, function () { return gl.attachShader(program, fragmentShader); });
webgl_util.linkProgram(gl, program);
if (this.autoDebugValidate) {
webgl_util.validateProgram(gl, program);
}
return program;
};
GPGPUContext.prototype.deleteProgram = function (program) {
var _this = this;
this.throwIfDisposed();
if (program === this.program) {
this.program = null;
}
if (program != null) {
webgl_util.callAndCheck(this.gl, function () { return _this.gl.deleteProgram(program); });
}
};
GPGPUContext.prototype.setProgram = function (program) {
var _this = this;
this.throwIfDisposed();
this.program = program;
if ((this.program != null) && this.autoDebugValidate) {
webgl_util.validateProgram(this.gl, this.program);
}
webgl_util.callAndCheck(this.gl, function () { return _this.gl.useProgram(program); });
};
GPGPUContext.prototype.getUniformLocation = function (program, uniformName) {
this.throwIfDisposed();
return webgl_util.getProgramUniformLocationOrThrow(this.gl, program, uniformName);
};
GPGPUContext.prototype.getAttributeLocation = function (program, attribute) {
var _this = this;
this.throwIfDisposed();
return webgl_util.callAndCheck(this.gl, function () { return _this.gl.getAttribLocation(program, attribute); });
};
GPGPUContext.prototype.getUniformLocationNoThrow = function (program, uniformName) {
this.throwIfDisposed();
return this.gl.getUniformLocation(program, uniformName);
};
GPGPUContext.prototype.setInputMatrixTexture = function (inputMatrixTexture, uniformLocation, textureUnit) {
this.throwIfDisposed();
this.throwIfNoProgram();
webgl_util.bindTextureToProgramUniformSampler(this.gl, this.program, inputMatrixTexture, uniformLocation, textureUnit);
};
GPGPUContext.prototype.setOutputMatrixTexture = function (outputMatrixTexture, rows, columns) {
this.setOutputMatrixTextureDriver(outputMatrixTexture, columns, rows);
};
GPGPUContext.prototype.setOutputPackedMatrixTexture = function (outputPackedMatrixTexture, rows, columns) {
this.throwIfDisposed();
var _a = tex_util.getPackedMatrixTextureShapeWidthHeight(rows, columns), width = _a[0], height = _a[1];
this.setOutputMatrixTextureDriver(outputPackedMatrixTexture, width, height);
};
GPGPUContext.prototype.setOutputMatrixWriteRegion = function (startRow, numRows, startColumn, numColumns) {
this.setOutputMatrixWriteRegionDriver(startColumn, startRow, numColumns, numRows);
};
GPGPUContext.prototype.setOutputPackedMatrixWriteRegion = function (startRow, numRows, startColumn, numColumns) {
throw new Error('setOutputPackedMatrixWriteRegion not implemented.');
};
GPGPUContext.prototype.debugValidate = function () {
if (this.program != null) {
webgl_util.validateProgram(this.gl, this.program);
}
webgl_util.validateFramebuffer(this.gl);
};
GPGPUContext.prototype.executeProgram = function (attribLocations) {
this.throwIfDisposed();
this.throwIfNoProgram();
var gl = this.gl;
gpgpu_util.bindVertexProgramAttributeStreams(gl, this.program, this.vertexBuffer, attribLocations);
if (this.autoDebugValidate) {
this.debugValidate();
}
webgl_util.callAndCheck(gl, function () { return gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0); });
};
GPGPUContext.prototype.blockUntilAllProgramsCompleted = function () {
var _this = this;
this.throwIfDisposed();
webgl_util.callAndCheck(this.gl, function () { return _this.gl.finish(); });
};
GPGPUContext.prototype.runQuery = function (queryFn) {
if (environment_1.ENV.get('WEBGL_VERSION') === 2) {
return this.runQueryWebGL2(queryFn);
}
return this.runQueryWebGL1(queryFn);
};
GPGPUContext.prototype.runQueryWebGL2 = function (benchmark) {
var _this = this;
var ext = webgl_util.getExtensionOrThrow(this.gl, 'EXT_disjoint_timer_query_webgl2');
var query = this.gl.createQuery();
this.gl.beginQuery(ext.TIME_ELAPSED_EXT, query);
benchmark();
this.gl.endQuery(ext.TIME_ELAPSED_EXT);
return new Promise(function (resolve, reject) {
var queryGPU = function () {
var available = _this.gl
.getQueryParameter(query, _this.gl.QUERY_RESULT_AVAILABLE);
var disjoint = _this.gl.getParameter(ext.GPU_DISJOINT_EXT);
return available && !disjoint;
};
var getTimeElapsed = function () {
var timeElapsedNanos = _this.gl
.getQueryParameter(query, _this.gl.QUERY_RESULT);
resolve(timeElapsedNanos / 1000000);
};
var resolveWithWarning = function () {
console.warn('Disjoint query timer never available.');
resolve(-1);
};
util.repeatedTry(queryGPU).then(getTimeElapsed).catch(resolveWithWarning);
});
};
GPGPUContext.prototype.runQueryWebGL1 = function (benchmark) {
var _this = this;
var ext = webgl_util.getExtensionOrThrow(this.gl, 'EXT_disjoint_timer_query');
var query = ext.createQueryEXT();
ext.beginQueryEXT(ext.TIME_ELAPSED_EXT, query);
benchmark();
ext.endQueryEXT(ext.TIME_ELAPSED_EXT);
return new Promise(function (resolve, reject) {
var queryGPU = function () {
var available = ext.getQueryObjectEXT(query, ext.QUERY_RESULT_AVAILABLE_EXT);
var disjoint = _this.gl.getParameter(ext.GPU_DISJOINT_EXT);
return available && !disjoint;
};
var getTimeElapsed = function () {
var timeElapsedNanos = ext.getQueryObjectEXT(query, ext.QUERY_RESULT_EXT);
resolve(timeElapsedNanos / 1000000);
};
var resolveWithWarning = function () {
console.warn('Disjoint query timer never available.');
resolve(-1);
};
util.repeatedTry(queryGPU).then(getTimeElapsed).catch(resolveWithWarning);
});
};
GPGPUContext.prototype.downloadMatrixDriverSetup = function (texture) {
this.throwIfDisposed();
webgl_util.bindColorTextureToFramebuffer(this.gl, texture, this.framebuffer);
if (this.autoDebugValidate) {
webgl_util.validateFramebuffer(this.gl);
}
};
GPGPUContext.prototype.downloadMatrixDriverTeardown = function () {
if (this.outputTexture != null) {
webgl_util.bindColorTextureToFramebuffer(this.gl, this.outputTexture, this.framebuffer);
if (this.autoDebugValidate) {
webgl_util.validateFramebuffer(this.gl);
}
}
else {
webgl_util.unbindColorTextureFromFramebuffer(this.gl, this.framebuffer);
}
};
GPGPUContext.prototype.downloadMatrixDriver = function (texture, downloadAndDecode) {
this.downloadMatrixDriverSetup(texture);
var result = downloadAndDecode();
this.downloadMatrixDriverTeardown();
return result;
};
GPGPUContext.prototype.downloadMatrixDriverAsync = function (texture, downloadAndDecode) {
return __awaiter(this, void 0, void 0, function () {
var result;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.downloadMatrixDriverSetup(texture);
return [4, downloadAndDecode()];
case 1:
result = _a.sent();
this.downloadMatrixDriverTeardown();
return [2, result];
}
});
});
};
GPGPUContext.prototype.setOutputMatrixTextureDriver = function (outputMatrixTextureMaybePacked, width, height) {
this.throwIfDisposed();
var gl = this.gl;
webgl_util.bindColorTextureToFramebuffer(gl, outputMatrixTextureMaybePacked, this.framebuffer);
if (this.autoDebugValidate) {
webgl_util.validateFramebuffer(gl);
}
this.outputTexture = outputMatrixTextureMaybePacked;
webgl_util.callAndCheck(gl, function () { return gl.viewport(0, 0, width, height); });
webgl_util.callAndCheck(gl, function () { return gl.scissor(0, 0, width, height); });
};
GPGPUContext.prototype.setOutputMatrixWriteRegionDriver = function (x, y, width, height) {
var _this = this;
this.throwIfDisposed();
webgl_util.callAndCheck(this.gl, function () { return _this.gl.scissor(x, y, width, height); });
};
GPGPUContext.prototype.throwIfDisposed = function () {
if (this.disposed) {
throw new Error('Attempted to use disposed GPGPUContext.');
}
};
GPGPUContext.prototype.throwIfNoProgram = function () {
if (this.program == null) {
throw new Error('No GPU program is currently set.');
}
};
return GPGPUContext;
}());
exports.GPGPUContext = GPGPUContext;
},{"../../../environment":15,"../../../util":101,"./gpgpu_util":73,"./tex_util":84,"./webgl_util":89}],72:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../../environment");
var util = require("../../../util");
var shader_compiler = require("./shader_compiler");
var ATTRIBUTE_NAMES = ['uv', 'clipSpacePos'];
var NAN_UNIFORM_NAME = 'NaN';
function shouldUploadNaNUniform() {
return !environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED');
}
function compileProgram(gpgpu, program, inputs, output) {
var userCode = program.userCode;
var inputInfos = inputs.map(function (input, i) {
var shapeInfo = {
logicalShape: input.array.shape,
texShape: input.texData.texShape,
textureType: input.texData.textureType
};
return { name: program.variableNames[i], shapeInfo: shapeInfo };
});
var inShapeInfos = inputInfos.map(function (x) { return x.shapeInfo; });
var outShapeInfo = {
logicalShape: output.array.shape,
texShape: output.texData.texShape,
textureType: output.texData.textureType
};
var source = shader_compiler.makeShader(inputInfos, outShapeInfo, userCode, program.supportsBroadcasting === true);
var webGLProgram = gpgpu.createProgram(source);
var uniformLocations = {};
for (var i = 0; i < program.variableNames.length; i++) {
var uniformName = program.variableNames[i];
uniformLocations[uniformName] =
gpgpu.getUniformLocation(webGLProgram, uniformName);
}
var attributeLocations = {};
ATTRIBUTE_NAMES.forEach(function (attribute) {
attributeLocations[attribute] =
gpgpu.getAttributeLocation(webGLProgram, attribute);
});
if (shouldUploadNaNUniform()) {
uniformLocations[NAN_UNIFORM_NAME] =
gpgpu.getUniformLocation(webGLProgram, NAN_UNIFORM_NAME);
}
return {
program: program,
source: source,
webGLProgram: webGLProgram,
uniformLocations: uniformLocations,
attributeLocations: attributeLocations,
gpgpu: gpgpu,
inShapeInfos: inShapeInfos,
outShapeInfo: outShapeInfo
};
}
exports.compileProgram = compileProgram;
function validateBinaryAndProgram(shapeInfos, inputs) {
if (shapeInfos.length !== inputs.length) {
throw Error("Binary was compiled with " + shapeInfos.length + " inputs, but " +
("was executed with " + inputs.length + " inputs"));
}
shapeInfos.forEach(function (s, i) {
var shapeA = s.logicalShape;
var texShapeA = s.texShape;
var shapeB = inputs[i].array.shape;
var texShapeB = inputs[i].texData.texShape;
if (!util.arraysEqual(shapeA, shapeB)) {
throw Error("Binary was compiled with different shapes than " +
("the current args. Shapes " + shapeA + " and " + shapeB + " must match"));
}
if (!util.arraysEqual(texShapeA, texShapeB)) {
throw Error("Binary was compiled with different texture shapes than the" +
(" current args. Shape " + texShapeA + " and " + texShapeB + " must match"));
}
});
}
function runProgram(binary, inputs, output, customSetup) {
validateBinaryAndProgram(binary.inShapeInfos, inputs);
validateBinaryAndProgram([binary.outShapeInfo], [output]);
var outTex = output.texData.texture;
var outTexShape = output.texData.texShape;
var gpgpu = binary.gpgpu;
gpgpu.setOutputMatrixTexture(outTex, outTexShape[0], outTexShape[1]);
gpgpu.setProgram(binary.webGLProgram);
inputs.forEach(function (input, i) {
var tex = input.texData.texture;
var variableName = binary.program.variableNames[i];
var variableUniformLocation = binary.uniformLocations[variableName];
gpgpu.setInputMatrixTexture(tex, variableUniformLocation, i);
});
if (shouldUploadNaNUniform()) {
gpgpu.gl.uniform1f(binary.uniformLocations[NAN_UNIFORM_NAME], NaN);
}
if (customSetup != null) {
customSetup(gpgpu, binary.webGLProgram);
}
gpgpu.executeProgram(binary.attributeLocations);
}
exports.runProgram = runProgram;
function makeShaderKey(program, inputs, output) {
var keyInputs = '';
inputs.concat(output).forEach(function (x) {
keyInputs += x.array.shape + "_" + x.texData.texShape;
});
var keyUserCode = program.userCode;
var keyBroadcast = (program.supportsBroadcasting === true).toString();
var key = program.constructor.name;
key += '_' + keyBroadcast + '_' + keyInputs + '_' + keyUserCode;
return key;
}
exports.makeShaderKey = makeShaderKey;
},{"../../../environment":15,"../../../util":101,"./shader_compiler":82}],73:[function(require,module,exports){
"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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, 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 environment_1 = require("../../../environment");
var tex_util = require("./tex_util");
var webgl_util = require("./webgl_util");
function getWebGLContextAttributes() {
return {
alpha: false,
antialias: false,
premultipliedAlpha: false,
preserveDrawingBuffer: false,
depth: false,
stencil: false,
failIfMajorPerformanceCaveat: true
};
}
exports.getWebGLContextAttributes = getWebGLContextAttributes;
function createWebGLContext(canvas) {
var attributes = getWebGLContextAttributes();
var gl;
if (canvas != null) {
gl = webgl_util.createWebGLRenderingContextFromCanvas(canvas, attributes);
}
else {
gl = webgl_util.createWebGLRenderingContext(attributes);
}
webgl_util.callAndCheck(gl, function () { return gl.disable(gl.DEPTH_TEST); });
webgl_util.callAndCheck(gl, function () { return gl.disable(gl.STENCIL_TEST); });
webgl_util.callAndCheck(gl, function () { return gl.disable(gl.BLEND); });
webgl_util.callAndCheck(gl, function () { return gl.disable(gl.DITHER); });
webgl_util.callAndCheck(gl, function () { return gl.disable(gl.POLYGON_OFFSET_FILL); });
webgl_util.callAndCheck(gl, function () { return gl.disable(gl.SAMPLE_COVERAGE); });
webgl_util.callAndCheck(gl, function () { return gl.enable(gl.SCISSOR_TEST); });
webgl_util.callAndCheck(gl, function () { return gl.enable(gl.CULL_FACE); });
webgl_util.callAndCheck(gl, function () { return gl.cullFace(gl.BACK); });
return gl;
}
exports.createWebGLContext = createWebGLContext;
function createVertexShader(gl) {
var vertexShaderSource = "\n precision highp float;\n attribute vec3 clipSpacePos;\n attribute vec2 uv;\n varying vec2 resultUV;\n\n void main() {\n gl_Position = vec4(clipSpacePos, 1);\n resultUV = uv;\n }";
return webgl_util.createVertexShader(gl, vertexShaderSource);
}
exports.createVertexShader = createVertexShader;
function createVertexBuffer(gl) {
var vertexArray = new Float32Array([-1, 1, 0, 0, 1, -1, -1, 0, 0, 0, 1, 1, 0, 1, 1, 1, -1, 0, 1, 0]);
return webgl_util.createStaticVertexBuffer(gl, vertexArray);
}
exports.createVertexBuffer = createVertexBuffer;
function createIndexBuffer(gl) {
var triangleVertexIndices = new Uint16Array([0, 1, 2, 2, 1, 3]);
return webgl_util.createStaticIndexBuffer(gl, triangleVertexIndices);
}
exports.createIndexBuffer = createIndexBuffer;
function getTextureInternalFormat(gl, numChannels) {
if (!environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED')) {
return gl.RGBA;
}
if (environment_1.ENV.get('WEBGL_VERSION') === 2) {
if (numChannels === 4) {
return gl.RGBA32F;
}
return gl.R32F;
}
return gl.RGBA;
}
function getTextureFormat(gl, numChannels) {
if (!environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED')) {
return gl.RGBA;
}
if (environment_1.ENV.get('WEBGL_VERSION') === 2) {
if (numChannels === 4) {
return gl.RGBA;
}
return gl.RED;
}
return gl.RGBA;
}
function getTextureType(gl) {
if (!environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED')) {
return gl.UNSIGNED_BYTE;
}
return gl.FLOAT;
}
function createAndConfigureTexture(gl, width, height, numChannels) {
webgl_util.validateTextureSize(gl, width, height);
var texture = webgl_util.createTexture(gl);
var tex2d = gl.TEXTURE_2D;
var internalFormat = getTextureInternalFormat(gl, numChannels);
var format = getTextureFormat(gl, numChannels);
webgl_util.callAndCheck(gl, function () { return gl.bindTexture(tex2d, texture); });
webgl_util.callAndCheck(gl, function () { return gl.texParameteri(tex2d, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); });
webgl_util.callAndCheck(gl, function () { return gl.texParameteri(tex2d, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); });
webgl_util.callAndCheck(gl, function () { return gl.texParameteri(tex2d, gl.TEXTURE_MIN_FILTER, gl.NEAREST); });
webgl_util.callAndCheck(gl, function () { return gl.texParameteri(tex2d, gl.TEXTURE_MAG_FILTER, gl.NEAREST); });
webgl_util.callAndCheck(gl, function () { return gl.texImage2D(tex2d, 0, internalFormat, width, height, 0, format, getTextureType(gl), null); });
webgl_util.callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, null); });
return texture;
}
function createMatrixTexture(gl, rows, columns) {
var _a = tex_util.getUnpackedMatrixTextureShapeWidthHeight(rows, columns), width = _a[0], height = _a[1];
var numChannels = 1;
return createAndConfigureTexture(gl, width, height, numChannels);
}
exports.createMatrixTexture = createMatrixTexture;
function createColorMatrixTexture(gl, rows, columns) {
var _a = tex_util.getColorMatrixTextureShapeWidthHeight(rows, columns), width = _a[0], height = _a[1];
var numChannels = 4;
return createAndConfigureTexture(gl, width, height, numChannels);
}
exports.createColorMatrixTexture = createColorMatrixTexture;
function createPackedMatrixTexture(gl, rows, columns) {
var _a = tex_util.getPackedMatrixTextureShapeWidthHeight(rows, columns), width = _a[0], height = _a[1];
var numChannels = 4;
return createAndConfigureTexture(gl, width, height, numChannels);
}
exports.createPackedMatrixTexture = createPackedMatrixTexture;
function bindVertexProgramAttributeStreams(gl, program, vertexBuffer, attribLocations) {
var posOffset = 0;
var uvOffset = 3 * 4;
var stride = (3 * 4) + (2 * 4);
webgl_util.callAndCheck(gl, function () { return gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); });
webgl_util.bindVertexBufferToProgramAttribute(gl, program, 'clipSpacePos', vertexBuffer, 3, stride, posOffset, attribLocations);
webgl_util.bindVertexBufferToProgramAttribute(gl, program, 'uv', vertexBuffer, 2, stride, uvOffset, attribLocations);
}
exports.bindVertexProgramAttributeStreams = bindVertexProgramAttributeStreams;
function uploadPixelDataToTexture(gl, texture, pixels) {
webgl_util.callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, texture); });
webgl_util.callAndCheck(gl, function () { return gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, pixels); });
webgl_util.callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, null); });
}
exports.uploadPixelDataToTexture = uploadPixelDataToTexture;
function uploadDataToTexture(gl, texture, width, height, data, numChannels) {
var textureFormat = getTextureFormat(gl, numChannels);
webgl_util.validateTextureSize(gl, width, height);
webgl_util.callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, texture); });
webgl_util.callAndCheck(gl, function () { return gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, width, height, textureFormat, getTextureType(gl), data); });
webgl_util.callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, null); });
}
function uploadMatrixToTexture(gl, texture, rows, columns, matrix, numChannels) {
var _a = tex_util.getUnpackedMatrixTextureShapeWidthHeight(rows, columns), w = _a[0], h = _a[1];
var unpackedArray;
if (environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED')) {
var channelsPerTexture = numChannels === 1 ? webgl_util.getChannelsPerTexture() : numChannels;
if (channelsPerTexture === 1) {
unpackedArray = matrix;
}
else {
unpackedArray =
new Float32Array(tex_util.getUnpackedArraySizeFromMatrixSize(matrix.length, channelsPerTexture));
tex_util.encodeMatrixToUnpackedArray(matrix, unpackedArray, channelsPerTexture);
}
}
else {
unpackedArray = tex_util.encodeFloatArray(matrix);
}
uploadDataToTexture(gl, texture, w, h, unpackedArray, numChannels);
}
exports.uploadMatrixToTexture = uploadMatrixToTexture;
function uploadMatrixToPackedTexture(gl, texture, rows, columns, matrix) {
var _a = tex_util.getPackedMatrixTextureShapeWidthHeight(rows, columns), w = _a[0], h = _a[1];
var packedRGBA = new Float32Array(tex_util.getPackedRGBAArraySizeFromMatrixShape(rows, columns));
tex_util.encodeMatrixToPackedRGBA(matrix, rows, columns, packedRGBA);
var numChannels = 4;
uploadDataToTexture(gl, texture, w, h, packedRGBA, numChannels);
}
exports.uploadMatrixToPackedTexture = uploadMatrixToPackedTexture;
function getDownloadTargetArrayBuffer(rows, columns, channelsPerTexture) {
var isFloatTexture = environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED');
var downloadTarget;
if (isFloatTexture) {
downloadTarget =
new Float32Array(tex_util.getUnpackedArraySizeFromMatrixSize(rows * columns, channelsPerTexture));
}
else {
downloadTarget = new Uint8Array(rows * columns * channelsPerTexture);
}
return downloadTarget;
}
function decodeDownloadTargetArrayBuffer(downloadTarget, rows, columns, channelsPerPixel) {
var isFloatTexture = environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED');
if (isFloatTexture) {
var matrix = new Float32Array(rows * columns);
tex_util.decodeMatrixFromUnpackedArray(downloadTarget, matrix, channelsPerPixel);
return matrix;
}
else {
return tex_util.decodeToFloatArray(downloadTarget);
}
}
function downloadMatrixFromOutputTextureAsync(gl, getBufferSubDataAsyncExtension, rows, columns) {
return __awaiter(this, void 0, void 0, function () {
var gl2, channelsPerPixel, downloadTarget, bufferSizeBytes, buffer;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
gl2 = gl;
channelsPerPixel = 4;
downloadTarget = getDownloadTargetArrayBuffer(rows, columns, channelsPerPixel);
bufferSizeBytes = downloadTarget instanceof Float32Array ?
downloadTarget.length * 4 :
downloadTarget;
buffer = gl.createBuffer();
webgl_util.callAndCheck(gl, function () { return gl.bindBuffer(gl2.PIXEL_PACK_BUFFER, buffer); });
webgl_util.callAndCheck(gl, function () { return gl.bufferData(gl2.PIXEL_PACK_BUFFER, bufferSizeBytes, gl.STATIC_DRAW); });
webgl_util.callAndCheck(gl, function () {
return gl2.readPixels(0, 0, columns, rows, gl.RGBA, getTextureType(gl), 0);
});
return [4, getBufferSubDataAsyncExtension.getBufferSubDataAsync(gl2.PIXEL_PACK_BUFFER, 0, downloadTarget)];
case 1:
_a.sent();
return [2, decodeDownloadTargetArrayBuffer(downloadTarget, rows, columns, channelsPerPixel)];
}
});
});
}
exports.downloadMatrixFromOutputTextureAsync = downloadMatrixFromOutputTextureAsync;
function downloadMatrixFromOutputTexture(gl, rows, columns) {
var _a = tex_util.getUnpackedMatrixTextureShapeWidthHeight(rows, columns), w = _a[0], h = _a[1];
var channelsPerPixel = 4;
var downloadTarget = getDownloadTargetArrayBuffer(rows, columns, channelsPerPixel);
webgl_util.callAndCheck(gl, function () { return gl.readPixels(0, 0, w, h, gl.RGBA, getTextureType(gl), downloadTarget); });
return decodeDownloadTargetArrayBuffer(downloadTarget, rows, columns, channelsPerPixel);
}
exports.downloadMatrixFromOutputTexture = downloadMatrixFromOutputTexture;
function downloadMatrixFromRGBAColorTexture(gl, rows, columns, channels) {
var size = rows * columns * 4;
var downloadTarget = new Uint8Array(size);
webgl_util.callAndCheck(gl, function () { return gl.readPixels(0, 0, columns, rows, gl.RGBA, gl.UNSIGNED_BYTE, downloadTarget); });
var packedRGBA = new Float32Array(size);
for (var i = 0; i < downloadTarget.length; i++) {
packedRGBA[i] = downloadTarget[i];
}
var matrix = new Float32Array(rows * columns * channels);
tex_util.decodeMatrixFromUnpackedColorRGBAArray(packedRGBA, matrix, channels);
return matrix;
}
exports.downloadMatrixFromRGBAColorTexture = downloadMatrixFromRGBAColorTexture;
function downloadMatrixFromPackedOutputTexture(gl, rows, columns) {
var _a = tex_util.getPackedMatrixTextureShapeWidthHeight(rows, columns), w = _a[0], h = _a[1];
var packedRGBA = new Float32Array(tex_util.getPackedRGBAArraySizeFromMatrixShape(rows, columns));
webgl_util.callAndCheck(gl, function () { return gl.readPixels(0, 0, w, h, gl.RGBA, getTextureType(gl), packedRGBA); });
var matrix = new Float32Array(rows * columns);
return tex_util.decodeMatrixFromPackedRGBA(packedRGBA, rows, columns, matrix);
}
exports.downloadMatrixFromPackedOutputTexture = downloadMatrixFromPackedOutputTexture;
},{"../../../environment":15,"./tex_util":84,"./webgl_util":89}],74:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var MaxPool2DBackpropProgram = (function () {
function MaxPool2DBackpropProgram(convInfo) {
this.variableNames = ['dy', 'maxPos'];
this.outputShape = convInfo.inShape;
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var padTop = filterHeight - 1 - convInfo.padInfo.top;
var padLeft = filterWidth - 1 - convInfo.padInfo.left;
var lastIndex = filterHeight * filterWidth - 1;
this.userCode = "\n const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int b = coords[0];\n int d = coords[3];\n\n ivec2 dyRCCorner = coords.yz - pads;\n int dyRCorner = dyRCCorner.x;\n int dyCCorner = dyRCCorner.y;\n\n // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n // ? = to be determined. : = across all values in that axis.\n float dotProd = 0.0;\n for (int wR = 0; wR < " + filterHeight + "; wR++) {\n float dyR = float(dyRCorner + wR) / " + strideHeight + ".0;\n\n if (dyR < 0.0 || dyR >= " + convInfo.outHeight + ".0 || fract(dyR) > 0.0) {\n continue;\n }\n int idyR = int(dyR);\n\n for (int wC = 0; wC < " + filterWidth + "; wC++) {\n float dyC = float(dyCCorner + wC) / " + strideWidth + ".0;\n\n if (dyC < 0.0 || dyC >= " + convInfo.outWidth + ".0 ||\n fract(dyC) > 0.0) {\n continue;\n }\n int idyC = int(dyC);\n\n float dyValue = getDy(b, idyR, idyC, d);\n int maxPosValue = " + lastIndex + " - int(getMaxPos(b, idyR, idyC, d));\n\n // Get the current value, check it against the value from the\n // position matrix.\n int curPosValue = wR * " + filterWidth + " + wC;\n float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n dotProd += dyValue * mask;\n }\n }\n setOutput(dotProd);\n }\n ";
}
return MaxPool2DBackpropProgram;
}());
exports.MaxPool2DBackpropProgram = MaxPool2DBackpropProgram;
},{}],75:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var matmul_1 = require("../types/matmul");
var MatMulProgram = (function () {
function MatMulProgram(aShape, bShape, aOrient, bOrient) {
if (aOrient === void 0) { aOrient = matmul_1.MatrixOrientation.REGULAR; }
if (bOrient === void 0) { bOrient = matmul_1.MatrixOrientation.REGULAR; }
this.variableNames = ['matrixA', 'matrixB'];
var outerShapeA = (aOrient === matmul_1.MatrixOrientation.REGULAR) ? aShape[0] : aShape[1];
var outerShapeB = (bOrient === matmul_1.MatrixOrientation.REGULAR) ? bShape[1] : bShape[0];
this.outputShape = [outerShapeA, outerShapeB];
var sharedDim = (aOrient === matmul_1.MatrixOrientation.REGULAR ? aShape[1] : aShape[0]);
var aSnippetFromOffset = function (vec4Offset, indexVar) {
return (aOrient === matmul_1.MatrixOrientation.REGULAR) ?
"aRow, " + indexVar + " + " + vec4Offset :
indexVar + " + " + vec4Offset + ", aRow";
};
var bSnippetFromOffset = function (vec4Offset, indexVar) {
return (bOrient === matmul_1.MatrixOrientation.REGULAR) ?
indexVar + " + " + vec4Offset + ", bCol" :
"bCol, " + indexVar + " + " + vec4Offset;
};
var sharedDimNearestVec4 = Math.floor(sharedDim / 4) * 4;
var sharedDimVec4Remainder = sharedDim % 4;
this.userCode = " float dotARowBCol(int aRow, int bCol) {\n float result = 0.0;\n for (int i = 0; i < " + sharedDimNearestVec4 + "; i += 4) {\n vec4 a = vec4(\n getMatrixA(" + aSnippetFromOffset(0, 'i') + "),\n getMatrixA(" + aSnippetFromOffset(1, 'i') + "),\n getMatrixA(" + aSnippetFromOffset(2, 'i') + "),\n getMatrixA(" + aSnippetFromOffset(3, 'i') + ")\n );\n vec4 b = vec4(\n getMatrixB(" + bSnippetFromOffset(0, 'i') + "),\n getMatrixB(" + bSnippetFromOffset(1, 'i') + "),\n getMatrixB(" + bSnippetFromOffset(2, 'i') + "),\n getMatrixB(" + bSnippetFromOffset(3, 'i') + ")\n );\n\n result += dot(a, b);\n }\n\n if (" + (sharedDimVec4Remainder === 1) + ") {\n result += getMatrixA(" + aSnippetFromOffset(0, sharedDimNearestVec4) + ") *\n getMatrixB(" + bSnippetFromOffset(0, sharedDimNearestVec4) + ");\n } else if (" + (sharedDimVec4Remainder === 2) + ") {\n vec2 a = vec2(\n getMatrixA(" + aSnippetFromOffset(0, sharedDimNearestVec4) + "),\n getMatrixA(" + aSnippetFromOffset(1, sharedDimNearestVec4) + ")\n );\n vec2 b = vec2(\n getMatrixB(" + bSnippetFromOffset(0, sharedDimNearestVec4) + "),\n getMatrixB(" + bSnippetFromOffset(1, sharedDimNearestVec4) + ")\n );\n result += dot(a, b);\n } else if (" + (sharedDimVec4Remainder === 3) + ") {\n vec3 a = vec3(\n getMatrixA(" + aSnippetFromOffset(0, sharedDimNearestVec4) + "),\n getMatrixA(" + aSnippetFromOffset(1, sharedDimNearestVec4) + "),\n getMatrixA(" + aSnippetFromOffset(2, sharedDimNearestVec4) + ")\n );\n vec3 b = vec3(\n getMatrixB(" + bSnippetFromOffset(0, sharedDimNearestVec4) + "),\n getMatrixB(" + bSnippetFromOffset(1, sharedDimNearestVec4) + "),\n getMatrixB(" + bSnippetFromOffset(2, sharedDimNearestVec4) + ")\n );\n result += dot(a, b);\n }\n\n return result;\n }\n\n void main() {\n ivec2 resRC = getOutputCoords();\n setOutput(dotARowBCol(resRC.x, resRC.y));\n }\n ";
}
return MatMulProgram;
}());
exports.MatMulProgram = MatMulProgram;
},{"../types/matmul":61}],76:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var MultinomialProgram = (function () {
function MultinomialProgram(batchSize, numOutcomes, numSamples) {
this.variableNames = ['probs'];
this.outputShape = [batchSize, numSamples];
this.userCode = "\n uniform float seed;\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n\n float r = random(seed);\n float cdf = 0.0;\n\n for (int i = 0; i < " + (numOutcomes - 1) + "; i++) {\n cdf += getProbs(batch, i);\n\n if (r < cdf) {\n setOutput(float(i));\n return;\n }\n }\n\n // If no other event happened, last event happened.\n setOutput(float(" + (numOutcomes - 1) + "));\n }\n ";
}
MultinomialProgram.prototype.getCustomSetupFunc = function (seed) {
var _this = this;
return function (gpgpu, webGLProgram) {
if (_this.seedLoc == null) {
_this.seedLoc = gpgpu.getUniformLocation(webGLProgram, 'seed');
}
gpgpu.gl.uniform1f(_this.seedLoc, seed);
};
};
return MultinomialProgram;
}());
exports.MultinomialProgram = MultinomialProgram;
},{}],77:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var OneHotProgram = (function () {
function OneHotProgram(numIndices, depth, onValue, offValue) {
this.variableNames = ['indices'];
this.outputShape = [numIndices, depth];
this.userCode = "\n void main() {\n ivec2 coords = getOutputCoords();\n int index = round(getIndices(coords.x));\n setOutput(mix(float(" + offValue + "), float(" + onValue + "),\n float(index == coords.y)));\n }\n ";
}
OneHotProgram.prototype.getCustomSetupFunc = function (seed) {
var _this = this;
return function (gpgpu, webGLProgram) {
if (_this.seedLoc == null) {
_this.seedLoc = gpgpu.getUniformLocation(webGLProgram, 'seed');
}
gpgpu.gl.uniform1f(_this.seedLoc, seed);
};
};
return OneHotProgram;
}());
exports.OneHotProgram = OneHotProgram;
},{}],78:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var Pool2DProgram = (function () {
function Pool2DProgram(convInfo, poolType, computePositions) {
this.variableNames = ['x'];
if (poolType === 'avg' && computePositions) {
throw new Error('Cannot compute positions for average pool.');
}
var filterHeight = convInfo.filterHeight;
var filterWidth = convInfo.filterWidth;
var strideHeight = convInfo.strideHeight;
var strideWidth = convInfo.strideWidth;
var padTop = convInfo.padInfo.top;
var padLeft = convInfo.padInfo.left;
this.outputShape = convInfo.outShape;
var isAvgPool = poolType === 'avg';
var initializationValue = '0.0';
if (!isAvgPool) {
if (poolType === 'min') {
initializationValue = '1.0 / 0.0';
}
else {
initializationValue = '-1.0 / 0.0';
}
}
if (computePositions) {
var compareOp_1 = poolType === 'min' ? '<=' : '>=';
this.userCode = "\n const ivec2 strides = ivec2(" + strideHeight + ", " + strideWidth + ");\n const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d = coords[3];\n\n ivec2 xRCCorner = coords.yz * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // max/min x(?, ?, d) to get y(yR, yC, d).\n // ? = to be determined\n float minMaxValue = 0.0;\n float minMaxValueFound = 0.0;\n int minMaxPosition = 0;\n float avgValue = 0.0;\n\n for (int wR = 0; wR < " + filterHeight + "; wR++) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= " + convInfo.inHeight + ") {\n continue;\n }\n\n for (int wC = 0; wC < " + filterWidth + "; wC++) {\n int xC = xCCorner + wC;\n\n if (xC < 0 || xC >= " + convInfo.inWidth + ") {\n continue;\n }\n\n float value = getX(batch, xR, xC, d);\n\n if (isNaN(value)) {\n setOutput(value);\n return;\n }\n\n // If a min / max value has already been found, use it. If not,\n // use the current value.\n float currMinMaxValue = mix(\n value, minMaxValue, minMaxValueFound);\n if (value " + compareOp_1 + " currMinMaxValue) {\n minMaxValue = value;\n minMaxValueFound = 1.0;\n minMaxPosition = wR * " + filterWidth + " + wC;\n }\n }\n }\n setOutput(float(minMaxPosition));\n }\n ";
return;
}
var compareOp = poolType === 'min' ? 'min' : 'max';
var returnValue = poolType + "(" + poolType + "(" + poolType + "(" +
'minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])';
if (poolType === 'avg') {
returnValue = "avgValue / " + filterHeight * filterWidth + ".0";
}
var filterWidthNearestVec4 = Math.floor(filterWidth / 4) * 4;
var filterWidthVec4Remainder = filterWidth % 4;
var updateSnippet = "\n if (hasNaN(values)) {\n setOutput(getNaN(values));\n return;\n }\n if (" + isAvgPool + ") {\n avgValue += dot(values, ones);\n } else {\n minMaxValue = " + compareOp + "(values, minMaxValue);\n }\n ";
this.userCode = "\n const ivec2 strides = ivec2(" + strideHeight + ", " + strideWidth + ");\n const ivec2 pads = ivec2(" + padTop + ", " + padLeft + ");\n const float initializationValue = " + initializationValue + ";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float getValue(int batch, int xR, int xC, int d) {\n if (xC < 0 || xC >= " + convInfo.inWidth + ") {\n return initializationValue;\n }\n return getX(batch, xR, xC, d);\n }\n\n void main() {\n ivec4 coords = getOutputCoords();\n int batch = coords[0];\n int d = coords[3];\n\n ivec2 xRCCorner = coords.yz * strides - pads;\n int xRCorner = xRCCorner.x;\n int xCCorner = xRCCorner.y;\n\n // max/min x(?, ?, d) to get y(yR, yC, d).\n // ? = to be determined\n vec4 minMaxValue = vec4(" + initializationValue + ");\n float avgValue = 0.0;\n\n for (int wR = 0; wR < " + filterHeight + "; wR++) {\n int xR = xRCorner + wR;\n\n if (xR < 0 || xR >= " + convInfo.inHeight + ") {\n continue;\n }\n\n for (int wC = 0; wC < " + filterWidthNearestVec4 + "; wC += 4) {\n int xC = xCCorner + wC;\n\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + 1, d),\n getValue(batch, xR, xC + 2, d),\n getValue(batch, xR, xC + 3, d)\n );\n\n " + updateSnippet + "\n }\n\n int xC = xCCorner + " + filterWidthNearestVec4 + ";\n if (" + (filterWidthVec4Remainder === 1) + ") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n initializationValue,\n initializationValue,\n initializationValue\n );\n " + updateSnippet + "\n } else if (" + (filterWidthVec4Remainder === 2) + ") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + 1, d),\n initializationValue,\n initializationValue\n );\n\n " + updateSnippet + "\n } else if (" + (filterWidthVec4Remainder === 3) + ") {\n vec4 values = vec4(\n getValue(batch, xR, xC, d),\n getValue(batch, xR, xC + 1, d),\n getValue(batch, xR, xC + 2, d),\n initializationValue\n );\n\n " + updateSnippet + "\n }\n }\n setOutput(" + returnValue + ");\n }\n ";
}
return Pool2DProgram;
}());
exports.Pool2DProgram = Pool2DProgram;
},{}],79:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ReduceProgram = (function () {
function ReduceProgram(reduceInfo, reduceType) {
this.variableNames = ['x'];
var windowSize = reduceInfo.windowSize;
var batchSize = reduceInfo.batchSize;
var inSize = reduceInfo.inSize;
var outSize = Math.ceil(inSize / windowSize);
this.outputShape = [batchSize, outSize];
var isReduceSum = reduceType === 'sum';
var initializationValue = '0.0';
if (!isReduceSum) {
if (reduceType === 'min') {
initializationValue = '1.0 / 0.0';
}
else {
initializationValue = '-1.0 / 0.0';
}
}
var compareOp = reduceType === 'min' ? 'min' : 'max';
var returnValue = reduceType + "(" + reduceType + "(" + reduceType + "(" +
'minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])';
if (reduceType === 'sum') {
returnValue = "sumValue";
}
var windowSizeNearestVec4 = Math.floor(windowSize / 4) * 4;
var windowSizeVec4Remainder = windowSize % 4;
var updateSnippet = "\n if (" + isReduceSum + ") {\n sumValue += dot(values, ones);\n } else {\n if (hasNaN(values)) {\n setOutput(getNaN(values));\n return;\n }\n minMaxValue = " + compareOp + "(values, minMaxValue);\n }\n ";
var checkOutOfBounds = '';
if (inSize % windowSize > 0) {
checkOutOfBounds = "\n if (inIdx < 0 || inIdx >= " + inSize + ") {\n return initializationValue;\n }\n ";
}
this.userCode = "\n const float initializationValue = " + initializationValue + ";\n const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n float getValue(int batch, int inIdx) {\n " + checkOutOfBounds + "\n return getX(batch, inIdx);\n }\n\n void main() {\n ivec2 coords = getOutputCoords();\n int batch = coords[0];\n int outIdx = coords[1];\n int inOffset = outIdx * " + windowSize + ";\n\n vec4 minMaxValue = vec4(" + initializationValue + ");\n float sumValue = 0.0;\n\n for (int i = 0; i < " + windowSizeNearestVec4 + "; i += 4) {\n int inIdx = inOffset + i;\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n getValue(batch, inIdx + 3)\n );\n\n " + updateSnippet + "\n }\n\n int inIdx = inOffset + " + windowSizeNearestVec4 + ";\n if (" + (windowSizeVec4Remainder === 1) + ") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n initializationValue,\n initializationValue,\n initializationValue\n );\n " + updateSnippet + "\n } else if (" + (windowSizeVec4Remainder === 2) + ") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n initializationValue,\n initializationValue\n );\n " + updateSnippet + "\n } else if (" + (windowSizeVec4Remainder === 3) + ") {\n vec4 values = vec4(\n getValue(batch, inIdx),\n getValue(batch, inIdx + 1),\n getValue(batch, inIdx + 2),\n initializationValue\n );\n " + updateSnippet + "\n }\n setOutput(" + returnValue + ");\n }\n ";
}
return ReduceProgram;
}());
exports.ReduceProgram = ReduceProgram;
},{}],80:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var webgl_util = require("./webgl_util");
function getRenderRGBShader(gpgpu, destinationWidth) {
var fragmentShaderSource = "\n precision highp float;\n uniform sampler2D source;\n varying vec2 resultUV;\n\n const float destinationWidth = " + destinationWidth + ".0;\n const float a = 1.0;\n\n void main() {\n float xr = floor(resultUV.s * destinationWidth) * 3.0;\n vec3 x = xr + vec3(0, 1, 2);\n\n float sourceWidth = destinationWidth * 3.0;\n vec3 u = (x + 0.5) / sourceWidth;\n float v = 1.0 - resultUV.t;\n\n float r = texture2D(source, vec2(u[0], v)).r;\n float g = texture2D(source, vec2(u[1], v)).r;\n float b = texture2D(source, vec2(u[2], v)).r;\n\n gl_FragColor = vec4(r, g, b, a);\n }";
return gpgpu.createProgram(fragmentShaderSource);
}
exports.getRenderRGBShader = getRenderRGBShader;
function renderToCanvas(gpgpu, renderShader, sourceTex) {
webgl_util.bindCanvasToFramebuffer(gpgpu.gl);
renderToFramebuffer(gpgpu, renderShader, sourceTex);
}
exports.renderToCanvas = renderToCanvas;
function renderToFramebuffer(gpgpu, renderShader, sourceTex) {
gpgpu.setProgram(renderShader);
var sourceSamplerLocation = webgl_util.getProgramUniformLocationOrThrow(gpgpu.gl, renderShader, 'source');
gpgpu.setInputMatrixTexture(sourceTex, sourceSamplerLocation, 0);
gpgpu.executeProgram();
}
exports.renderToFramebuffer = renderToFramebuffer;
},{"./webgl_util":89}],81:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var ResizeBilinear3DProgram = (function () {
function ResizeBilinear3DProgram(inputShape, outputDimensionsRowCol, alignCorners) {
this.variableNames = ['A'];
this.outputShape = [];
var depth = inputShape[2];
this.outputShape =
[outputDimensionsRowCol[0], outputDimensionsRowCol[1], depth];
var effectiveInputShape = alignCorners ?
[inputShape[0] - 1, inputShape[1] - 1, depth] :
inputShape;
var effectiveOutputShape = alignCorners ?
[this.outputShape[0] - 1, this.outputShape[1] - 1, depth] :
this.outputShape;
this.userCode = "\n const vec2 effectiveInputOverOutputRatioRC = vec2(\n " + effectiveInputShape[0] / effectiveOutputShape[0] + ",\n " + effectiveInputShape[1] / effectiveOutputShape[1] + ");\n const vec2 inputShapeRC = vec2(" + inputShape[0] + ".0, " + inputShape[1] + ".0);\n\n void main() {\n ivec3 coords = getOutputCoords();\n ivec2 yRC = coords.xy;\n int d = coords.z;\n\n // Fractional source index.\n vec2 sourceFracIndexRC = vec2(yRC) * effectiveInputOverOutputRatioRC;\n\n // Compute the four integer indices.\n ivec2 sourceFloorRC = ivec2(sourceFracIndexRC);\n ivec2 sourceCeilRC = ivec2(\n min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n float topLeft = getA(sourceFloorRC.x, sourceFloorRC.y, d);\n float bottomLeft = getA(sourceCeilRC.x, sourceFloorRC.y, d);\n float topRight = getA(sourceFloorRC.x, sourceCeilRC.y, d);\n float bottomRight = getA(sourceCeilRC.x, sourceCeilRC.y, d);\n\n vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);\n\n float top = topLeft + (topRight - topLeft) * fracRC.y;\n float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;\n float newValue = top + (bottom - top) * fracRC.x;\n\n setOutput(newValue);\n }\n ";
}
return ResizeBilinear3DProgram;
}());
exports.ResizeBilinear3DProgram = ResizeBilinear3DProgram;
},{}],82:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../../../environment");
var util = require("../../../util");
var broadcast_util = require("../../broadcast_util");
var tex_util = require("./tex_util");
var tex_util_1 = require("./tex_util");
function makeShader(inputsInfo, outputShape, userCode, broadcast) {
var sampleSnippet = getSampleSnippet();
var setOutputSnippet = getSetOutputSnippet();
var inputPrefixSnippet = inputsInfo.map(function (x) { return "uniform sampler2D " + x.name + ";"; }).join('\n');
var inputSamplingSnippet = inputsInfo.map(function (x) { return getInputSamplingSnippet(x, outputShape, broadcast); })
.join('\n');
var outTexShape = outputShape.texShape;
var outputSamplingSnippet = getOutputSamplingSnippet(outputShape.logicalShape, outTexShape);
var source = [
SHADER_PREFIX, sampleSnippet, setOutputSnippet, inputPrefixSnippet,
outputSamplingSnippet, inputSamplingSnippet, userCode
].join('\n');
return source;
}
exports.makeShader = makeShader;
function getSampleSnippet() {
return environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED') ?
FLOAT_TEXTURE_SAMPLE_SNIPPET :
UNSIGNED_BYTE_TEXTURE_SAMPLE_SNIPPET;
}
function getSetOutputSnippet() {
return environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED') ?
FLOAT_TEXTURE_SETOUTPUT_SNIPPET :
UNSIGNED_BYTE_TEXTURE_SETOUTPUT_SNIPPET;
}
function getSamplerFromInInfo(inInfo) {
var shape = inInfo.shapeInfo.logicalShape;
switch (shape.length) {
case 0:
return getSamplerScalar(inInfo);
case 1:
return getSampler1D(inInfo);
case 2:
return getSampler2D(inInfo);
case 3:
return getSampler3D(inInfo);
case 4:
return getSampler4D(inInfo);
default:
throw new Error(shape.length + "-D input sampling" +
" is not yet supported");
}
}
function getInputSamplingSnippet(inInfo, outShapeInfo, broadcast) {
var res = getSamplerFlat(inInfo);
res += getSamplerFromInInfo(inInfo);
if (broadcast ||
util.arraysEqual(inInfo.shapeInfo.logicalShape, outShapeInfo.logicalShape)) {
res += getSamplerAtOutputCoords(inInfo, outShapeInfo, broadcast);
}
return res;
}
function getOutputSamplingSnippet(outShape, outTexShape) {
switch (outShape.length) {
case 0:
return getOutputScalarCoords();
case 1:
return getOutput1DCoords(outShape, outTexShape);
case 2:
return getOutput2DCoords(outShape, outTexShape);
case 3:
return getOutput3DCoords(outShape, outTexShape);
case 4:
return getOutput4DCoords(outShape, outTexShape);
default:
throw new Error(outShape.length + "-D output sampling is not yet supported");
}
}
var SAMPLE_1D_SNIPPET = "\nvec2 UVfrom1D(int texNumR, int texNumC, int index) {\n int texR = index / texNumC;\n int texC = index - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n";
var SAMPLE_2D_SNIPPET = "\nvec2 UVfrom2D(int texNumR, int texNumC, int numC, int row, int col) {\n int index = row * numC + col;\n int texR = index / texNumC;\n int texC = index - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n";
var SAMPLE_3D_SNIPPET = "\nvec2 UVfrom3D(int texNumR, int texNumC, int stride0,\n int stride1, int row, int col, int depth) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * stride0 + col * stride1 + depth;\n int texR = index / texNumC;\n int texC = index - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n";
var SAMPLE_4D_SNIPPET = "\nvec2 UVfrom4D(int texNumR, int texNumC, int stride0,\n int stride1, int stride2, int row, int col, int depth,\n int depth2) {\n // Explicitly use integer operations as dot() only works on floats.\n int index = row * stride0 + col * stride1 + depth * stride2 + depth2;\n int texR = index / texNumC;\n int texC = index - texR * texNumC;\n return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n";
var UNSIGNED_BYTE_TEXTURE_SAMPLE_SNIPPET = "\n uniform float NaN;\n\n const vec4 floatDeltas = vec4(\n 1.0,\n 1.0 / 255.0,\n 1.0 / (255.0 * 255.0),\n 1.0 / (255.0 * 255.0 * 255.0)\n );\n const float minValue = " + tex_util.FLOAT_MIN + ".0;\n const float maxValue = " + tex_util.FLOAT_MAX + ".0;\n const float range = (maxValue - minValue) / 255.0;\n const vec2 dotRange = vec2(1.0, range);\n\n float sample(sampler2D texture, vec2 uv) {\n vec4 sampleValue = texture2D(texture, uv);\n if (all(equal(sampleValue, vec4(" + tex_util.BYTE_NAN_VALUE + ")))) {\n return NaN;\n }\n\n vec4 encValue = floor(sampleValue * 255.0 + 0.5);\n float decodedValue = dot(encValue, floatDeltas);\n return dot(vec2(minValue, decodedValue), dotRange);\n }\n";
var UNSIGNED_BYTE_TEXTURE_SETOUTPUT_SNIPPET = "\n const vec4 floatPowers = vec4(\n 1.0,\n 255.0,\n 255.0 * 255.0,\n 255.0 * 255.0 * 255.0\n );\n const vec2 recipRange = vec2(1.0/range);\n const vec2 recipRange255 = vec2(1.0/(maxValue - minValue));\n\n void setOutput(float decodedValue) {\n if (isNaN(decodedValue)) {\n gl_FragColor = vec4(" + tex_util.BYTE_NAN_VALUE + ");\n return;\n }\n\n float a = dot(vec2(decodedValue, -minValue), recipRange);\n float b = fract(a) * 255.0;\n float c = fract(b) * 255.0;\n float d = fract(c) * 255.0;\n gl_FragColor = floor(vec4(a, b, c, d)) / 255.0;\n\n // TODO(dsmilkov): Version above gets better accuracy but probably slower\n // than the version below. Benchmark to determine if the accuracy is worth\n // the cost.\n\n // float normValue = dot(vec2(decodedValue, -minValue), recipRange255);\n // vec4 f = normValue * floatPowers;\n // gl_FragColor = floor(fract(f) * 255.0) / 255.0;\n }\n";
var FLOAT_TEXTURE_SAMPLE_SNIPPET = "\n float sample(sampler2D texture, vec2 uv) {\n return texture2D(texture, uv).r;\n }\n";
var FLOAT_TEXTURE_SETOUTPUT_SNIPPET = "\n void setOutput(float val) {\n gl_FragColor = vec4(val, 0, 0, 0);\n }\n";
var SHADER_PREFIX = "\n precision highp float;\n precision highp int;\n varying vec2 resultUV;\n const vec2 halfCR = vec2(0.5, 0.5);\n\n bool isNaN(float val) {\n float v1 = val * val;\n float v2 = val * val;\n return v1 == v2 ? false : true;\n }\n\n bool hasNaN(vec4 values) {\n vec4 v1 = values * values;\n vec4 v2 = values * values;\n return any(notEqual(v1, v2));\n }\n\n float getNaN(vec4 values) {\n return dot(vec4(1), values);\n }\n\n int round(float value) {\n return int(floor(value + 0.5));\n }\n\n int imod(int x, int y) {\n return x - y * (x / y);\n }\n\n const vec2 randomConst = vec2(\n 23.14069263277926, // e^pi (Gelfond's constant)\n 2.665144142690225 // 2^sqrt(2) (Gelfond\u2013Schneider constant)\n );\n\n float random(float seed) {\n return fract(cos(dot(resultUV * seed, randomConst)) * 12345.6789);\n }\n\n float sampleUVAndDepth(sampler2D texture, vec2 uv, int depth) {\n float value;\n if (depth == 0) {\n value = texture2D(texture, uv).r;\n } else if (depth == 1) {\n value = texture2D(texture, uv).g;\n } else if (depth == 2) {\n value = texture2D(texture, uv).b;\n } else if (depth == 3) {\n value = texture2D(texture, uv).a;\n }\n return floor(value * 255.0 + 0.5);\n }\n\n " + SAMPLE_1D_SNIPPET + "\n " + SAMPLE_2D_SNIPPET + "\n " + SAMPLE_3D_SNIPPET + "\n " + SAMPLE_4D_SNIPPET + "\n";
function getOutputScalarCoords() {
return "\n int getOutputCoords() {\n return 0;\n }\n ";
}
function getOutput1DCoords(shape, texShape) {
if (texShape[0] === 1) {
return "\n int getOutputCoords() {\n return int(resultUV.x * " + texShape[1] + ".0);\n }\n ";
}
if (texShape[1] === 1) {
return "\n int getOutputCoords() {\n return int(resultUV.y * " + texShape[0] + ".0);\n }\n ";
}
return "\n int getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + texShape[0] + ", " + texShape[1] + "));\n return resTexRC.x * " + texShape[1] + " + resTexRC.y;\n }\n ";
}
function getOutput3DCoords(shape, texShape) {
var stride0 = shape[1] * shape[2];
var stride1 = shape[2];
return "\n ivec3 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + texShape[0] + ", " + texShape[1] + "));\n int index = resTexRC.x * " + texShape[1] + " + resTexRC.y;\n int r = index / " + stride0 + ";\n index -= r * " + stride0 + ";\n int c = index / " + stride1 + ";\n int d = index - c * " + stride1 + ";\n return ivec3(r, c, d);\n }\n ";
}
function getOutput4DCoords(shape, texShape) {
var stride2 = shape[3];
var stride1 = shape[2] * stride2;
var stride0 = shape[1] * stride1;
return "\n ivec4 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + texShape[0] + ", " + texShape[1] + "));\n int index = resTexRC.x * " + texShape[1] + " + resTexRC.y;\n\n int r = index / " + stride0 + ";\n index -= r * " + stride0 + ";\n\n int c = index / " + stride1 + ";\n index -= c * " + stride1 + ";\n\n int d = index / " + stride2 + ";\n int d2 = index - d * " + stride2 + ";\n\n return ivec4(r, c, d, d2);\n }\n ";
}
function getOutput2DCoords(shape, texShape) {
if (util.arraysEqual(shape, texShape)) {
return "\n ivec2 getOutputCoords() {\n return ivec2(resultUV.yx * vec2(" + texShape[0] + ", " + texShape[1] + "));\n }\n ";
}
if (shape[1] === 1) {
return "\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + texShape[0] + ", " + texShape[1] + "));\n int index = resTexRC.x * " + texShape[1] + " + resTexRC.y;\n return ivec2(index, 0);\n }\n ";
}
if (shape[0] === 1) {
return "\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + texShape[0] + ", " + texShape[1] + "));\n int index = resTexRC.x * " + texShape[1] + " + resTexRC.y;\n return ivec2(0, index);\n }\n ";
}
return "\n ivec2 getOutputCoords() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + texShape[0] + ", " + texShape[1] + "));\n int index = resTexRC.x * " + texShape[1] + " + resTexRC.y;\n int r = index / " + shape[1] + ";\n int c = index - r * " + shape[1] + ";\n return ivec2(r, c);\n }\n ";
}
function getSamplerScalar(inputInfo) {
var texName = inputInfo.name;
var funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1);
return "\n float " + funcName + "() {\n return sample(" + texName + ", halfCR);\n }\n ";
}
function getSampler1D(inputInfo) {
var texName = inputInfo.name;
var funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1);
return "\n float " + funcName + "(int index) {\n return " + funcName + "Flat(index);\n }\n ";
}
function getSampler2D(inputInfo) {
var shape = inputInfo.shapeInfo.logicalShape;
var texShape = inputInfo.shapeInfo.texShape;
var texName = inputInfo.name;
var funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1);
var texNumR = texShape[0];
var texNumC = texShape[1];
if (util.arraysEqual(shape, texShape)) {
return "\n float " + funcName + "(int row, int col) {\n vec2 uv = (vec2(col, row) + halfCR) / vec2(" + texNumC + ".0, " + texNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
var _a = util.squeezeShape(shape), newShape = _a.newShape, keptDims = _a.keptDims;
var squeezedShape = newShape;
if (squeezedShape.length < shape.length) {
var newInputInfo = squeezeInputInfo(inputInfo, squeezedShape);
var params = ['row', 'col'];
return "\n " + getSamplerFromInInfo(newInputInfo) + "\n float " + funcName + "(int row, int col) {\n return " + funcName + "(" + getSqueezedParams(params, keptDims) + ");\n }\n ";
}
if (texNumC === 1) {
return "\n float " + funcName + "(int row, int col) {\n int index = row * " + shape[1] + " + col;\n vec2 uv = vec2(0.5, (float(index) + 0.5) / " + texNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
if (texNumR === 1) {
return "\n float " + funcName + "(int row, int col) {\n int index = row * " + shape[1] + " + col;\n vec2 uv = vec2((float(index) + 0.5) / " + texNumC + ".0, 0.5);\n return sample(" + texName + ", uv);\n }\n ";
}
return "\n float " + funcName + "(int row, int col) {\n vec2 uv = UVfrom2D(" + texNumR + ", " + texNumC + ", " + shape[1] + ", row, col);\n return sample(" + texName + ", uv);\n }\n";
}
function getSampler3D(inputInfo) {
var texShape = inputInfo.shapeInfo.texShape;
var shape = inputInfo.shapeInfo.logicalShape;
var texName = inputInfo.name;
var funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1);
var texNumR = texShape[0];
var texNumC = texShape[1];
var stride0 = shape[1] * shape[2];
var stride1 = shape[2];
var texType = inputInfo.shapeInfo.textureType;
if (texType === tex_util_1.TextureType.DEFAULT) {
var _a = util.squeezeShape(shape), newShape = _a.newShape, keptDims = _a.keptDims;
var squeezedShape = newShape;
if (squeezedShape.length < shape.length) {
var newInputInfo = squeezeInputInfo(inputInfo, squeezedShape);
var params = ['row', 'col', 'depth'];
return "\n " + getSamplerFromInInfo(newInputInfo) + "\n float " + funcName + "(int row, int col, int depth) {\n return " + funcName + "(" + getSqueezedParams(params, keptDims) + ");\n }\n ";
}
}
if (texNumC === stride0) {
if (texType === tex_util_1.TextureType.DEFAULT) {
return "\n float " + funcName + "(int row, int col, int depth) {\n int texR = row;\n int texC = col * " + stride1 + " + depth;\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(" + texNumC + ".0, " + texNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
else if (texType === tex_util_1.TextureType.RGBA_COLOR) {
return "\n float " + funcName + "(int row, int col, int depth) {\n vec2 uv = (vec2(col, row) + halfCR) /\n vec2(" + texNumC + ".0, " + texNumR + ".0);\n return sampleUVAndDepth(" + texName + ", uv, depth);\n }\n ";
}
else {
throw new Error("Unknown TextureType " + texType + ".");
}
}
if (texNumC === stride1 && texType === tex_util_1.TextureType.DEFAULT) {
return "\n float " + funcName + "(int row, int col, int depth) {\n int texR = row * " + shape[1] + " + col;\n int texC = depth;\n vec2 uv = (vec2(texC, texR) + halfCR) / vec2(" + texNumC + ".0, " + texNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
if (texType === tex_util_1.TextureType.DEFAULT) {
return "\n float " + funcName + "(int row, int col, int depth) {\n vec2 uv = UVfrom3D(\n " + texNumR + ", " + texNumC + ", " + stride0 + ", " + stride1 + ", row, col, depth);\n return sample(" + texName + ", uv);\n }\n ";
}
else if (texType === tex_util_1.TextureType.RGBA_COLOR) {
return "\n float " + funcName + "(int row, int col, int depth) {\n vec2 uv = UVfrom2D(" + texNumR + ", " + texNumC + ", " + shape[1] + ", row, col);\n return sampleUVAndDepth(" + texName + ", uv, depth);\n }\n ";
}
else {
throw new Error("Unknown TextureType " + texType + ".");
}
}
function getSampler4D(inputInfo) {
var shape = inputInfo.shapeInfo.logicalShape;
var texShape = inputInfo.shapeInfo.texShape;
var texName = inputInfo.name;
var funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1);
var texNumR = texShape[0];
var texNumC = texShape[1];
var stride2 = shape[3];
var stride1 = shape[2] * stride2;
var stride0 = shape[1] * stride1;
var _a = util.squeezeShape(shape), newShape = _a.newShape, keptDims = _a.keptDims;
if (newShape.length < shape.length) {
var newInputInfo = squeezeInputInfo(inputInfo, newShape);
var params = ['row', 'col', 'depth', 'depth2'];
return "\n " + getSamplerFromInInfo(newInputInfo) + "\n float " + funcName + "(int row, int col, int depth, int depth2) {\n return " + funcName + "(" + getSqueezedParams(params, keptDims) + ");\n }\n ";
}
if (texNumC === stride0) {
return "\n float " + funcName + "(int row, int col, int depth, int depth2) {\n int texR = row;\n int texC = col * " + stride1 + " + depth * " + stride2 + " + depth2;\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(" + texNumC + ".0, " + texNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
if (texNumC === stride2) {
return "\n float " + funcName + "(int row, int col, int depth, int depth2) {\n int texR = row * " + shape[1] * shape[2] + " + col * " + shape[2] + " + depth;\n int texC = depth2;\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(" + texNumC + ".0, " + texNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
return "\n float " + funcName + "(int row, int col, int depth, int depth2) {\n vec2 uv = UVfrom4D(" + texNumR + ", " + texNumC + ", " + stride0 + ", " + stride1 + ",\n " + stride2 + ", row, col, depth, depth2);\n return sample(" + texName + ", uv);\n }\n ";
}
function getSamplerFlat(inputInfo) {
var texName = inputInfo.name;
var texShape = inputInfo.shapeInfo.texShape;
var funcName = 'get' + texName.charAt(0).toUpperCase() + texName.slice(1) + 'Flat';
var tNumR = texShape[0];
var tNumC = texShape[1];
if (tNumC === 1 && tNumR === 1) {
return "\n float " + funcName + "(int index) {\n return sample(" + texName + ", halfCR);\n }\n ";
}
if (tNumC === 1) {
return "\n float " + funcName + "(int index) {\n vec2 uv = vec2(0.5, (float(index) + 0.5) / " + tNumR + ".0);\n return sample(" + texName + ", uv);\n }\n ";
}
if (tNumR === 1) {
return "\n float " + funcName + "(int index) {\n vec2 uv = vec2((float(index) + 0.5) / " + tNumC + ".0, 0.5);\n return sample(" + texName + ", uv);\n }\n ";
}
return "\n float " + funcName + "(int index) {\n vec2 uv = UVfrom1D(" + tNumR + ", " + tNumC + ", index);\n return sample(" + texName + ", uv);\n }\n ";
}
function getBroadcastOutputCoordsSampler(inputInfo, outShapeInfo, texFuncSnippet, funcName) {
var inRank = inputInfo.shapeInfo.logicalShape.length;
var outRank = outShapeInfo.logicalShape.length;
var type = 'int';
if (outRank === 2) {
type = 'ivec2';
}
else if (outRank === 3) {
type = 'ivec3';
}
else if (outRank === 4) {
type = 'ivec4';
}
var broadcastDims = broadcast_util.getBroadcastDims(inputInfo.shapeInfo.logicalShape, outShapeInfo.logicalShape);
var rankDiff = outRank - inRank;
var coordsSnippet;
if (inRank === 0) {
coordsSnippet = '';
}
else if (outRank < 2 && broadcastDims.length >= 1) {
coordsSnippet = 'coords = 0;';
}
else {
coordsSnippet =
broadcastDims.map(function (d) { return "coords[" + (d + rankDiff) + "] = 0;"; }).join('\n');
}
var unpackedCoordsSnippet = '';
if (outRank < 2 && inRank > 0) {
unpackedCoordsSnippet = 'coords';
}
else {
unpackedCoordsSnippet = inputInfo.shapeInfo.logicalShape
.map(function (s, i) { return "coords[" + (i + rankDiff) + "]"; })
.join(', ');
}
return "\n float " + funcName + "() {\n " + type + " coords = getOutputCoords();\n " + coordsSnippet + "\n return get" + texFuncSnippet + "(" + unpackedCoordsSnippet + ");\n }\n ";
}
function getSamplerAtOutputCoords(inputInfo, outShapeInfo, supportsBroadcasting) {
var inTexShape = inputInfo.shapeInfo.texShape;
var texName = inputInfo.name;
var isRGBAColorTexture = inputInfo.shapeInfo.textureType === tex_util_1.TextureType.RGBA_COLOR;
var texFuncSnippet = texName.charAt(0).toUpperCase() + texName.slice(1);
var funcName = 'get' + texFuncSnippet + 'AtOutCoords';
var broadcastDims = broadcast_util.getBroadcastDims(inputInfo.shapeInfo.logicalShape, outShapeInfo.logicalShape);
var inRank = inputInfo.shapeInfo.logicalShape.length;
var outRank = outShapeInfo.logicalShape.length;
var doBroadcast = supportsBroadcasting && ((outRank > inRank) || broadcastDims.length > 0);
var broadcastOverOuter = broadcast_util.broadcastDimsAreOuter(broadcastDims);
if (doBroadcast && !broadcastOverOuter) {
return getBroadcastOutputCoordsSampler(inputInfo, outShapeInfo, texFuncSnippet, funcName);
}
var outTexShape = outShapeInfo.texShape;
if (util.arraysEqual(inTexShape, outTexShape) && !isRGBAColorTexture) {
return "\n float " + funcName + "() {\n return sample(" + texName + ", resultUV);\n }\n ";
}
var inTexExpandedShape = isRGBAColorTexture ?
[inTexShape[0], inTexShape[1] * inputInfo.shapeInfo.logicalShape[2]] :
inTexShape;
var sampleSnippet = "return sample(" + texName + ", uv);";
var rgbaColorSnippet = '';
if (isRGBAColorTexture) {
rgbaColorSnippet = "\n int col = texC / " + inputInfo.shapeInfo.logicalShape[2] + ";\n int texD = texC - col * " + inputInfo.shapeInfo.logicalShape[2] + ";\n texC = col;\n ";
sampleSnippet = "return sampleUVAndDepth(" + texName + ", uv, texD);";
}
var inSize = util.sizeFromShape(inTexExpandedShape);
var broadcastSnippet = '';
if (doBroadcast && broadcastOverOuter) {
broadcastSnippet = "\n int mainPart = index / " + inSize + ";\n index -= mainPart * " + inSize + ";\n ";
}
return "\n float " + funcName + "() {\n ivec2 resTexRC = ivec2(resultUV.yx *\n vec2(" + outTexShape[0] + ", " + outTexShape[1] + "));\n int index = resTexRC.x * " + outTexShape[1] + " + resTexRC.y;\n " + broadcastSnippet + "\n int texR = index / " + inTexExpandedShape[1] + ";\n int texC = index - texR * " + inTexExpandedShape[1] + ";\n\n " + rgbaColorSnippet + "\n\n vec2 uv = (vec2(texC, texR) + halfCR) /\n vec2(" + inTexShape[1] + ".0, " + inTexShape[0] + ".0);\n\n " + sampleSnippet + "\n }\n ";
}
function getCoordsDataType(rank) {
if (rank === 1) {
return 'int';
}
else if (rank === 2) {
return 'ivec2';
}
else if (rank === 3) {
return 'ivec3';
}
else if (rank === 4) {
return 'ivec4';
}
else {
throw Error("GPU for rank " + rank + " is not yet supported");
}
}
exports.getCoordsDataType = getCoordsDataType;
function squeezeInputInfo(inInfo, squeezedShape) {
var newInputInfo = JSON.parse(JSON.stringify(inInfo));
newInputInfo.shapeInfo.logicalShape = squeezedShape;
return newInputInfo;
}
function getSqueezedParams(params, keptDims) {
return keptDims.map(function (d) { return params[d]; }).join(', ');
}
},{"../../../environment":15,"../../../util":101,"../../broadcast_util":90,"./tex_util":84}],83:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var shader_compiler_1 = require("./shader_compiler");
var SliceProgram = (function () {
function SliceProgram(destSize) {
this.variableNames = ['source'];
this.outputShape = destSize;
this.rank = destSize.length;
var dtype = shader_compiler_1.getCoordsDataType(this.rank);
var sourceCoords = getCoords(this.rank);
this.userCode = "\n uniform " + dtype + " start;\n\n void main() {\n " + dtype + " sourceLoc = start + getOutputCoords();\n setOutput(getSource(" + sourceCoords + "));\n }\n ";
}
SliceProgram.prototype.getCustomSetupFunc = function (start) {
var _this = this;
if (start.length !== this.rank) {
throw Error("The rank (" + this.rank + ") of the program must match the " +
("length of start (" + start.length + ")"));
}
return function (gpgpu, webGLProgram) {
if (_this.startLoc == null) {
_this.startLoc = gpgpu.getUniformLocationNoThrow(webGLProgram, 'start');
if (_this.startLoc == null) {
return;
}
}
if (_this.rank === 1) {
gpgpu.gl.uniform1i(_this.startLoc, start[0]);
}
else if (_this.rank === 2) {
gpgpu.gl.uniform2i(_this.startLoc, start[0], start[1]);
}
else if (_this.rank === 3) {
gpgpu.gl.uniform3i(_this.startLoc, start[0], start[1], start[2]);
}
else if (_this.rank === 4) {
gpgpu.gl.uniform4i(_this.startLoc, start[0], start[1], start[2], start[3]);
}
else {
throw Error("Slicing for rank " + _this.rank + " is not yet supported");
}
};
};
return SliceProgram;
}());
exports.SliceProgram = SliceProgram;
function getCoords(rank) {
if (rank === 1) {
return 'sourceLoc';
}
else if (rank === 2) {
return 'sourceLoc.x, sourceLoc.y';
}
else if (rank === 3) {
return 'sourceLoc.x, sourceLoc.y, sourceLoc.z';
}
else if (rank === 4) {
return 'sourceLoc.x, sourceLoc.y, sourceLoc.z, sourceLoc.w';
}
else {
throw Error("Slicing for rank " + rank + " is not yet supported");
}
}
},{"./shader_compiler":82}],84:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var TextureType;
(function (TextureType) {
TextureType[TextureType["DEFAULT"] = 0] = "DEFAULT";
TextureType[TextureType["RGBA_COLOR"] = 1] = "RGBA_COLOR";
})(TextureType = exports.TextureType || (exports.TextureType = {}));
function getUnpackedMatrixTextureShapeWidthHeight(rows, columns) {
return [columns, rows];
}
exports.getUnpackedMatrixTextureShapeWidthHeight = getUnpackedMatrixTextureShapeWidthHeight;
function getUnpackedArraySizeFromMatrixSize(matrixSize, channelsPerTexture) {
return matrixSize * channelsPerTexture;
}
exports.getUnpackedArraySizeFromMatrixSize = getUnpackedArraySizeFromMatrixSize;
function getColorMatrixTextureShapeWidthHeight(rows, columns) {
return [columns * 4, rows];
}
exports.getColorMatrixTextureShapeWidthHeight = getColorMatrixTextureShapeWidthHeight;
function getMatrixSizeFromUnpackedArraySize(unpackedSize, channelsPerTexture) {
if (unpackedSize % channelsPerTexture !== 0) {
throw new Error("unpackedSize (" + unpackedSize + ") must be a multiple of " +
("" + channelsPerTexture));
}
return unpackedSize / channelsPerTexture;
}
exports.getMatrixSizeFromUnpackedArraySize = getMatrixSizeFromUnpackedArraySize;
function encodeMatrixToUnpackedArray(matrix, unpackedArray, channelsPerTexture) {
var requiredSize = getUnpackedArraySizeFromMatrixSize(matrix.length, channelsPerTexture);
if (unpackedArray.length < requiredSize) {
throw new Error("unpackedArray length (" + unpackedArray.length + ") must be >= " +
("" + requiredSize));
}
var dst = 0;
for (var src = 0; src < matrix.length; ++src) {
unpackedArray[dst] = matrix[src];
dst += channelsPerTexture;
}
}
exports.encodeMatrixToUnpackedArray = encodeMatrixToUnpackedArray;
exports.FLOAT_MAX = 20000;
exports.FLOAT_MIN = -exports.FLOAT_MAX;
var FLOAT_RANGE = (exports.FLOAT_MAX - exports.FLOAT_MIN) / 255;
var FLOAT_DELTAS = [1, 1 / 255, 1 / (255 * 255), 1 / (255 * 255 * 255)];
var FLOAT_POWERS = [1, 255, 255 * 255];
exports.BYTE_NAN_VALUE = 0;
function encodeFloatArray(floatArray) {
var uintArray = new Uint8Array(floatArray.length * 4);
var _loop_1 = function (i) {
var value = floatArray[i / 4];
if (isNaN(value)) {
uintArray[i] = exports.BYTE_NAN_VALUE;
uintArray[i + 1] = exports.BYTE_NAN_VALUE;
uintArray[i + 2] = exports.BYTE_NAN_VALUE;
uintArray[i + 3] = exports.BYTE_NAN_VALUE;
return "continue";
}
var normalizedValue = (value - exports.FLOAT_MIN) / FLOAT_RANGE;
var enc = FLOAT_POWERS.map(function (pow) { return pow * normalizedValue; });
var buckets = enc.map(function (value) { return Math.floor((value % 1) * 255); });
uintArray[i] = Math.floor(normalizedValue);
uintArray[i + 1] = buckets[0];
uintArray[i + 2] = buckets[1];
uintArray[i + 3] = buckets[2];
};
for (var i = 0; i < uintArray.length; i += 4) {
_loop_1(i);
}
return uintArray;
}
exports.encodeFloatArray = encodeFloatArray;
function decodeToFloatArray(uintArray) {
var floatArray = new Float32Array(uintArray.length / 4);
var _loop_2 = function (i) {
if (uintArray[i] === exports.BYTE_NAN_VALUE &&
uintArray[i + 1] === exports.BYTE_NAN_VALUE &&
uintArray[i + 2] === exports.BYTE_NAN_VALUE &&
uintArray[i + 3] === exports.BYTE_NAN_VALUE) {
floatArray[i / 4] = NaN;
return "continue";
}
var dot = 0;
FLOAT_DELTAS.forEach(function (delta, j) {
dot += delta * uintArray[i + j];
});
var value = dot * FLOAT_RANGE + exports.FLOAT_MIN;
floatArray[i / 4] = value;
};
for (var i = 0; i < uintArray.length; i += 4) {
_loop_2(i);
}
return floatArray;
}
exports.decodeToFloatArray = decodeToFloatArray;
function decodeMatrixFromUnpackedArray(unpackedArray, matrix, channelsPerTexture) {
var requiredSize = getMatrixSizeFromUnpackedArraySize(unpackedArray.length, channelsPerTexture);
if (matrix.length < requiredSize) {
throw new Error("matrix length (" + matrix.length + ") must be >= " + requiredSize);
}
var dst = 0;
for (var src = 0; src < unpackedArray.length; src += channelsPerTexture) {
matrix[dst++] = unpackedArray[src];
}
}
exports.decodeMatrixFromUnpackedArray = decodeMatrixFromUnpackedArray;
function decodeMatrixFromUnpackedColorRGBAArray(unpackedArray, matrix, channels) {
var requiredSize = unpackedArray.length * channels / 4;
if (matrix.length < requiredSize) {
throw new Error("matrix length (" + matrix.length + ") must be >= " + requiredSize);
}
var dst = 0;
for (var src = 0; src < unpackedArray.length; src += 4) {
for (var c = 0; c < channels; c++) {
matrix[dst++] = unpackedArray[src + c];
}
}
}
exports.decodeMatrixFromUnpackedColorRGBAArray = decodeMatrixFromUnpackedColorRGBAArray;
function getPackedMatrixTextureShapeWidthHeight(rows, columns) {
return [Math.ceil(columns / 2), Math.ceil(rows / 2)];
}
exports.getPackedMatrixTextureShapeWidthHeight = getPackedMatrixTextureShapeWidthHeight;
function getPackedRGBAArraySizeFromMatrixShape(rows, columns) {
var _a = getPackedMatrixTextureShapeWidthHeight(rows, columns), w = _a[0], h = _a[1];
return w * h * 4;
}
exports.getPackedRGBAArraySizeFromMatrixShape = getPackedRGBAArraySizeFromMatrixShape;
function encodeMatrixToPackedRGBA(matrix, rows, columns, packedRGBA) {
var requiredSize = getPackedRGBAArraySizeFromMatrixShape(rows, columns);
if (packedRGBA.length < requiredSize) {
throw new Error("packedRGBA length (" + packedRGBA.length + ") must be >= " + requiredSize);
}
var _a = getPackedMatrixTextureShapeWidthHeight(rows, columns), textureWidth = _a[0], textureHeight = _a[1];
var oddWidth = (columns % 2) === 1;
var oddHeight = (rows % 2) === 1;
var widthInFullBlocks = Math.floor(columns / 2);
var heightInFullBlocks = Math.floor(rows / 2);
{
var dstStride = (oddWidth ? 4 : 0);
var oneRow = columns;
var dst = 0;
for (var blockY = 0; blockY < heightInFullBlocks; ++blockY) {
var matrixSrcRow = (blockY * 2 * columns);
for (var blockX = 0; blockX < widthInFullBlocks; ++blockX) {
var matrixSrcCol = blockX * 2;
var src = matrixSrcRow + matrixSrcCol;
packedRGBA[dst] = matrix[src];
packedRGBA[dst + 1] = matrix[src + 1];
packedRGBA[dst + 2] = matrix[src + oneRow];
packedRGBA[dst + 3] = matrix[src + oneRow + 1];
dst += 4;
}
dst += dstStride;
}
}
if (oddWidth) {
var src = columns - 1;
var dst = (textureWidth - 1) * 4;
var srcStride = 2 * columns;
var dstStride = textureWidth * 4;
for (var blockY = 0; blockY < heightInFullBlocks; ++blockY) {
packedRGBA[dst] = matrix[src];
packedRGBA[dst + 2] = matrix[src + columns];
src += srcStride;
dst += dstStride;
}
}
if (oddHeight) {
var src = (rows - 1) * columns;
var dst = (textureHeight - 1) * textureWidth * 4;
for (var blockX = 0; blockX < widthInFullBlocks; ++blockX) {
packedRGBA[dst++] = matrix[src++];
packedRGBA[dst++] = matrix[src++];
dst += 2;
}
}
if (oddWidth && oddHeight) {
packedRGBA[packedRGBA.length - 4] = matrix[matrix.length - 1];
}
return packedRGBA;
}
exports.encodeMatrixToPackedRGBA = encodeMatrixToPackedRGBA;
function decodeMatrixFromPackedRGBA(packedRGBA, rows, columns, matrix) {
var requiredSize = rows * columns;
if (requiredSize < matrix.length) {
throw new Error("matrix length (" + matrix.length + ") must be >= " + requiredSize);
}
var oddWidth = (columns % 2) === 1;
var oddHeight = (rows % 2) === 1;
var widthInFullBlocks = Math.floor(columns / 2);
var heightInFullBlocks = Math.floor(rows / 2);
var _a = getPackedMatrixTextureShapeWidthHeight(rows, columns), textureWidth = _a[0], textureHeight = _a[1];
{
var srcStride = oddWidth ? 4 : 0;
var dstStride = columns + (oddWidth ? 1 : 0);
var src = 0;
var dstRow1 = 0;
var dstRow2 = columns;
for (var blockY = 0; blockY < heightInFullBlocks; ++blockY) {
for (var blockX = 0; blockX < widthInFullBlocks; ++blockX) {
matrix[dstRow1++] = packedRGBA[src++];
matrix[dstRow1++] = packedRGBA[src++];
matrix[dstRow2++] = packedRGBA[src++];
matrix[dstRow2++] = packedRGBA[src++];
}
src += srcStride;
dstRow1 += dstStride;
dstRow2 += dstStride;
}
}
if (oddWidth) {
var src = (textureWidth - 1) * 4;
var dst = columns - 1;
var srcStride = textureWidth * 4;
var dstStride = 2 * columns;
for (var blockY = 0; blockY < heightInFullBlocks; ++blockY) {
matrix[dst] = packedRGBA[src];
matrix[dst + columns] = packedRGBA[src + 2];
src += srcStride;
dst += dstStride;
}
}
if (oddHeight) {
var src = (textureHeight - 1) * textureWidth * 4;
var dst = (rows - 1) * columns;
for (var blockX = 0; blockX < widthInFullBlocks; ++blockX) {
matrix[dst++] = packedRGBA[src++];
matrix[dst++] = packedRGBA[src++];
src += 2;
}
}
if (oddWidth && oddHeight) {
matrix[matrix.length - 1] = packedRGBA[packedRGBA.length - 4];
}
return matrix;
}
exports.decodeMatrixFromPackedRGBA = decodeMatrixFromPackedRGBA;
},{}],85:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var TextureManager = (function () {
function TextureManager(gpgpu) {
this.gpgpu = gpgpu;
this.numUsedTextures = 0;
this.numFreeTextures = 0;
this.freeTextures = {};
this.logEnabled = false;
this.usedTextureCount = {};
}
TextureManager.prototype.acquireTexture = function (shapeRC) {
var shapeKey = getKeyFromTextureShape(shapeRC);
if (!(shapeKey in this.freeTextures)) {
this.freeTextures[shapeKey] = [];
}
if (!(shapeKey in this.usedTextureCount)) {
this.usedTextureCount[shapeKey] = 0;
}
this.usedTextureCount[shapeKey]++;
if (this.freeTextures[shapeKey].length > 0) {
this.numFreeTextures--;
this.numUsedTextures++;
this.log();
return this.freeTextures[shapeKey].shift();
}
this.numUsedTextures++;
this.log();
return this.gpgpu.createMatrixTexture(shapeRC[0], shapeRC[1]);
};
TextureManager.prototype.releaseTexture = function (texture, shape) {
var shapeKey = getKeyFromTextureShape(shape);
if (!(shapeKey in this.freeTextures)) {
this.freeTextures[shapeKey] = [];
}
this.freeTextures[shapeKey].push(texture);
this.numFreeTextures++;
this.numUsedTextures--;
this.usedTextureCount[shapeKey]--;
this.log();
};
TextureManager.prototype.log = function () {
if (!this.logEnabled) {
return;
}
var total = this.numFreeTextures + this.numUsedTextures;
console.log('Free/Used', this.numFreeTextures + " / " + this.numUsedTextures, "(" + total + ")");
};
TextureManager.prototype.getNumUsedTextures = function () {
return this.numUsedTextures;
};
TextureManager.prototype.getNumFreeTextures = function () {
return this.numFreeTextures;
};
TextureManager.prototype.dispose = function () {
for (var shape in this.freeTextures) {
if (this.freeTextures.hasOwnProperty(shape)) {
for (var i = 0; i < this.freeTextures[shape].length; i++) {
this.gpgpu.deleteMatrixTexture(this.freeTextures[shape][i]);
}
}
}
};
return TextureManager;
}());
exports.TextureManager = TextureManager;
function getKeyFromTextureShape(shapeRowsCol) {
return shapeRowsCol[0] + "_" + shapeRowsCol[1];
}
},{}],86:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var shader_compiler_1 = require("./shader_compiler");
var TileProgram = (function () {
function TileProgram(aShape, reps) {
this.variableNames = ['A'];
var outputShape = new Array(aShape.length);
for (var i = 0; i < outputShape.length; i++) {
outputShape[i] = aShape[i] * reps[i];
}
this.outputShape = outputShape;
this.rank = outputShape.length;
var dtype = shader_compiler_1.getCoordsDataType(this.rank);
var sourceCoords = getSourceCoords(aShape);
this.userCode = "\n void main() {\n " + dtype + " resRC = getOutputCoords();\n setOutput(getA(" + sourceCoords + "));\n }\n ";
}
return TileProgram;
}());
exports.TileProgram = TileProgram;
function getSourceCoords(aShape) {
var rank = aShape.length;
if (rank > 4) {
throw Error("Tile for rank " + rank + " is not yet supported");
}
if (rank === 1) {
return "imod(resRC, " + aShape[0] + ")";
}
var currentCoords = ['resRC.x', 'resRC.y', 'resRC.z', 'resRC.w'];
var sourceCoords = [];
for (var i = 0; i < aShape.length; i++) {
sourceCoords.push("imod(" + currentCoords[i] + ", " + aShape[i] + ")");
}
return sourceCoords.join();
}
},{"./shader_compiler":82}],87:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var shader_compiler_1 = require("./shader_compiler");
var TransposeProgram = (function () {
function TransposeProgram(aShape, newDim) {
this.variableNames = ['A'];
var outputShape = new Array(aShape.length);
for (var i = 0; i < outputShape.length; i++) {
outputShape[i] = aShape[newDim[i]];
}
this.outputShape = outputShape;
this.rank = outputShape.length;
var dtype = shader_compiler_1.getCoordsDataType(this.rank);
var switched = getSwitchedCoords(newDim);
this.userCode = "\n void main() {\n " + dtype + " resRC = getOutputCoords();\n setOutput(getA(" + switched + "));\n }\n ";
}
return TransposeProgram;
}());
exports.TransposeProgram = TransposeProgram;
function getSwitchedCoords(newDim) {
var rank = newDim.length;
if (rank > 4) {
throw Error("Transpose for rank " + rank + " is not yet supported");
}
var originalOrder = ['resRC.x', 'resRC.y', 'resRC.z', 'resRC.w'];
var switchedCoords = new Array(rank);
for (var i = 0; i < newDim.length; i++) {
switchedCoords[newDim[i]] = originalOrder[i];
}
return switchedCoords.join();
}
},{"./shader_compiler":82}],88:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var UnaryOpProgram = (function () {
function UnaryOpProgram(aShape, opSnippet) {
this.variableNames = ['A'];
this.outputShape = aShape;
this.userCode = "\n float unaryOperation(float x) {\n " + opSnippet + "\n }\n\n void main() {\n float x = getAAtOutCoords();\n float y = unaryOperation(x);\n\n setOutput(y);\n }\n ";
}
return UnaryOpProgram;
}());
exports.UnaryOpProgram = UnaryOpProgram;
exports.CHECK_NAN_SNIPPET = "\n if (isNaN(x)) {\n return x;\n }\n";
exports.ABS = "\n return abs(x);\n";
exports.RELU = exports.CHECK_NAN_SNIPPET + "\n return (x < 0.0) ? 0.0 : x;\n";
exports.ELU = "\n return (x >= 0.0) ? x : (exp(x) - 1.0);\n";
exports.ELU_DER = "\n return (x >= 0.0) ? 1.0 : exp(x);\n";
exports.SELU = "\n // Stable and Attracting Fixed Point (0, 1) for Normalized Weights.\n // see: https://arxiv.org/abs/1706.02515\n float scaleAlpha = 1.7580993408473768599402175208123;\n float scale = 1.0507009873554804934193349852946;\n return (x >= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);\n";
function LEAKY_RELU(alpha) {
return "\n return (x >= 0.0) ? x : " + alpha + " * x;\n ";
}
exports.LEAKY_RELU = LEAKY_RELU;
function STEP(alpha) {
if (alpha === void 0) { alpha = 0.0; }
return exports.CHECK_NAN_SNIPPET + ("\n return x > 0.0 ? 1.0 : float(" + alpha + ");\n ");
}
exports.STEP = STEP;
exports.NEG = "\n return -x;\n";
exports.CEIL = "\n return ceil(x);\n";
exports.FLOOR = "\n return floor(x);\n";
exports.EXP = "\n return exp(x);\n";
exports.LOG = "\n return log(x);\n";
exports.SQRT = exports.CHECK_NAN_SNIPPET + "\n return sqrt(x);\n";
exports.SIGMOID = "\n return 1.0 / (1.0 + exp(-1.0 * x));\n";
exports.SIN = exports.CHECK_NAN_SNIPPET + "\n return sin(x);\n";
exports.COS = exports.CHECK_NAN_SNIPPET + "\n return cos(x);\n";
exports.TAN = "\n return tan(x);\n";
exports.ASIN = exports.CHECK_NAN_SNIPPET + "\n return asin(x);\n";
exports.ACOS = exports.CHECK_NAN_SNIPPET + "\n return acos(x);\n";
exports.ATAN = exports.CHECK_NAN_SNIPPET + "\n return atan(x);\n";
exports.SINH = "\n float e2x = exp(x);\n return (e2x - 1.0 / e2x) / 2.0;\n";
exports.COSH = "\n float e2x = exp(-x);\n return (e2x + 1.0 / e2x) / 2.0;\n";
exports.TANH = "\n float e2x = exp(-2.0 * abs(x));\n return sign(x) * (1.0 - e2x) / (1.0 + e2x);\n";
exports.SQUARE = "\n return x * x;\n";
},{}],89:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var MAX_TEXTURE_SIZE = null;
var util = require("../../../util");
var environment_1 = require("../../../environment");
function createWebGLRenderingContext(attributes) {
var canvas = document.createElement('canvas');
canvas.width = 1;
canvas.height = 1;
return createWebGLRenderingContextFromCanvas(canvas, attributes);
}
exports.createWebGLRenderingContext = createWebGLRenderingContext;
function createWebGLRenderingContextFromCanvas(canvas, attributes) {
var gl;
var webglVersion = environment_1.ENV.get('WEBGL_VERSION');
if (webglVersion === 2) {
gl = canvas.getContext('webgl2', attributes);
}
else if (webglVersion === 1) {
gl = (canvas.getContext('webgl', attributes) ||
canvas.getContext('experimental-webgl', attributes));
}
if (webglVersion === 0 || gl == null) {
throw new Error('This browser does not support WebGL.');
}
return gl;
}
exports.createWebGLRenderingContextFromCanvas = createWebGLRenderingContextFromCanvas;
function callAndCheck(gl, func) {
var returnValue = func();
checkWebGLError(gl);
return returnValue;
}
exports.callAndCheck = callAndCheck;
var webGLDebugErrorCheckingEnabled = false;
function enableDebugWebGLErrorChecking(enabled) {
webGLDebugErrorCheckingEnabled = enabled;
}
exports.enableDebugWebGLErrorChecking = enableDebugWebGLErrorChecking;
function checkWebGLError(gl) {
if (webGLDebugErrorCheckingEnabled) {
var error = gl.getError();
if (error !== gl.NO_ERROR) {
throw new Error('WebGL Error: ' + getWebGLErrorMessage(gl, error));
}
}
}
exports.checkWebGLError = checkWebGLError;
function getWebGLErrorMessage(gl, status) {
switch (status) {
case gl.NO_ERROR:
return 'NO_ERROR';
case gl.INVALID_ENUM:
return 'INVALID_ENUM';
case gl.INVALID_VALUE:
return 'INVALID_VALUE';
case gl.INVALID_OPERATION:
return 'INVALID_OPERATION';
case gl.INVALID_FRAMEBUFFER_OPERATION:
return 'INVALID_FRAMEBUFFER_OPERATION';
case gl.OUT_OF_MEMORY:
return 'OUT_OF_MEMORY';
case gl.CONTEXT_LOST_WEBGL:
return 'CONTEXT_LOST_WEBGL';
default:
return "Unknown error code " + status;
}
}
exports.getWebGLErrorMessage = getWebGLErrorMessage;
function getExtensionOrThrow(gl, extensionName) {
return throwIfNull(gl, function () { return gl.getExtension(extensionName); }, 'Extension "' + extensionName + '" not supported on this browser.');
}
exports.getExtensionOrThrow = getExtensionOrThrow;
function createVertexShader(gl, vertexShaderSource) {
var vertexShader = throwIfNull(gl, function () { return gl.createShader(gl.VERTEX_SHADER); }, 'Unable to create vertex WebGLShader.');
callAndCheck(gl, function () { return gl.shaderSource(vertexShader, vertexShaderSource); });
callAndCheck(gl, function () { return gl.compileShader(vertexShader); });
if (gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS) === false) {
console.log(gl.getShaderInfoLog(vertexShader));
throw new Error('Failed to compile vertex shader.');
}
return vertexShader;
}
exports.createVertexShader = createVertexShader;
function createFragmentShader(gl, fragmentShaderSource) {
var fragmentShader = throwIfNull(gl, function () { return gl.createShader(gl.FRAGMENT_SHADER); }, 'Unable to create fragment WebGLShader.');
callAndCheck(gl, function () { return gl.shaderSource(fragmentShader, fragmentShaderSource); });
callAndCheck(gl, function () { return gl.compileShader(fragmentShader); });
if (gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) === false) {
logShaderSourceAndInfoLog(fragmentShaderSource, gl.getShaderInfoLog(fragmentShader));
throw new Error('Failed to compile fragment shader.');
}
return fragmentShader;
}
exports.createFragmentShader = createFragmentShader;
var lineNumberRegex = /ERROR: [0-9]+:([0-9]+):/g;
function logShaderSourceAndInfoLog(shaderSource, shaderInfoLog) {
var lineNumberRegexResult = lineNumberRegex.exec(shaderInfoLog);
if (lineNumberRegexResult == null) {
console.log("Couldn't parse line number in error: " + shaderInfoLog);
console.log(shaderSource);
return;
}
var lineNumber = +lineNumberRegexResult[1];
var shaderLines = shaderSource.split('\n');
var pad = shaderLines.length.toString().length + 2;
var linesWithLineNumbers = shaderLines.map(function (line, lineNumber) {
return util.rightPad((lineNumber + 1).toString(), pad) + line;
});
var maxLineLength = 0;
for (var i = 0; i < linesWithLineNumbers.length; i++) {
maxLineLength = Math.max(linesWithLineNumbers[i].length, maxLineLength);
}
var beforeErrorLines = linesWithLineNumbers.slice(0, lineNumber - 1);
var errorLine = linesWithLineNumbers.slice(lineNumber - 1, lineNumber);
var afterErrorLines = linesWithLineNumbers.slice(lineNumber);
console.log(beforeErrorLines.join('\n'));
console.log(shaderInfoLog.split('\n')[0]);
console.log("%c " + util.rightPad(errorLine[0], maxLineLength), 'border:1px solid red; background-color:#e3d2d2; color:#a61717');
console.log(afterErrorLines.join('\n'));
}
function createProgram(gl) {
return throwIfNull(gl, function () { return gl.createProgram(); }, 'Unable to create WebGLProgram.');
}
exports.createProgram = createProgram;
function linkProgram(gl, program) {
callAndCheck(gl, function () { return gl.linkProgram(program); });
if (gl.getProgramParameter(program, gl.LINK_STATUS) === false) {
console.log(gl.getProgramInfoLog(program));
throw new Error('Failed to link vertex and fragment shaders.');
}
}
exports.linkProgram = linkProgram;
function validateProgram(gl, program) {
callAndCheck(gl, function () { return gl.validateProgram(program); });
if (gl.getProgramParameter(program, gl.VALIDATE_STATUS) === false) {
console.log(gl.getProgramInfoLog(program));
throw new Error('Shader program validation failed.');
}
}
exports.validateProgram = validateProgram;
function createStaticVertexBuffer(gl, data) {
var buffer = throwIfNull(gl, function () { return gl.createBuffer(); }, 'Unable to create WebGLBuffer');
callAndCheck(gl, function () { return gl.bindBuffer(gl.ARRAY_BUFFER, buffer); });
callAndCheck(gl, function () { return gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW); });
return buffer;
}
exports.createStaticVertexBuffer = createStaticVertexBuffer;
function createStaticIndexBuffer(gl, data) {
var buffer = throwIfNull(gl, function () { return gl.createBuffer(); }, 'Unable to create WebGLBuffer');
callAndCheck(gl, function () { return gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer); });
callAndCheck(gl, function () { return gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, data, gl.STATIC_DRAW); });
return buffer;
}
exports.createStaticIndexBuffer = createStaticIndexBuffer;
function queryMaxTextureSize(gl) {
if (MAX_TEXTURE_SIZE != null) {
return MAX_TEXTURE_SIZE;
}
MAX_TEXTURE_SIZE =
callAndCheck(gl, function () { return gl.getParameter(gl.MAX_TEXTURE_SIZE); });
return MAX_TEXTURE_SIZE;
}
exports.queryMaxTextureSize = queryMaxTextureSize;
function getChannelsPerTexture() {
if (!environment_1.ENV.get('WEBGL_FLOAT_TEXTURE_ENABLED')) {
return 4;
}
if (environment_1.ENV.get('WEBGL_VERSION') === 2) {
return 1;
}
return 4;
}
exports.getChannelsPerTexture = getChannelsPerTexture;
function createTexture(gl) {
return throwIfNull(gl, function () { return gl.createTexture(); }, 'Unable to create WebGLTexture.');
}
exports.createTexture = createTexture;
function validateTextureSize(gl, width, height) {
var maxTextureSize = queryMaxTextureSize(gl);
if ((width <= 0) || (height <= 0)) {
var requested = "[" + width + "x" + height + "]";
throw new Error('Requested texture size ' + requested + ' is invalid.');
}
if ((width > maxTextureSize) || (height > maxTextureSize)) {
var requested = "[" + width + "x" + height + "]";
var max = "[" + maxTextureSize + "x" + maxTextureSize + "]";
throw new Error('Requested texture size ' + requested +
' greater than WebGL maximum on this browser / GPU ' + max + '.');
}
}
exports.validateTextureSize = validateTextureSize;
function createFramebuffer(gl) {
return throwIfNull(gl, function () { return gl.createFramebuffer(); }, 'Unable to create WebGLFramebuffer.');
}
exports.createFramebuffer = createFramebuffer;
function bindVertexBufferToProgramAttribute(gl, program, attribute, buffer, arrayEntriesPerItem, itemStrideInBytes, itemOffsetInBytes, attribLocations) {
var loc = -1;
if ((attribLocations != null) && (attribute in attribLocations)) {
loc = attribLocations[attribute];
}
else {
loc = gl.getAttribLocation(program, attribute);
}
if (loc === -1) {
return;
}
callAndCheck(gl, function () { return gl.bindBuffer(gl.ARRAY_BUFFER, buffer); });
callAndCheck(gl, function () { return gl.vertexAttribPointer(loc, arrayEntriesPerItem, gl.FLOAT, false, itemStrideInBytes, itemOffsetInBytes); });
callAndCheck(gl, function () { return gl.enableVertexAttribArray(loc); });
}
exports.bindVertexBufferToProgramAttribute = bindVertexBufferToProgramAttribute;
function bindTextureUnit(gl, texture, textureUnit) {
validateTextureUnit(gl, textureUnit);
callAndCheck(gl, function () { return gl.activeTexture(gl.TEXTURE0 + textureUnit); });
callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, texture); });
}
exports.bindTextureUnit = bindTextureUnit;
function unbindTextureUnit(gl, textureUnit) {
validateTextureUnit(gl, textureUnit);
callAndCheck(gl, function () { return gl.activeTexture(gl.TEXTURE0 + textureUnit); });
callAndCheck(gl, function () { return gl.bindTexture(gl.TEXTURE_2D, null); });
}
exports.unbindTextureUnit = unbindTextureUnit;
function getProgramUniformLocationOrThrow(gl, program, uniformName) {
return throwIfNull(gl, function () { return gl.getUniformLocation(program, uniformName); }, 'uniform "' + uniformName + '" not present in program.');
}
exports.getProgramUniformLocationOrThrow = getProgramUniformLocationOrThrow;
function bindTextureToProgramUniformSampler(gl, program, texture, uniformSamplerLocation, textureUnit) {
callAndCheck(gl, function () { return bindTextureUnit(gl, texture, textureUnit); });
callAndCheck(gl, function () { return gl.uniform1i(uniformSamplerLocation, textureUnit); });
}
exports.bindTextureToProgramUniformSampler = bindTextureToProgramUniformSampler;
function bindCanvasToFramebuffer(gl) {
callAndCheck(gl, function () { return gl.bindFramebuffer(gl.FRAMEBUFFER, null); });
callAndCheck(gl, function () { return gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); });
callAndCheck(gl, function () { return gl.scissor(0, 0, gl.canvas.width, gl.canvas.height); });
}
exports.bindCanvasToFramebuffer = bindCanvasToFramebuffer;
function bindColorTextureToFramebuffer(gl, texture, framebuffer) {
callAndCheck(gl, function () { return gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); });
callAndCheck(gl, function () { return gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); });
}
exports.bindColorTextureToFramebuffer = bindColorTextureToFramebuffer;
function unbindColorTextureFromFramebuffer(gl, framebuffer) {
callAndCheck(gl, function () { return gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); });
callAndCheck(gl, function () { return gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, null, 0); });
}
exports.unbindColorTextureFromFramebuffer = unbindColorTextureFromFramebuffer;
function validateFramebuffer(gl) {
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
if (status !== gl.FRAMEBUFFER_COMPLETE) {
throw new Error('Error binding framebuffer: ' + getFramebufferErrorMessage(gl, status));
}
}
exports.validateFramebuffer = validateFramebuffer;
function getFramebufferErrorMessage(gl, status) {
switch (status) {
case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
return 'FRAMEBUFFER_INCOMPLETE_ATTACHMENT';
case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
return 'FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT';
case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
return 'FRAMEBUFFER_INCOMPLETE_DIMENSIONS';
case gl.FRAMEBUFFER_UNSUPPORTED:
return 'FRAMEBUFFER_UNSUPPORTED';
default:
return "unknown error " + status;
}
}
exports.getFramebufferErrorMessage = getFramebufferErrorMessage;
function throwIfNull(gl, returnTOrNull, failureMessage) {
var tOrNull = callAndCheck(gl, function () { return returnTOrNull(); });
if (tOrNull == null) {
throw new Error(failureMessage);
}
return tOrNull;
}
function validateTextureUnit(gl, textureUnit) {
var maxTextureUnit = gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS - 1;
var glTextureUnit = textureUnit + gl.TEXTURE0;
if (glTextureUnit < gl.TEXTURE0 || glTextureUnit > maxTextureUnit) {
var textureUnitRange = "[gl.TEXTURE0, gl.TEXTURE" + maxTextureUnit + "]";
throw new Error("textureUnit must be in " + textureUnitRange + ".");
}
}
function getTextureShapeFromLogicalShape(gl, logShape) {
if (logShape.length !== 2) {
var squeezeResult = util.squeezeShape(logShape);
logShape = squeezeResult.newShape;
}
var maxTexSize = queryMaxTextureSize(gl);
var size = util.sizeFromShape(logShape);
if (logShape.length <= 1 && size <= maxTexSize) {
return [size, 1];
}
else if (logShape.length === 2 && logShape[0] <= maxTexSize &&
logShape[1] <= maxTexSize) {
return logShape;
}
else if (logShape.length === 3 && logShape[0] <= maxTexSize &&
logShape[1] * logShape[2] <= maxTexSize) {
return [logShape[0], logShape[1] * logShape[2]];
}
else if (logShape.length === 4 && logShape[0] <= maxTexSize &&
logShape[1] * logShape[2] * logShape[3] <= maxTexSize) {
return [logShape[0], logShape[1] * logShape[2] * logShape[3]];
}
else {
return util.sizeToSquarishShape(size);
}
}
exports.getTextureShapeFromLogicalShape = getTextureShapeFromLogicalShape;
},{"../../../environment":15,"../../../util":101}],90:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
function getBroadcastDims(inShape, outShape) {
var inRank = inShape.length;
var dims = [];
for (var i = 0; i < inRank; i++) {
var dim = inRank - 1 - i;
var a = inShape[dim] || 1;
var b = outShape[outShape.length - 1 - i] || 1;
if (b > 1 && a === 1) {
dims.unshift(dim);
}
}
return dims;
}
exports.getBroadcastDims = getBroadcastDims;
function broadcastDimsAreOuter(dims) {
for (var i = 0; i < dims.length; i++) {
if (dims[i] !== i) {
return false;
}
}
return true;
}
exports.broadcastDimsAreOuter = broadcastDimsAreOuter;
function assertAndGetBroadcastShape(shapeA, shapeB) {
var result = [];
var errMsg = "Operands could not be broadcast together with shapes " +
(shapeA + " and " + shapeB + ".");
var l = Math.max(shapeA.length, shapeB.length);
for (var i = 0; i < l; i++) {
var a = shapeA[shapeA.length - i - 1] || 1;
var b = shapeB[shapeB.length - i - 1] || 1;
if (a > 1 && b > 1 && a !== b) {
throw Error(errMsg);
}
result.unshift(Math.max(a, b));
}
return result;
}
exports.assertAndGetBroadcastShape = assertAndGetBroadcastShape;
},{}],91:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../util");
function assertParams(aShape, bShape, axis) {
var aRank = aShape.length;
var bRank = bShape.length;
util.assert(aShape.length === bShape.length, "Error in concat" + aRank + "D: rank of x1 (" + aRank + ") and x2 (" + bRank + ") " +
"must be the same.");
util.assert(axis >= 0 && axis < aRank, "Error in concat" + aRank + "D: axis must be " +
("between 0 and " + (aRank - 1) + "."));
for (var i = 0; i < aRank; i++) {
util.assert((i === axis) || (aShape[i] === bShape[i]), "Error in concat" + aRank + "D: Shape (" + aShape + ") does not match " +
("(" + bShape + ") along the non-concatenated axis " + i + "."));
}
}
exports.assertParams = assertParams;
function computeOutShape(x1Shape, x2Shape, axis) {
util.assert(x1Shape.length === x2Shape.length, 'x1 and x2 should have the same rank.');
var outputShape = x1Shape.slice();
outputShape[axis] += x2Shape[axis];
return outputShape;
}
exports.computeOutShape = computeOutShape;
},{"../util":101}],92:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../util");
function computePool2DInfo(inShape, filterSize, strides, pad, dataFormat) {
if (dataFormat === void 0) { dataFormat = 'channelsLast'; }
var _a = parseTupleParam(filterSize), filterHeight = _a[0], filterWidth = _a[1];
var filterShape;
if (dataFormat === 'channelsLast') {
filterShape = [filterHeight, filterWidth, inShape[3], inShape[3]];
}
else if (dataFormat === 'channelsFirst') {
filterShape = [filterHeight, filterWidth, inShape[1], inShape[1]];
}
else {
throw new Error("Unknown dataFormat " + dataFormat);
}
return computeConv2DInfo(inShape, filterShape, strides, pad, false, dataFormat);
}
exports.computePool2DInfo = computePool2DInfo;
function computeConv2DInfo(inShape, filterShape, strides, pad, depthwise, dataFormat) {
if (depthwise === void 0) { depthwise = false; }
if (dataFormat === void 0) { dataFormat = 'channelsLast'; }
var _a = [-1, -1, -1, -1], batchSize = _a[0], inHeight = _a[1], inWidth = _a[2], inChannels = _a[3];
if (dataFormat === 'channelsLast') {
batchSize = inShape[0], inHeight = inShape[1], inWidth = inShape[2], inChannels = inShape[3];
}
else if (dataFormat === 'channelsFirst') {
batchSize = inShape[0], inChannels = inShape[1], inHeight = inShape[2], inWidth = inShape[3];
}
else {
throw new Error("Unknown dataFormat " + dataFormat);
}
var filterHeight = filterShape[0], filterWidth = filterShape[1], filterChannels = filterShape[3];
var _b = parseTupleParam(strides), strideHeight = _b[0], strideWidth = _b[1];
var _c = getPadAndOutInfo(pad, inHeight, inWidth, strideHeight, strideWidth, filterHeight, filterWidth), padInfo = _c.padInfo, outHeight = _c.outHeight, outWidth = _c.outWidth;
var outChannels = depthwise ? filterChannels * inChannels : filterChannels;
var outShape;
if (dataFormat === 'channelsFirst') {
outShape = [batchSize, outChannels, outHeight, outWidth];
}
else if (dataFormat === 'channelsLast') {
outShape = [batchSize, outHeight, outWidth, outChannels];
}
return {
batchSize: batchSize,
dataFormat: dataFormat,
inHeight: inHeight,
inWidth: inWidth,
inChannels: inChannels,
outHeight: outHeight,
outWidth: outWidth,
outChannels: outChannels,
padInfo: padInfo,
strideHeight: strideHeight,
strideWidth: strideWidth,
filterHeight: filterHeight,
filterWidth: filterWidth,
inShape: inShape,
outShape: outShape,
filterShape: filterShape
};
}
exports.computeConv2DInfo = computeConv2DInfo;
function computeOutputShape3D(inShape, fieldSize, outDepth, stride, zeroPad) {
if (zeroPad == null) {
zeroPad = computeDefaultPad(inShape, fieldSize, stride);
}
var inputRows = inShape[0];
var inputCols = inShape[1];
var outputRows = (inputRows - fieldSize + 2 * zeroPad) / stride + 1;
util.assert(util.isInt(outputRows), "The output # of rows (" + outputRows + ") must be an integer. Change the " +
"stride and/or zero pad parameters");
var outputCols = (inputCols - fieldSize + 2 * zeroPad) / stride + 1;
util.assert(util.isInt(outputCols), "The output # of columns (" + outputCols + ") must be an integer. Change " +
"the stride and/or zero pad parameters");
return [outputRows, outputCols, outDepth];
}
exports.computeOutputShape3D = computeOutputShape3D;
function computeDefaultPad(inputShape, fieldSize, stride) {
return Math.floor((inputShape[0] * (stride - 1) - stride + fieldSize) / 2);
}
exports.computeDefaultPad = computeDefaultPad;
function computeWeightsShape4D(inputDepth, outputDepth, filterHeight, filterWidth) {
return [filterHeight, filterWidth, inputDepth, outputDepth];
}
exports.computeWeightsShape4D = computeWeightsShape4D;
function computeDilatedRC(rc, origStride) {
var rowsDilated = (rc[0] - 1) * origStride + 1;
var colsDilated = (rc[1] - 1) * origStride + 1;
return [rowsDilated, colsDilated];
}
exports.computeDilatedRC = computeDilatedRC;
function parseTupleParam(param) {
return typeof param === 'number' ? [param, param] : param;
}
function getPadAndOutInfo(pad, inHeight, inWidth, strideHeight, strideWidth, filterHeight, filterWidth) {
var padInfo;
var outHeight;
var outWidth;
if (typeof pad === 'number') {
padInfo = { top: pad, bottom: pad, left: pad, right: pad };
var outShape = computeOutputShape3D([inHeight, inWidth, 1], filterHeight, 1, strideHeight, pad);
outHeight = outShape[0];
outWidth = outShape[1];
}
else if (pad === 'same') {
outHeight = Math.ceil(inHeight / strideHeight);
outWidth = Math.ceil(inWidth / strideWidth);
var padAlongHeight = (outHeight - 1) * strideHeight + filterHeight - inHeight;
var padAlongWidth = (outWidth - 1) * strideWidth + filterWidth - inWidth;
var top_1 = Math.floor(padAlongHeight / 2);
var bottom = padAlongHeight - top_1;
var left = Math.floor(padAlongWidth / 2);
var right = padAlongWidth - left;
padInfo = { top: top_1, bottom: bottom, left: left, right: right };
}
else if (pad === 'valid') {
padInfo = { top: 0, bottom: 0, left: 0, right: 0 };
outHeight = Math.ceil((inHeight - filterHeight + 1) / strideHeight);
outWidth = Math.ceil((inWidth - filterWidth + 1) / strideWidth);
}
else {
throw Error("Unknown padding parameter: " + pad);
}
return { padInfo: padInfo, outHeight: outHeight, outWidth: outWidth };
}
},{"../util":101}],93:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../environment");
var ndarray_1 = require("./ndarray");
var SquareCostFunc = (function () {
function SquareCostFunc() {
this.halfOne = environment_1.ENV.math.keep(ndarray_1.Scalar.new(0.5));
}
SquareCostFunc.prototype.cost = function (math, x1, x2) {
var diff = math.subStrict(x1, x2);
var diffSquared = math.elementWiseMul(diff, diff);
var result = math.scalarTimesArray(this.halfOne, diffSquared);
diff.dispose();
diffSquared.dispose();
return result;
};
SquareCostFunc.prototype.der = function (math, x1, x2) {
return math.subStrict(x1, x2);
};
SquareCostFunc.prototype.dispose = function () {
this.halfOne.dispose();
};
return SquareCostFunc;
}());
exports.SquareCostFunc = SquareCostFunc;
},{"../environment":15,"./ndarray":95}],94:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("../environment");
var util = require("../util");
var axis_util = require("./axis_util");
var backend_engine_1 = require("./backends/backend_engine");
var matmul_1 = require("./backends/types/matmul");
var broadcast_util = require("./broadcast_util");
var concat_util = require("./concat_util");
var conv_util = require("./conv_util");
var ndarray_1 = require("./ndarray");
var slice_util = require("./slice_util");
var NDArrayMath = (function () {
function NDArrayMath(backend, safeMode) {
this.safeMode = safeMode;
this.numArrays = 0;
this.customBackend = false;
this.ndarrayScopes = [];
this.ndarraysToKeep = [];
this.activeScopeNDArraysToKeep = [];
if (typeof backend === 'string') {
this.backend = environment_1.ENV.getBackend(backend);
}
else {
this.customBackend = true;
this.backend = backend;
}
this.backendEngine = new backend_engine_1.BackendEngine(this.backend);
}
NDArrayMath.prototype.time = function (query) {
return this.backend.time(query);
};
NDArrayMath.prototype.getNumArrays = function () {
return this.numArrays;
};
NDArrayMath.prototype.register = function (a) {
this.track(a);
this.numArrays++;
};
NDArrayMath.prototype.writePixels = function (id, pixels, numChannels) {
this.backend.writePixels(id, pixels, numChannels);
};
NDArrayMath.prototype.write = function (id, values, dtype, shape) {
this.backend.write(id, values, dtype, shape);
};
NDArrayMath.prototype.readSync = function (id) {
return this.backend.readSync(id);
};
NDArrayMath.prototype.read = function (id) {
return this.backend.read(id);
};
NDArrayMath.prototype.scope = function (scopeFn) {
var _this = this;
this.startScope();
var keepFn = function (ndarray) { return _this.keep(ndarray); };
var trackFn = function (ndarray) { return ndarray; };
var result = scopeFn(keepFn, trackFn);
if (result instanceof Promise) {
result.then(function (r) { return _this.endScope(r); });
return result;
}
else {
this.endScope(result);
return result;
}
};
NDArrayMath.prototype.enableDebugMode = function () {
this.backendEngine.enableDebugMode();
console.warn('Debugging mode is ON. The output of every math call will ' +
'be downloaded to CPU and checked for NaNs. ' +
'This significantly impacts performance.');
};
NDArrayMath.prototype.startScope = function () {
var newScope = [];
this.ndarrayScopes.push(newScope);
this.activeScope = newScope;
var newNDArraysToKeep = [];
this.ndarraysToKeep.push(newNDArraysToKeep);
this.activeScopeNDArraysToKeep = newNDArraysToKeep;
};
NDArrayMath.prototype.extractNDArraysFromScopeResult = function (result) {
if (result == null) {
return [];
}
if (result instanceof ndarray_1.NDArray) {
return [result];
}
var list = [];
var resultObj = result;
for (var k in resultObj) {
var val = resultObj[k];
if (val instanceof ndarray_1.NDArray) {
list.push(val);
}
}
return list;
};
NDArrayMath.prototype.endScope = function (result) {
var _this = this;
var arraysToKeep = this.activeScopeNDArraysToKeep;
var resultArrays = this.extractNDArraysFromScopeResult(result);
arraysToKeep = arraysToKeep.concat(resultArrays);
for (var i = 0; i < this.activeScope.length; i++) {
var ndarray = this.activeScope[i];
if (this.isNDArrayDataInList(ndarray, arraysToKeep)) {
continue;
}
ndarray.dispose();
}
this.ndarrayScopes.pop();
this.activeScope = this.ndarrayScopes.length === 0 ?
null :
this.ndarrayScopes[this.ndarrayScopes.length - 1];
resultArrays.forEach(function (val) {
if (!_this.isNDArrayDataInList(val, _this.activeScopeNDArraysToKeep)) {
_this.track(val);
}
});
this.ndarraysToKeep.pop();
this.activeScopeNDArraysToKeep = this.ndarraysToKeep.length === 0 ?
null :
this.ndarraysToKeep[this.ndarraysToKeep.length - 1];
};
NDArrayMath.prototype.isNDArrayDataInList = function (ndarray, ndarrayList) {
for (var i = 0; i < ndarrayList.length; i++) {
if (ndarrayList[i].id === ndarray.id) {
return true;
}
}
return false;
};
NDArrayMath.prototype.keep = function (result) {
if (this.activeScope == null) {
if (this.safeMode) {
throw new Error('You are using math in safe mode. Enclose all ' +
'math.method() calls inside a scope: ' +
'math.scope(() => {math.method();...}) to avoid memory ' +
'leaks.');
}
return result;
}
this.activeScopeNDArraysToKeep.push(result);
return result;
};
NDArrayMath.prototype.track = function (result) {
if (this.activeScope == null) {
if (this.safeMode) {
throw new Error('You are using math in safe mode. Enclose all ' +
'math.method() calls inside a scope: ' +
'math.scope(() => {math.method();...}) to avoid memory ' +
'leaks.');
}
return result;
}
this.activeScope.push(result);
return result;
};
NDArrayMath.prototype.dispose = function () {
if (this.customBackend) {
this.backend.dispose();
}
};
NDArrayMath.prototype.matMul = function (a, b, aOrientation, bOrientation) {
var _this = this;
if (aOrientation === void 0) { aOrientation = matmul_1.MatrixOrientation.REGULAR; }
if (bOrientation === void 0) { bOrientation = matmul_1.MatrixOrientation.REGULAR; }
var innerShapeA = (aOrientation === matmul_1.MatrixOrientation.REGULAR) ? a.shape[1] : a.shape[0];
var innerShapeB = (bOrientation === matmul_1.MatrixOrientation.REGULAR) ? b.shape[0] : b.shape[1];
util.assert(a.rank === 2 && b.rank === 2, "Error in matMul: inputs must be rank 2, got ranks " + a.rank +
(" and " + b.rank + "."));
util.assert(innerShapeA === innerShapeB, "Error in matMul: inner shapes (" + innerShapeA + ") and (" +
(innerShapeB + ") of NDArrays with shapes " + a.shape + " and ") +
(b.shape + " and orientations " + matmul_1.MatrixOrientation[aOrientation]) +
(" and " + matmul_1.MatrixOrientation[bOrientation] + " must match."));
return this.backendEngine.executeKernel('MatMul', { inputs: { a: a, b: b }, args: { aOrientation: aOrientation, bOrientation: bOrientation } }, function (dy, y) {
return {
a: function () { return _this.matMul(dy, b, matmul_1.MatrixOrientation.REGULAR, matmul_1.MatrixOrientation.TRANSPOSED); },
b: function () { return _this.matMul(a, dy, matmul_1.MatrixOrientation.TRANSPOSED, matmul_1.MatrixOrientation.REGULAR); }
};
});
};
NDArrayMath.prototype.executeOp = function (name, f) {
return f();
};
NDArrayMath.prototype.vectorTimesMatrix = function (v, matrix) {
util.assert(v.rank === 1, "Error in vectorTimesMatrix: first input must be rank 1, but got " +
("rank " + v.rank + "."));
util.assert(matrix.rank === 2, "Error in vectorTimesMatrix: second input must be rank 2, but got " +
("rank " + matrix.rank + "."));
util.assert(v.size === matrix.shape[0], "Error in vectorTimesMatrix: size of vector (" + v.size + ") " +
("must match first dimension of matrix (" + matrix.shape[0] + ")"));
return this.matMul(v.as2D(1, -1), matrix).as1D();
};
NDArrayMath.prototype.matrixTimesVector = function (matrix, v) {
util.assert(v.rank === 1, "Error in matrixTimesVector: second input must rank 1, but got " +
("rank " + v.rank + "."));
util.assert(matrix.rank === 2, "Error in matrixTimesVector: first input must be a rank 2, but got " +
("rank " + matrix.rank + "."));
util.assert(v.size === matrix.shape[1], "Error in matrixTimesVector: size of first rank 1 input " + v.size + " " +
"must match inner dimension of second rank 2 input, but got " +
("shape " + matrix.shape + "."));
return this.matMul(matrix, v.as2D(-1, 1)).as1D();
};
NDArrayMath.prototype.dotProduct = function (v1, v2) {
util.assert(v1.rank === 1 && v2.rank === 1, "Error in dotProduct: inputs must be rank 1, but got ranks " +
(v1.rank + " and " + v2.rank + "."));
util.assert(v1.size === v2.size, "Error in dotProduct: size of inputs (" + v1.size + ") and (" +
(v2.size + ") must match."));
return this.matMul(v1.as2D(1, -1), v2.as2D(-1, 1)).asScalar();
};
NDArrayMath.prototype.outerProduct = function (v1, v2) {
util.assert(v1.rank === 1 && v2.rank === 1, "Error in outerProduct: inputs must be rank 1, but got ranks " +
(v1.rank + " and " + v2.rank + "."));
return this.matMul(v1.as2D(-1, 1), v2.as2D(1, -1));
};
NDArrayMath.prototype.clone = function (x) {
return this.backendEngine.executeKernel('Clone', { inputs: { x: x } });
};
NDArrayMath.prototype.reshape = function (ndarray, newShape) {
console.warn('math.reshape() is deprecated. Please call reshape() ' +
'directly on the ndarray object');
return ndarray.reshape(newShape);
};
NDArrayMath.prototype.slice1D = function (x, begin, size) {
slice_util.assertParamsValid(x, [begin], [size]);
return this.backendEngine.executeKernel('Slice1D', { inputs: { x: x }, args: { begin: begin, size: size } });
};
NDArrayMath.prototype.slice2D = function (x, begin, size) {
slice_util.assertParamsValid(x, begin, size);
return this.backendEngine.executeKernel('Slice2D', { inputs: { x: x }, args: { begin: begin, size: size } });
};
NDArrayMath.prototype.slice3D = function (x, begin, size) {
slice_util.assertParamsValid(x, begin, size);
return this.backendEngine.executeKernel('Slice3D', { inputs: { x: x }, args: { begin: begin, size: size } });
};
NDArrayMath.prototype.slice4D = function (x, begin, size) {
slice_util.assertParamsValid(x, begin, size);
return this.backendEngine.executeKernel('Slice4D', { inputs: { x: x }, args: { begin: begin, size: size } });
};
NDArrayMath.prototype.concat1D = function (a, b) {
concat_util.assertParams(a.shape, b.shape, 0);
return this.backendEngine.executeKernel('Concat1D', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.concat2D = function (a, b, axis) {
concat_util.assertParams(a.shape, b.shape, axis);
return this.backendEngine.executeKernel('Concat2D', { inputs: { a: a, b: b }, args: { axis: axis } });
};
NDArrayMath.prototype.concat3D = function (a, b, axis) {
concat_util.assertParams(a.shape, b.shape, axis);
return this.backendEngine.executeKernel('Concat3D', { inputs: { a: a, b: b }, args: { axis: axis } });
};
NDArrayMath.prototype.concat4D = function (a, b, axis) {
concat_util.assertParams(a.shape, b.shape, axis);
return this.backendEngine.executeKernel('Concat4D', { inputs: { a: a, b: b }, args: { axis: axis } });
};
NDArrayMath.prototype.logSumExp = function (input, axis, keepDims) {
var _this = this;
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
var axes = axis_util.parseAxisParam(axis, input.shape);
return this.executeOp('logSumExp', function () {
var xMax = _this.max(input, axes, true);
var a = _this.subtract(input, xMax);
var b = _this.exp(a);
var c = _this.sum(b, axes);
var d = _this.log(c);
var res = _this.add(xMax.reshape(d.shape), d);
if (keepDims) {
var newShape = axis_util.expandShapeToKeepDim(res.shape, axes);
return res.reshape(newShape);
}
return res;
});
};
NDArrayMath.prototype.sum = function (x, axis, keepDims) {
var _this = this;
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
var origAxes = axis_util.parseAxisParam(axis, x.shape);
var axes = origAxes;
var permutedAxes = axis_util.getPermutedAxes(axes, x.rank);
return this.executeOp('sum', function () {
if (permutedAxes != null) {
x = _this.transpose(x, permutedAxes);
axes = axis_util.getInnerMostAxes(axes.length, x.rank);
}
var res = _this.backendEngine.executeKernel('Sum', { inputs: { x: x }, args: { axes: axes } }, function (dy, y) {
return {
x: function () {
if (axis != null) {
throw new Error("Gradients for sum with axis reduction not yet " +
"supported.");
}
return _this.multiply(dy, ndarray_1.NDArray.onesLike(x));
}
};
});
if (keepDims) {
var newShape = axis_util.expandShapeToKeepDim(res.shape, origAxes);
return res.reshape(newShape);
}
return res;
});
};
NDArrayMath.prototype.mean = function (x, axis, keepDims) {
var _this = this;
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
var axes = axis_util.parseAxisParam(axis, x.shape);
var shapes = axis_util.computeOutAndReduceShapes(x.shape, axes);
var reduceShape = shapes[1];
var reduceSize = util.sizeFromShape(reduceShape);
return this.executeOp('mean', function () {
return _this.scope(function (keep) {
var res = _this.divide(x, ndarray_1.Scalar.new(reduceSize));
return _this.sum(res, axis, keepDims);
});
});
};
NDArrayMath.prototype.argMin = function (x, axis) {
var _this = this;
if (axis === void 0) { axis = null; }
var axes = axis_util.parseAxisParam(axis, x.shape);
var permutedAxes = axis_util.getPermutedAxes(axes, x.rank);
return this.executeOp('argMin', function () {
if (permutedAxes != null) {
x = _this.transpose(x, permutedAxes);
axes = axis_util.getInnerMostAxes(axes.length, x.rank);
}
return _this.backendEngine.executeKernel('ArgMin', { inputs: { x: x }, args: { axes: axes } });
});
};
NDArrayMath.prototype.argMax = function (x, axis) {
var _this = this;
if (axis === void 0) { axis = null; }
var axes = axis_util.parseAxisParam(axis, x.shape);
var permutedAxes = axis_util.getPermutedAxes(axes, x.rank);
return this.executeOp('argMax', function () {
if (permutedAxes != null) {
x = _this.transpose(x, permutedAxes);
axes = axis_util.getInnerMostAxes(axes.length, x.rank);
}
return _this.backendEngine.executeKernel('ArgMax', { inputs: { x: x }, args: { axes: axes } });
});
};
NDArrayMath.prototype.argMaxEquals = function (x1, x2) {
var _this = this;
util.assertShapesMatch(x1.shape, x2.shape, 'Error in argMaxEquals: ');
return this.executeOp('argMaxEquals', function () { return _this.scope(function () {
return _this.equal(_this.argMax(x1), _this.argMax(x2));
}); });
};
NDArrayMath.prototype.equal = function (a, b) {
return this.backendEngine.executeKernel('Equal', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.equalStrict = function (a, b) {
util.assertShapesMatch(a.shape, b.shape, 'Error in equalStrict: ');
return this.equal(a, b);
};
NDArrayMath.prototype.topK = function (x, k) {
var _this = this;
util.assert(k <= x.size, "Error in topK: k value (" + k + ") must be less than size of input " +
("ndarray, got shape " + x.shape + "."));
var values;
var indices;
this.executeOp('topK', function () {
values = _this.backendEngine.executeKernel('TopKValues', { inputs: { x: x }, args: { k: k } });
indices = _this.backendEngine.executeKernel('TopKIndices', { inputs: { x: x }, args: { k: k } });
return values;
});
var result = { values: values, indices: indices };
return result;
};
NDArrayMath.prototype.min = function (x, axis, keepDims) {
var _this = this;
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
var origAxes = axis_util.parseAxisParam(axis, x.shape);
var axes = origAxes;
var permutedAxes = axis_util.getPermutedAxes(axes, x.rank);
return this.executeOp('min', function () {
if (permutedAxes != null) {
x = _this.transpose(x, permutedAxes);
axes = axis_util.getInnerMostAxes(axes.length, x.rank);
}
var res = _this.backendEngine.executeKernel('Min', { inputs: { x: x }, args: { axes: axes } });
if (keepDims) {
var newShape = axis_util.expandShapeToKeepDim(res.shape, origAxes);
return res.reshape(newShape);
}
return res;
});
};
NDArrayMath.prototype.max = function (x, axis, keepDims) {
var _this = this;
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
var origAxes = axis_util.parseAxisParam(axis, x.shape);
var axes = origAxes;
var permutedAxes = axis_util.getPermutedAxes(axes, x.rank);
return this.executeOp('max', function () {
if (permutedAxes != null) {
x = _this.transpose(x, permutedAxes);
axes = axis_util.getInnerMostAxes(axes.length, x.rank);
}
var res = _this.backendEngine.executeKernel('Max', { inputs: { x: x }, args: { axes: axes } });
if (keepDims) {
var newShape = axis_util.expandShapeToKeepDim(res.shape, origAxes);
return res.reshape(newShape);
}
return res;
});
};
NDArrayMath.prototype.softmax = function (logits, dim) {
var _this = this;
if (dim === void 0) { dim = -1; }
if (dim === -1) {
dim = logits.rank - 1;
}
if (dim !== logits.rank - 1) {
throw Error('Softmax along a non-last dimension is not yet supported. ' +
("Logits was rank " + logits.rank + " and dim was " + dim));
}
return this.executeOp('softmax', function () {
return _this.scope(function () {
var lse = _this.logSumExp(logits, [dim], true);
var logResult = _this.subtract(logits, lse);
return _this.exp(logResult);
});
});
};
NDArrayMath.prototype.switchDim = function (a, newDim) {
return this.transpose(a, newDim);
};
NDArrayMath.prototype.tile = function (x, reps) {
util.assert(x.rank === reps.length, "Error in transpose: rank of input " + x.rank + " " +
("must match length of reps " + reps + "."));
return this.backendEngine.executeKernel('Tile', { inputs: { x: x }, args: { reps: reps } });
};
NDArrayMath.prototype.transpose = function (x, perm) {
if (perm == null) {
perm = x.shape.map(function (s, i) { return i; }).reverse();
}
util.assert(x.rank === perm.length, "Error in transpose: rank of input " + x.rank + " " +
("must match length of perm " + perm + "."));
return this.backendEngine.executeKernel('Transpose', { inputs: { x: x }, args: { perm: perm } });
};
NDArrayMath.prototype.scalarPlusArray = function (c, a) {
util.assert(c.size === 1, "Error in scalarPlusArray: first argument must be rank 0, but got " +
("rank " + c.rank + "."));
return this.add(c, a);
};
NDArrayMath.prototype.scalarMinusArray = function (c, a) {
util.assert(c.size === 1, "Error in scalarMinusArray: first argument must be rank 0, but got " +
("rank " + c.rank + "."));
return this.subtract(c, a);
};
NDArrayMath.prototype.arrayMinusScalar = function (a, c) {
util.assert(c.size === 1, "Error in arrayMinusScalar: second argument must be rank 0, but " +
("got rank " + c.rank + "."));
return this.subtract(a, c);
};
NDArrayMath.prototype.neg = function (x) {
return this.backendEngine.executeKernel('Neg', { inputs: { x: x } });
};
NDArrayMath.prototype.add = function (a, b) {
broadcast_util.assertAndGetBroadcastShape(a.shape, b.shape);
return this.backendEngine.executeKernel('Add', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.addStrict = function (a, b) {
util.assertShapesMatch(a.shape, b.shape, 'Error in addStrict: ');
return this.add(a, b);
};
NDArrayMath.prototype.subtract = function (a, b) {
broadcast_util.assertAndGetBroadcastShape(a.shape, b.shape);
return this.backendEngine.executeKernel('Sub', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.pow = function (a, b) {
util.assert(b.dtype === 'int32', 'only supports int32 data type for the exponent parameter.');
broadcast_util.assertAndGetBroadcastShape(a.shape, b.shape);
return this.backendEngine.executeKernel('Pow', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.powStrict = function (a, b) {
util.assertShapesMatch(a.shape, b.shape, 'Error in powStrict: ');
return this.pow(a, b);
};
NDArrayMath.prototype.sub = function (a, b) {
return this.subtract(a, b);
};
NDArrayMath.prototype.subStrict = function (a, b) {
util.assertShapesMatch(a.shape, b.shape, 'Error in subStrict: ');
return this.subtract(a, b);
};
NDArrayMath.prototype.multiply = function (a, b) {
broadcast_util.assertAndGetBroadcastShape(a.shape, b.shape);
return this.backendEngine.executeKernel('Mul', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.elementWiseMul = function (a, b) {
return this.multiplyStrict(a, b);
};
NDArrayMath.prototype.multiplyStrict = function (a, b) {
util.assertShapesMatch(a.shape, b.shape, 'Error in multiplyStrict: ');
return this.multiply(a, b);
};
NDArrayMath.prototype.divide = function (a, b) {
broadcast_util.assertAndGetBroadcastShape(a.shape, b.shape);
return this.backendEngine.executeKernel('Div', { inputs: { a: a, b: b } });
};
NDArrayMath.prototype.divideStrict = function (a, b) {
util.assertShapesMatch(a.shape, b.shape, 'Error in divideStrict: ');
return this.divide(a, b);
};
NDArrayMath.prototype.scalarDividedByArray = function (c, a) {
util.assert(c.size === 1, "Error in scalarDividedByArray: first argument must be rank 0, but " +
("got NDArray of rank " + c.rank + "."));
return this.divide(c, a);
};
NDArrayMath.prototype.arrayDividedByScalar = function (a, c) {
util.assert(c.size === 1, "Error in arrayDividedByScalar: second argument must be rank 0, " +
("but got NDArray of rank " + c.rank + "."));
return this.divide(a, c);
};
NDArrayMath.prototype.ceil = function (x) {
return this.backendEngine.executeKernel('Ceil', { inputs: { x: x } });
};
NDArrayMath.prototype.floor = function (x) {
return this.backendEngine.executeKernel('Floor', { inputs: { x: x } });
};
NDArrayMath.prototype.exp = function (x) {
return this.backendEngine.executeKernel('Exp', { inputs: { x: x } });
};
NDArrayMath.prototype.log = function (x) {
return this.backendEngine.executeKernel('Log', { inputs: { x: x } });
};
NDArrayMath.prototype.sqrt = function (x) {
return this.backendEngine.executeKernel('Sqrt', { inputs: { x: x } });
};
NDArrayMath.prototype.square = function (x) {
return this.backendEngine.executeKernel('Square', { inputs: { x: x } });
};
NDArrayMath.prototype.abs = function (x) {
return this.backendEngine.executeKernel('Abs', { inputs: { x: x } });
};
NDArrayMath.prototype.clip = function (x, min, max) {
util.assert((min <= max), "Error in clip: min (" + min + ") must be" +
("less than or equal to max (" + max + ")."));
return this.backendEngine.executeKernel('Clip', { inputs: { x: x }, args: { min: min, max: max } });
};
NDArrayMath.prototype.relu = function (x) {
var _this = this;
return this.backendEngine.executeKernel('Relu', { inputs: { x: x } }, function (dy, y) {
return { x: function () { return _this.step(x); } };
});
};
NDArrayMath.prototype.elu = function (x) {
return this.backendEngine.executeKernel('Elu', { inputs: { x: x } });
};
NDArrayMath.prototype.eluDer = function (x) {
return this.backendEngine.executeKernel('EluDer', { inputs: { x: x } });
};
NDArrayMath.prototype.selu = function (x) {
return this.backendEngine.executeKernel('Selu', { inputs: { x: x } });
};
NDArrayMath.prototype.leakyRelu = function (x, alpha) {
if (alpha === void 0) { alpha = 0.2; }
return this.backendEngine.executeKernel('LeakyRelu', { inputs: { x: x }, args: { alpha: alpha } });
};
NDArrayMath.prototype.prelu = function (x, alpha) {
return this.backendEngine.executeKernel('PReLU', { inputs: { x: x, alpha: alpha } });
};
NDArrayMath.prototype.preluDer = function (x, alpha) {
return this.backendEngine.executeKernel('PReLUDer', { inputs: { x: x, alpha: alpha } });
};
NDArrayMath.prototype.sigmoid = function (x) {
return this.backendEngine.executeKernel('Sigmoid', { inputs: { x: x } });
};
NDArrayMath.prototype.sin = function (x) {
return this.backendEngine.executeKernel('Sin', { inputs: { x: x } });
};
NDArrayMath.prototype.cos = function (x) {
return this.backendEngine.executeKernel('Cos', { inputs: { x: x } });
};
NDArrayMath.prototype.tan = function (x) {
return this.backendEngine.executeKernel('Tan', { inputs: { x: x } });
};
NDArrayMath.prototype.asin = function (x) {
return this.backendEngine.executeKernel('Asin', { inputs: { x: x } });
};
NDArrayMath.prototype.acos = function (x) {
return this.backendEngine.executeKernel('Acos', { inputs: { x: x } });
};
NDArrayMath.prototype.atan = function (x) {
return this.backendEngine.executeKernel('Atan', { inputs: { x: x } });
};
NDArrayMath.prototype.sinh = function (x) {
return this.backendEngine.executeKernel('Sinh', { inputs: { x: x } });
};
NDArrayMath.prototype.cosh = function (x) {
return this.backendEngine.executeKernel('Cosh', { inputs: { x: x } });
};
NDArrayMath.prototype.tanh = function (x) {
return this.backendEngine.executeKernel('Tanh', { inputs: { x: x } });
};
NDArrayMath.prototype.step = function (x, alpha) {
if (alpha === void 0) { alpha = 0.0; }
return this.backendEngine.executeKernel('Step', { inputs: { x: x }, args: { alpha: alpha } });
};
NDArrayMath.prototype.scaledArrayAdd = function (c1, a, c2, b) {
var _this = this;
util.assert(c1.size === 1, "Error in scaledArrayAdd: first argument must rank 0, but got " +
(" rank " + c1.rank + "."));
util.assert(c2.size === 1, "Error in scaledArrayAdd: third argument must be rank 0, but got " +
("NDArray of rank " + c2.rank + "."));
util.assertShapesMatch(a.shape, b.shape, 'Error in scaledArrayAdd: ');
return this.executeOp('scaledArrayAdd', function () {
return _this.scope(function () {
return _this.add(_this.multiply(c1, a), _this.multiply(c2, b));
});
});
};
NDArrayMath.prototype.scalarTimesArray = function (c, a) {
util.assert(c.size === 1, "Error in arrayDividedByScalar: first argument must be rank 0, but " +
("got rank " + c.rank + "."));
return this.multiply(c, a);
};
NDArrayMath.prototype.elementWiseMulBroadcast = function (a, b) {
util.assert(a.rank === 2, "Error in elementWiseMulBroadcast: first argument must be " +
("rank 2, but got rank " + a.rank + "."));
util.assert(b.rank === 2, "Error in elementWiseMulBroadcast: second argument must be " +
("rank 2, but got rank " + b.rank + "."));
return this.multiply(a, b);
};
NDArrayMath.prototype.conv1d = function (input, filter, bias, stride, pad) {
var _this = this;
var input3D = input;
var reshapedTo3D = false;
if (input.rank === 2) {
reshapedTo3D = true;
input3D = input.as3D(1, input.shape[0], input.shape[1]);
}
util.assert(input3D.rank === 3, "Error in conv1d: input must be rank 3, but got rank " + input3D.rank + ".");
util.assert(filter.rank === 3, "Error in conv1d: filter must be rank 3, but got rank " +
(filter.rank + "."));
if (bias != null) {
util.assert(bias.rank === 1, "Error in conv1d: bias must be rank 1, but got rank " +
(bias.rank + "."));
}
util.assert(input3D.shape[2] === filter.shape[1], "Error in conv1d: depth of input (" + input3D.shape[2] + ") must match " +
("input depth for filter " + filter.shape[1] + "."));
var filter4D = filter.as4D(1, filter.shape[0], filter.shape[1], filter.shape[2]);
var input4D = input3D.as4D(input3D.shape[0], 1, input3D.shape[1], input3D.shape[2]);
var strides = [1, stride];
return this.executeOp('Conv1D', function () {
var res = _this.conv2d(input4D, filter4D, bias, strides, pad);
if (reshapedTo3D) {
return res.as2D(res.shape[2], res.shape[3]);
}
return res.as3D(res.shape[0], res.shape[2], res.shape[3]);
});
};
NDArrayMath.prototype.conv2d = function (input, filter, bias, strides, pad) {
var _this = this;
var input4D = input;
var reshapedTo4D = false;
if (input.rank === 3) {
reshapedTo4D = true;
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
}
util.assert(input4D.rank === 4, "Error in conv2d: input must be rank 4, but got rank " + input4D.rank + ".");
util.assert(filter.rank === 4, "Error in conv2d: filter must be rank 4, but got rank " +
(filter.rank + "."));
if (bias != null) {
util.assert(bias.rank === 1, "Error in conv2d: bias must be rank 1, but got rank " +
(bias.rank + "."));
}
util.assert(input4D.shape[3] === filter.shape[2], "Error in conv2d: depth of input (" + input4D.shape[3] + ") must match " +
("input depth for filter " + filter.shape[2] + "."));
var convInfo = conv_util.computeConv2DInfo(input4D.shape, filter.shape, strides, pad);
return this.executeOp('Conv2D', function () {
var res = _this.backendEngine.executeKernel('Conv2D', { inputs: { x: input4D, filter: filter, bias: bias }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.conv2dDerInput = function (inShape, dy, filter, strides, pad) {
var _this = this;
util.assert(inShape.length === dy.rank, "Length of inShape " +
("(" + inShape.length + ") and rank of dy (" + dy.rank + ") must match"));
var inShape4D = inShape;
var dy4D = dy;
var reshapedTo4D = false;
if (dy.rank === 3) {
reshapedTo4D = true;
dy4D = dy.as4D(1, dy.shape[0], dy.shape[1], dy.shape[2]);
inShape4D = [1, inShape[0], inShape[1], inShape[2]];
}
var inDepth = inShape4D[3];
var outDepth = dy4D.shape[3];
util.assert(inShape4D.length === 4, "Error in conv2dDerInput: inShape must be length 4, but got length " +
(inShape4D.length + "."));
util.assert(dy4D.rank === 4, "Error in conv2dDerInput: dy must be rank 4, but got " +
("rank " + dy4D.rank));
util.assert(filter.rank === 4, "Error in conv2dDerInput: filter must be rank 4, but got " +
("rank " + filter.rank));
util.assert(inDepth === filter.shape[2], "Error in conv2dDerInput: depth of input (" + inDepth + ") must " +
("match input depth for filter " + filter.shape[2] + "."));
util.assert(outDepth === filter.shape[3], "Error in conv2dDerInput: depth of output (" + outDepth + ") must" +
("match output depth for filter " + filter.shape[3] + "."));
var convInfo = conv_util.computeConv2DInfo(inShape4D, filter.shape, strides, pad);
return this.executeOp('conv2dDerInput', function () {
var res = _this.backendEngine.executeKernel('Conv2DDerInput', { inputs: { dy: dy4D, filter: filter }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.conv2dDerBias = function (dy) {
var dy4D = dy;
if (dy.rank === 3) {
dy4D = dy.as4D(1, dy.shape[0], dy.shape[1], dy.shape[2]);
}
return this.backendEngine.executeKernel('Conv2DDerBias', { inputs: { dy: dy4D } });
};
NDArrayMath.prototype.conv2dDerFilter = function (input, dy, filterShape, strides, pad) {
var input4D = input;
if (input.rank === 3) {
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
}
var dy4D = dy;
if (dy4D.rank === 3) {
dy4D = dy.as4D(1, dy.shape[0], dy.shape[1], dy.shape[2]);
}
util.assert(input4D.rank === 4, "Error in conv2dDerFilter: input must be rank 4, but got shape " +
(input4D.shape + "."));
util.assert(dy4D.rank === 4, "Error in conv2dDerFilter: dy must be rank 4, but got shape " +
(dy4D.shape + "."));
util.assert(filterShape.length === 4, "Error in conv2dDerFilter: filterShape must be length 4, but got " +
(filterShape + "."));
util.assert(input4D.shape[3] === filterShape[2], "Error in conv2dDerFilter: depth of input " + input4D.shape[3] + ") must " +
("match input depth in filter (" + filterShape[2] + "."));
util.assert(dy4D.shape[3] === filterShape[3], "Error in conv2dDerFilter: depth of dy (" + dy4D.shape[3] + ") must " +
("match output depth for filter (" + filterShape[3] + ")."));
var convInfo = conv_util.computeConv2DInfo(input4D.shape, filterShape, strides, pad);
return this.backendEngine.executeKernel('Conv2DDerFilter', { inputs: { x: input4D, dy: dy4D }, args: { convInfo: convInfo } });
};
NDArrayMath.prototype.conv2dTranspose = function (x, filter, outputShape, strides, pad) {
return this.conv2dDerInput(outputShape, x, filter, strides, pad);
};
NDArrayMath.prototype.depthwiseConv2D = function (input, filter, strides, pad, rates) {
var _this = this;
if (rates === void 0) { rates = [1, 1]; }
var input4D = input;
var reshapedTo4D = false;
if (input.rank === 3) {
reshapedTo4D = true;
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
}
util.assert(input4D.rank === 4, "Error in depthwiseConv2D: input must be rank 4, but got " +
("rank " + input4D.rank + "."));
util.assert(filter.rank === 4, "Error in depthwiseConv2D: filter must be rank 4, but got rank " +
(filter.rank + "."));
util.assert(input4D.shape[3] === filter.shape[2], "Error in depthwiseConv2D: number of input channels " +
("(" + input4D.shape[3] + ") must match the inChannels dimension in ") +
("filter " + filter.shape[2] + "."));
rates = rates || [1, 1];
var _a = parseTupleParam(rates), rateHeight = _a[0], rateWidth = _a[1];
util.assert(rateHeight === 1 && rateWidth === 1, 'Error in depthwiseConv2D: rates greater than 1 are not yet ' +
("supported. Got rates '" + rates + "'"));
var convInfo = conv_util.computeConv2DInfo(input4D.shape, filter.shape, strides, pad, true);
return this.executeOp('depthwiseConv2D', function () {
var res = _this.backendEngine.executeKernel('DepthwiseConv2D', { inputs: { x: input4D, filter: filter }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.maxPool = function (input, filterSize, strides, pad) {
var _this = this;
var input4D = input;
var reshapedTo4D = false;
if (input.rank === 3) {
reshapedTo4D = true;
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
}
util.assert(input4D.rank === 4, "Error in maxPool: input must be rank 4 but got rank " + input4D.rank + ".");
var convInfo = conv_util.computePool2DInfo(input4D.shape, filterSize, strides, pad);
return this.executeOp('maxPool', function () {
var res = _this.backendEngine.executeKernel('MaxPool', { inputs: { x: input4D }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.maxPoolBackprop = function (dy, input, filterSize, strides, pad) {
var _this = this;
util.assert(input.rank === dy.rank, "Rank of input (" + input.rank + ") does not match rank of dy (" + dy.rank + ")");
var input4D = input;
var dy4D = dy;
var reshapedTo4D = false;
if (input.rank === 3) {
reshapedTo4D = true;
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
dy4D = dy.as4D(1, dy.shape[0], dy.shape[1], dy.shape[2]);
}
util.assert(dy4D.rank === 4, "Error in maxPoolBackprop: dy must be rank 4 but got rank " +
(dy4D.rank + "."));
util.assert(input4D.rank === 4, "Error in maxPoolBackprop: input must be rank 4 but got rank " +
(input4D.rank + "."));
var convInfo = conv_util.computePool2DInfo(input4D.shape, filterSize, strides, pad);
return this.executeOp('maxPoolBackprop', function () {
var res = _this.backendEngine.executeKernel('MaxPoolBackprop', { inputs: { dy: dy4D, x: input4D }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.minPool = function (input, filterSize, strides, pad) {
var _this = this;
var input4D = input;
var reshapedTo4D = false;
if (input.rank === 3) {
reshapedTo4D = true;
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
}
util.assert(input4D.rank === 4, "Error in minPool: x must be rank 4 but got rank " + input4D.rank + ".");
var convInfo = conv_util.computePool2DInfo(input4D.shape, filterSize, strides, pad);
return this.executeOp('minPool', function () {
var res = _this.backendEngine.executeKernel('MinPool', { inputs: { x: input4D }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.avgPool = function (input, filterSize, strides, pad) {
var _this = this;
var input4D = input;
var reshapedTo4D = false;
if (input.rank === 3) {
reshapedTo4D = true;
input4D = input.as4D(1, input.shape[0], input.shape[1], input.shape[2]);
}
util.assert(input4D.rank === 4, "Error in avgPool: x must be rank 4 but got rank " + input4D.rank + ".");
var convInfo = conv_util.computePool2DInfo(input4D.shape, filterSize, strides, pad);
return this.executeOp('avgPool', function () {
var res = _this.backendEngine.executeKernel('AvgPool', { inputs: { x: input4D }, args: { convInfo: convInfo } });
if (reshapedTo4D) {
return res.as3D(res.shape[1], res.shape[2], res.shape[3]);
}
return res;
});
};
NDArrayMath.prototype.resizeBilinear3D = function (x, newShape2D, alignCorners) {
if (alignCorners === void 0) { alignCorners = false; }
util.assert(x.rank === 3, "Error in resizeBilinear3D: x must be rank 3 but got rank " + x.rank + ".");
util.assert(newShape2D.length === 2, "Error in resizeBilinear3D: new shape must 2D, but got shape " +
(newShape2D + "."));
return this.backendEngine.executeKernel('ResizeBilinear3D', { inputs: { x: x }, args: { newShape2D: newShape2D, alignCorners: alignCorners } });
};
NDArrayMath.prototype.batchNormalization2D = function (x, mean, variance, varianceEpsilon, scale, offset) {
if (varianceEpsilon === void 0) { varianceEpsilon = .001; }
util.assert(x.rank === 2, "Error in batchNormalization3D: x must be rank 3 but got rank " +
(x.rank + "."));
util.assert(mean.rank === 2 || mean.rank === 1, "Error in batchNormalization2D: mean must be rank 2 or rank 1 but " +
("got rank " + mean.rank + "."));
util.assert(variance.rank === 2 || variance.rank === 1, "Error in batchNormalization2D: variance must be rank 2 or rank 1 " +
("but got rank " + variance.rank + "."));
if (scale != null) {
util.assert(scale.rank === 2 || scale.rank === 1, "Error in batchNormalization2D: scale must be rank 2 or rank 1 " +
("but got rank " + scale.rank + "."));
}
if (offset != null) {
util.assert(offset.rank === 2 || offset.rank === 1, "Error in batchNormalization2D: offset must be rank 2 or rank 1 " +
("but got rank " + offset.rank + "."));
}
return this.backendEngine.executeKernel('BatchNorm2D', { inputs: { x: x, mean: mean, variance: variance, scale: scale, offset: offset }, args: { varianceEpsilon: varianceEpsilon } });
};
NDArrayMath.prototype.batchNormalization3D = function (x, mean, variance, varianceEpsilon, scale, offset) {
if (varianceEpsilon === void 0) { varianceEpsilon = .001; }
util.assert(x.rank === 3, "Error in batchNormalization3D: x must be rank 3 but got rank " +
(x.rank + "."));
util.assert(mean.rank === 3 || mean.rank === 1, "Error in batchNormalization3D: mean must be rank 3 or rank 1 but " +
("got rank " + mean.rank + "."));
util.assert(variance.rank === 3 || variance.rank === 1, "Error in batchNormalization3D: variance must be rank 3 or rank 1 " +
("but got rank " + variance.rank + "."));
if (scale != null) {
util.assert(scale.rank === 3 || scale.rank === 1, "Error in batchNormalization3D: scale must be rank 3 or rank 1 " +
("but got rank " + scale.rank + "."));
}
if (offset != null) {
util.assert(offset.rank === 3 || offset.rank === 1, "Error in batchNormalization3D: offset must be rank 3 or rank 1 " +
("but got rank " + offset.rank + "."));
}
return this.backendEngine.executeKernel('BatchNorm3D', { inputs: { x: x, mean: mean, variance: variance, scale: scale, offset: offset }, args: { varianceEpsilon: varianceEpsilon } });
};
NDArrayMath.prototype.multiRNNCell = function (lstmCells, data, c, h) {
var res = this.scope(function () {
var input = data;
var newStates = [];
for (var i = 0; i < lstmCells.length; i++) {
var output = lstmCells[i](input, c[i], h[i]);
newStates.push(output[0]);
newStates.push(output[1]);
input = output[1];
}
return newStates;
});
var newC = [];
var newH = [];
for (var i = 0; i < res.length; i += 2) {
newC.push(res[i]);
newH.push(res[i + 1]);
}
return [newC, newH];
};
NDArrayMath.prototype.basicLSTMCell = function (forgetBias, lstmKernel, lstmBias, data, c, h) {
var _this = this;
var res = this.scope(function () {
var combined = _this.concat2D(data, h, 1);
var weighted = _this.matMul(combined, lstmKernel);
var res = _this.add(weighted, lstmBias);
var batchSize = res.shape[0];
var sliceCols = res.shape[1] / 4;
var sliceSize = [batchSize, sliceCols];
var i = _this.slice2D(res, [0, 0], sliceSize);
var j = _this.slice2D(res, [0, sliceCols], sliceSize);
var f = _this.slice2D(res, [0, sliceCols * 2], sliceSize);
var o = _this.slice2D(res, [0, sliceCols * 3], sliceSize);
var newC = _this.addStrict(_this.multiplyStrict(c, _this.sigmoid(_this.scalarPlusArray(forgetBias, f))), _this.multiplyStrict(_this.sigmoid(i), _this.tanh(j)));
var newH = _this.multiplyStrict(_this.tanh(newC), _this.sigmoid(o));
return [newC, newH];
});
return [res[0], res[1]];
};
NDArrayMath.prototype.multinomial = function (probabilities, numSamples, seed) {
var _this = this;
var numOutcomes = probabilities.size;
if (numOutcomes < 2) {
throw new Error("Error in multinomial: you need at least 2 outcomes, but got " +
(numOutcomes + "."));
}
if (probabilities.rank > 2) {
throw new Error("Rank of probabilities must be 1 or 2, but is " + probabilities.rank);
}
seed = seed || Math.random();
var origRank = probabilities.rank;
if (probabilities.rank === 1) {
probabilities = probabilities.as2D(1, -1);
}
return this.executeOp('multinomial', function () {
var res = _this.backendEngine.executeKernel('Multinomial', {
inputs: { probs: probabilities },
args: { numSamples: numSamples, seed: seed }
});
if (origRank === 1) {
return res.as1D();
}
return res;
});
};
NDArrayMath.prototype.oneHot = function (indices, depth, onValue, offValue) {
if (onValue === void 0) { onValue = 1; }
if (offValue === void 0) { offValue = 0; }
if (depth < 2) {
throw new Error("Error in oneHot: depth must be >=2, but it is " + depth);
}
return this.backendEngine.executeKernel('OneHot', { inputs: { indices: indices }, args: { depth: depth, onValue: onValue, offValue: offValue } });
};
NDArrayMath.prototype.moments = function (x, axis, keepDims) {
var _this = this;
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
var axes = axis_util.parseAxisParam(axis, x.shape);
var result = this.scope(function () {
var mean = _this.mean(x, axes, keepDims);
var keepDimsShape = mean.shape;
if (!keepDims) {
keepDimsShape = axis_util.expandShapeToKeepDim(mean.shape, axes);
}
var devSquared = _this.square(_this.subtract(x, mean.reshape(keepDimsShape)));
var variance = _this.mean(devSquared, axes, keepDims);
return { mean: mean, variance: variance };
});
return result;
};
NDArrayMath.prototype.norm = function (x, ord, axis, keepDims) {
var _this = this;
if (ord === void 0) { ord = 'euclidean'; }
if (axis === void 0) { axis = null; }
if (keepDims === void 0) { keepDims = false; }
return this.scope(function () {
var norm = _this.normInternal(x, ord, axis);
var keepDimsShape = norm.shape;
if (keepDims) {
var axes = axis_util.parseAxisParam(axis, x.shape);
keepDimsShape = axis_util.expandShapeToKeepDim(norm.shape, axes);
}
return norm.reshape(keepDimsShape);
});
};
NDArrayMath.prototype.normInternal = function (x, p, axis) {
if (axis === void 0) { axis = null; }
if (x.rank === 0) {
return this.abs(x);
}
if (x.rank !== 1 && axis === null) {
return this.normInternal(x.reshape([-1]), p, axis);
}
if (x.rank === 1 || typeof axis === 'number' ||
axis instanceof Array && axis.length === 1) {
if (p === 1) {
return this.sum(this.abs(x), axis);
}
if (p === Infinity) {
return this.max(this.abs(x), axis);
}
if (p === -Infinity) {
return this.min(this.abs(x), axis);
}
if (p === 'euclidean' || p === 2) {
return this.sqrt(this.sum(this.pow(this.abs(x), ndarray_1.Scalar.new(2, 'int32')), axis));
}
throw new Error("Error in norm: invalid ord value: " + p);
}
if (axis instanceof Array && axis.length === 2) {
if (p === 1) {
return this.max(this.sum(this.abs(x), axis[0]), axis[1] - 1);
}
if (p === Infinity) {
return this.max(this.sum(this.abs(x), axis[1]), axis[0]);
}
if (p === -Infinity) {
return this.min(this.sum(this.abs(x), axis[1]), axis[0]);
}
if (p === 'fro' || p === 'euclidean') {
return this.sqrt(this.sum(this.pow(x, ndarray_1.Scalar.new(2, 'int32')), axis));
}
throw new Error("Error in norm: invalid ord value: " + p);
}
throw new Error("Error in norm: invalid axis: " + axis);
};
NDArrayMath.prototype.gradientWrt = function (y, x) {
var xIsArray = x instanceof ndarray_1.NDArray;
var xs = [];
var xKeys;
if (xIsArray) {
xs.push(x);
}
else {
var xMap = x;
xKeys = Object.keys(xMap);
for (var i = 0; i < xKeys.length; i++) {
xs.push(xMap[xKeys[i]]);
}
}
var gradients = this.backendEngine.gradientWrt(y, xs);
if (xIsArray) {
return gradients[0];
}
else {
var result = {};
for (var i = 0; i < xKeys.length; i++) {
result[xKeys[i]] = gradients[i];
}
return result;
}
};
NDArrayMath.prototype.disposeData = function (id) {
this.backend.disposeData(id);
this.numArrays--;
};
return NDArrayMath;
}());
exports.NDArrayMath = NDArrayMath;
function parseTupleParam(param) {
return typeof param === 'number' ? [param, param] : param;
}
},{"../environment":15,"../util":101,"./axis_util":54,"./backends/backend_engine":56,"./backends/types/matmul":61,"./broadcast_util":90,"./concat_util":91,"./conv_util":92,"./ndarray":95,"./slice_util":98}],95:[function(require,module,exports){
"use strict";
var __extends = (this && this.__extends) || (function () {
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]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
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 = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [0, 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 environment_1 = require("../environment");
var util = require("../util");
var rand_1 = require("./rand");
var DType;
(function (DType) {
DType["float32"] = "float32";
DType["int32"] = "int32";
DType["bool"] = "bool";
})(DType = exports.DType || (exports.DType = {}));
var NDArray = (function () {
function NDArray(shape, dtype, values, id, math) {
this.isDisposed = false;
this.math = math || environment_1.ENV.math;
this.size = util.sizeFromShape(shape);
if (values != null) {
util.assert(this.size === values.length, "Constructing ndarray of shape (" + this.size + ") should match the " +
("length of values (" + values.length + ")"));
}
this.shape = shape;
this.dtype = dtype || 'float32';
var dim = this.shape.length;
if (dim < 2) {
this.strides = [];
}
else {
this.strides = new Array(dim - 1);
this.strides[dim - 2] = this.shape[dim - 1];
for (var i = dim - 3; i >= 0; --i) {
this.strides[i] = this.strides[i + 1] * this.shape[i + 1];
}
}
this.id = id;
if (this.id == null) {
this.id = NDArray.nextId++;
this.math.register(this);
this.math.write(this.id, values, this.dtype, this.shape);
}
}
NDArray.ones = function (shape, dtype) {
var values = makeOnesTypedArray(util.sizeFromShape(shape), dtype);
return NDArray.make(shape, { values: values }, dtype);
};
NDArray.zeros = function (shape, dtype) {
var values = makeZerosTypedArray(util.sizeFromShape(shape), dtype);
return NDArray.make(shape, { values: values }, dtype);
};
NDArray.onesLike = function (another) {
return NDArray.ones(another.shape, another.dtype);
};
NDArray.zerosLike = function (another) {
return NDArray.zeros(another.shape, another.dtype);
};
NDArray.like = function (another) {
var newValues = copyTypedArray(another.getValues(), another.dtype);
return NDArray.make(another.shape, { values: newValues }, another.dtype);
};
NDArray.make = function (shape, data, dtype, math) {
switch (shape.length) {
case 0:
return new Scalar(shape, dtype, data.values, data.id, math);
case 1:
return new Array1D(shape, dtype, data.values, data.id, math);
case 2:
return new Array2D(shape, dtype, data.values, data.id, math);
case 3:
return new Array3D(shape, dtype, data.values, data.id, math);
case 4:
return new Array4D(shape, dtype, data.values, data.id, math);
default:
return new NDArray(shape, dtype, data.values, data.id, math);
}
};
NDArray.fromPixels = function (pixels, numChannels, math) {
if (numChannels === void 0) { numChannels = 3; }
if (numChannels > 4) {
throw new Error('Cannot construct NDArray with more than 4 channels from pixels.');
}
var ndarrayData = {};
var shape = [pixels.height, pixels.width, numChannels];
var res = NDArray.make(shape, ndarrayData, 'int32');
math = math || environment_1.ENV.math;
math.writePixels(res.id, pixels, numChannels);
return res;
};
NDArray.prototype.reshape = function (newShape) {
this.throwIfDisposed();
newShape = util.inferFromImplicitShape(newShape, this.size);
if (util.arraysEqual(this.shape, newShape)) {
return this;
}
var data = { id: this.id };
util.assert(this.size === util.sizeFromShape(newShape), 'new shape and old shape must have the same number of elements.');
return NDArray.make(newShape, data, this.dtype);
};
NDArray.prototype.flatten = function () {
this.throwIfDisposed();
if (this instanceof Array1D) {
return this;
}
return this.as1D();
};
NDArray.prototype.asScalar = function () {
this.throwIfDisposed();
util.assert(this.size === 1, 'The array must have only 1 element.');
return this.reshape([]);
};
NDArray.prototype.as1D = function () {
this.throwIfDisposed();
return this.reshape([this.size]);
};
NDArray.prototype.as2D = function (rows, columns) {
this.throwIfDisposed();
return this.reshape([rows, columns]);
};
NDArray.prototype.as3D = function (rows, columns, depth) {
this.throwIfDisposed();
return this.reshape([rows, columns, depth]);
};
NDArray.prototype.as4D = function (rows, columns, depth, depth2) {
this.throwIfDisposed();
return this.reshape([rows, columns, depth, depth2]);
};
NDArray.prototype.asType = function (dtype) {
this.throwIfDisposed();
if (this.dtype === dtype) {
return this;
}
var vals = this.dataSync();
var newVals = toTypedArray(vals, dtype);
return NDArray.make(this.shape, { values: newVals }, dtype);
};
Object.defineProperty(NDArray.prototype, "rank", {
get: function () {
return this.shape.length;
},
enumerable: true,
configurable: true
});
NDArray.prototype.get = function () {
var locs = [];
for (var _i = 0; _i < arguments.length; _i++) {
locs[_i] = arguments[_i];
}
var index = locs[locs.length - 1];
for (var i = 0; i < locs.length - 1; ++i) {
index += this.strides[i] * locs[i];
}
return this.getValues()[index];
};
NDArray.prototype.add = function (value) {
var locs = [];
for (var _i = 1; _i < arguments.length; _i++) {
locs[_i - 1] = arguments[_i];
}
this.set.apply(this, [this.get.apply(this, locs) + value].concat(locs));
};
NDArray.prototype.set = function (value) {
var locs = [];
for (var _i = 1; _i < arguments.length; _i++) {
locs[_i - 1] = arguments[_i];
}
this.throwIfDisposed();
util.assert(locs.length === this.rank, "The number of provided coordinates (" + locs.length + ") must " +
("match the rank (" + this.rank + ")"));
var index = locs.length > 0 ? locs[locs.length - 1] : 0;
for (var i = 0; i < locs.length - 1; ++i) {
index += this.strides[i] * locs[i];
}
var vals = this.getValues();
vals[index] = value;
this.math.disposeData(this.id);
this.math.write(this.id, vals, this.dtype, this.shape);
};
NDArray.prototype.val = function () {
var locs = [];
for (var _i = 0; _i < arguments.length; _i++) {
locs[_i] = arguments[_i];
}
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
this.throwIfDisposed();
return [4, this.data()];
case 1:
_a.sent();
return [2, this.get.apply(this, locs)];
}
});
});
};
NDArray.prototype.locToIndex = function (locs) {
this.throwIfDisposed();
var index = locs[locs.length - 1];
for (var i = 0; i < locs.length - 1; ++i) {
index += this.strides[i] * locs[i];
}
return index;
};
NDArray.prototype.indexToLoc = function (index) {
this.throwIfDisposed();
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;
};
NDArray.prototype.fill = function (value) {
this.throwIfDisposed();
var vals = this.getValues();
vals.fill(value);
this.math.disposeData(this.id);
this.math.write(this.id, vals, this.dtype, this.shape);
};
NDArray.prototype.getValues = function () {
return this.dataSync();
};
NDArray.prototype.getValuesAsync = function () {
return this.data();
};
NDArray.prototype.data = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
this.throwIfDisposed();
return [2, this.math.read(this.id)];
});
});
};
NDArray.prototype.dataSync = function () {
this.throwIfDisposed();
return this.math.readSync(this.id);
};
NDArray.prototype.dispose = function () {
this.isDisposed = true;
this.math.disposeData(this.id);
};
NDArray.prototype.equals = function (t) {
this.throwIfDisposed();
return this.dtype === t.dtype && util.arraysEqual(this.shape, t.shape) &&
util.arraysEqual(this.getValues(), t.getValues());
};
NDArray.rand = function (shape, randFunction, dtype) {
var size = util.sizeFromShape(shape);
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);
}
for (var i = 0; i < size; i++) {
values[i] = randFunction();
}
return NDArray.make(shape, { values: values }, dtype);
};
NDArray.randNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, false, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
NDArray.randTruncatedNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, true, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
NDArray.randUniform = function (shape, a, b, dtype) {
return NDArray.rand(shape, function () { return util.randUniform(a, b); }, dtype);
};
NDArray.prototype.throwIfDisposed = function () {
if (this.isDisposed) {
throw new Error("NDArray is disposed.");
}
};
NDArray.nextId = 0;
return NDArray;
}());
exports.NDArray = NDArray;
var Scalar = (function (_super) {
__extends(Scalar, _super);
function Scalar() {
return _super !== null && _super.apply(this, arguments) || this;
}
Scalar.new = function (value, dtype) {
var values = [value];
return new Scalar([], dtype, toTypedArray(values, dtype));
};
Scalar.prototype.get = function () {
return this.getValues()[0];
};
Scalar.prototype.val = function () {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.data()];
case 1:
_a.sent();
return [2, this.get()];
}
});
});
};
Scalar.prototype.add = function (value) {
this.getValues()[0] += value;
};
Scalar.prototype.asType = function (dtype) {
return _super.prototype.asType.call(this, dtype);
};
Scalar.prototype.locToIndex = function (loc) {
return 0;
};
Scalar.prototype.indexToLoc = function (index) {
return [];
};
return Scalar;
}(NDArray));
exports.Scalar = Scalar;
var Array1D = (function (_super) {
__extends(Array1D, _super);
function Array1D() {
return _super !== null && _super.apply(this, arguments) || this;
}
Array1D.new = function (values, dtype) {
if (!instanceofTypedArray(values)) {
var inferredShape = util.inferShape(values);
util.assert(inferredShape.length === 1, "Error constructing Array1D. Shape of values " + inferredShape + " is " +
"not 1 dimensional.");
}
return new Array1D([values.length], dtype, toTypedArray(values, dtype));
};
Array1D.prototype.get = function (i) {
return this.getValues()[i];
};
Array1D.prototype.val = function (i) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.data()];
case 1:
_a.sent();
return [2, this.get(i)];
}
});
});
};
Array1D.prototype.add = function (value, i) {
this.getValues()[i] += value;
};
Array1D.prototype.locToIndex = function (loc) {
return loc[0];
};
Array1D.prototype.indexToLoc = function (index) {
return [index];
};
Array1D.prototype.asType = function (dtype) {
return _super.prototype.asType.call(this, dtype);
};
Array1D.ones = function (shape, dtype) {
return NDArray.ones(shape, dtype);
};
Array1D.zeros = function (shape, dtype) {
return NDArray.zeros(shape, dtype);
};
Array1D.randNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, false, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array1D.randTruncatedNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, true, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array1D.randUniform = function (shape, a, b, dtype) {
return NDArray.rand(shape, function () { return util.randUniform(a, b); }, dtype);
};
return Array1D;
}(NDArray));
exports.Array1D = Array1D;
var Array2D = (function (_super) {
__extends(Array2D, _super);
function Array2D(shape, dtype, values, id, math) {
var _this = this;
util.assert(shape.length === 2, 'Shape should be of length 2');
_this = _super.call(this, shape, dtype, values, id, math) || this;
_this.stride0 = _this.strides[0];
return _this;
}
Array2D.new = function (shape, values, dtype) {
if (!instanceofTypedArray(values)) {
var inferredShape = util.inferShape(values);
if (inferredShape.length > 1) {
util.assertShapesMatch(shape, inferredShape, "Error when constructing Array2D. Shape of values " +
(inferredShape + " does not match the provided shape ") +
(shape + ". "));
}
}
return new Array2D(shape, dtype, toTypedArray(values, dtype));
};
Array2D.prototype.get = function (i, j) {
return this.getValues()[this.stride0 * i + j];
};
Array2D.prototype.add = function (value, i, j) {
this.getValues()[this.stride0 * i + j] += value;
};
Array2D.prototype.val = function (i, j) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.data()];
case 1:
_a.sent();
return [2, this.get(i, j)];
}
});
});
};
Array2D.prototype.locToIndex = function (locs) {
return this.stride0 * locs[0] + locs[1];
};
Array2D.prototype.indexToLoc = function (index) {
return [Math.floor(index / this.stride0), index % this.stride0];
};
Array2D.prototype.asType = function (dtype) {
return _super.prototype.asType.call(this, dtype);
};
Array2D.ones = function (shape, dtype) {
return NDArray.ones(shape, dtype);
};
Array2D.zeros = function (shape, dtype) {
return NDArray.zeros(shape, dtype);
};
Array2D.randNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, false, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array2D.randTruncatedNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, true, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array2D.randUniform = function (shape, a, b, dtype) {
return NDArray.rand(shape, function () { return util.randUniform(a, b); }, dtype);
};
return Array2D;
}(NDArray));
exports.Array2D = Array2D;
var Array3D = (function (_super) {
__extends(Array3D, _super);
function Array3D(shape, dtype, values, id, math) {
var _this = this;
util.assert(shape.length === 3, 'Shape should be of length 3');
_this = _super.call(this, shape, dtype, values, id, math) || this;
_this.stride0 = _this.strides[0];
_this.stride1 = _this.strides[1];
return _this;
}
Array3D.new = function (shape, values, dtype) {
if (!instanceofTypedArray(values)) {
var inferredShape = util.inferShape(values);
if (inferredShape.length > 1) {
util.assertShapesMatch(shape, inferredShape, "Error when constructing Array3D. Shape of values " +
(inferredShape + " does not match the provided shape ") +
(shape + ". "));
}
}
return new Array3D(shape, dtype, toTypedArray(values, dtype));
};
Array3D.prototype.get = function (i, j, k) {
return this.getValues()[this.stride0 * i + this.stride1 * j + k];
};
Array3D.prototype.val = function (i, j, k) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.data()];
case 1:
_a.sent();
return [2, this.get(i, j, k)];
}
});
});
};
Array3D.prototype.add = function (value, i, j, k) {
this.getValues()[this.stride0 * i + this.stride1 * j + k] += value;
};
Array3D.prototype.locToIndex = function (locs) {
return this.stride0 * locs[0] + this.stride1 * locs[1] + locs[2];
};
Array3D.prototype.indexToLoc = function (index) {
var i = Math.floor(index / this.stride0);
index -= i * this.stride0;
return [i, Math.floor(index / this.stride1), index % this.stride1];
};
Array3D.prototype.asType = function (dtype) {
return _super.prototype.asType.call(this, dtype);
};
Array3D.ones = function (shape, dtype) {
return NDArray.ones(shape, dtype);
};
Array3D.zeros = function (shape, dtype) {
return NDArray.zeros(shape, dtype);
};
Array3D.randNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, false, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array3D.randTruncatedNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, true, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array3D.randUniform = function (shape, a, b, dtype) {
return NDArray.rand(shape, function () { return util.randUniform(a, b); }, dtype);
};
return Array3D;
}(NDArray));
exports.Array3D = Array3D;
var Array4D = (function (_super) {
__extends(Array4D, _super);
function Array4D(shape, dtype, values, id, math) {
var _this = this;
util.assert(shape.length === 4, 'Shape should be of length 4');
_this = _super.call(this, shape, dtype, values, id, math) || this;
_this.stride0 = _this.strides[0];
_this.stride1 = _this.strides[1];
_this.stride2 = _this.strides[2];
return _this;
}
Array4D.new = function (shape, values, dtype) {
if (!instanceofTypedArray(values)) {
var inferredShape = util.inferShape(values);
if (inferredShape.length > 1) {
util.assertShapesMatch(shape, inferredShape, "Error when constructing Array4D. Shape of values " +
(inferredShape + " does not match the provided shape ") +
(shape + ". "));
}
}
return new Array4D(shape, dtype, toTypedArray(values, dtype));
};
Array4D.prototype.get = function (i, j, k, l) {
return this.getValues()[this.stride0 * i + this.stride1 * j + this.stride2 * k + l];
};
Array4D.prototype.val = function (i, j, k, l) {
return __awaiter(this, void 0, void 0, function () {
return __generator(this, function (_a) {
switch (_a.label) {
case 0: return [4, this.data()];
case 1:
_a.sent();
return [2, this.get(i, j, k, l)];
}
});
});
};
Array4D.prototype.add = function (value, i, j, k, l) {
this.getValues()[this.stride0 * i + this.stride1 * j + this.stride2 * k + l] += value;
};
Array4D.prototype.locToIndex = function (locs) {
return this.stride0 * locs[0] + this.stride1 * locs[1] +
this.stride2 * locs[2] + locs[3];
};
Array4D.prototype.indexToLoc = function (index) {
var i = Math.floor(index / this.stride0);
index -= i * this.stride0;
var j = Math.floor(index / this.stride1);
index -= j * this.stride1;
return [i, j, Math.floor(index / this.stride2), index % this.stride2];
};
Array4D.prototype.asType = function (dtype) {
return _super.prototype.asType.call(this, dtype);
};
Array4D.ones = function (shape, dtype) {
return NDArray.ones(shape, dtype);
};
Array4D.zeros = function (shape, dtype) {
return NDArray.zeros(shape, dtype);
};
Array4D.randNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, false, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array4D.randTruncatedNormal = function (shape, mean, stdDev, dtype, seed) {
if (mean === void 0) { mean = 0; }
if (stdDev === void 0) { stdDev = 1; }
if (dtype != null && dtype === 'bool') {
throw new Error("Unsupported data type " + dtype);
}
var randGauss = new rand_1.MPRandGauss(mean, stdDev, dtype, true, seed);
return NDArray.rand(shape, function () { return randGauss.nextValue(); }, dtype);
};
Array4D.randUniform = function (shape, a, b, dtype) {
return NDArray.rand(shape, function () { return util.randUniform(a, b); }, dtype);
};
return Array4D;
}(NDArray));
exports.Array4D = Array4D;
function copyTypedArray(array, dtype) {
if (dtype == null || dtype === 'float32') {
return new Float32Array(array);
}
else if (dtype === 'int32') {
var vals = new Int32Array(array.length);
for (var i = 0; i < vals.length; ++i) {
var val = array[i];
if (util.isValNaN(val, 'int32')) {
vals[i] = util.getNaN('int32');
}
else {
vals[i] = val;
}
}
return vals;
}
else if (dtype === 'bool') {
var bool = new Uint8Array(array.length);
for (var i = 0; i < bool.length; ++i) {
var val = array[i];
if (util.isValNaN(val, 'bool')) {
bool[i] = util.getNaN('bool');
}
else if (Math.round(val) !== 0) {
bool[i] = 1;
}
}
return bool;
}
else {
throw new Error("Unknown data type " + dtype);
}
}
function instanceofTypedArray(a) {
return a instanceof Float32Array || a instanceof Int32Array ||
a instanceof Uint8Array;
}
function noConversionNeeded(a, dtype) {
return (a instanceof Float32Array && dtype === 'float32') ||
(a instanceof Int32Array && dtype === 'int32') ||
(a instanceof Uint8Array && dtype === 'bool');
}
function toTypedArray(a, dtype) {
if (noConversionNeeded(a, dtype)) {
return a;
}
if (Array.isArray(a)) {
a = util.flatten(a);
}
return copyTypedArray(a, dtype);
}
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 makeOnesTypedArray(size, dtype) {
var array = makeZerosTypedArray(size, dtype);
for (var i = 0; i < array.length; i++) {
array[i] = 1;
}
return array;
}
},{"../environment":15,"../util":101,"./rand":96}],96:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var seedrandom = require("seedrandom");
var MPRandGauss = (function () {
function MPRandGauss(mean, stdDeviation, dtype, truncated, seed) {
this.mean = mean;
this.stdDev = stdDeviation;
this.dtype = dtype;
this.nextVal = NaN;
this.truncated = truncated;
if (this.truncated) {
this.upper = this.mean + this.stdDev * 2;
this.lower = this.mean - this.stdDev * 2;
}
var seedValue = seed ? seed : Math.random();
this.random = seedrandom.alea(seedValue.toString());
}
MPRandGauss.prototype.nextValue = function () {
if (!isNaN(this.nextVal)) {
var value = this.nextVal;
this.nextVal = NaN;
return value;
}
var resultX, resultY;
var isValid = false;
while (!isValid) {
var v1 = void 0, v2 = void 0, s = void 0;
do {
v1 = 2 * this.random() - 1;
v2 = 2 * this.random() - 1;
s = v1 * v1 + v2 * v2;
} while (s >= 1 || s === 0);
var mul = Math.sqrt(-2.0 * Math.log(s) / s);
resultX = this.mean + this.stdDev * v1 * mul;
resultY = this.mean + this.stdDev * v2 * mul;
if (!this.truncated || this.isValidTruncated(resultX)) {
isValid = true;
}
}
if (!this.truncated || this.isValidTruncated(resultY)) {
this.nextVal = this.convertValue(resultY);
}
return this.convertValue(resultX);
};
MPRandGauss.prototype.convertValue = function (value) {
if (this.dtype == null || this.dtype === 'float32') {
return value;
}
return Math.round(value);
};
MPRandGauss.prototype.isValidTruncated = function (value) {
return value <= this.upper && value >= this.lower;
};
return MPRandGauss;
}());
exports.MPRandGauss = MPRandGauss;
},{"seedrandom":2}],97:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.PARALLELIZE_THRESHOLD = 30;
function computeOptimalWindowSize(inSize) {
if (inSize <= exports.PARALLELIZE_THRESHOLD) {
return inSize;
}
return nearestDivisor(inSize, Math.floor(Math.sqrt(inSize)));
}
exports.computeOptimalWindowSize = computeOptimalWindowSize;
function nearestDivisor(size, start) {
for (var i = start; i < size; ++i) {
if (size % i === 0) {
return i;
}
}
return size;
}
},{}],98:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var util = require("../util");
function assertParamsValid(input, begin, size) {
util.assert(input.rank === begin.length, "Error in slice" + input.rank + "D: Length of begin " + begin + " must " +
("match the rank of the array (" + input.rank + ")."));
util.assert(input.rank === size.length, "Error in slice" + input.rank + "D: Length of size " + size + " must " +
("match the rank of the array (" + input.rank + ")."));
for (var i = 0; i < input.rank; ++i) {
util.assert(begin[i] + size[i] <= input.shape[i], "Error in slice" + input.rank + "D: begin[" + i + "] + size[" + i + "] " +
("(" + (begin[i] + size[i]) + ") would overflow input.shape[" + i + "] (" + input.shape[i] + ")"));
}
}
exports.assertParamsValid = assertParamsValid;
},{"../util":101}],99:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var SumTypesMap;
(function (SumTypesMap) {
SumTypesMap["float32"] = "float32";
SumTypesMap["int32"] = "int32";
SumTypesMap["bool"] = "int32";
})(SumTypesMap = exports.SumTypesMap || (exports.SumTypesMap = {}));
var UpcastInt32AndMap;
(function (UpcastInt32AndMap) {
UpcastInt32AndMap["float32"] = "float32";
UpcastInt32AndMap["int32"] = "int32";
UpcastInt32AndMap["bool"] = "int32";
})(UpcastInt32AndMap = exports.UpcastInt32AndMap || (exports.UpcastInt32AndMap = {}));
var UpcastBoolAndMap;
(function (UpcastBoolAndMap) {
UpcastBoolAndMap["float32"] = "float32";
UpcastBoolAndMap["int32"] = "int32";
UpcastBoolAndMap["bool"] = "bool";
})(UpcastBoolAndMap = exports.UpcastBoolAndMap || (exports.UpcastBoolAndMap = {}));
var UpcastFloat32AndMap;
(function (UpcastFloat32AndMap) {
UpcastFloat32AndMap["float32"] = "float32";
UpcastFloat32AndMap["int32"] = "float32";
UpcastFloat32AndMap["bool"] = "float32";
})(UpcastFloat32AndMap = exports.UpcastFloat32AndMap || (exports.UpcastFloat32AndMap = {}));
var upcastTypeMap = {
float32: UpcastFloat32AndMap,
int32: UpcastInt32AndMap,
bool: UpcastBoolAndMap
};
function upcastType(typeA, typeB) {
return upcastTypeMap[typeA][typeB];
}
exports.upcastType = upcastType;
},{}],100:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var environment_1 = require("./environment");
var backend_cpu_1 = require("./math/backends/backend_cpu");
var backend_webgl_1 = require("./math/backends/backend_webgl");
var math_1 = require("./math/math");
var util = require("./util");
exports.TEST_EPSILON = 1e-2;
function mean(values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
sum += values[i];
}
return sum / values.length;
}
exports.mean = mean;
function standardDeviation(values, mean) {
var squareDiffSum = 0;
for (var i = 0; i < values.length; i++) {
var diff = values[i] - mean;
squareDiffSum += diff * diff;
}
return Math.sqrt(squareDiffSum / values.length);
}
exports.standardDeviation = standardDeviation;
function kurtosis(values) {
var valuesMean = mean(values);
var n = values.length;
var sum2 = 0;
var sum4 = 0;
for (var i = 0; i < n; i++) {
var v = values[i] - valuesMean;
sum2 += Math.pow(v, 2);
sum4 += Math.pow(v, 4);
}
return (1 / n) * sum4 / Math.pow((1 / n) * sum2, 2);
}
exports.kurtosis = kurtosis;
function skewness(values) {
var valuesMean = mean(values);
var n = values.length;
var sum2 = 0;
var sum3 = 0;
for (var i = 0; i < n; i++) {
var v = values[i] - valuesMean;
sum2 += Math.pow(v, 2);
sum3 += Math.pow(v, 3);
}
return (1 / n) * sum3 / Math.pow((1 / (n - 1)) * sum2, 3 / 2);
}
exports.skewness = skewness;
function jarqueBeraNormalityTest(values) {
var n = values.length;
var s = skewness(values);
var k = kurtosis(values);
var jb = n / 6 * (Math.pow(s, 2) + 0.25 * Math.pow(k - 3, 2));
var CHI_SQUARE_2DEG = 5.991;
if (jb > CHI_SQUARE_2DEG) {
throw new Error("Invalid p-value for JB: " + jb);
}
}
exports.jarqueBeraNormalityTest = jarqueBeraNormalityTest;
function expectArrayInMeanStdRange(actual, expectedMean, expectedStdDev, epsilon) {
if (epsilon === void 0) { epsilon = exports.TEST_EPSILON; }
var actualMean = mean(actual);
expectNumbersClose(actualMean, expectedMean, epsilon);
expectNumbersClose(standardDeviation(actual, actualMean), expectedStdDev, epsilon);
}
exports.expectArrayInMeanStdRange = expectArrayInMeanStdRange;
function expectArraysClose(actual, expected, epsilon) {
if (epsilon === void 0) { epsilon = exports.TEST_EPSILON; }
var aType = actual.constructor.name;
var bType = expected.constructor.name;
if (aType !== bType) {
throw new Error("Arrays are of different type " + aType + " vs " + bType);
}
if (actual.length !== expected.length) {
throw new Error("Matrices have different lengths (" + actual.length + " vs " +
(expected.length + ")."));
}
for (var i = 0; i < expected.length; ++i) {
var a = actual[i];
var e = expected[i];
if (!areClose(a, e, epsilon)) {
var actualStr = "actual[" + i + "] === " + a;
var expectedStr = "expected[" + i + "] === " + e;
throw new Error('Arrays differ: ' + actualStr + ', ' + expectedStr);
}
}
}
exports.expectArraysClose = expectArraysClose;
function expectNumbersClose(a, e, epsilon) {
if (epsilon === void 0) { epsilon = exports.TEST_EPSILON; }
if (!areClose(a, e, epsilon)) {
throw new Error("Numbers differ: actual === " + a + ", expected === " + e);
}
}
exports.expectNumbersClose = expectNumbersClose;
function areClose(a, e, epsilon) {
if (isNaN(a) && isNaN(e)) {
return true;
}
if (isNaN(a) || isNaN(e) || Math.abs(a - e) > epsilon) {
return false;
}
return true;
}
function expectValuesInRange(actual, low, high) {
for (var i = 0; i < actual.length; i++) {
if (actual[i] < low || actual[i] > high) {
throw new Error("Value out of range:" + actual[i] + " low: " + low + ", high: " + high);
}
}
}
exports.expectValuesInRange = expectValuesInRange;
function randomArrayInRange(n, minValue, maxValue) {
var v = new Float32Array(n);
var range = maxValue - minValue;
for (var i = 0; i < n; ++i) {
v[i] = (Math.random() * range) + minValue;
}
return v;
}
exports.randomArrayInRange = randomArrayInRange;
function makeIdentity(n) {
var i = new Float32Array(n * n);
for (var j = 0; j < n; ++j) {
i[(j * n) + j] = 1;
}
return i;
}
exports.makeIdentity = makeIdentity;
function cpuMultiplyMatrix(a, aRow, aCol, b, bRow, bCol) {
var result = new Float32Array(aRow * bCol);
for (var r = 0; r < aRow; ++r) {
var aOffset = (r * aCol);
var cOffset = (r * bCol);
for (var c = 0; c < bCol; ++c) {
var d = 0;
for (var k = 0; k < aCol; ++k) {
d += a[aOffset + k] * b[(k * bCol) + c];
}
result[cOffset + c] = d;
}
}
return result;
}
exports.cpuMultiplyMatrix = cpuMultiplyMatrix;
function cpuDotProduct(a, b) {
if (a.length !== b.length) {
throw new Error('cpuDotProduct: incompatible vectors.');
}
var d = 0;
for (var i = 0; i < a.length; ++i) {
d += a[i] * b[i];
}
return d;
}
exports.cpuDotProduct = cpuDotProduct;
function describeMathCPU(name, tests, featuresList) {
var testNameBase = 'CPU: math.' + name;
describeWithFeaturesAndExecutor(testNameBase, tests, function (testName, tests, features) { return executeMathTests(testName, tests, function () {
var safeMode = true;
return new math_1.NDArrayMath(new backend_cpu_1.MathBackendCPU(), safeMode);
}, features); }, featuresList);
}
exports.describeMathCPU = describeMathCPU;
function describeMathGPU(name, tests, featuresList) {
var testNameBase = 'WebGL: math.' + name;
describeWithFeaturesAndExecutor(testNameBase, tests, function (testName, tests, features) { return executeMathTests(testName, tests, function () {
var safeMode = true;
return new math_1.NDArrayMath(new backend_webgl_1.MathBackendWebGL(), safeMode);
}, features); }, featuresList);
}
exports.describeMathGPU = describeMathGPU;
function describeCustom(name, tests, featuresList, customBeforeEach, customAfterEach) {
describeWithFeaturesAndExecutor(name, [tests], function (testName, tests, features) { return executeTests(testName, tests, features, customBeforeEach, customAfterEach); }, featuresList);
}
exports.describeCustom = describeCustom;
function describeWithFeaturesAndExecutor(testNameBase, tests, executor, featuresList) {
if (featuresList != null) {
featuresList.forEach(function (features) {
var testName = testNameBase + ' ' + JSON.stringify(features);
executor(testName, tests, features);
});
}
else {
executor(testNameBase, tests);
}
}
var PROMISE_IT = function (name, testFunc) {
it(name, function (done) {
var result = testFunc();
if (result instanceof Promise) {
result.then(done, function (e) {
fail(e);
done();
});
}
else {
done();
}
});
};
function executeMathTests(testName, tests, mathFactory, features) {
var math;
var customBeforeEach = function () {
math = mathFactory();
environment_1.ENV.setMath(math);
math.startScope();
};
var customAfterEach = function () {
math.endScope(null);
math.dispose();
};
var customIt = function (name, testFunc) {
PROMISE_IT(name, function () { return testFunc(math); });
};
executeTests(testName, tests, features, customBeforeEach, customAfterEach, customIt);
}
exports.executeMathTests = executeMathTests;
function executeTests(testName, tests, features, customBeforeEach, customAfterEach, customIt) {
if (customIt === void 0) { customIt = PROMISE_IT; }
describe(testName, function () {
beforeEach(function () {
if (features != null) {
environment_1.ENV.setFeatures(features);
environment_1.ENV.registerBackend('webgl', function () { return new backend_webgl_1.MathBackendWebGL(); });
environment_1.ENV.registerBackend('cpu', function () { return new backend_cpu_1.MathBackendCPU(); });
}
if (customBeforeEach != null) {
customBeforeEach();
}
});
afterEach(function () {
if (customAfterEach != null) {
customAfterEach();
}
if (features != null) {
environment_1.ENV.reset();
}
});
tests.forEach(function (test) { return test(customIt); });
});
}
exports.executeTests = executeTests;
function assertIsNan(val, dtype) {
if (!util.isValNaN(val, dtype)) {
throw new Error("Value " + val + " does not represent NaN for dtype " + dtype);
}
}
exports.assertIsNan = assertIsNan;
},{"./environment":15,"./math/backends/backend_cpu":55,"./math/backends/backend_webgl":57,"./math/math":94,"./util":101}],101:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
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;
}
}
exports.shuffle = shuffle;
function clamp(min, x, max) {
return Math.max(min, Math.min(x, max));
}
exports.clamp = clamp;
function randUniform(a, b) {
return Math.random() * (b - a) + a;
}
exports.randUniform = randUniform;
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;
}
exports.distSquared = distSquared;
function assert(expr, msg) {
if (!expr) {
throw new Error(msg);
}
}
exports.assert = assert;
function assertShapesMatch(shapeA, shapeB, errorMessagePrefix) {
if (errorMessagePrefix === void 0) { errorMessagePrefix = ''; }
assert(arraysEqual(shapeA, shapeB), errorMessagePrefix + ("Shapes " + shapeA + " and " + shapeB + " must match"));
}
exports.assertShapesMatch = assertShapesMatch;
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;
}
exports.flatten = flatten;
function inferShape(arr) {
var shape = [];
while (arr instanceof Array) {
shape.push(arr.length);
arr = arr[0];
}
return shape;
}
exports.inferShape = inferShape;
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;
}
exports.sizeFromShape = sizeFromShape;
function isScalarShape(shape) {
return shape.length === 0;
}
exports.isScalarShape = isScalarShape;
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;
}
exports.arraysEqual = arraysEqual;
function isInt(a) {
return a % 1 === 0;
}
exports.isInt = isInt;
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);
}
}
exports.tanh = tanh;
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];
}
exports.sizeToSquarishShape = sizeToSquarishShape;
function createShuffledIndices(n) {
var shuffledIndices = new Uint32Array(n);
for (var i = 0; i < n; ++i) {
shuffledIndices[i] = i;
}
shuffle(shuffledIndices);
return shuffledIndices;
}
exports.createShuffledIndices = createShuffledIndices;
function rightPad(a, size) {
if (size <= a.length) {
return a;
}
return a + ' '.repeat(size - a.length);
}
exports.rightPad = rightPad;
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);
};
setTimeout(tryFn, 0);
});
}
exports.repeatedTry = repeatedTry;
function getQueryParams(queryString) {
var params = {};
queryString.replace(/[?&]([^=?&]+)(?:=([^&]*))?/g, function (s) {
var t = [];
for (var _i = 1; _i < arguments.length; _i++) {
t[_i - 1] = arguments[_i];
}
decodeParam(params, t[0], t[1]);
return t.join('=');
});
return params;
}
exports.getQueryParams = getQueryParams;
function decodeParam(params, name, value) {
params[decodeURIComponent(name)] = decodeURIComponent(value || '');
}
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 (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;
}
exports.inferFromImplicitShape = inferFromImplicitShape;
exports.NAN_INT32 = 1 << 31;
exports.NAN_BOOL = 255;
exports.NAN_FLOAT32 = NaN;
function getNaN(dtype) {
if (dtype === 'float32') {
return exports.NAN_FLOAT32;
}
else if (dtype === 'int32') {
return exports.NAN_INT32;
}
else if (dtype === 'bool') {
return exports.NAN_BOOL;
}
else {
throw new Error("Unknown dtype " + dtype);
}
}
exports.getNaN = getNaN;
function isValNaN(val, dtype) {
if (isNaN(val)) {
return true;
}
if (dtype === 'float32') {
return false;
}
else if (dtype === 'int32') {
return val === exports.NAN_INT32;
}
else if (dtype === 'bool') {
return val === exports.NAN_BOOL;
}
else {
throw new Error("Unknown dtype " + dtype);
}
}
exports.isValNaN = isValNaN;
function squeezeShape(shape) {
var newShape = [];
var keptDims = [];
for (var i = 0; i < shape.length; ++i) {
if (shape[i] > 1) {
newShape.push(shape[i]);
keptDims.push(i);
}
}
return { newShape: newShape, keptDims: keptDims };
}
exports.squeezeShape = squeezeShape;
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;
}
exports.getTypedArrayFromDType = getTypedArrayFromDType;
},{}],102:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var version = '0.3.15';
exports.version = version;
},{}]},{},[51])(51)
});
this.dl = this.deeplearn;