Skip to content

Commit

Permalink
Merge branch 'master' into fix-hpp-generation
Browse files Browse the repository at this point in the history
  • Loading branch information
andrjohns committed Jan 8, 2024
2 parents d180e4e + 48a2b3e commit 447f5f7
Show file tree
Hide file tree
Showing 173 changed files with 5,638 additions and 1,833 deletions.
56 changes: 56 additions & 0 deletions .github/CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Contributing to cmdstanr

This outlines how to propose a change to cmdstanr and is based on similar
instructions for tidyverse packages, including the contributing guidelines
generated by `usethis::use_tidy_contributing()`.

## Fixing typos

You can fix typos, spelling mistakes, or grammatical errors in the documentation
directly using the GitHub web interface, as long as the changes are made in the
_source_ file. This generally means you'll need to edit
[roxygen2 comments](https://roxygen2.r-lib.org/articles/roxygen2.html) in an `.R`,
not a `.Rd` file. You can find the `.R` file that generates the `.Rd` by reading
the comment in the first line.

## Bigger changes

If you want to make a bigger change, it's a good idea to first file an issue and
make sure someone from the team agrees that it’s needed. If you’ve found a bug,
please file an issue that illustrates the bug with a minimal reproducible
example (see e.g. the [tidyverse reprex instructions](https://www.tidyverse.org/help/#reprex)).
The tidyverse guide on [how to create a great issue](https://code-review.tidyverse.org/issues/)
has more advice.

### Pull request process

If you are new to creating pull requests here are some tips. Using the functions
from the `usethis` package is not required but can be helpful if this process is
new to you.

* Fork the package and clone onto your computer. If you haven't done this before, we recommend using `usethis::create_from_github("stan-dev/cmdstanr", fork = TRUE)`.

* Install all development dependencies with `devtools::install_dev_deps()`, and then make sure the package passes R CMD check by running `devtools::check()`.
If R CMD check doesn't pass cleanly, it's a good idea to ask for help before continuing.
* Create a Git branch for your pull request (PR). We recommend using `usethis::pr_init("brief-description-of-change")`.

* Make your changes, commit to git, and then create a PR by running `usethis::pr_push()`, and following the prompts in your browser.
The title of your PR should briefly describe the change.
The body of your PR should contain `Fixes #issue-number`.

* For user-facing changes, add a bullet to the top of `NEWS.md` (i.e. just below the first header). Follow the style already used in `NEWS.md`.

### Code style

* New code should attempt to follow the style used in the package. When in doubt follow the tidyverse [style guide](https://style.tidyverse.org).

* We use [roxygen2](https://cran.r-project.org/package=roxygen2), with [Markdown syntax](https://cran.r-project.org/web/packages/roxygen2/vignettes/rd-formatting.html), for documentation.

* We use [testthat](https://cran.r-project.org/package=testthat) for unit tests.
Contributions with test cases included are easier to accept.

## Code of Conduct

Please note that the cmdstanr project follows the Stan project's
[Code of Conduct](https://discourse.mc-stan.org/t/announcing-our-new-stan-code-of-conduct/23764).
By contributing to this project you agree to abide by its terms.
6 changes: 3 additions & 3 deletions .github/workflows/R-CMD-check-wsl.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ jobs:

- uses: actions/checkout@v4

- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5
with:
r-version: 'release'
rtools-version: '42'
- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5

- name: Query dependencies
run: |
Expand Down Expand Up @@ -98,7 +98,7 @@ jobs:

- name: Upload check results
if: failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: wsl-backend-results
path: check
6 changes: 3 additions & 3 deletions .github/workflows/R-CMD-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ jobs:
sudo apt-get install -y libcurl4-openssl-dev || true
sudo apt-get install -y openmpi-bin openmpi-common libopenmpi-dev || true
- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5
with:
r-version: ${{ matrix.config.r }}
rtools-version: ${{ matrix.config.rtools }}
- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5

- name: Query dependencies
run: |
Expand Down Expand Up @@ -113,7 +113,7 @@ jobs:

- name: Upload check results
if: failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
path: check
8 changes: 4 additions & 4 deletions .github/workflows/Test-coverage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@ jobs:
if: "!startsWith(github.ref, 'refs/tags/') && github.ref != 'refs/heads/master'"
- uses: actions/checkout@v4

- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5
- uses: r-lib/actions/[email protected].5

- name: Install Ubuntu dependencies
run: |
Expand Down Expand Up @@ -85,12 +85,12 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5
with:
r-version: 'release'
rtools-version: '42'

- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5

- name: Query dependencies
run: |
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/cmdstan-tarball-check.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ jobs:
sudo apt-get install -y libcurl4-openssl-dev || true
sudo apt-get install -y openmpi-bin openmpi-common libopenmpi-dev || true
- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5
with:
r-version: ${{ matrix.config.r }}
rtools-version: ${{ matrix.config.rtools }}

- uses: r-lib/actions/[email protected].4
- uses: r-lib/actions/[email protected].5

- name: Query dependencies
run: |
Expand Down Expand Up @@ -95,7 +95,7 @@ jobs:

- name: Upload check results
if: failure()
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
path: check
8 changes: 5 additions & 3 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: cmdstanr
Title: R Interface to 'CmdStan'
Version: 0.6.1.9000
Date: 2023-08-25
Version: 0.7.0.9000
Date: 2023-12-13
Authors@R:
c(person(given = "Jonah", family = "Gabry", role = c("aut", "cre"),
email = "[email protected]"),
Expand All @@ -16,7 +16,8 @@ Authors@R:
person(given = c("William", "Michael"), family = "Landau", role = "ctb",
email = "[email protected]", comment = c(ORCID = "0000-0003-1878-3253")),
person(given = "Jacob", family = "Socolar", role = "ctb"),
person(given = "Martin", family = "Modrák", role = "ctb"))
person(given = "Martin", family = "Modrák", role = "ctb"),
person(given = "Steve", family = "Bronder", role = "ctb"))
Description: A lightweight interface to 'Stan' <https://mc-stan.org>.
The 'CmdStanR' interface is an alternative to 'RStan' that calls the command
line interface for compilation and running algorithms instead of interfacing
Expand Down Expand Up @@ -44,6 +45,7 @@ Imports:
rlang (>= 0.4.7)
Suggests:
bayesplot,
ggplot2,
knitr (>= 1.37),
loo (>= 2.0.0),
rmarkdown,
Expand Down
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ S3method(as_draws,CmdStanGQ)
S3method(as_draws,CmdStanLaplace)
S3method(as_draws,CmdStanMCMC)
S3method(as_draws,CmdStanMLE)
S3method(as_draws,CmdStanPathfinder)
S3method(as_draws,CmdStanVB)
export(as_cmdstan_fit)
export(as_draws)
Expand Down
29 changes: 28 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
# cmdstanr 0.6.1.9000
# cmdstanr 0.7.0.9000

Items for next release go here

# cmdstanr 0.7.0

## Major new features

* New `laplace` method by @jgabry in #800
* New `pathfinder` method by @SteveBronder in #848

## Other improvements and bug fixes

* Add missing link to diagnose method in CmdStanModel doc by @jgabry in #833
* Improvements to compile tests by @martinmodrak in #836
* Changed the delay behavior in wsl_installed by @martinmodrak in #839
* Update array syntax in website vignette by @andrjohns in #841
* Compatibility fixes for cmdstan 2.33+ by @jgabry in #843
* Suggest format method after error due to old syntax by @jgabry in #852
* Clarifications in R-markdown vignette by @jgcolman in #854
* Update linux/wsl detection for install arch by @andrjohns in #856
* Fix handling of single-length inits for containers by @andrjohns in #857
* Add support/tests for exposing functions with tuples by @andrjohns in #860
* Add support/tests for exporting functions with complex types by @andrjohns in #861
* Add option for installing from release archive by @andrjohns in #866
* Improve Pathfinder doc by @avehtari in #875
* Rename `jacobian_adjustment` argument to `jacobian` by @jgabry in #879
* Fix get_cmdstan_flags('STANCFLAGS') in recursive make by @pearsonca in #881

# cmdstanr 0.6.1

Expand Down
130 changes: 129 additions & 1 deletion R/args.R
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#' * `OptimizeArgs`: stores arguments specific to `method=optimize`.
#' * `LaplaceArgs`: stores arguments specific to `method=laplace`.
#' * `VariationalArgs`: stores arguments specific to `method=variational`
#' * `PathfinderArgs`: stores arguments specific to `method=pathfinder`
#' * `GenerateQuantitiesArgs`: stores arguments specific to `method=generate_quantities`
#' * `DiagnoseArgs`: stores arguments specific to `method=diagnose`
#'
Expand All @@ -41,7 +42,8 @@ CmdStanArgs <- R6::R6Class(
output_basename = NULL,
sig_figs = NULL,
opencl_ids = NULL,
model_variables = NULL) {
model_variables = NULL,
num_threads = NULL) {

self$model_name <- model_name
self$stan_code <- stan_code
Expand Down Expand Up @@ -82,6 +84,7 @@ CmdStanArgs <- R6::R6Class(
}
self$init <- init
self$opencl_ids <- opencl_ids
self$num_threads = NULL
self$method_args$validate(num_procs = length(self$proc_ids))
self$validate()
},
Expand Down Expand Up @@ -179,6 +182,9 @@ CmdStanArgs <- R6::R6Class(
if (!is.null(self$opencl_ids)) {
args$opencl <- c("opencl", paste0("platform=", self$opencl_ids[1]), paste0("device=", self$opencl_ids[2]))
}
if (!is.null(self$num_threads)) {
num_threads <- c(args$output, paste0("num_threads=", self$num_threads))
}
args <- do.call(c, append(args, list(use.names = FALSE)))
self$method_args$compose(idx, args)
},
Expand Down Expand Up @@ -541,6 +547,75 @@ VariationalArgs <- R6::R6Class(
)
)

# PathfinderArgs ---------------------------------------------------------

PathfinderArgs <- R6::R6Class(
"PathfinderArgs",
lock_objects = FALSE,
public = list(
method = "pathfinder",
initialize = function(init_alpha = NULL,
tol_obj = NULL,
tol_rel_obj = NULL,
tol_grad = NULL,
tol_rel_grad = NULL,
tol_param = NULL,
history_size = NULL,
single_path_draws = NULL,
draws = NULL,
num_paths = NULL,
max_lbfgs_iters = NULL,
num_elbo_draws = NULL,
save_single_paths = NULL) {
self$init_alpha <- init_alpha
self$tol_obj <- tol_obj
self$tol_rel_obj <- tol_rel_obj
self$tol_grad <- tol_grad
self$tol_rel_grad <- tol_rel_grad
self$tol_param <- tol_param
self$history_size <- history_size
self$num_psis_draws <- draws
self$num_draws <- single_path_draws
self$num_paths <- num_paths
self$max_lbfgs_iters <- max_lbfgs_iters
self$num_elbo_draws <- num_elbo_draws
self$save_single_paths <- save_single_paths
invisible(self)
},

validate = function(num_procs) {
validate_pathfinder_args(self)
},

# Compose arguments to CmdStan command for pathfinder-specific
# non-default arguments. Works the same way as compose for sampler args,
# but `idx` (multiple pathfinders are handled in cmdstan)
compose = function(idx = NULL, args = NULL) {
.make_arg <- function(arg_name) {
compose_arg(self, arg_name, idx = NULL)
}
new_args <- list(
"method=pathfinder",
.make_arg("init_alpha"),
.make_arg("tol_obj"),
.make_arg("tol_rel_obj"),
.make_arg("tol_grad"),
.make_arg("tol_rel_grad"),
.make_arg("tol_param"),
.make_arg("history_size"),
.make_arg("num_psis_draws"),
.make_arg("num_draws"),
.make_arg("num_paths"),
.make_arg("max_lbfgs_iters"),
.make_arg("num_elbo_draws"),
.make_arg("save_single_paths")
)
new_args <- do.call(c, new_args)
c(args, new_args)
}
)
)

# DiagnoseArgs -------------------------------------------------------------

DiagnoseArgs <- R6::R6Class(
Expand Down Expand Up @@ -854,6 +929,59 @@ validate_variational_args <- function(self) {
invisible(TRUE)
}

#' Validate arguments for pathfinder inference
#' @noRd
#' @param self A `PathfinderArgs` object.
#' @return `TRUE` invisibly unless an error is thrown.
validate_pathfinder_args <- function(self) {

checkmate::assert_integerish(self$max_lbfgs_iters, lower = 1, null.ok = TRUE, len = 1)
if (!is.null(self$max_lbfgs_iters)) {
self$iter <- as.integer(self$max_lbfgs_iters)
}
checkmate::assert_integerish(self$num_paths, lower = 1, null.ok = TRUE,
len = 1)
if (!is.null(self$num_paths)) {
self$num_paths <- as.integer(self$num_paths)
}
checkmate::assert_integerish(self$num_draws, lower = 1, null.ok = TRUE,
len = 1, .var.name = "single_path_draws")
if (!is.null(self$num_draws)) {
self$num_draws <- as.integer(self$num_draws)
}
checkmate::assert_integerish(self$num_psis_draws, lower = 1, null.ok = TRUE,
len = 1, .var.name = "draws")
if (!is.null(self$num_psis_draws)) {
self$num_psis_draws <- as.integer(self$num_psis_draws)
}
checkmate::assert_integerish(self$num_elbo_draws, lower = 1, null.ok = TRUE, len = 1)
if (!is.null(self$num_elbo_draws)) {
self$num_elbo_draws <- as.integer(self$num_elbo_draws)
}
if (!is.null(self$save_single_paths) && is.logical(self$save_single_paths)) {
self$save_single_paths = as.integer(self$save_single_paths)
}
checkmate::assert_integerish(self$save_single_paths, null.ok = TRUE,
lower = 0, upper = 1, len = 1)
if (!is.null(self$save_single_paths)) {
self$save_single_paths <- 0
}


# check args only available for lbfgs and bfgs
bfgs_args <- c("init_alpha", "tol_obj", "tol_rel_obj", "tol_grad", "tol_rel_grad", "tol_param")
for (arg in bfgs_args) {
checkmate::assert_number(self[[arg]], .var.name = arg, lower = 0, null.ok = TRUE)
}

if (!is.null(self$history_size)) {
checkmate::assert_integerish(self$history_size, lower = 1, len = 1, null.ok = FALSE)
self$history_size <- as.integer(self$history_size)
}

invisible(TRUE)
}


# Validation helpers ------------------------------------------------------

Expand Down
Loading

0 comments on commit 447f5f7

Please sign in to comment.