English · Español
Lab 00 — Value skeleton¶
Goal: write the
Valueclass skeleton: constructor, repr, the_prev/_op/_backwardplumbing, and thebackward()traversal. No ops yet. This lab makes the topology explicit before any math runs.Estimated time: 90–120 minutes.
Prereqs: read
theory/00..04. Phase 6 utilities exist.
What you produce¶
src/minigrad/scalar.pycontaining theValueclass skeleton:__init__(self, data: float, _prev: tuple = (), _op: str = "") -> None__repr__data: float,grad: float,_prev: tuple[Value, ...],_op: str,_backward: Callable[[], None]backward(self) -> None— topological sort + reverse traversalsrc/minigrad/scalar/BLUEPRINT.md— already pre-written by Claude. Read it now. Open it in a split withscalar.py.tests/test_scalar_skeleton.py— three tests that pass even with no ops implemented:Value(2.5).data == 2.5repr(Value(2.5))contains "2.5"Value(2.5).backward()runs without error and setsgradto 1.0- No
experiments/directory yet — labs 01 and 02 produce experiments.
TODOs¶
Block A — read BLUEPRINT first¶
- Open
src/minigrad/scalar/BLUEPRINT.md. Read the "API surface" and "anti-goals" sections fully. Disagreements? Flag them in your/phase-checkpoint; do not silently diverge.
Block B — class skeleton¶
- Create
src/minigrad/__init__.py(empty or with__all__ = ["Value"]after step C). - Create
src/minigrad/scalar.py. Add theValueclass. - Constructor takes
data: float,_prev: tuple[Value, ...] = (),_op: str = "". Initializeself.data = float(data),self.grad = 0.0,self._prev = _prev,self._op = _op,self._backward = lambda: None. -
__repr__returnsf"Value(data={self.data:.4f}, grad={self.grad:.4f})"or similar — your call, but make it informative. - Add type hints on all attributes and methods.
mypy --strictmust pass. - No ops yet. Resist the temptation.
Block C — backward()¶
- Implement
backward(self): - Build the topo order. Use a recursive helper or an iterative stack — your call. Doc the choice.
- Set
self.grad = 1.0(seed). - Walk reversed topo, calling
v._backward()for eachv. - Defensive: assert
self._backward is callable. (It always is, but the assertion documents the invariant.) - Decide and document: does
backward()reset gradients first, or assume the caller has zeroed them? Phase 7 default: does NOT reset. The caller (Phase 9's optimizer eventually) is responsible forzero_grad(). Note this in the docstring.
Block D — type and lint¶
-
mypy --strict src/minigrad/scalar.py— green. -
ruff check src/minigrad/scalar.py— green. -
ruff format src/minigrad/scalar.py— applied.
Block E — skeleton tests¶
-
tests/test_scalar_skeleton.py:
Constraints¶
- No NumPy.
scalar.pyoperates on Pythonfloatonly.import mathis allowed forexp,log,tanhin later labs. - No PyTorch in
src/. PyTorch is a test-only dep. Callable[[], None]is the right type for_backward. Usefrom collections.abc import Callable._prevas a tuple, not a list. Tuples are hashable and signal "fixed at construction".- No mutation of
_prevafter construction. Make it_prev: tuple[Value, ...](immutable).
Stop conditions¶
Done when:
mypy --strictandruffboth green onscalar.py.- All three skeleton tests pass.
- You can
from minigrad.scalar import Valuein a Python shell and instantiateValue(2.0).
Pitfalls¶
- Forward reference for type hint.
_prev: tuple["Value", ...](string-quoted) because the class is mid-definition when the annotation is read. Or usefrom __future__ import annotationsat the top of the file. - Mutable default argument. Don't write
_prev: tuple = ()and then mutate it. Tuples are immutable so this is fine, but if you accidentally make it alist, you've made the Python "default mutable arg" bug. self.grad: float = 0.0. Use0.0, not0. Otherwise NumPy/Python int promotion could surprise you in tests.- Topo sort recursion depth. Python's default recursion limit is ~1000. For Phase 7 graphs (tens of nodes), no problem. Phase 18+ training loops will need an iterative topo sort or
sys.setrecursionlimit(...). Document but don't optimize yet.
When to consult solutions/¶
After all three skeleton tests pass. Then solutions/00-value-skeleton-ref.md (at phase open) shows the reference structure and any style choices to consider before lab 01.
Next lab: lab/01-implement-ops.md.