UNPKG

@hoff97/tensor-js

Version:

PyTorch like deep learning inferrence library

344 lines 11.2 kB
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