From 0eb126e0ad6a74e4e7005dc6cd886d44ac8e5340 Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 21 Aug 2024 12:34:43 +0200 Subject: [PATCH] Improve Docs and Warnings around cpp_options Make it more clear that setting cpp_options = list(OPTION = FALSE) results in OPTION being set (turned on) rather than unset (turned off). --- R/model.R | 23 +++++++++++++++++++---- man/model-method-compile.Rd | 7 ++++--- tests/testthat/test-threads.R | 10 ++++++++-- 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/R/model.R b/R/model.R index 04fc000e..63666cf4 100644 --- a/R/model.R +++ b/R/model.R @@ -398,10 +398,11 @@ CmdStanModel <- R6::R6Class( #' program. #' @param user_header (string) The path to a C++ file (with a .hpp extension) #' to compile with the Stan model. -#' @param cpp_options (list) Any makefile options to be used when compiling the +#' @param cpp_options (list) Makefile options to be used when compiling the #' model (`STAN_THREADS`, `STAN_MPI`, `STAN_OPENCL`, etc.). Anything you would -#' otherwise write in the `make/local` file. For an example of using threading -#' see the Stan case study +#' otherwise write in the `make/local` file. Setting a value to `NULL` or `""` +#' within the list unsets the flag. +#' For an example of using threading see the Stan case study. #' [Reduce Sum: A Minimal Example](https://mc-stan.org/users/documentation/case-studies/reduce_sum_tutorial.html). #' @param stanc_options (list) Any Stan-to-C++ transpiler options to be used #' when compiling the model. See the **Examples** section below as well as the @@ -486,6 +487,8 @@ compile <- function(quiet = TRUE, if (length(cpp_options) == 0 && !is.null(private$precompile_cpp_options_)) { cpp_options <- private$precompile_cpp_options_ } + assert_no_falsy_flags(cpp_options) + if (length(stanc_options) == 0 && !is.null(private$precompile_stanc_options_)) { stanc_options <- private$precompile_stanc_options_ } @@ -2261,7 +2264,7 @@ assert_valid_threads <- function(threads, cpp_options, multiple_chains = FALSE) if (!is.null(threads)) { warning( "'", threads_arg, "' is set but the model was not compiled with ", - "'cpp_options = list(stan_threads = TRUE)' ", + "'cpp_options = list(stan_threads = TRUE)' or equivalent ", "so '", threads_arg, "' will have no effect!", call. = FALSE ) @@ -2277,6 +2280,18 @@ assert_valid_threads <- function(threads, cpp_options, multiple_chains = FALSE) invisible(threads) } +assert_no_falsy_flags <- function(cpp_options) { + names(cpp_options) <- toupper(names(cpp_options)) + flags <- c("STAN_THREADS", "STAN_MPI", "STAN_OPENCL", "INTEGRATED_OPENCL") + for (flag in flags) { + if (isFALSE(cpp_options[[flag]])) warning( + flag, " set to ", cpp_options[flag], " Since this is a non-empty value, ", + "it will result in the corresponding ccp option being turned ON. To turn this", + " option off, use cpp_options = list(", tolower(flag), " = NULL)." + ) + } +} + assert_valid_stanc_options <- function(stanc_options) { i <- 1 names <- names(stanc_options) diff --git a/man/model-method-compile.Rd b/man/model-method-compile.Rd index c92f2704..40e0f41e 100644 --- a/man/model-method-compile.Rd +++ b/man/model-method-compile.Rd @@ -45,10 +45,11 @@ program.} \item{user_header}{(string) The path to a C++ file (with a .hpp extension) to compile with the Stan model.} -\item{cpp_options}{(list) Any makefile options to be used when compiling the +\item{cpp_options}{(list) Makefile options to be used when compiling the model (\code{STAN_THREADS}, \code{STAN_MPI}, \code{STAN_OPENCL}, etc.). Anything you would -otherwise write in the \code{make/local} file. For an example of using threading -see the Stan case study +otherwise write in the \code{make/local} file. Setting a value to \code{NULL} or \code{""} +within the list unsets the flag. +For an example of using threading see the Stan case study. \href{https://mc-stan.org/users/documentation/case-studies/reduce_sum_tutorial.html}{Reduce Sum: A Minimal Example}.} \item{stanc_options}{(list) Any Stan-to-C++ transpiler options to be used diff --git a/tests/testthat/test-threads.R b/tests/testthat/test-threads.R index e3104fe5..7bb9e3fc 100644 --- a/tests/testthat/test-threads.R +++ b/tests/testthat/test-threads.R @@ -15,7 +15,7 @@ test_that("using threads_per_chain without stan_threads set in compile() warns", "Running MCMC with 4 sequential chains", fixed = TRUE ), - "'threads_per_chain' is set but the model was not compiled with 'cpp_options = list(stan_threads = TRUE)' so 'threads_per_chain' will have no effect!", + "'threads_per_chain' is set but the model was not compiled with 'cpp_options = list(stan_threads = TRUE)' or equivalent so 'threads_per_chain' will have no effect!", fixed = TRUE) }) @@ -175,7 +175,13 @@ test_that("correct output when stan_threads unset", { mod <- cmdstan_model(stan_program, cpp_options = list(stan_threads = NULL), force_recompile = TRUE) expect_warning( mod$sample(data = data_file_json, threads_per_chain = 4), - "'threads_per_chain' is set but the model was not compiled with 'cpp_options = list(stan_threads = TRUE)' so 'threads_per_chain' will have no effect!", + "'threads_per_chain' is set but the model was not compiled with 'cpp_options = list(stan_threads = TRUE)' or equivalent so 'threads_per_chain' will have no effect!", + fixed = TRUE + ) + + expect_warning( + cmdstan_model(stan_program, cpp_options = list(stan_threads = FALSE), force_recompile = TRUE), + "STAN_THREADS set to FALSE Since this is a non-empty value, it will result in the corresponding ccp option being turned ON. To turn this option off, use cpp_options = list(stan_threads = NULL).", fixed = TRUE ) })