Skip to main content

MiniTensor Logo

A lightweight, high-performance tensor operations library with automatic differentiation, inspired by PyTorch and powered by Rust engine.


Current Release Python 3.10+ rustc 1.89+ Test Linux Test Windows Test MacOS Lints CodeQL Documentation License codecov arXiv DOI:48550/arXiv.2602.00125 PyPI Downloads

Highlights

  • High Performance: Rust engine for maximum speed and memory efficiency
  • Python-Friendly: Familiar PyTorch-like API for easy adoption
  • Neural Networks: Complete neural network layers and optimizers
  • NumPy Integration: Seamless interoperability with NumPy arrays
  • Automatic Differentiation: Built-in gradient computation for training
  • Extensible: Modular design for easy customization and extension

Quick Start

Installation

MiniTensor can be installed either from PyPI or from source. Source installs compile the Rust extension, so they require Python 3.10+, Rust/Cargo, and maturin. The full, platform-aware instructions live in the installation guide.

From PyPI:

pip install minitensor

From source with the installer (recommended for contributors):

# Clone the repository
git clone https://github.com/neuralsorcerer/minitensor.git
cd minitensor

bash install.sh

The installer creates .venv by default, installs maturin (with patchelf on Linux), installs Rust with rustup if needed, builds a release extension, and verifies the import.

Manual source install:

python -m pip install 'maturin[patchelf]'  # Linux; use `maturin` on macOS/Windows
maturin develop --release

For contributor tooling and editable builds, use the dev extra:

python -m pip install -e '.[dev]'
pre-commit install

Note: Editable pip installs use the release profile configured in pyproject.toml; use maturin develop --debug when you intentionally need a debug build.

Basic Usage

import minitensor as mt
from minitensor import nn, optim

# Create tensors
mt.manual_seed(7)
x = mt.randn(32, 784)  # Batch of 32 samples
y = mt.zeros(32, 10)   # Target labels

# Build a neural network
model = nn.Sequential([
    nn.DenseLayer(784, 128),
    nn.ReLU(),
    nn.DenseLayer(128, 10)
])

# Set up training
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), epsilon=1e-8)

print(f"Model type: {type(model).__name__}")
print(f"Input shape: {x.shape}")
Model type: Sequential
Input shape: Shape([32, 784])

Documentation

MiniTensor ships documentation in docs/, starting with the documentation index. Key guides include the installation guide, API reference, development guide, custom operations guide, plugin system guide, and performance guide. For a runtime overview of what's available, use the introspection helpers below.

import minitensor as mt

submodules = mt.available_submodules()
nn_api = mt.list_public_api()["nn"]
loss_hits = mt.search_api("loss")
ce_desc = mt.describe_api("nn.CrossEntropyLoss")

print(f"has submodules: {len(submodules) > 0}")
print(f"has nn API entries: {len(nn_api) > 0}")
print(f"loss search non-empty: {len(loss_hits) > 0}")
print(f"CrossEntropyLoss described: {'CrossEntropyLoss' in ce_desc}")
has submodules: True
has nn API entries: True
loss search non-empty: True
CrossEntropyLoss described: True

Core Components

Tensors

import minitensor as mt
import numpy as np

# Create tensors
x = mt.zeros(3, 4)          # Zeros
y = mt.ones(3, 4)           # Ones
z = mt.randn(2, 2)          # Random normal
np_array = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.float32)
w = mt.from_numpy(np_array) # From NumPy

# Operations
result = x + y                             # Element-wise addition
product = x.matmul(y.transpose(0, 1))      # Matrix multiplication
mean_val = x.mean()                        # Reduction operations
nan_median = mt.nanmedian(mt.Tensor([1.0, np.nan, 5.0]))
std_by_row = w.astype("float32").std(dim=1, unbiased=False)
var_all = w.astype("float32").var(dim=(0, 1), unbiased=False)
max_val = x.max()                          # -inf for empty or all-NaN tensors
min_vals, min_idx = x.min(dim=1)           # Returns values & indices; empty dims yield (inf, 0)
close_mask = mt.isclose([[1.0, 2.0]], [1.0 + 1e-6, 3.0])
close = mt.allclose([0.0, float("inf")], [-0.0, float("inf")])
exact = mt.array_equal([1, 2], mt.tensor([1.0, 2.0], dtype="float32"))
broadcasted_shape = mt.broadcast_shapes(x.shape, (1, 4))
broadcasted_x, broadcasted_row = mt.broadcast_tensors(
    mt.ones(3, 1), mt.Tensor([[1.0, 2.0, 3.0, 4.0]])
)
row = mt.atleast_2d(mt.Tensor([1.0, 2.0, 3.0]))
grid_x, grid_y = mt.meshgrid(mt.Tensor([1.0, 2.0]), mt.Tensor([10.0, 20.0, 30.0]))

