# Rbm A C++11 library and set of executables implementing Restricted Boltzmann Machines (RBMs), stacked into deep belief networks (`DeepStack`) or recurrent structures (`RnnStack`) for character-level text generation ("poet"). Three build targets share the same core sources: a JUCE-based desktop GUI, a project test suite, and a text-generation CLI. See `CLAUDE.md` for the full architecture writeup (core RBM/Layer/Stack hierarchy, entry points, project file format) and `docs/RNN_ARCHITECTURE.md` for how the RNN text-generation stack works specifically. ## Dependencies System-installed, not vendored: - **Armadillo** (`libarmadillo`) — all matrix/vector math. - **JsonCpp** (`libjsoncpp`) — project files (`*.prj`) serialize to/from JSON. - **JUCE** (vendored under `juce/`, only needed for the GUI target) plus its Linux deps: freetype, X11, Xinerama, Xext, GL, pthread, dl, rt. ## Build The build system is a hand-written `Makefile` (no CMake). Select the target with `PRJ` and the build flavor with `CONFIG`: ```sh make PRJ=POET CONFIG=release # builds build/release/poet.elf (default: PRJ=POET, CONFIG=release) make PRJ=TEST CONFIG=debug # builds build/debug/test.elf make PRJ=GUI # builds build/release/rbm.elf, also builds the JUCE static lib first make clean # removes build/${CONFIG} (respects CONFIG, defaults to release) make install # copies build/release/rbm.elf to ${HOME}/bin ``` Running `make` with no arguments builds `POET` in `release`. Object/dependency files land in `build/${CONFIG}/`; `.d` files are auto-included, so incremental rebuilds correctly pick up header changes. All three targets (`POET`/`TEST`/`GUI`) × both configs (`release`/`debug`) have been verified to build cleanly from a fresh `make clean`. ### Running each target ```sh # Text generation ("poet") -- loads prj/poet_2v_5s/ by default ./build/release/poet.elf c # create a fresh project ./build/release/poet.elf r # reset (randomize) weights ./build/release/poet.elf t some_text.txt # train on a text file ./build/release/poet.elf f "seed text" 0.7 # generate text from a seed, optional sampling temperature # (temperature <= 0 or omitted = deterministic greedy decode) # Project test suite -- checks every project listed in main.cpp's `projects` vector ./build/release/test.elf # Desktop GUI -- must be run from the repo root (resolves prj// paths relative to cwd) ./build/release/rbm.elf ``` ## GPU acceleration (optional) `run_gpu.sh` runs any built binary with NVBLAS (configured via `nvblas.conf`), which transparently intercepts Armadillo's large matrix-multiply BLAS calls (`v_to_h`, `h_to_v`, CD gradients) and offloads them to an NVIDIA GPU via cuBLAS, falling back to the system's CPU BLAS otherwise. This is a runtime `LD_PRELOAD` shim — **no source changes**, and it's opt-in only (nothing changes if you just run the binary directly): ```sh ./run_gpu.sh ./build/release/poet.elf t some_text.txt ./run_gpu.sh ./build/release/rbm.elf ``` Requires an NVIDIA GPU and the CUDA runtime's `libnvblas.so`. Verified on this machine (RTX 4070 Ti): output is byte-identical to a plain CPU run, and GPU utilization/memory visibly rise during training. Practical speedup depends on matrix size — most projects in `prj/` are fairly small (hundreds of rows, ~100-200 cols), so the benefit is real but modest compared to larger workloads like `mnist`/`many`. ## Project files Named projects (e.g. `mnist`, `poet_2v_5s`, `context99` — see `prj/`) each live under `prj//` as a `.prj` JSON file plus per-layer weight/bias `.dat` files and a `.training.dat` batch matrix. These are experiment data and generated artifacts, not something to hand-edit — see `CLAUDE.md` for the exact file layout and how paths get resolved.