Exposing Stan user-defined functions using CmdStanR and Rcpp

I have written a tutorial on how to expose user-defined Stan functions to R using CmdStanR and Rcpp. You can read the tutorial here.

I have refactored the expose_cmdstanr_functions() R function that I previously posted on Discourse a few times. The code can be found here. It is also linked and included in the tutorial

Any comments or suggestions are welcome. You can comment here or on the repository’s issue tracker.

10 Likes

Thanks so much. I LOVE THIS!!! So great to test and apply functions directly with cmdstanr (rather than rstan).

One question is about compiling. Right now it looks like the expose command recompiles the Stan code (which takes time). Is there anyway after compiling once to keep the compiled code in the same directory with Stan code and then subsequently just load the compiled code? This would be directly analogous to what we can do with full Stan code. We compile it once and the next time it can just be loaded (and cmdstanr tells us the model executable is up to date).

1 Like

Thanks for the kind words.

Yes, I think that should be doable. Would you mind posting this request on the issue tracker so I dont forget? Might be able to get to this over the weekend.

1 Like

@rok_cesnovar

Thank you very much for expose_cmdstanr_functions(). It is very useful and helpful. Let me ask you one question.

I get an error when I compile a function that contains ode_bdf in the attached R and Stan code. If I use ode_rk45 instead of ode_bdf, no error occurs and I can use the time_dev normally in R. I think this is not due to expose_cmdstanr_functions.R, but I have no idea where to report it. Any suggestions?

test_model.stan (705 Bytes)
run-test_model.R (283 Bytes)

Environment: Ubuntu 20.04, R 4.2.1, cmdstan 2.31.0, cmdstanr 0.5.3
Error messages (sorry for some Japanese):

/usr/bin/ld: /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_cvodes.a(cvodes.o): relocation R_X86_64_PC32 against symbol `stderr@@GLIBC_2.2.5' can not be used when making a shared object。 -fPIC を付けて再コンパイルしてください。
/usr/bin/ld: 最終リンクに失敗しました: bad value
collect2: error: ld returned 1 exit status
make: *** [/usr/share/R/share/make/shlib.mk:10: sourceCpp_4.so] エラー 1
g++ -std=gnu++14 -I"/usr/share/R/include" -DNDEBUG   -I"/home/username/R/x86_64-pc-linux-gnu-library/4.2/Rcpp/include" -I"/home/username/R/x86_64-pc-linux-gnu-library/4.2/RcppEigen/include" -I"/tmp/RtmpTVrvKe/sourceCpp-x86_64-pc-linux-gnu-1.0.10"   -std=c++1y -pthread -D_REENTRANT -Wno-sign-compare -Wno-ignored-attributes -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/tbb_2020.3/include -O3 -I /home/username/.cmdstan/cmdstan-2.31.0/src -I /home/username/.cmdstan/cmdstan-2.31.0/stan/src -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/rapidjson_1.1.0/ -I /home/username/.cmdstan/cmdstan-2.31.0/lib/CLI11-1.9.1/ -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/ -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/eigen_3.3.9 -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/boost_1.78.0 -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/include -I /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/src/sundials -fpic  -g -O2 -fdebug-prefix-map=/build/r-base-zYgbYq/r-base-4.2.1=. -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2  -c file11f0ca68826bb8.cpp -o file11f0ca68826bb8.o
g++ -std=gnu++14 -shared -L/usr/lib/R/lib -Wl,-Bsymbolic-functions -Wl,-z,relro -o sourceCpp_4.so file11f0ca68826bb8.o -Wl,-L,/home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/tbb -Wl,-rpath,/home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/tbb /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_nvecserial.a /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_cvodes.a /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_idas.a /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/sundials_6.1.1/lib/libsundials_kinsol.a /home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/tbb/libtbb.so.2 -Wl,-L,/home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/tbb -Wl,-rpath,/home/username/.cmdstan/cmdstan-2.31.0/stan/lib/stan_math/lib/tbb -L/usr/lib/R/lib -lR
 Rcpp::sourceCpp(code = code, env = env) でエラー: 
  Error 1 occurred building shared library. 
1 Like

This functionality is now available in the development version of cmdstanr itself. Just install from github:

remotes::install_github("stan-dev/cmdstanr")

Then you can request the model functions be compiled in your cmdstan_model() call:

mod <- cmdstan_model(stan_file = stanfile, compile_standalone = TRUE)

Your model’s functions will then be available in the functions member of the model object:

mod$functions$your_function()

You can make the functions available in your global R environment using expose_functions(global = TRUE):

mod$expose_functions(global = TRUE)
your_function()

You can also see the tests for more examples

5 Likes

@andrjohns
Thank you very much for the reply. I can use compile_standalone = TRUE option and ode_rk45. It is very easy to use! But, I got the same error when I used ode_bdf.
It looks like either a lack of compile options or a namespace issue when using ode_bdf

Apologies for the delay in responding, but I’ve just checked the test_model.stan file you posted using the latest cmdstanr github version with cmdstan 2.31.0, and all compiled without issue.

Would you be able to double-check your cmdstan version and the code you’re using?