tensor

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 17, 2025 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package tensor provides the core tensor types and operations for Born ML framework.

Package tensor provides the core tensor types and operations for Born ML framework.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Backend

type Backend interface {
	// Element-wise binary operations
	Add(a, b *RawTensor) *RawTensor
	Sub(a, b *RawTensor) *RawTensor
	Mul(a, b *RawTensor) *RawTensor
	Div(a, b *RawTensor) *RawTensor

	// Matrix operations
	MatMul(a, b *RawTensor) *RawTensor

	// Convolutional operations
	Conv2D(input, kernel *RawTensor, stride, padding int) *RawTensor
	MaxPool2D(input *RawTensor, kernelSize, stride int) *RawTensor

	// Shape operations
	Reshape(t *RawTensor, newShape Shape) *RawTensor
	Transpose(t *RawTensor, axes ...int) *RawTensor

	// Metadata
	Name() string
	Device() Device
}

Backend defines the interface that all compute backends must implement. Backends handle the actual computation for tensor operations.

Implementations:

  • CPU: Pure Go with SIMD optimizations (TASK-003)
  • CUDA: NVIDIA GPU via driver API (Phase 2)
  • Vulkan: Cross-platform GPU compute (Phase 2)
  • Metal: Apple GPU (Phase 2)
  • WebGPU: Browser/native GPU (Phase 2)

type DType

type DType interface {
	~float32 | ~float64 | ~int32 | ~int64 | ~uint8 | ~bool
}

DType is a constraint for supported tensor data types. It uses Go generics to ensure compile-time type safety.

type DataType

type DataType int

DataType represents runtime type information for tensors.

const (
	Float32 DataType = iota
	Float64
	Int32
	Int64
	Uint8
	Bool
)

Supported data types for tensors.

func (DataType) Size

func (dt DataType) Size() int

Size returns the byte size of the data type.

func (DataType) String

func (dt DataType) String() string

String returns a human-readable name for the data type.

type Device

type Device int

Device represents the compute device for tensor operations.

const (
	CPU Device = iota
	CUDA
	Vulkan
	Metal
	WebGPU
)

Supported compute devices.

func (Device) String

func (d Device) String() string

String returns a human-readable device name.

type MockBackend

type MockBackend struct{}

MockBackend is a simple backend for testing. It implements all operations naively for correctness verification.

func NewMockBackend

func NewMockBackend() *MockBackend

NewMockBackend creates a new MockBackend.

func (*MockBackend) Add

func (m *MockBackend) Add(a, b *RawTensor) *RawTensor

Add performs element-wise addition with broadcasting.

func (*MockBackend) Conv2D

func (m *MockBackend) Conv2D(input, kernel *RawTensor, stride, padding int) *RawTensor

Conv2D performs 2D convolution (naive implementation for testing).

func (*MockBackend) Device

func (m *MockBackend) Device() Device

Device returns the device type.

func (*MockBackend) Div

func (m *MockBackend) Div(a, b *RawTensor) *RawTensor

Div performs element-wise division with broadcasting.

func (*MockBackend) MatMul

func (m *MockBackend) MatMul(a, b *RawTensor) *RawTensor

MatMul performs matrix multiplication.

func (*MockBackend) MaxPool2D

func (m *MockBackend) MaxPool2D(input *RawTensor, kernelSize, stride int) *RawTensor

MaxPool2D performs 2D max pooling (naive implementation for testing).

func (*MockBackend) Mul

func (m *MockBackend) Mul(a, b *RawTensor) *RawTensor

Mul performs element-wise multiplication with broadcasting.

func (*MockBackend) Name

func (m *MockBackend) Name() string

Name returns the backend name.

func (*MockBackend) Reshape

func (m *MockBackend) Reshape(t *RawTensor, newShape Shape) *RawTensor

Reshape changes tensor shape.

func (*MockBackend) Sub

func (m *MockBackend) Sub(a, b *RawTensor) *RawTensor

Sub performs element-wise subtraction with broadcasting.

func (*MockBackend) Transpose

func (m *MockBackend) Transpose(t *RawTensor, axes ...int) *RawTensor

Transpose transposes tensor dimensions.

type RawTensor

type RawTensor struct {
	// contains filtered or unexported fields
}

RawTensor is the low-level tensor representation. It uses reference-counted shared buffers for Copy-on-Write semantics.

func NewRaw

func NewRaw(shape Shape, dtype DataType, device Device) (*RawTensor, error)

