Skip to content

Commit

Permalink
Sketch #16
Browse files Browse the repository at this point in the history
  • Loading branch information
wlandau-lilly committed Jan 9, 2024
1 parent f64fcf4 commit 2dc073c
Show file tree
Hide file tree
Showing 22 changed files with 94 additions and 253 deletions.
10 changes: 0 additions & 10 deletions .github/workflows/check-cran.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,19 +33,9 @@ jobs:
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
extra-repositories: 'https://mc-stan.org/r-packages/'
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true

- name: Repos
run: |
cat("\noptions(repos=c(stan='https://mc-stan.org/r-packages/',CRAN ='https://cloud.r-project.org'))\n", file = "~/.Rprofile", append = TRUE)
shell: Rscript {0}

- name: Remove cmdstanr
shell: Rscript {0}
run: try(remove.packages("cmdstanr"), silent = TRUE)

- uses: r-lib/actions/setup-r-dependencies@v2
with:
extra-packages: any::rcmdcheck, local::.
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/check-fixed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ jobs:
- uses: r-lib/actions/setup-r@v2
with:
r-version: ${{ matrix.config.r }}
extra-repositories: 'https://mc-stan.org/r-packages/'
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ jobs:
with:
r-version: ${{ matrix.config.r }}
rtools-version: '42'
extra-repositories: 'https://mc-stan.org/r-packages/'
http-user-agent: ${{ matrix.config.http-user-agent }}
use-public-rspm: true

Expand Down
57 changes: 0 additions & 57 deletions .github/workflows/install-internal.yaml

This file was deleted.

6 changes: 0 additions & 6 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,6 @@ jobs:
- uses: r-lib/actions/setup-r@v2
with:
use-public-rspm: true
extra-repositories: 'https://mc-stan.org/r-packages/'

- name: Repos
run: |
cat("\noptions(repos=c(stan='https://mc-stan.org/r-packages/',CRAN ='https://cloud.r-project.org'))\n", file = "~/.Rprofile", append = TRUE)
shell: Rscript {0}

