Installation
StableTested and in active use. Breaking changes will be called out.
noeira uses pixi for dependency management. pixi installs the Mojo compiler, the MAX runtime, the native libraries the I/O layer links (libcurl, libhdf5, qhull, ffmpeg), the Python packages used as reference oracles, and the CUDA toolchain where relevant. You do not install Mojo separately.
Requirements
Section titled “Requirements”| Platforms | linux-64 (CUDA 12) · linux-aarch64 (CUDA 12, Jetson Orin) · osx-arm64 (macOS 15.0+) |
| Toolchain | Mojo 1.1.0 and MAX 26.6.0, pinned exactly in pixi.toml |
| Python | 3.13 (the environments pin it; see below) |
| GPU (optional) | NVIDIA via CUDA, Apple Silicon via Metal, Jetson Orin via JetPack’s CUDA |
| Rendering (optional) | SDL3 — installed by pixi, not needed for training |
1. Install pixi
Section titled “1. Install pixi”# macOS / Linuxcurl -fsSL https://pixi.sh/install.sh | bash
# or with Homebrewbrew install pixi2. Clone and install
Section titled “2. Clone and install”git clone https://github.com/noeira/noeira.gitcd noeirapixi installThe first solve downloads the full dependency set and takes a while. Subsequent commands reuse the cached environment.
3. Run something
Section titled “3. Run something”Every command runs from the repository root, and the -I . flag puts the
repository on Mojo’s module search path. Without it, import noeira fails.
pixi run mojo run -I . examples/solve_gridworld.mojoIf that prints Q-Learning, SARSA and SARSA(λ) training progress and a rendered grid, you are set. Walk through what it does in Quickstart: tabular.
Choosing an environment
Section titled “Choosing an environment”pixi.toml declares six named environments plus default. They differ in the
packages they install and in their activation scripts, not in the Mojo source
they build.
| Environment | For | What it adds |
|---|---|---|
default | whatever pixi run picks with no -e | the nvidia feature — not a CPU-only environment |
nvidia | Linux x86-64 with an NVIDIA GPU | cuda-toolkit 12.9, cudnn, cuda-gdb, nsight-compute; points MAX at the system ptxas and preloads the CUDA interceptor |
jetson | Jetson Orin (linux-aarch64, sm_87) | no CUDA packages at all — uses the CUDA that JetPack installed in /usr/local/cuda; adds run-jetson / build-jetson |
apple | Apple Silicon (Metal) | nothing beyond the base set |
amd | AMD GPUs | nothing beyond the base set; no AMD-specific tasks exist yet |
cpu | CI and headless runs | the Python pin, without the CUDA toolchain |
act-ref | reference gates only | PyTorch, torchvision, safetensors, transformers |
Pick the environment with -e:
pixi run -e apple mojo run -I . examples/half_cheetah/sac_half_cheetah_training_gpu.mojopixi run -e nvidia mojo run -I . examples/half_cheetah/sac_half_cheetah_training_gpu.mojoA few things are worth knowing about these:
defaultisnvidia. On a Mac, pass-e applefor anything that touches the GPU; plainpixi runstill works for CPU examples.- The
nvidiaenvironment expects a CUDA install at/usr/local/cuda. Its activation setsMODULAR_NVPTX_COMPILER_PATH=/usr/local/cuda/bin/ptxas, bypassing the PTX compiler bundled with MAX (which is tied to CUDA 13 and a driver ≥ 580). A CUDA 12.x or 13.x container on driver ≥ 570 works. The activation also builds and preloadsnoeira/cuda/cuda_intercept.c, which the legacy CUDA-graph path needs (see CPU and GPU paths). cpuexists so CI runners do not pull gigabytes ofcuda-toolkitandcudnnthey will never use.act-refis for dumping reference activations from PyTorch and HuggingFace implementations. Nothing undernoeira/imports torch; this environment only exists so the ports can be checked against someone else’s code.
Python 3.13
Section titled “Python 3.13”The base dependency set allows Python 3.12 or 3.13, but every environment’s
activation sets MOJO_PYTHON_LIBRARY to libpython3.13 in the active
environment, and the nvidia, jetson and cpu features pin
python >=3.13.14,<3.14 to match. The training path no longer imports Python —
metrics go out over native HTTP — but the Gymnasium wrappers and a few
reference tools still use Mojo’s Python interop.
Jetson Orin
Section titled “Jetson Orin”The Orin needs --target-accelerator sm_87 on every compile: MAX picks the
kernel target by asking NVML, Tegra’s NVML answers wrongly, and a binary built
for the wrong target is refused by the driver at the first kernel load. The
jetson environment wraps the flag in two tasks, and its activation preloads
the same CUDA interceptor as nvidia, which on a Tegra board also answers
NVML’s device queries from CUDA so MAX can find the integrated GPU at all:
pixi run -e jetson run-jetson examples/nn/mlp/mlp_mnist_training_storage_gpu.mojopixi run -e jetson build-jetson -o /tmp/out examples/nn/mlp/mlp_mnist_training_storage_gpu.mojoBoard setup and deployment are covered on the Jetson Orin page.
Native shims
Section titled “Native shims”A few C libraries cannot be called directly from Mojo’s FFI — mostly because
their entry points are C-variadic (ioctl, curl_easy_setopt) or C++-only
(OpenCV, Dear ImGui). Each is wrapped by a small shim you build once. None of
the built libraries is tracked in git, so a fresh checkout has to build the ones
its features use.
| Task | Wraps | Needed for |
|---|---|---|
pixi run build-http | libcurl (+ zlib) for noeira/io/http.mojo | every network call: RemoteLogger, noeira cloud (projects, datasets, asset packs), the HuggingFace downloader, the MNIST and TinyShakespeare loaders |
pixi run build-qhull | qhull for noeira/physics3d/collision/ | any model with mesh geoms |
pixi run build-serial | ioctl for noeira/io/serial/ | the SO-101 servo bus — anything under noeira/robot/ |
pixi run build-opencv | OpenCV (C++) for noeira/vision/opencv/ | camera capture |
pixi run build-imgui | Dear ImGui (cloned into third_party/ on first run) | the ImGui viewers under noeira/render/imgui/ |
Tasks that need a shim declare it, so for those pixi builds it first. For
example, soarm-record depends on build-serial and build-opencv,
camera-studio on build-imgui and build-opencv, and soarm-tower-viewer
on build-imgui. Nothing declares build-http or build-qhull: run those by
hand before the first training run that logs remotely or the first mesh model.
Optional extras
Section titled “Optional extras”SDL3 — for on-screen rendering
Section titled “SDL3 — for on-screen rendering”Required to open a window: environment renderers, the 3D viewer, the ImGui
tools. Not required for training. Video encoding goes through ffmpeg.
Nothing to install. pixi install brings SDL3 — the library and its
headers — into the environment on macOS and Linux alike, and noeira loads it
from there. A system SDL3 is neither needed nor used. That matters on Ubuntu
24.04 LTS, which ships no SDL3 package: libsdl3-dev only exists from Ubuntu
25.04 and Debian 13.
On a headless machine SDL3 is installed but has no display to open a window on: training runs, the viewers need a desktop session or X forwarding.
To use a different build of SDL3, point SDL3_LIB at it:
SDL3_LIB=/path/to/libSDL3.so pixi run mojo run -I . examples/cartpole/cartpole_demo.mojoAtari ROMs — for the 2600 emulator
Section titled “Atari ROMs — for the 2600 emulator”ale-py ships without ROMs. This task downloads the canonical Farama bundle and
symlinks roms/:
pixi run setup-romsOnly needed for the Atari 2600 emulator. The native arcade engines (Pong, Breakout, Space Invaders) are independent of it and need no ROMs.
Useful tasks
Section titled “Useful tasks”pixi run test-smoke # fast curated CPU test tier (what CI runs)pixi run test-cpu # every non-GPU test — takes hourspixi run -e apple test-gpu # GPU tests on Metalpixi run -e nvidia test-gpu # GPU tests on CUDABuilding against a precompiled package
Section titled “Building against a precompiled package”Every mojo run from source pays a per-build import cost that grows with the
symbols a driver references. When you are iterating on a driver, a config or an
example rather than on noeira/ itself, build the package once and compile
against it:
pixi run build-pkg # precompile noeira into build/pkg/ (~3 min)pixi run run-pkg examples/cartpole/cartpole_dqn_training.mojo # build against it, then runpixi run compile-pkg examples/cartpole/cartpole_dqn_training.mojo -o /tmp/dqnOn the SAC HalfCheetah driver this took a warm rebuild from 38 s to 8 s. The
wrapper (scripts/pkg.sh) compiles from inside build/pkg/, because the
source tree shadows the package whenever the working directory contains
noeira/, and it runs the binary from the repository root so the shims and
assets resolve. run-pkg warns when files under noeira/ are newer than the
package — rebuild it then.
Troubleshooting
Section titled “Troubleshooting”- Quickstart: tabular — train Q-Learning on GridWorld
- Quickstart: GPU training — SAC on HalfCheetah
- The stack — what you just installed