nicksenger/glowstick

Type-level tensor shapes in Rust

Rust

73

152 commits

updated Sep 8, 2026

See the code

README

glowstick

This crate makes working with tensors in Rust safe, easy, and fun by tracking their shapes in the type system!

Example usage with candle:

use candle::{DType, Device};
use glowstick::{assert_shape_type_eq, num::{U1, U2}, Shape2};
use glowstick_candle::Tensor;

let a: Tensor<Shape2<U2, U1>> = Tensor::zeros(DType::F32, &Device::Cpu).expect("tensor A");
let b: Tensor<Shape2<U1, U2>> = Tensor::zeros(DType::F32, &Device::Cpu).expect("tensor B");
let c = a.matmul(&b).expect("matmul");
assert_shape_type_eq!(c, Shape2<U2, U2>);

Several operations are available:

use candle::{DType, Device};
use glowstick::{assert_shape_type_eq, num::{U0, U1, U8, U64}, Shape1, Shape2};
use glowstick_candle::Tensor;

let my_tensor: Tensor<Shape2<U8, U8>> = Tensor::zeros(DType::F32, &Device::Cpu).expect("tensor");
let reshaped: Tensor<Shape1<U64>> = my_tensor.reshape().expect("reshape");
let unsqueezed = reshaped.unsqueeze::<U0>().expect("unsqueeze");
assert_shape_type_eq!(unsqueezed, Shape2<U1, U64>);
assert_eq!(unsqueezed.inner().dims(), &[1, 64]);

For examples of more extensive usage and integration with popular Rust ML frameworks like candle and Burn, check out the examples directory.

The project is currently pre-1.0: breaking changes will be made!

Features

  • Express tensor shapes as types
  • Support for dynamic dimensions (gradual typing)
  • Human-readable error messages (sort of)

Contributors

nicksenger

35 commits

nicksenger/glowstick

Type-level tensor shapes in Rust

Rust

73

152 commits

updated Sep 8, 2026

See the code

README

glowstick

This crate makes working with tensors in Rust safe, easy, and fun by tracking their shapes in the type system!

Example usage with candle:

use candle::{DType, Device};
use glowstick::{assert_shape_type_eq, num::{U1, U2}, Shape2};
use glowstick_candle::Tensor;

let a: Tensor<Shape2<U2, U1>> = Tensor::zeros(DType::F32, &Device::Cpu).expect("tensor A");
let b: Tensor<Shape2<U1, U2>> = Tensor::zeros(DType::F32, &Device::Cpu).expect("tensor B");
let c = a.matmul(&b).expect("matmul");
assert_shape_type_eq!(c, Shape2<U2, U2>);

Several operations are available:

use candle::{DType, Device};
use glowstick::{assert_shape_type_eq, num::{U0, U1, U8, U64}, Shape1, Shape2};
use glowstick_candle::Tensor;

let my_tensor: Tensor<Shape2<U8, U8>> = Tensor::zeros(DType::F32, &Device::Cpu).expect("tensor");
let reshaped: Tensor<Shape1<U64>> = my_tensor.reshape().expect("reshape");
let unsqueezed = reshaped.unsqueeze::<U0>().expect("unsqueeze");
assert_shape_type_eq!(unsqueezed, Shape2<U1, U64>);
assert_eq!(unsqueezed.inner().dims(), &[1, 64]);

For examples of more extensive usage and integration with popular Rust ML frameworks like candle and Burn, check out the examples directory.

The project is currently pre-1.0: breaking changes will be made!

Features

  • Express tensor shapes as types
  • Support for dynamic dimensions (gradual typing)
  • Human-readable error messages (sort of)

Contributors

nicksenger

35 commits

Languages

Rust

100.0%