- uses: r-lib/actions/setup-r-dependencies@v2
with:
Expand Down
17 changes: 4 additions & 13 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,12 @@ Description: Similar to 'rstantools' for 'rstan',
The models compile once during installation,
the executables live inside the file systems of their respective packages,
and users have the full power and convenience of
'cmdstanr' without any additional compilation.
This approach saves time, allows R package developers
to migrate from 'rstan' to the more modern
'cmdstanr', and fits well with centrally maintained
R installations where users have trouble installing
their own packages, diagnosing compilation errors,
and setting environment variables.
'cmdstanr' without any additional compilation after package installation.
This approach saves time and helps R package developers
migrate from 'rstan' to the more modern 'cmdstanr'.
Packages 'rstantools', 'cmdstanr', 'stannis', and
'stanapi' are similar Stan clients with different objectives.
Version: 0.1.0.9000
Version: 0.2.0
License: MIT + file LICENSE
URL: https://wlandau.github.io/instantiate/,
https://github.com/wlandau/instantiate
Expand All @@ -39,16 +35,11 @@ Imports:
rlang,
utils
Suggests:
cmdstanr (>= 0.5.2),
knitr (>= 1.30),
markdown (>= 1.1),
rmarkdown (>= 2.4),
testthat (>= 3.0.0),
withr
Additional_repositories:
https://mc-stan.org/r-packages/
SystemRequirements: CmdStan (https://mc-stan.org/users/interfaces/cmdstan)
StagedInstall: no
Encoding: UTF-8
Language: en-US
Config/testthat/edition: 3
Expand Down
36 changes: 12 additions & 24 deletions R/stan_cmdstan_path.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
#' 1. `""` (default): look at the original value that the `CMDSTAN_INSTALL`
#' environment variable contained when `instantiate` at the time
#' when it was installed.
#' If it was `"implicit"`, `"fixed"`, or `"internal"`, then choose
#' the corresponding option below. Otherwise, default to `"internal"`.
#' If it was `"implicit"` or `"fixed"`, then choose
#' the corresponding option below. Otherwise, default to `"implicit"`.
#' 2. `"implicit"`: Let the `cmdstanr::cmdstan_path()` decide where
#' to look for CmdStan. As explained in the `cmdstanr` documentation,
#' the output of `cmdstanr::cmdstan_path()` depends
Expand All @@ -24,32 +24,20 @@
#' 3. `"fixed"`: Use the path to CmdStan that was originally
#' contained in `Sys.getenv("CMDSTAN")` at the time when `instantiate`
#' was installed.
#' 4. `"internal"`: Use the copy of CmdStan installed internally inside the
#' `instantiate` package file system. To use this option,
#' `instantiate` needs to have been originally installed with the
#' `CMDSTAN_INSTALL` environment variable set to `"internal"`.
#' @examples
#' stan_cmdstan_path()
stan_cmdstan_path <- function(
cmdstan_install = Sys.getenv("CMDSTAN_INSTALL", unset = "")
) {
# It is not feasible to test all these cases in a single test coverage run.
# Covered in several GitHub Actions workflows.
# nocov start
install <- cmdstan_install
if (identical(install, "")) {
install <- .Call(c_cmdstan_path_install, PACKAGE = "instantiate")
}
install <- if_any(
identical(cmdstan_install, ""),
.Call(c_cmdstan_path_install, PACKAGE = "instantiate"),
cmdstan_install
)
stan_assert_install(install)
if (identical(install, "implicit") || identical(install, "")) {
out <- cmdstanr_path()
} else if (identical(install, "fixed")) {
out <- .Call(c_cmdstan_path_fixed, PACKAGE = "instantiate")
} else if (identical(install, "internal")) {
bin <- system.file("bin", package = "instantiate", mustWork = FALSE)
parent <- file.path(bin, "cmdstan")
out <- file.path(parent, list.files(parent)) %||% ""
}
# nocov end
out
if_any(
identical(install, "fixed"),
.Call(c_cmdstan_path_fixed, PACKAGE = "instantiate"),
cmdstanr_path()
)
}
6 changes: 3 additions & 3 deletions R/stan_cmdstan_version.R
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ stan_cmdstan_version <- function(
stan_assert_cmdstanr()
path_old <- cmdstanr_path()
if (cmdstan_valid(path_old)) {
on.exit(suppressMessages(cmdstanr::set_cmdstan_path(path = path_old)))
on.exit(suppressMessages(cmdstanr("set_cmdstan_path")(path = path_old)))
}
path_new <- stan_cmdstan_path(cmdstan_install = cmdstan_install)
suppressMessages(cmdstanr::set_cmdstan_path(path = path_new))
cmdstanr::cmdstan_version(error_on_NA = error_on_NA)
suppressMessages(cmdstanr("set_cmdstan_path")(path = path_new))
cmdstanr("cmdstan_version")(error_on_NA = error_on_NA)
}
11 changes: 4 additions & 7 deletions R/stan_package.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,10 @@
#' the executables live inside the file systems of their
#' respective packages, and users have the full power
#' and convenience of [`CmdStanR`](https://mc-stan.org/cmdstanr/)
#' without any additional compilation. This approach saves time,
#' allows R package developers to migrate from
#' [`rstan`](https://mc-stan.org/rstan/)
#' to the more modern [`CmdStanR`](https://mc-stan.org/cmdstanr/),
#' and fits well with centrally maintained R installations
#' where users may have trouble installing their own packages,
#' diagnosing compilation errors, and setting environment variables.
#' without any additional compilation after package installation.
#' This approach saves time and helps R package developers
#' migrate from [`rstan`](https://mc-stan.org/rstan/)
#' to the more modern [`CmdStanR`](https://mc-stan.org/cmdstanr/).
#' @useDynLib instantiate, .registration = TRUE
#' @importFrom fs dir_copy
#' @importFrom rlang abort check_installed inform is_installed warn
Expand Down
6 changes: 3 additions & 3 deletions R/stan_package_compile.R
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,10 @@ stan_package_compile <- function(
}
path_old <- cmdstanr_path()
if (cmdstan_valid(path_old)) {
on.exit(suppressMessages(cmdstanr::set_cmdstan_path(path = path_old)))
on.exit(suppressMessages(cmdstanr("set_cmdstan_path")(path = path_old)))
}
path_new <- stan_cmdstan_path(cmdstan_install = cmdstan_install)
suppressMessages(cmdstanr::set_cmdstan_path(path = path_new))
suppressMessages(cmdstanr("set_cmdstan_path")(path = path_new))
lapply(
X = models,
FUN = stan_compile_model,
Expand Down Expand Up @@ -118,7 +118,7 @@ stan_compile_model <- function(
on.exit(options("cmdstanr_verbose" = old))
options("cmdstanr_verbose" = TRUE)
}
cmdstanr::cmdstan_model(
cmdstanr("cmdstan_model")(
stan_file = model,
compile = TRUE,
quiet = quiet,
Expand Down
6 changes: 3 additions & 3 deletions R/stan_package_model.R
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ stan_package_model <- function(
exe_file <- if_any(stan_on_windows(), paste0(exe_file, ".exe"), exe_file)
path_old <- cmdstanr_path()
if (cmdstan_valid(path_old)) {
on.exit(suppressMessages(cmdstanr::set_cmdstan_path(path = path_old)))
on.exit(suppressMessages(cmdstanr("set_cmdstan_path")(path = path_old)))
}
path_new <- stan_cmdstan_path(cmdstan_install = cmdstan_install)
suppressMessages(cmdstanr::set_cmdstan_path(path = path_new))
cmdstanr::cmdstan_model(
suppressMessages(cmdstanr("set_cmdstan_path")(path = path_new))
cmdstanr("cmdstan_model")(
stan_file = stan_file,
exe_file = exe_file,
compile = FALSE
Expand Down
6 changes: 3 additions & 3 deletions R/utils_assert.R
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ stan_assert <- function(

stan_assert_install <- function(install) {
message <- paste(
"The CMDSTAN_INSTALL environment variable and the install argument",
"must be \"implicit\", \"fixed\", \"internal\", \"\", or unset",
"The CMDSTAN_INSTALL environment variable and the cmdstan_install",
"argument must be \"implicit\", \"fixed\", \"\", or unset",
"both when {instantiate} is installed and when {instantiate} is used.",
"If you are using {instantiate} and you get this error even though",
"CMDSTAN_INSTALL is an allowable value, please reinstall {instantiate}",
Expand All @@ -40,7 +40,7 @@ stan_assert_install <- function(install) {
message = message
)
stan_assert(
install %in% c("implicit", "fixed", "internal", ""),
install %in% c("implicit", "fixed", ""),
message = message
)
invisible()
Expand Down
6 changes: 5 additions & 1 deletion R/utils_cmdstan.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
cmdstanr <- function(name) {
eval(parse(text = paste0("cmdstanr::", name)))
}

cmdstanr_path <- function() {
if_any(
rlang::is_installed("cmdstanr"),
tryCatch(cmdstanr::cmdstan_path(), error = function(condition) ""),
tryCatch(cmdstanr("cmdstan_path")(), error = function(condition) ""),
""
)
}
20 changes: 9 additions & 11 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ knitr::opts_chunk$set(
[![codecov](https://codecov.io/gh/wlandau/instantiate/branch/main/graph/badge.svg)](https://app.codecov.io/gh/wlandau/instantiate)
[![lint](https://github.com/wlandau/instantiate/workflows/lint/badge.svg)](https://github.com/wlandau/instantiate/actions?query=workflow%3Alint)

Similar to [`rstantools`](https://mc-stan.org/rstantools/) for [`rstan`](https://mc-stan.org/rstan/), the `instantiate` package builds pre-compiled [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) models into CRAN-ready statistical modeling R packages. The models compile once during installation, the executables live inside the file systems of their respective packages, and users have the full power and convenience of [`CmdStanR`](https://mc-stan.org/cmdstanr/) without any additional compilation. This approach saves time, allows R package developers to migrate from [`rstan`](https://mc-stan.org/rstan/) to the more modern [`CmdStanR`](https://mc-stan.org/cmdstanr/), and fits well with centrally maintained R installations where users may have trouble installing their own packages, diagnosing compilation errors, and setting environment variables.
Similar to [`rstantools`](https://mc-stan.org/rstantools/) for [`rstan`](https://mc-stan.org/rstan/), the `instantiate` package builds pre-compiled [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) models into CRAN-ready statistical modeling R packages. The models compile once during installation, the executables live inside the file systems of their respective packages, and users have the full power and convenience of [`CmdStanR`](https://mc-stan.org/cmdstanr/) without any additional compilation after package installation. This approach saves time and helps R package developers migrate from [`rstan`](https://mc-stan.org/rstan/) to the more modern [`CmdStanR`](https://mc-stan.org/cmdstanr/).

# Documentation

Expand Down Expand Up @@ -51,20 +51,18 @@ The `instantiate` package uses environment variables to manage the installation

# Administering CmdStan

With `instantiate`, you have three different options for managing [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan). These options are called "installation types". To choose an installation type, set the `CMDSTAN_INSTALL` environment variable before installing `instantiate`. Your choice determines
By default, `instantiate` looks for the copy of [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) located at `cmdstanr::install_cmdstan()`. If you upgrade [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan), then the path returned by `cmdstanr::install_cmdstan()` will change, which may not be desirable in some cases. To permanently lock the path that `instantiate` uses, follow these steps:

1. Whether [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) will be installed inside `instantiate` during `install.packages("instantiate")`.
2. The location where `instantiate` will automatically look for [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) at runtime.
1. Set the `CMDSTAN` environment variable to the desired path to [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan).
2. Set the `CMDSTAN_INSTALL` environment variable to `"fixed"`.
3. Install `instantiate`.

The following table describes the role of the `CMDSTAN_INSTALL` environment variable at installation time (i.e. during `install.packages("instantiate")`). Implicit installation is recommended for most situations.
Henceforth, `instantiate` will automatically use the [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) path from (1), regardless of the value of `CMDSTAN` after (3). To prefer `cmdstanr::cmdstan_path()` instead, you could do one of the following:

Installation type | `CMDSTAN_INSTALL` | Install CmdStan? | Default path to CmdStan at runtime
---|---|---|---
Implicit (default) | `"implicit"` or `""` or unset | No | `cmdstanr::cmdstan_path()`, which depends on the current value of the `CMDSTAN` environment value at runtime.
Fixed | `"fixed"` | No | The value that the `CMDSTAN` environment variable originally contained at installation time, regardless of the current value of `CMDSTAN` at runtime.
Internal | `"internal"` | Yes | The internal copy of [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan) inside `instantiate`.
* Reinstall `instantiate` with `CMDSTAN_INSTALL` not equal to `"fixed"`, or
* Set `CMDSTAN_INSTALL` to `"implicit"` at runtime, or
* Set the `cmdstan_install` argument to `"implicit"` for the current `instantiate` package function you are using.

At runtime `instantiate`, the `CMDSTAN_INSTALL` environment variable takes on a different role: it overrides the automatic preference that `instantiate` has for the path to [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan). (So does the `cmdstan_install` function argument.) For example, if you installed `instantiate` with `CMDSTAN_INSTALL` equal `"internal"`, you can set `Sys.setenv(CMDSTAN_INSTALL = "implicit")` at runtime to let `cmdstanr::cmdstan_path()` choose the path to [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan). You can always choose implicit or fixed installation, but you can only choose internal installation if `instantiate` was installed with an internal copy of [`CmdStan`](https://mc-stan.org/users/interfaces/cmdstan).

# Packaging Stan models

Expand Down
Loading

0 comments on commit 2dc073c

Please sign in to comment.