NewRaw creates a new RawTensor with the given shape and type. Memory is allocated but not initialized (contains zeros).

func (*RawTensor) AsBool

func (r *RawTensor) AsBool() []bool

AsBool interprets the data as []bool. Panics if the tensor's dtype is not Bool.

func (*RawTensor) AsFloat32

func (r *RawTensor) AsFloat32() []float32

AsFloat32 interprets the data as []float32. Panics if the tensor's dtype is not Float32.

func (*RawTensor) AsFloat64

func (r *RawTensor) AsFloat64() []float64

AsFloat64 interprets the data as []float64. Panics if the tensor's dtype is not Float64.

func (*RawTensor) AsInt32

func (r *RawTensor) AsInt32() []int32

AsInt32 interprets the data as []int32. Panics if the tensor's dtype is not Int32.

func (*RawTensor) AsInt64

func (r *RawTensor) AsInt64() []int64

AsInt64 interprets the data as []int64. Panics if the tensor's dtype is not Int64.

func (*RawTensor) AsUint8

func (r *RawTensor) AsUint8() []uint8

AsUint8 interprets the data as []uint8. Panics if the tensor's dtype is not Uint8.

func (*RawTensor) ByteSize

func (r *RawTensor) ByteSize() int

ByteSize returns the total memory size in bytes.

func (*RawTensor) Clone

func (r *RawTensor) Clone() *RawTensor

Clone creates a shallow copy of the RawTensor (shares buffer with reference counting). The buffer is reference-counted and will be copied only when modified (copy-on-write). This enables cheap cloning and inplace optimizations when refCount == 1.

Example:

a := tensor.Ones[float32](Shape{1000, 1000}, backend)
b := a.Clone()  // Shares buffer with a (just increments refCount)
c := a.Add(b)   // May use inplace if refCount allows

func (*RawTensor) DType

func (r *RawTensor) DType() DataType

DType returns the tensor's data type.

func (*RawTensor) Data

func (r *RawTensor) Data() []byte

Data returns the raw byte slice. WARNING: Direct access to underlying memory. Use with caution.

func (*RawTensor) Device

func (r *RawTensor) Device() Device

Device returns the tensor's compute device.

func (*RawTensor) ForceNonUnique

func (r *RawTensor) ForceNonUnique() func()

ForceNonUnique temporarily increases refCount to prevent inplace modifications. Returns a cleanup function that MUST be called to restore refCount (use defer).

This is used by autodiff backend to preserve original input values: inplace optimizations would corrupt the computational graph.

Example:

defer tensor.ForceNonUnique()()
result := backend.Mul(tensor, other)  // No inplace modification!

func (*RawTensor) IsUnique

func (r *RawTensor) IsUnique() bool

IsUnique returns true if this tensor is the only reference to the buffer. When true, backends can perform inplace operations for better performance.

func (*RawTensor) NumElements

func (r *RawTensor) NumElements() int

NumElements returns the total number of elements.

func (*RawTensor) Release

func (r *RawTensor) Release()

Release decrements the reference count and deallocates if it reaches 0. This is called automatically when a tensor is no longer needed (e.g., by GC finalizer).

func (*RawTensor) Shape

func (r *RawTensor) Shape() Shape

Shape returns the tensor's shape.

func (*RawTensor) Strides

func (r *RawTensor) Strides() []int

Strides returns the tensor's memory strides.

type Shape

type Shape []int

Shape represents the dimensions of a tensor.

func BroadcastShapes

func BroadcastShapes(a, b Shape) (Shape, bool, error)

BroadcastShapes implements NumPy-style broadcasting rules.

Rules: 1. Compare shapes element-wise from right to left 2. Dimensions are compatible if:

  • They are equal, OR
  • One of them is 1

3. Missing dimensions are treated as 1

Returns the broadcasted shape, a flag indicating if broadcasting is needed, and an error if incompatible.

Examples:

(3, 1) + (3, 5) → (3, 5), true, nil
(1, 5) + (3, 5) → (3, 5), true, nil
(3, 5) + (3, 5) → (3, 5), false, nil
(3, 4) + (3, 5) → nil, false, Error

func (Shape) Clone

func (s Shape) Clone() Shape

Clone returns a copy of the shape.

func (Shape) ComputeStrides

func (s Shape) ComputeStrides() []int

ComputeStrides calculates row-major strides for the shape. Strides define memory layout: stride[i] = product of all dimensions after i.

func (Shape) Equal

