Skip to content

SwiftProjectOrganization/Stan

Repository files navigation

A MacOSv26/Xcode/Swift based CLI for Stan programs.

Project Status

Purpose

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!).

Supported functionality

The initial set of cmdstan methods supported is:

  1. Compile a Stan model.
  2. Sample from a compiled model and extract the samples in a clean "<model>.samples.csv" file.
  3. 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'.
  4. Run Stan's optimize method and collect the results in a clean "<model>.optimize.csv" file.
  5. Run Stan's pathfinder method. The result is written to the "<model>.pathfinder.csv" file.

Working environment

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").

Prerequisites

Downloading the repository

To get going, start Xcode and:

  1. Click on 'Integrate'.
  2. Select 'Clone'.
  3. Enter the http address for this repository: "https://github.com/SwiftProjectOrganization/Stan".
  4. Click 'Clone'.

The repository will be downloaded and the project will open in Xcode.

Setup

  1. 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.

  2. By default it expects all Stan models and associated "<model>.data.json" files to be in a subdirectory of the "~/Documents" directory.

  3. Below usage examples use the bernoulli example provided in the installation cmdstan folder.

  4. 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.

  5. 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.

Usage

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

  1. '<model>' is used twice, once as a subdirectory path component and once in the input and output file names.

  2. '<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.

Extracting the "stan" binary (from Xcode's build environment)

To copy the "stan" binary from the Xcode build directory to the "~/Documents/Stan" directory, after the initial build, it can be found here:

  1. Click on 'Library' in your home folder.
  2. Click on 'Developer'.
  3. Click on 'Xcode/DerivedData'.
  4. Click on 'Stan_xxxxxxx'.
  5. Click on 'Build'.
  6. Click on 'Products'.
  7. 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.

A few help screens

In these example, I have used the shell interface.

Help (top level))


  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.

Compile


  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.

Sample


  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).

Optimize, pathfinder and stansummary.

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.

Test all commands

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.

To do

  1. Test the setup based on "~/Documents" in project SwiftStats.
  2. With this setup, is it possible (and useful) to run cmdstan on a separate server?
  3. Fix dependency of stansummary on 4 output files.
  4. ...

References

  1. Stan
  2. cmdstan
  3. SwiftStats
  4. StatKit

About

Swift CLI wrapper for Stan's cmdstan

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages