diff --git a/CLAUDE.md b/CLAUDE.md index 70ac663..8f843a2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,8 +92,8 @@ behavior change, same output, just optionally GPU-accelerated matrix multiplies. ### Entry points -- **`source/main.cpp`** — `TEST` target; exercises `DeepStack` directly (build/train/save a small DBN, - or load an existing one, depending on `CREATE_TEST`/`TRAIN_TEST` compile-time flags). +- **`source/main.cpp`** — `TEST` target; the project test suite (see "Build" above) — loads each named + project under `prj//` and checks its reconstruction error. - **`source/poet.cpp`** — `POET` target; loads an `RnnStack` project (default `poet_2v_5s`) and dispatches on `argv[1]`: `c`(reate)/`r`(eset weights)/`t`(rain, optionally with a training-text path in `argv[2]`)/ `f`(orward-generate text, optional seed string in `argv[2]`). Training periodically calls back into diff --git a/README.md b/README.md new file mode 100644 index 0000000..a831e9f --- /dev/null +++ b/README.md @@ -0,0 +1,79 @@ +# 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.