func (s Shape) Equal(other Shape) bool

Equal checks if two shapes are equal.

func (Shape) NumElements

func (s Shape) NumElements() int

NumElements returns the total number of elements in the tensor.

func (Shape) Validate

func (s Shape) Validate() error

Validate checks if the shape is valid (all dimensions > 0).

type Tensor

type Tensor[T DType, B Backend] struct {
	// contains filtered or unexported fields
}

Tensor is a generic tensor with type T and backend B. It provides type-safe operations over multi-dimensional arrays.

Type Parameters:

  • T: Data type (must satisfy DType constraint)
  • B: Computation backend (must implement Backend interface)

Example:

backend := cpu.New()
t := tensor.Zeros[float32](Shape{3, 4}, backend)
result := t.Add(t) // Type-safe addition

func Arange

func Arange[T DType, B Backend](start, end T, b B) *Tensor[T, B]

Arange creates a 1D tensor with values from start to end (exclusive). Only works with numeric types (not bool).

Example:

t := tensor.Arange[int32](0, 10, backend) // [0, 1, 2, ..., 9]

func Eye

func Eye[T DType, B Backend](n int, b B) *Tensor[T, B]

Eye creates a 2D identity matrix.

Example:

t := tensor.Eye[float32](3, backend) // 3x3 identity matrix

func FromSlice

func FromSlice[T DType, B Backend](data []T, shape Shape, b B) (*Tensor[T, B], error)

FromSlice creates a tensor from a Go slice. The slice is copied into the tensor's memory.

func Full

func Full[T DType, B Backend](shape Shape, value T, b B) *Tensor[T, B]

Full creates a tensor filled with a specific value.

Example:

t := tensor.Full[float32](Shape{3, 3}, 3.14, backend)

func New

func New[T DType, B Backend](raw *RawTensor, b B) *Tensor[T, B]

New creates a Tensor from a RawTensor and backend.

func Ones

func Ones[T DType, B Backend](shape Shape, b B) *Tensor[T, B]

Ones creates a tensor filled with ones.

Example:

t := tensor.Ones[float64](Shape{2, 3}, backend)

func Rand

func Rand[T DType, B Backend](shape Shape, b B) *Tensor[T, B]

Rand creates a tensor with random values uniformly distributed in [0, 1). Only works with float types.

Example:

t := tensor.Rand[float32](Shape{10, 10}, backend)

func Randn

func Randn[T DType, B Backend](shape Shape, b B) *Tensor[T, B]

Randn creates a tensor with random values from a normal distribution (mean=0, std=1). Uses Box-Muller transform for generating normal distribution. Only works with float types. Note: Uses math/rand (not crypto/rand) - appropriate for ML/statistical purposes.

Example:

t := tensor.Randn[float32](Shape{100, 100}, backend)

func Zeros

func Zeros[T DType, B Backend](shape Shape, b B) *Tensor[T, B]

Zeros creates a tensor filled with zeros.

Example:

backend := cpu.New()
t := tensor.Zeros[float32](Shape{3, 4}, backend)

func (*Tensor[T, B]) Add

func (t *Tensor[T, B]) Add(other *Tensor[T, B]) *Tensor[T, B]

Add performs element-wise addition with broadcasting.

Example:

a := tensor.Ones[float32](Shape{3, 1}, backend)
b := tensor.Ones[float32](Shape{3, 5}, backend)
c := a.Add(b) // Shape: [3, 5] (broadcasted)

func (*Tensor[T, B]) At

func (t *Tensor[T, B]) At(indices ...int) T

At returns the element at the given indices. Panics if indices are out of bounds.

Example:

t := tensor.Zeros[float32](Shape{3, 4}, backend)
value := t.At(1, 2) // Row 1, column 2

func (*Tensor[T, B]) Backend

func (t *Tensor[T, B]) Backend() B

Backend returns the computation backend.

func (*Tensor[T, B]) Clone

func (t *Tensor[T, B]) Clone() *Tensor[T, B]

Clone creates a deep copy of the tensor.

func (*Tensor[T, B]) DType

func (t *Tensor[T, B]) DType() DataType

DType returns the tensor's data type.

func (*Tensor[T, B]) Data

func (t *Tensor[T, B]) Data() []T

Data returns a typed slice view of the tensor's data. The slice directly accesses the underlying memory (zero-copy).

WARNING: Modifications to the returned slice will modify the tensor.

func (*Tensor[T, B]) Device

func (t *Tensor[T, B]) Device() Device