print(result.shape)                        # Shape([3, 4])
print(product.shape)                       # Shape([3, 3])
print(float(mean_val.numpy().ravel()[0]))  # 0.0
print(float(nan_median.numpy().ravel()[0]))  # 3.0
print(std_by_row.shape)                    # Shape([2])
print(float(var_all.numpy().ravel()[0]))   # 2.9166667
print(float(max_val.numpy().ravel()[0]))   # 0.0
print(min_idx.numpy())                     # [0 0 0]
print(close, exact)                        # True True
print(broadcasted_shape)                    # (3, 4)
print(broadcasted_x.shape, broadcasted_row.shape)  # Shape([3, 4]) Shape([3, 4])
print(row.shape)                           # Shape([1, 3])
print(grid_x.shape, grid_y.shape)           # Shape([3, 2]) Shape([3, 2])

Neural Networks

from minitensor import nn

# Layers
dense = nn.DenseLayer(10, 5)        # Dense layer (fully connected)
conv = nn.Conv2d(3, 16, 3)          # 2D convolution
bn = nn.BatchNorm1d(128)            # Batch normalization
dropout = nn.Dropout(0.5)           # Dropout regularization

# Activations
relu = nn.ReLU()                    # ReLU activation
sigmoid = nn.Sigmoid()              # Sigmoid activation
tanh = nn.Tanh()                    # Tanh activation
gelu = nn.GELU()                    # GELU activation

# Loss functions
mse = nn.MSELoss()                  # Mean squared error
ce = nn.CrossEntropyLoss()          # Cross entropy
bce = nn.BCELoss()                  # Binary cross entropy

print(type(dense).__name__, type(conv).__name__, type(relu).__name__, type(ce).__name__)
DenseLayer Conv2d ReLU CrossEntropyLoss

Optimizers

from minitensor import nn, optim

# Optimizers
model = nn.DenseLayer(10, 5)
params = model.parameters()

sgd = optim.SGD(params, lr=0.01, momentum=0.9, weight_decay=0.0, nesterov=False)
adam = optim.Adam(params, lr=0.001, betas=(0.9, 0.999), epsilon=1e-8, weight_decay=0.0)
adamw = optim.AdamW(params, lr=0.001, betas=(0.9, 0.999), epsilon=1e-8, weight_decay=0.01)
rmsprop = optim.RMSprop(params, lr=0.01, alpha=0.99, epsilon=1e-8, weight_decay=0.0, momentum=0.0)

print(type(sgd).__name__, type(adam).__name__, type(adamw).__name__, type(rmsprop).__name__)
SGD Adam AdamW RMSprop

Architecture

Minitensor is built with a modular architecture:

┌─────────────────┐    ┌──────────────────┐    ┌─────────────────┐
│   Python API    │    │   PyO3 Bindings  │    │   Rust Engine   │
│                 │<-->│                  │<-->│                 │
│ • Tensor        │    │ • Type Safety    │    │ • Performance   │
│ • nn.Module     │    │ • Memory Mgmt    │    │ • Autograd      │
│ • Optimizers    │    │ • Error Handling │    │ • SIMD/GPU      │
└─────────────────┘    └──────────────────┘    └─────────────────┘

Components

  • Engine: High-performance Rust backend with SIMD optimizations
  • Bindings: PyO3-based Python bindings for seamless interop
  • Python API: Familiar PyTorch-like interface for ease of use

Examples

Simple Neural Network

import minitensor as mt
from minitensor import nn, optim

# Create a simple classifier
model = nn.Sequential([
    nn.DenseLayer(784, 128),
    nn.ReLU(),
    nn.DenseLayer(128, 10),
])

# Initialize model
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001, betas=(0.9, 0.999), epsilon=1e-8)

print(type(model).__name__, type(optimizer).__name__)
Sequential Adam

Training Loop

import minitensor as mt
from minitensor import nn, optim

