@hoff97/tensor-js
Version:
PyTorch like deep learning inferrence library
344 lines • 11.2 kB
JavaScript
import { averagePool } from '../../ops/cpu/averagePool';
import { abs, acos, acosh, add, addMultiplyScalar, asin, asinh, atan, atanh, ceil, clip, clipBackward, cos, cosh, divide, exp, floor, hardSigmoid, log, multiply, negate, power, powerScalar, round, sigmoid, sign, sin, sinh, sqrt, subtract, tan, tanh, } from '../../ops/cpu/basic';
import { concat } from '../../ops/cpu/concat';
import { conv } from '../../ops/cpu/conv';
import { convTranspose } from '../../ops/cpu/convTranspose';
import { expand } from '../../ops/cpu/expand';
import { gather } from '../../ops/cpu/gather';
import { gemm } from '../../ops/cpu/gemm';
import { matMul } from '../../ops/cpu/matMul';
import { max } from '../../ops/cpu/max';
import { min } from '../../ops/cpu/min';
import { normalize } from '../../ops/cpu/normalize';
import { pad } from '../../ops/cpu/pad';
import { product } from '../../ops/cpu/product';
import { reduceLogSum } from '../../ops/cpu/reduceLogSum';
import { reduceLogSumExp } from '../../ops/cpu/reduceLogSumExp';
import { reduceMean } from '../../ops/cpu/reduceMean';
import { reduceMeanSquare } from '../../ops/cpu/reduceMeanSquare';
import { repeat } from '../../ops/cpu/repeat';
import { setValues } from '../../ops/cpu/setValues';
import { slice } from '../../ops/cpu/slice';
import { sum } from '../../ops/cpu/sum';
import { sumSquare } from '../../ops/cpu/sumSquare';
import { transpose } from '../../ops/cpu/transpose';
import { upsample } from '../../ops/cpu/upsample';
import Tensor, { tensorValuesConstructor, } from '../../types';
import { compareShapes, computeStrides, getSize, indexToPos, } from '../../util/shape';
export class CPUTensor extends Tensor {
constructor(shape, values, dtype) {
super(dtype || 'float32');
/**
* If this tensor was already deleted
*/
this.deleted = false;
this.shape = shape;
this.strides = computeStrides(shape);
this.size = getSize(shape);
if (values !== undefined) {
if (values instanceof Array) {
this.values = new tensorValuesConstructor[this.dtype](values);
}
else {
this.values = values;
}
}
else {
this.values = new tensorValuesConstructor[this.dtype](this.size);
}
}
static range(start, limit, delta) {
const size = Math.max(Math.ceil((limit - start) / delta), 0);
const values = new Float32Array(size);
for (let i = 0; i < size; i++) {
values[i] = start + i * delta;
}
return new CPUTensor([size], values);
}
getValues() {
return Promise.resolve(this.values);
}
getShape() {
return this.shape;
}
constantLike(value) {
return new CPUTensor(this.shape, new tensorValuesConstructor[this.dtype](this.size).fill(value), this.dtype);
}
singleConstant(value) {
return new CPUTensor([1], [value], this.dtype);
}
cast(dtype) {
// TODO: Catch special cases here
// Eg casting to the same type
return new CPUTensor(this.shape, Array.from(this.values), dtype);
}
delete() {
//@ts-ignore
this.values = undefined;
this.deleted = true;
}
copy(newShape) {
if (newShape === undefined) {
newShape = [...this.shape];
}
const values = new tensorValuesConstructor[this.dtype](this.size);
for (let i = 0; i < this.size; i++) {
values[i] = this.values[i];
}
return new CPUTensor(newShape, values, this.dtype);
}
get(index) {
let pos;
if (Array.isArray(index)) {
pos = indexToPos(index, this.strides, this.shape);
}
else {
pos = index;
}
return this.values[pos];
}
set(index, value) {
let pos;
if (Array.isArray(index)) {
pos = indexToPos(index, this.strides);
}
else {
pos = index;
}
this.values[pos] = value;
}
setValues(values, starts) {
if (!(values instanceof CPUTensor)) {
throw new Error('Can only set CPU values to CPU values');
}
return setValues(this, values, starts);
}
exp() {
return exp(this);
}
log() {
return log(this);
}
sqrt() {
return sqrt(this);
}
abs() {
return abs(this);
}
sin() {
return sin(this);
}
cos() {
return cos(this);
}
tan() {
return tan(this);
}
asin() {
return asin(this);
}
acos() {
return acos(this);
}
atan() {
return atan(this);
}
sinh() {
return sinh(this);
}
cosh() {
return cosh(this);
}
tanh() {
return tanh(this);
}
asinh() {
return asinh(this);
}
acosh() {
return acosh(this);
}
atanh() {
return atanh(this);
}
floor() {
return floor(this);
}
ceil() {
return ceil(this);
}
round() {
return round(this);
}
negate() {
return negate(this);
}
powerScalar(power, factor) {
return powerScalar(this, power, factor);
}
multiplyScalar(value) {
return addMultiplyScalar(this, value, 0);
}
addScalar(value) {
return addMultiplyScalar(this, 1, value);
}
addMultiplyScalar(factor, add) {
return addMultiplyScalar(this, factor, add);
}
sign() {
return sign(this);
}
clip(min, max) {
return clip(this, min, max);
}
clipBackward(grad, min, max) {
if (!(grad instanceof CPUTensor)) {
throw new Error('Can only do clipBackward with CPUTensor');
}
return clipBackward(this, grad, this.getShape(), min, max);
}
sigmoid() {
return sigmoid(this);
}
hardSigmoid(alpha, beta) {
return hardSigmoid(this, alpha, beta);
}
add_impl(th, tensor, resultShape, alpha, beta) {
if (!(tensor instanceof CPUTensor) || !(th instanceof CPUTensor)) {
throw new Error('Can only add CPU tensor to CPU tensor');
}
return add(th, tensor, resultShape, alpha, beta);
}
subtract_impl(th, tensor, resultShape, alpha, beta) {
if (!(tensor instanceof CPUTensor) || !(th instanceof CPUTensor)) {
throw new Error('Can only subtract CPU tensor to CPU tensor');
}
return subtract(th, tensor, resultShape, alpha, beta);
}
multiply_impl(th, tensor, resultShape, alpha) {
if (!(tensor instanceof CPUTensor) || !(th instanceof CPUTensor)) {
throw new Error('Can only add CPU tensor to CPU tensor');
}
return multiply(th, tensor, resultShape, alpha);
}
divide_impl(th, tensor, resultShape, alpha) {
if (!(tensor instanceof CPUTensor) || !(th instanceof CPUTensor)) {
throw new Error('Can only add CPU tensor to CPU tensor');
}
return divide(th, tensor, resultShape, alpha);
}
power_impl(th, tensor, resultShape) {
if (!(tensor instanceof CPUTensor) || !(th instanceof CPUTensor)) {
throw new Error('Can only take CPU tensor to power of CPU tensor');
}
return power(th, tensor, resultShape);
}
matMul(tensor) {
if (!(tensor instanceof CPUTensor)) {
throw new Error('Can only add CPU tensor to CPU tensor');
}
return matMul(this, tensor);
}
gemm_impl(b, aTranspose, bTranspose, alpha, beta, c) {
if (!(b instanceof CPUTensor && (c === undefined || c instanceof CPUTensor))) {
throw new Error('Can only do gemm with CPU tensors');
}
return gemm(this, b, aTranspose, bTranspose, alpha, beta, c);
}
sum_impl(axes, keepDims) {
return sum(this, axes, keepDims);
}
sumSquare_impl(axes, keepDims) {
return sumSquare(this, axes, keepDims);
}
product_impl(axes, keepDims) {
return product(this, axes, keepDims);
}
max_impl(axes, keepDims) {
return max(this, axes, keepDims);
}
min_impl(axes, keepDims) {
return min(this, axes, keepDims);
}
reduceMean_impl(axes, keepDims) {
return reduceMean(this, axes, keepDims);
}
reduceMeanSquare_impl(axes, keepDims) {
return reduceMeanSquare(this, axes, keepDims);
}
reduceLogSum_impl(axes, keepDims) {
return reduceLogSum(this, axes, keepDims);
}
reduceLogSumExp_impl(axes, keepDims) {
return reduceLogSumExp(this, axes, keepDims);
}
conv_impl(kernel, dilations, group, pads, strides, activation, bias) {
if (!(kernel instanceof CPUTensor) ||
(bias !== undefined && !(bias instanceof CPUTensor))) {
throw new Error('Can only do convolution of CPU tensor with CPU tensor');
}
return conv(this, kernel, dilations, group, pads, strides, activation, bias);
}
convTranspose_impl(kernel, dilations, group, pads, strides) {
if (!(kernel instanceof CPUTensor)) {
throw new Error('Can only do transpose convolution of CPU tensor with CPU tensor');
}
return convTranspose(this, kernel, dilations, group, pads, strides);
}
pad_impl(pads, mode, value) {
return pad(this, pads, mode, value);
}
averagePool_impl(kernelShape, pads, strides, includePad) {
return averagePool(this, kernelShape, pads, strides, includePad);
}
reshape_impl(shape, copy) {
if (copy) {
return this.copy(shape);
}
else {
return new CPUTensor(shape, this.values, this.dtype);
}
}
concat(tensor, axis) {
if (!(tensor instanceof CPUTensor)) {
throw new Error('Can only concat CPU tensor to CPU tensor');
}
if (axis < 0) {
axis += this.shape.length;
}
return concat(this, tensor, axis);
}
transpose_impl(permutation) {
return transpose(this, permutation);
}
repeat(repeats) {
return repeat(this, repeats);
}
expand(shape) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [_shape, goal, resultShape] = this.alignShapes(this.shape, shape);
if (compareShapes(this.shape, resultShape)) {
return this.copy();
}
return expand(this.reshape(_shape, false), resultShape);
}
gather(axis, indices) {
return gather(this, axis, indices);
}
slice_impl(starts, ends, axes, steps) {
return slice(this, starts, ends, axes, steps);
}
upsample(scales) {
return upsample(this, scales);
}
normalize(mean, variance, epsilon, scale, bias) {
if (!(mean instanceof CPUTensor) ||
!(variance instanceof CPUTensor) ||
!(scale instanceof CPUTensor) ||
!(bias instanceof CPUTensor)) {
throw new Error('Can only normalize with CPU tensors');
}
return normalize(this, mean, variance, epsilon, scale, bias);
}
}
//# sourceMappingURL=tensor.js.map