Device returns the tensor's compute device.

func (*Tensor[T, B]) Div

func (t *Tensor[T, B]) Div(other *Tensor[T, B]) *Tensor[T, B]

Div performs element-wise division with broadcasting.

func (*Tensor[T, B]) Grad

func (t *Tensor[T, B]) Grad() *Tensor[T, B]

Grad returns the gradient tensor (if computed by autodiff).

func (*Tensor[T, B]) Item

func (t *Tensor[T, B]) Item() T

Item returns the scalar value of a 0-D tensor. Panics if the tensor is not a scalar.

func (*Tensor[T, B]) MatMul

func (t *Tensor[T, B]) MatMul(other *Tensor[T, B]) *Tensor[T, B]

MatMul performs matrix multiplication.

Requirements:

  • For 2D tensors: (M, K) @ (K, N) → (M, N)
  • For batched: (B, M, K) @ (B, K, N) → (B, M, N)

Example:

a := tensor.Randn[float32](Shape{3, 4}, backend)
b := tensor.Randn[float32](Shape{4, 5}, backend)
c := a.MatMul(b) // Shape: [3, 5]

func (*Tensor[T, B]) Mul

func (t *Tensor[T, B]) Mul(other *Tensor[T, B]) *Tensor[T, B]

Mul performs element-wise multiplication with broadcasting.

func (*Tensor[T, B]) NumElements

func (t *Tensor[T, B]) NumElements() int

NumElements returns the total number of elements.

func (*Tensor[T, B]) Raw

func (t *Tensor[T, B]) Raw() *RawTensor

Raw returns the underlying RawTensor. Used by backend implementations for low-level operations.

func (*Tensor[T, B]) RequireGrad

func (t *Tensor[T, B]) RequireGrad() *Tensor[T, B]

RequireGrad marks this tensor for gradient computation. When called, subsequent operations involving this tensor will be tracked in the computation graph (if using an AutodiffBackend).

Returns the tensor itself for method chaining.

Example:

x := tensor.Ones[float32](Shape{2, 2}, autodiffBackend).RequireGrad()
y := x.Mul(x) // Operations are tracked
y.Backward()  // Computes gradients
fmt.Println(x.Grad()) // dy/dx available

func (*Tensor[T, B]) RequiresGrad

func (t *Tensor[T, B]) RequiresGrad() bool

RequiresGrad returns true if this tensor requires gradient computation.

func (*Tensor[T, B]) Reshape

func (t *Tensor[T, B]) Reshape(newShape ...int) *Tensor[T, B]

Reshape returns a tensor with the same data but different shape. The new shape must have the same number of elements.

Example:

t := tensor.Arange[int32](0, 12, backend) // Shape: [12]
reshaped := t.Reshape(3, 4)               // Shape: [3, 4]

func (*Tensor[T, B]) Set

func (t *Tensor[T, B]) Set(value T, indices ...int)

Set sets the element at the given indices. Panics if indices are out of bounds.

func (*Tensor[T, B]) SetGrad

func (t *Tensor[T, B]) SetGrad(grad *Tensor[T, B])

SetGrad sets the gradient tensor. Used internally by autodiff (TASK-004).

func (*Tensor[T, B]) Shape

func (t *Tensor[T, B]) Shape() Shape

Shape returns the tensor's shape.

func (*Tensor[T, B]) String

func (t *Tensor[T, B]) String() string

String returns a human-readable representation of the tensor.

func (*Tensor[T, B]) Sub

func (t *Tensor[T, B]) Sub(other *Tensor[T, B]) *Tensor[T, B]

Sub performs element-wise subtraction with broadcasting.

func (*Tensor[T, B]) T

func (t *Tensor[T, B]) T() *Tensor[T, B]

T is a shortcut for 2D transpose (swaps rows and columns). Panics if the tensor is not 2D.

Example:

t := tensor.Randn[float32](Shape{3, 4}, backend)
transposed := t.T() // Shape: [4, 3]

func (*Tensor[T, B]) Transpose

func (t *Tensor[T, B]) Transpose(axes ...int) *Tensor[T, B]

Transpose transposes the tensor by permuting its dimensions.

If axes is empty, reverses all dimensions (for 2D, this is standard transpose). Otherwise, axes specifies the permutation.

Example:

t := tensor.Randn[float32](Shape{2, 3, 4}, backend)
transposed := t.Transpose(2, 0, 1) // Shape: [4, 2, 3]

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL