Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warning but no error if compile_standalone but no functions found #956

Merged
merged 3 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
Expand Up @@ -979,6 +979,11 @@ expose_stan_functions <- function(function_env, global = FALSE, verbose = FALSE)
stop("Exporting standalone functions with external C++ is not available before CmdStan 2.32",
call. = FALSE)
}
if (!is.null(function_env$hpp_code) &&
!any(grepl("[[stan::function]]", function_env$hpp_code, fixed = TRUE))) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andrjohns Is this an ok way to check whether there are any user defined functions?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, looks right to me

warning("No standalone functions found to compile and expose to R!", call. = FALSE)
return(invisible(NULL))
}
require_suggested_package("Rcpp")
if (function_env$compiled) {
if (!global) {
Expand Down
44 changes: 29 additions & 15 deletions tests/testthat/test-model-expose-functions.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
context("model-expose-functions")

# Standalone functions not expected to work on WSL yet
skip_if(os_is_wsl())

set_cmdstan_path()

function_decl <- "
Expand Down Expand Up @@ -81,14 +84,11 @@ fit <- mod$sample(data = data_list)


test_that("Functions can be exposed in model object", {
skip_if(os_is_wsl())
expect_no_error(mod$expose_functions(verbose = TRUE))
})


test_that("Functions handle types correctly", {
skip_if(os_is_wsl())

### Scalar

expect_equal(mod$functions$rtn_int(10), 10)
Expand Down Expand Up @@ -178,8 +178,6 @@ test_that("Functions handle types correctly", {
})

test_that("Functions handle complex types correctly", {
skip_if(os_is_wsl())

### Scalar

complex_scalar <- complex(real = 2.1, imaginary = 21.3)
Expand Down Expand Up @@ -262,7 +260,6 @@ test_that("Functions handle complex types correctly", {
})

test_that("Functions can be exposed in fit object", {
skip_if(os_is_wsl())
fit$expose_functions(verbose = TRUE)

expect_equal(
Expand All @@ -272,7 +269,6 @@ test_that("Functions can be exposed in fit object", {
})

test_that("Compiled functions can be copied to global environment", {
skip_if(os_is_wsl())
expect_message(
fit$expose_functions(global = TRUE),
"Functions already compiled, copying to global environment",
Expand All @@ -287,7 +283,6 @@ test_that("Compiled functions can be copied to global environment", {


test_that("Functions can be compiled with model", {
skip_if(os_is_wsl())
mod <- cmdstan_model(model, force_recompile = TRUE, compile_standalone = TRUE)
fit <- mod$sample(data = data_list)

Expand All @@ -314,8 +309,33 @@ test_that("Functions can be compiled with model", {
)
})

test_that("compile_standalone warns but doesn't error if no functions", {
stan_no_funs_block <- write_stan_file("
parameters {
real x;
}
model {
x ~ std_normal();
}
")
expect_warning(
mod1 <- cmdstan_model(stan_no_funs_block, compile = TRUE, compile_standalone = TRUE, force_recompile = TRUE),
"No standalone functions found to compile and expose to R"
)
checkmate::expect_r6(mod1, "CmdStanModel")

stan_empty_funs_block <- write_stan_file("
functions {
}
")
expect_warning(
mod2 <- cmdstan_model(stan_empty_funs_block, compile = TRUE, compile_standalone = TRUE, force_recompile = TRUE),
"No standalone functions found to compile and expose to R"
)
checkmate::expect_r6(mod2, "CmdStanModel")
})

test_that("rng functions can be exposed", {
skip_if(os_is_wsl())
function_decl <- "functions { real wrap_normal_rng(real mu, real sigma) { return normal_rng(mu, sigma); } }"
stan_prog <- paste(function_decl,
paste(readLines(testing_stan_file("bernoulli")),
Expand All @@ -341,8 +361,6 @@ test_that("rng functions can be exposed", {
})

test_that("Overloaded functions give meaningful errors", {
skip_if(os_is_wsl())

funcode <- "
functions {
real fun1(real x) { return x; }
Expand All @@ -359,8 +377,6 @@ test_that("Overloaded functions give meaningful errors", {
})

test_that("Exposing external functions errors before v2.32", {
skip_if(os_is_wsl())

fake_cmdstan_version("2.26.0")

tmpfile <- tempfile(fileext = ".hpp")
Expand All @@ -387,8 +403,6 @@ test_that("Exposing external functions errors before v2.32", {
})

test_that("Exposing functions with precompiled model gives meaningful error", {
skip_if(os_is_wsl())

stan_file <- write_stan_file("
functions {
real a_plus_b(real a, real b) { return a + b; }
Expand Down
Loading