| Project Status |
|---|
A MacOSv26/Xcode/Swift based CLI (Command Line Interface) to Stan's cmdstan executable.
This project is still in early stages!!! I can see a million improvements, but wanted to run Stan models for an accompanying project SwiftStats (also work in progress!).
The initial set of cmdstan methods supported is:
- Compile a Stan model.
- Sample from a compiled model and extract the samples in a clean
"<model>.samples.csv"file. - Run the stansummary program on the 4 output files created during sampling and create a proper, combined .csv file (
"<model>.stansummary.csv"). Also by default included in'sample'. - Run Stan's optimize method and collect the results in a clean
"<model>.optimize.csv"file. - Run Stan's pathfinder method. The result is written to the
"<model>.pathfinder.csv"file.
This repository is an Xcode project. For me, after years of using Stan from within R and Julia, running Stan's "cmdstan" in Xcode was a partial goal for this project. Some familiarity with running Xcode and Swift programs on MacOS is assumed.
After an initial build (see "Prerequisites" below), the above 5 methods can be run from within Xcode by specifying input arguments before hitting 'build and run' in Xcode.
Or, if you want to run the CLI from a shell, you can copy the generated "stan" binary to a location of your choice (see below under "Extracting stan").
To get going, start Xcode and:
- Click on
'Integrate'. - Select
'Clone'. - Enter the http address for this repository: "https://github.com/SwiftProjectOrganization/Stan".
- Click
'Clone'.
The repository will be downloaded and the project will open in Xcode.
-
It expects an environment variable
"CMDSTAN"to point to the cmdstan directory, see reference 1 below on how to install cmdstan. Note that you can also define environment variables within Xcode (see step 4). These won't work when running'./stan'from a shell. -
By default it expects all Stan models and associated
"<model>.data.json"files to be in a subdirectory of the"~/Documents"directory. -
Below usage examples use the bernoulli example provided in the installation cmdstan folder.
-
For the examples to work out of the box, there is an
'--install (-I)'flag that will help to bootstrap the initial build and, later on, new Stan projects. -
To initially build and run the project, do the following in Xcode:
4.1. Click on 'Product'.
4.2. Click on 'Scheme'.
4.3. Choose on 'Edit Scheme'.
Here you can specify "Arguments passed on launch" (and also "Environment Variables").
4.4. Under "Arguments passed on launch" type: 'compile -V -I'.
The '-V' flag means verbose, it will produce extra output in the Xcode console.
The '-I' flag activates installing "bootstrap" files needed for an initial 'compile' and 'sample'.
Press 'build and run' and this will create a bernoulli subdirectory in "~/Documents/Stan" and install '"bernoulli.stan"`.
It will compile this Stan model and create a binary "bernoulli" in "~/Documents/Stan/bernoulli/", e.g. as "~/Documents/Stan/bernoulli/bernoulli".
If step 4.4. finishes without problems, continue with:
4.5. Update the "Arguments passed on launch" to 'sample -V -I'.
4.6. Press 'build and run'.
In this case the '-I' will install a suitable "bernoulli.data.json" input file.
Below the help screens for "stan" are shown in more detail.
A typical set of "Arguments passed on launch" looks like:
<command> [-V] ... [--directory <directory>] [--model <model>] [<arguments] ...]
This expects that for 'compile' the "<directory>/<model>" contains at least a "<model>.stan" file and, if the model needs input data, for 'sample' a "<model>.data.json" file.
All created output files will be written to "~/Documents/<directory>/<model>".
In my setup, the SwiftStats project will pick up these files from there.
Note that
-
'<model>'is used twice, once as a subdirectory path component and once in the input and output file names. -
'<directory>'can be a sequence of path elements. Intermediate directories will be created if not present.
The '<arguments>' are passed on to cmdstan, e.g. 'num_chains=4' and 'num_samples=1000' for 'sample' or 'save_iterations=true' for 'optimize', etc.
To copy the "stan" binary from the Xcode build directory to the "~/Documents/Stan" directory, after the initial build, it can be found here:
- Click on
'Library'in your home folder. - Click on
'Developer'. - Click on
'Xcode/DerivedData'. - Click on
'Stan_xxxxxxx'. - Click on
'Build'. - Click on
'Products'. - Click on
'Debug', et voilá, there is the"stan"binary.
I typically move or copy it to "~/Documents/Stan" directory and use a Terminal to run './stan' from there.
In these example, I have used the shell interface.
Stan % ./stan help
OVERVIEW: A wrapper for running Stan's cmdstan.
USAGE: ./stan -h
OPTIONS:
--version, -V Show the version.
--help, -h Show this help information.
SUBCOMMANDS:
compile Compile a Stan model.
sample Sample the compiled Stan model.
optimize Optimize the compiled Stan Model.
pathfinder Pathfinder approximation.
stansummary Run the stansummary program.
test (default) Test the CLI functions.
Stan % ./stan compile -h
OVERVIEW: Compile a Stan model.
USAGE: ./stan compile [--verbose] [--install] [--directory <directory>] [--model <model>] [<values> ...]
ARGUMENTS:
<values> Arguments for the method.
OPTIONS:
-V, --verbose Show the version.
-I, --install Install a <model>.stan file before compiling.
--cmdstan <cmdstan> Location of cmdstan.
--directory <directory> Directory path in "~/Documents".
--model <model> Model name.
--version Show the version of "stan".
-h, --help Show help information.
Stan % ./stan sample -h
OVERVIEW: Sample a Stan model.
USAGE: ./stan sample [--verbose] [--install] [--nosummary] [--directory <directory>] [--model <model>] [<values> ...]
ARGUMENTS:
<values> Arguments for the method.
OPTIONS:
-V, --verbose Show the version.
-I, --install Install a <model>.data.json file before sampling.
-S, --nosummary Don't run stansummary.
--cmdstan <cmdstan> Location of cmdstan.
--directory <directory> Directory path in "~/Documents".
--model <model> Model name.
--version Show the version of "stan".
-h, --help Show help information.
The method 'sample' expects a compiled Stan model to be available. By default it passes 'num_chains=4' and 'num_sample=1000' as default arguments.
After sampling the model, a combined samples file ("<model>.samples.csv") is created.
It will also run 'stansummary' (unless the '-S' flag is specified) and create a clean (no comment lines) "<model>.stansummary.csv" file.
Note: Currently 'stansummary' depends on 'sample' creating 4 output files (num_chains=4).
Replace 'sample' by either 'optimize', 'pathfinder' or 'stansummary'.
Optimize will create a "<model>.optimize.csv" file with the results.
Similarly, 'pathfinder' will create a "<model>.pathfinder.csv" file.
The option to run Stan's 'stansummary' is by default done at the end of sample but can also be run separatedly. It will expect the 4 "<model>_output_[1...4].csv" files. It creates a "<model>.stansummary.csv" file.
In addition to the earlier Stan subcommands (compile, sample, ...), there is a subcommand 'test' which cycles through all regular subcommands using "Stan/Test" as directory and "Bernoulli" as model name. Run the test in a terminal as: $ ./stan.
- Test the setup based on
"~/Documents"in project SwiftStats. - With this setup, is it possible (and useful) to run cmdstan on a separate server?
- Fix dependency of stansummary on 4 output files.
- ...