Skip to main content

kopitiam_tensor/
lib.rs

1//! Kopitiam Runtime: tensor.
2//!
3//! The CPU tensor type and the inference-time op set (matmul, broadcasting
4//! arithmetic, softmax, reductions, normalization, activations, embedding
5//! gather) that every layer of a transformer forward pass is built from,
6//! plus decoders for the `f16`/`bf16`/GGUF-quantized formats model weights
7//! ship in.
8//!
9//! # Scope: Phase 1, inference only
10//!
11//! This crate has no autograd, no gradient tape, and no training ops. That
12//! is a scope decision, not an oversight: the Kopitiam Runtime's stated
13//! purpose (see `docs/ai-decisions/`) is local inference, and every op
14//! here is chosen because a forward pass needs it. Concretely, this means:
15//!
16//! * Every general-purpose op (arithmetic, softmax, reductions,
17//!   normalization, activations, [`Tensor::matmul`]) works on `f32` and
18//!   rejects other dtypes with [`Error::DTypeMismatch`] (see
19//!   [`Tensor::require_dtype`]). The one exception is
20//!   [`Tensor::quantized_matmul`], which computes directly on Q4_0/Q8_0
21//!   weight blocks — see that method's docs for why a fused quantized
22//!   matmul earns an exception to "everything is f32" (memory: a
23//!   dequantized 7B Q4_0 model is ~28GB of `f32` vs ~4GB quantized) and for
24//!   the correctness gate that keeps it honest against the plain
25//!   `to_dtype(F32)` + [`Tensor::matmul`] reference path, which remains
26//!   this crate's default and stays permanently, both as the general
27//!   fallback for every other op and as that oracle.
28//! * There is no backward pass, so there is nothing here resembling a
29//!   `requires_grad` flag or a computation graph — `Tensor` is a plain
30//!   value type.
31//! * [`Tensor::gather_rows`] implements embedding lookup specifically
32//!   (indices select whole rows), not PyTorch's general per-element
33//!   `gather`; see that method's docs for why the general form is out of
34//!   scope.
35//! * There is still no *general* `f32 -> quantized` encoder (no
36//!   `Tensor::to_dtype(DType::Q4_0)`) — see [`Tensor::to_dtype`]'s docs for
37//!   why requantizing weights is a model-export concern out of this
38//!   crate's scope. The quantized module's `quantize_row_q8_0` is a
39//!   narrower thing: an *activation*-only Q8_0 encoder, private to
40//!   [`Tensor::quantized_matmul`]'s implementation, not a public
41//!   `Tensor -> Tensor` conversion.
42//!
43//! # Layering
44//!
45//! This crate depends only on `kopitiam-core` for the shared vocabulary
46//! ([`DType`], [`Shape`], [`Device`], [`Error`]) and re-exports it so
47//! downstream crates (`kopitiam-loader`, `kopitiam-runtime`) need not add
48//! a direct `kopitiam-core` dependency just to name a dtype:
49//!
50//! ```text
51//! kopitiam-runtime -> { kopitiam-loader, kopitiam-tokenizer } -> kopitiam-tensor -> kopitiam-core
52//! ```
53//!
54//! # Module map
55//!
56//! * [`Tensor`] — the shape + strided-view + shared-storage tensor type,
57//!   and every op, split across `tensor/*.rs` by concern (see that
58//!   module's docs for why the split is by Rust module rather than by
59//!   flat file, and how that lets internals stay module-private instead of
60//!   crate-wide `pub(crate)`).
61//! * [`Storage`] — the owned CPU buffer `Tensor` is a view into.
62//! * `half` — `f16`/`bf16` <-> `f32` conversion (re-exported as free
63//!   functions; useful on their own, e.g. for a loader converting a whole
64//!   weight file up front).
65//! * `quant` (private) — GGUF block-quantized format decoders, used only
66//!   through [`Tensor::to_dtype`].
67
68mod half;
69mod quant;
70mod storage;
71mod tensor;
72
73pub use half::{bf16_to_f32, f16_to_f32, f32_to_bf16, f32_to_f16};
74pub use storage::Storage;
75pub use tensor::{has_fused_matmul_kernel, LstmState, Tensor};
76
77// Re-export the runtime's shared vocabulary so downstream crates can depend
78// on `kopitiam-tensor` alone for the common inference-time types, the same
79// way `kopitiam-ontology` types flow through the Semantic Runtime's crates.
80pub use kopitiam_core::{DType, Device, Error, Result, Shape};