# Synthetic data: y = 3x + 0.5 + noise
mt.manual_seed(7)
x = mt.randn(256, 1)
noise = 0.1 * mt.randn(256, 1)
y = 3 * x + 0.5 + noise

# Model, loss, optimizer
model = nn.DenseLayer(1, 1)
criterion = nn.MSELoss()
optimizer = optim.SGD(model.parameters(), lr=0.05)

for epoch in range(100):
    pred = model(x)
    loss = criterion(pred, y)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    if (epoch + 1) % 20 == 0:
        loss_val = float(loss.numpy().ravel()[0])
        w = float(model.weight.numpy().ravel()[0])
        b = float(model.bias.numpy().ravel()[0])
        print(f"Epoch {epoch+1:03d} | Loss: {loss_val:.4f} | w: {w:.3f} | b: {b:.3f}")
Epoch 020 | Loss: 0.2520 | w: 2.545 | b: 0.407
Epoch 040 | Loss: 0.0150 | w: 2.934 | b: 0.485
Epoch 060 | Loss: 0.0103 | w: 2.988 | b: 0.498
Epoch 080 | Loss: 0.0102 | w: 2.995 | b: 0.500
Epoch 100 | Loss: 0.0102 | w: 2.996 | b: 0.501

Development & Testing

The Python package is a thin wrapper around the compiled Rust engine, so native and Python changes should be validated in a deterministic order. See the development guide and installation guide for full setup and troubleshooting details.

# 1) One-time contributor setup (installs dev tooling + editable release extension)
python -m pip install -e '.[dev]'
pre-commit install

# 2) Rebuild the extension after changes under engine/ or bindings/
python -m pip install -e .

# 3) Run Rust unit/integration tests
cargo test --workspace --all-targets

# 4) Run Python tests with warnings treated as errors by project config
python -m pytest

# 5) Run formatting/lint hooks
pre-commit run --all-files

Notes:

  • Use python -m pip so installs target the same interpreter used for python -m pytest.
  • The dev extra installs black[jupyter], matching the pre-commit Black hook and avoiding missing-Jupyter warnings when checking notebooks.
  • Step 2 is only required when Rust or PyO3 bindings changed; pure-Python/docs edits can skip it.
  • Keep Step 1 as one-time setup unless dev dependencies change.

Code Style

  • Rust: Follow rustfmt and clippy recommendations
  • Python: Use black[jupyter] and isort for formatting Python files and notebooks

Performance

Minitensor is designed for performance:

  • Memory Efficient: Zero-copy operations where possible
  • SIMD Optimized: Vectorized operations for maximum throughput
  • Parallel: Multi-threaded operations for large tensors

Citation

If you use minitensor in your work and wish to refer to it, please use the following BibTeX entry.

@misc{sarkar2026minitensorlightweighthighperformancetensor,
      title={MiniTensor: A Lightweight, High-Performance Tensor Operations Library},
      author={Soumyadip Sarkar},
      year={2026},
      eprint={2602.00125},
      archivePrefix={arXiv},
      primaryClass={cs.LG},
      url={https://arxiv.org/abs/2602.00125},
}

License

This project is licensed under the Apache License - see the LICENSE file for details.

Acknowledgments

Metadata

Release files for minitensor 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for minitensor 0.2.0
File Size Uploaded
minitensor-0.2.0.tar.gz 368.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for minitensor 0.2.0
File Interpreter ABI Platform
minitensor-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl CPython 3.13 CPython 3.13 Linux glibc 2.17+ x86-64 Details

Total release size: 3.6 MB

Release files / minitensor-0.2.0.tar.gz

Download URL minitensor-0.2.0.tar.gz
Size 368.3 kB
Tags Source
SHA-256 checksum
How to use checksums
d27dc095ecab9f4e928baef1bb567849d3b1e07ef43f99884b151607f632e6b4
BLAKE2b-256 checksum
How to use checksums
a4c03b2b2653ab48ca0b902ebbebfcab0f45ef027c7c5c9c1028a3b1203f4961
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release files / minitensor-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl

Download URL minitensor-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Size 3.3 MB
Tags CPython 3.13 Linux glibc 2.17+ x86-64
SHA-256 checksum
How to use checksums
be4c145d77241164a3dc775e3a8d5357a170598e2defa0db56fb04d51be9e35b
BLAKE2b-256 checksum
How to use checksums
a8008c718d205f624eac689e09408d4a7ef641f2a895ab87b18ea40a0a7ee3a9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.9

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page