S-exp GPU
All pages
Docs · The run fileMarkdown

Modules and require

Every file is a module with its own scope. require imports named definitions from a standard module compiled into the binary or from a file next to yours.

(require "sexpgpu/nn" cross-entropy gpt)       ; a standard module
(require "sexpgpu/optim" adamw warmup-stable-decay)
(require "../lib/mine.sx" my-gpt)              ; a file, relative to this one

Resolution

pathresolves to
sexpgpu/nn, sexpgpu/optimthe standard modules; see nn and optim. Anything else under sexpgpu/ is E-EVAL-033
./name.sx, ../dir/name.sxa file, relative to the directory of the file holding the require, never to a project root or the working directory
anything elseE-EVAL-032: a path must start with ./ or ../

A file is loaded once per compilation, by canonical path. A cycle is E-EVAL-030, a missing file E-EVAL-031. Because paths are relative to the file, every command works from any working directory.

Scope

A file sees three things: the prelude, what it defines, and the names its requires list. It sees nothing a library required in turn.

  • Every top-level definition of a file can be imported; there is no export list. Generated top-level definitions (from a macro) can be imported too.
  • A require names at least one definition. Naming something the file does not define is E-EVAL-035, and the fix is the nearest name it does.
  • A name is bound once per file. Two imports of one name from different modules, or an import and a local definition, are E-EVAL-036.
  • Imported names are not re-exported.
  • require runs at module top level, including inside a top-level progn or a macro expansion. In a local scope it is E-EVAL-034.
  • Import a name before writing a function or quoted datum that uses its identity; imports do not rewrite symbols already constructed. See macros.

A library macro's expansion keeps the library's symbol identities, so it can call the library's private helpers without the caller importing them. See macros and symbols.

Writing a library

A library is a plain .sx file that your runs require. It can hold models, schedules and constants shared by several runs, and it can require sexpgpu/nn for the generic parts:

;;; lib/mine.sx
(require "sexpgpu/nn" rmsnorm linear)

(defvar init-std 0.02)

(defmodel my-gpt (&key vocab layers dim) ...)

A library can also carry diagnostics for its models, off until a run selects them; see writing diagnostics.

A bundle flattens every required file into files/deps/ and rewrites the paths; see bundle.

Related: the run file, the prelude.