import Tensor, { Activation, DType, PadMode, TensorValues } from '../../types'; import { CPUTensor } from '../cpu/tensor'; export declare class SparseTensor extends Tensor { /** * Values of the nonzero entries */ values: Tensor; /** * Coordinates of the nonzero entries. Has shape [nnz, S], * where nnz is the number of nonzero entries and S the number of * sparse dimension. * * Each row contains the coordinate of the respective nonzero entry. */ indices: Tensor<'uint32'>; /** * Shape of the tensor */ shape: readonly number[]; /** * Number of dense dimensions. Defaults to 0 */ denseDims: number; /** * Creates a sparse tensor with zero dense dimensions from a dense CPU tensor. * * @example * ```typescript * const denseTensor = new CPUTensor([3,3],[1,0,0,0,2,0,0,3,4]); * * const sparseTensor = SparseTensor.fromDense(denseTensor); * console.log(sparseTensor.nnz); // Will log '4' * console.log(sparseTensor.sparseDims); // Will log '2' * ``` */ static fromDense(tensor: CPUTensor): SparseTensor; /** * Total number of entries (including zero entries) in the tensor */ size: number; /** * Dense strides of the tensor */ strides: number[]; /** * Number of nonzero entries in the tensor */ nnz: number; /** * Number of sparse dimensions */ sparseDims: number; /** * Creates a new sparse tensor in coordinate format. The tensor has * a number of sparse dimensions and optionally a number of dense * dimensions. The shape of a sparse tensor can thus be decomposed * into [...S, ...D], where S is the shape of the sparse dimensions * and D the shape of the dense dimensions. By default the number of * dense dimensions is zero * * The values tensor holds all non-zero values and has shape [NNZ, ...D] * where NNZ is the number of non-zero entries. The indices tensor * holds the location of all non-zero entries of the tensor and * has shape [NNZ, |S|] (where |S| is the number of sparse dimensions). * * Note that all indexes that are not specified are implicitly zero. * This does however **not** mean that they become non-zero on * certain element wise operations. Instead element wise operations * maintain the sparsity pattern. Otherwise, many operations would * create effectively dense tensors (eg. exp()), or would simply not be * well defined (eg. log()). * * @example * * If you want to create a sparse tensor, equivalent to the following CPU * tensor: * ```typescript * const a = new CPUTensor([3,3],[1,0,0,0,2,0,0,3,4]); * ``` * you collect the indices, where the value is nonzero: * ```typescript * const indices = [ * 0,0, // Corresponds to value 1 * 1,1, // Corresponds to value 2 * 2,1, // Corresponds to value 3 * 2,2 // Corresponds to value 4 * ]; * const indiceTensor = new CPUTensor([4, 2], indices, 'uint32'); * ``` * and the corresponding values: * ```typescript * const values = [1,2,3,4]; * const valueTensor = new CPUTensor([4],values); * * const sparseTensor = new SparseTensor(valueTensor, indiceTensor, [3,3]); * ``` */ constructor( /** * Values of the nonzero entries */ values: Tensor, /** * Coordinates of the nonzero entries. Has shape [nnz, S], * where nnz is the number of nonzero entries and S the number of * sparse dimension. * * Each row contains the coordinate of the respective nonzero entry. */ indices: Tensor<'uint32'>, /** * Shape of the tensor */ shape: readonly number[], /** * Number of dense dimensions. Defaults to 0 */ denseDims?: number); getValues(): Promise; /** * Sparse part of the shape of the tensor, ie. the S first values of * the shape, where S is then number of sparse dimension. */ getSparseShape(): readonly number[]; /** * Dense part of the shape of the tensor, ie. the D last values of * the shape, where D is then number of dense dimension. */ getDenseShape(): readonly number[]; getShape(): readonly number[]; /** * Creates a new sparse tensor with the same sparsity shape * and the given value everywhere. * * @param value Constant value to set at every position */ constantLike(value: number): Tensor; /** * Not implemented yet */ singleConstant(value: number): Tensor; cast(dtype: DTpe2): Tensor; delete(): void; protected reshape_impl(shape: readonly number[], copy: boolean): Tensor; exp(): Tensor; log(): Tensor; sqrt(): Tensor; abs(): Tensor; sin(): Tensor; cos(): Tensor; tan(): Tensor; asin(): Tensor; acos(): Tensor; atan(): Tensor; sinh(): Tensor; cosh(): Tensor; tanh(): Tensor; asinh(): Tensor; acosh(): Tensor; atanh(): Tensor; negate(): Tensor; powerScalar(power: number, factor: number): Tensor; sigmoid(): Tensor; hardSigmoid(alpha: number, beta: number): Tensor; sign(): Tensor; addMultiplyScalar(factor: number, add: number): Tensor; /** * Calculates the matrix product. This tensor should have shape [M,N] * * Two cases are supported for sparse tensors: * - If this tensor has one sparse dimension, the resulting tensor is * a sparse tensor with the same number of non-zero entries * - If this tensor has two sparse dimensions, the resulting tensor * is dense. * Right now this only supports sparse-dense matrix multiplication. * Supported on * - All backends if the sparse tensor has 1 sparse dimensions * - Only on CPU/WASM if the sparse tensor has no sparse dimensions * * @param tensor Dense matrix to multiply with. Should have shape [N,O] * * @result Tensor with shape [M,O] */ matMul(tensor: Tensor): Tensor; /** * Concatenate the two tensors along the given axis * * Note that at the moment, only concatenation along * sparse dimensions is supported! * */ concat(tensor: Tensor, axis: number): Tensor; clip(min?: number, max?: number): Tensor; /** * Not implemented yet */ clipBackward(grad: Tensor, min?: number, max?: number): Tensor; repeat(repeats: number[]): Tensor; /** * Not implemented yet */ expand(shape: readonly number[]): Tensor; copy(): Tensor; /** * Not implemented yet */ gather(axis: number, indices: CPUTensor<'uint32'>): Tensor; /** * Not implemented yet */ setValues(values: Tensor, starts: number[]): Tensor; floor(): Tensor; ceil(): Tensor; round(): Tensor; /** * Not implemented yet */ upsample(scales: number[]): Tensor; /** * Not implemented yet */ normalize(mean: Tensor, variance: Tensor, epsilon: number, scale: Tensor, bias: Tensor): Tensor; /** * Adds a second tensor, which can either be a sparse or a dense tensor: * - If the second tensor is a dense tensor, it is assumed that it has a rank at most * equal to the dense dimensions of the first tensor. * If this is not the case, entries in the second tensors that are zero in the first * tensor are simply ignored! * This also means that broadcasting in the first tensor is only supported * on the dense dimensions! * - If the second tensor is a sparse tensor, it is assumed that the first and * second tensor have exactly the same sparsity pattern! * * This is not supported on the WebGL backend yet. */ add(tensor: Tensor, alpha?: number, beta?: number): Tensor; /** * Subtracts a second tensor, which can either be a sparse or a dense tensor. * The same restrictions as for {@link SparseTensor.add} apply! */ subtract(tensor: Tensor, alpha?: number, beta?: number): Tensor; /** * Multiplies a second tensor element wise, which can either be a sparse or a dense tensor. * The same restrictions as for {@link SparseTensor.add} apply! */ multiply(tensor: Tensor, alpha?: number): Tensor; /** * Divides a second tensor element wise, which can either be a sparse or a dense tensor. * The same restrictions as for {@link SparseTensor.add} apply! */ divide(tensor: Tensor, alpha?: number): Tensor; add_impl(th: Tensor, tensor: Tensor, resultShape: readonly number[], alpha: number, beta: number): Tensor; subtract_impl(th: Tensor, tensor: Tensor, resultShape: readonly number[], alpha: number, beta: number): Tensor; multiply_impl(th: Tensor, tensor: Tensor, resultShape: readonly number[], alpha: number): Tensor; divide_impl(th: Tensor, tensor: Tensor, resultShape: readonly number[], alpha: number): Tensor; /** * Not implemented yet */ power_impl(th: Tensor, tensor: Tensor, resultShape: readonly number[]): Tensor; /** * Not implemented yet */ gemm_impl(b: Tensor, aTranspose: boolean, bTranspose: boolean, alpha: number, beta: number, C?: Tensor): Tensor; /** * Sums over sparse and/or dense dimensions according to the specified * axes. * * - If summing only over dense dimensions, all backends are supported. * - If summing over sparse dimensions, only CPU/WebGL are supported */ sum(axes?: number | number[], keepDims?: boolean): Tensor; protected sum_impl(axes: number[], keepDims: boolean): Tensor; protected sumSquare_impl(axes: number[], keepDims: boolean): Tensor; protected product_impl(axes: number[], keepDims: boolean): Tensor; protected max_impl(axes: number[], keepDims: boolean): Tensor; protected min_impl(axes: number[], keepDims: boolean): Tensor; protected reduceMean_impl(axes: number[], keepDims: boolean): Tensor; protected reduceMeanSquare_impl(axes: number[], keepDims: boolean): Tensor; protected reduceLogSum_impl(axes: number[], keepDims: boolean): Tensor; protected reduceLogSumExp_impl(axes: number[], keepDims: boolean): Tensor; /** * Not implemented yet */ protected conv_impl(kernel: Tensor, dilations: number[], group: number, pads: number[], strides: number[], activation: Activation, bias?: Tensor): Tensor; /** * Not implemented yet */ protected convTranspose_impl(kernel: Tensor, dilations: number[], group: number, pads: number[], strides: number[]): Tensor; /** * Not implemented yet */ protected pad_impl(pads: number[], mode: PadMode, value: number): Tensor; /** * Not implemented yet */ protected averagePool_impl(kernelShape: number[], pads: number[], strides: number[], includePad: boolean): Tensor; /** * Not implemented yet */ protected transpose_impl(permutation: number[]): Tensor; /** * Not implemented yet */ protected slice_impl(starts: number[], ends: number[], axes: number[], steps: number[]): Tensor; }