Skip to content

Repository files navigation

xgboost

Racket bindings for XGBoost.

The default API is high level:

#lang racket

(require xgboost)

(define dtrain
  (make-dmatrix '((1.0 2.0 0.5)
                  (2.0 1.0 1.5)
                  (3.0 0.5 0.0)
                  (0.5 3.0 2.0))
                #:labels '(3.5 3.5 6.5 2.0)))

(define booster
  (train dtrain
         #:objective "reg:squarederror"
         #:max-depth 2
         #:eta 0.2
         #:verbosity 0
         #:rounds 10))

(predict booster dtrain)

Use (require xgboost/foreign) for the contracted low-level DMatrix/Booster wrappers, and (require xgboost/foreign/raw) for direct C FFI bindings.

Installation

raco pkg install xgboost

The package ships a prebuilt native library and picks the right one for your platform at install time. On Linux it prefers a CUDA-enabled build when one is available and falls back to the CPU build otherwise.

Development

Development uses Nix, which provides a reproducible toolchain (Racket, CMake, the XGBoost C++ library, and the linters).

nix develop

Inside the dev shell, build and test the C++ library:

cmake -S cpp -B cpp/build -G Ninja -DBUILD_TESTING=ON
cmake --build cpp/build
ctest --test-dir cpp/build --output-on-failure

Run the Racket tests:

raco test xgboost/
raco test xgboost/examples/test/                       # the example harnesses
racket xgboost/examples/test/01-train-regression.rkt   # run one example's output

nix build runs both the package tests and the example harnesses under xgboost/examples/test/. Each xgboost/examples/NN-name.rkt is a literate scribble/lp2 program woven into the docs; its runner and checks live in the matching xgboost/examples/test/NN-name.rkt.

Every new public API or user-visible feature should land with an example-backed E2E test unless that is impractical for runtime, platform, or dependency reasons.

Building the native library locally

scripts/build-so.sh builds libxgbcompat plus its bundled dependencies and stages them under xgboost/native-libs/candidates/<platform>/, so a plain raco pkg install works afterwards without Nix. Run it from inside nix develop:

./scripts/build-so.sh darwin        # macOS (CPU)         → candidates/darwin/
./scripts/build-so.sh linux         # Linux CPU           → candidates/linux-cpu/
./scripts/build-so.sh linux-cuda    # Linux CUDA (x86_64) → candidates/linux-cuda/

# Then install from the local checkout:
raco pkg install --name xgboost ./xgboost

Linters

The dev shell provisions Resyntax (refactoring suggestions) and racket-review (surface-level style/correctness checks):

resyntax analyze --directory xgboost     # report suggestions
resyntax fix --directory xgboost         # apply them in place
raco review xgboost/**/*.rkt             # surface-level lint

The Nix checks CI workflow runs resyntax analyze as a gate, so run resyntax fix before pushing.

Layout

  • cpp/ - C++ wrapper library (libxgbcompat) built with CMake, links against pkgs.xgboost.
  • xgboost/examples/ - runnable examples bundled with the package; selected fast RackUnit-backed examples run by default checks. See xgboost/examples/README.md for an indexed tour mapped to the upstream demos and tutorials.
  • xgboost/main.rkt - high-level root API for (require xgboost).
  • xgboost/foreign.rkt - contracted low-level Racket wrappers.
  • xgboost/foreign/raw.rkt - direct C FFI bindings.
  • xgboost/private/ - native library installer implementation.
  • flake.nix - cpp and racket derivations.

See AGENTS.md for architecture notes and the full set of build/test commands.