glowstick
This is crate makes working with tensors in Rust safe, easy, and fun by tracking their shapes in the type system!
Example usage with candle:
use ;
use ;
use ;
let a: = zeros.expect;
let b: = zeros.expect;
let c = matmul!.expect;
//debug_tensor!(c); // Compile error: [glowstick shape]: (RANK<_2>, (DIM<_2>, DIM<_2>))
Several operations are available:
use ;
use ;
use ;
use debug_tensor;
let my_tensor: = zeros.expect;
//debug_tensor!(my_tensor); // Compile error: [glowstick shape]: (RANK<_2>, (DIM<_8>, DIM<_8>))
let reshaped = reshape!.expect;
//debug_tensor!(reshaped); // [glowstick shape]: (RANK<_1>, (DIM<_64>))
let unsqueezed = unsqueeze!.expect;
//debug_tensor!(unsqueezed); // [glowstick shape]: (RANK<_3>, (DIM<_1>, DIM<_64>, DIM<_1>))
let squeezed = squeeze!.expect;
//debug_tensor!(squeezed); // [glowstick shape]: (RANK<_1>, (DIM<_64>))
let narrowed = narrow!.expect;
//debug_tensor!(narrowed); // [glowstick shape]: (RANK<_1>, (DIM<_5>))
let expanded = broadcast_add!.expect;
//debug_tensor!(expanded); // [glowstick shape]: (RANK<_4>, (DIM<_2>, DIM<_5>, DIM<_2>, DIM<_5>))
let swapped = transpose!.expect;
//debug_tensor!(swapped); // [glowstick shape]: (RANK<_2>, (DIM<_2>, DIM<_5>, DIM<_5>))
let kernel: = zeros.expect;
let conv = conv2d!.expect;
//debug_tensor!(conv); // [glowstick shape]: (RANK<_4>, (DIM<_2>, DIM<_4>, DIM<_3>, DIM<_3>))
let flattened = flatten!.expect;
//debug_tensor!(swapped); // [glowstick shape]: (RANK<_3>, (DIM<_2>, DIM<_12>, DIM<_3>))
assert_eq!;
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)
- Manually check type-level shapes (
debug_tensor!(_)) - Support for all ONNX operations