Stan & R 4.2 on Windows

If you are wondering about or having issue with the Stan experience running R 4.2 on Windows, please see the blog post for details and instructions: Stan & R 4.2 on Windows – The Stan Blog

We don’t anticipate any additional issues for macOS and Linux users upgrading to R 4.2.

4 Likes

The rstan section currently links to the cmdstanr github repo for issues, looks like a copy-paste thing.

copy-paste error indeed. Thanks!

ctsem uses Rstan and is still passing CRAN windows release checks, from my reading of the blog post I should have expected problems here?

It is hard to say what exactly is going on wrt to CRAN rstan and the tests. They may have the toolchain set up so that CRAN rstan actually works on their end - we don’t really have all the details.

What we know so far is that a clean install of Windows + R 4.2 + Rtools42 + CRAN rstan does not work - the package installs, the example model fails to compile. This goes for both installing the binary version as well as installing from source.

This obviously doesn’t mean that you can’t get it to work with some makevars/renviron/rprofile/… lines, we just don’t have a recipe for that right now. If someone does get that working you are very welcome to share that information.

Side note of why we got here:

Unfortunately, the R core team has gone backwards in terms of the Windows toolchain - we are back to less testing, less of an open process, so not a ton is known at this time. If you want to know more on that read Tweaks to build with Rtools42 by yutannihilation · Pull Request #34 · r-windows/r-base · GitHub and [Rd] Update on rtools4 and ucrt support

I see, thanks. I just got everything installed and tested and yes, apparently CRAN has some magic tricks to get things compiled, so precompiled models are fine, but the nonlinear models from ctsem that require compilation fail like so:

make cmd is
  make -f "C:/PROGRA~1/R/R-42~1.0/etc/x64/Makeconf" -f "C:/PROGRA~1/R/R-42~1.0/share/make/winshlib.mk" -f "C:/Users/Driver/Documents/.R/Makevars.win" CXX='$(CXX14) $(CXX14STD)' CXXFLAGS='$(CXX14FLAGS)' CXXPICFLAGS='$(CXX14PICFLAGS)' SHLIB_LDFLAGS='$(SHLIB_CXX14LDFLAGS)' SHLIB_LD='$(SHLIB_CXX14LD)' SHLIB="file34dc4266ea.dll" WIN=64 TCLBIN= OBJECTS="file34dc4266ea.o"

make would use
if test "zfile34dc4266ea.o" != "z"; then \
  if test -e "file34dc4266ea-win.def"; then \
    echo g++  -shared -s -static-libgcc -o file34dc4266ea.dll file34dc4266ea-win.def file34dc4266ea.o  -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib"  -L"C:/PROGRA~1/R/R-42~1.0/bin/x64" -lR ; \
    g++  -shared -s -static-libgcc -o file34dc4266ea.dll file34dc4266ea-win.def file34dc4266ea.o  -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib"  -L"C:/PROGRA~1/R/R-42~1.0/bin/x64" -lR ; \
  else \
    echo EXPORTS > tmp.def; \
    nm file34dc4266ea.o | sed -n 's/^.* [BCDRT] / /p' | sed -e '/[.]refptr[.]/d' -e '/[.]weak[.]/d' | sed 's/[^ ][^ ]*/"&"/g'  >> tmp.def; \
    echo g++  -shared -s -static-libgcc -o file34dc4266ea.dll tmp.def file34dc4266ea.o  -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib"  -L"C:/PROGRA~1/R/R-42~1.0/bin/x64" -lR ; \
    g++  -shared -s -static-libgcc -o file34dc4266ea.dll tmp.def file34dc4266ea.o  -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib/x64" -L"C:/rtools42/x86_64-w64-mingw32.static.posix/lib"  -L"C:/PROGRA~1/R/R-42~1.0/bin/x64" -lR ; \
    rm -f tmp.def; \
  fi \
fi

Error in compileCode(f, code, language = language, verbose = verbose) : 
  C:\rtools42\x86_64-w64-mingw32.static.posix\bin/ld.exe: file34dc4266ea.o:file34dc4266ea:(.text+0x309a): undefined reference to `tbb::internal::task_scheduler_observer_v3::observe(bool)'C:\rtools42\x86_64-w64-mingw32.static.posix\bin/ld.exe: file34dc4266ea.o:file34dc4266ea:(.text+0x30c3): undefined reference to `tbb::internal::task_scheduler_observer_v3::observe(bool)'C:\rtools42\x86_64-w64-mingw32.static.posix\bin/ld.exe: file34dc4266ea.o:file34dc4266ea:(.text$_ZN3tbb8internal26task_scheduler_observer_v3D1Ev[_ZN3tbb8internal26task_scheduler_observer_v3D1Ev]+0x1b): undefined reference to `tbb::internal::task_scheduler_observer_v3::observe(bool)'C:\rtools42\x86_64-w64-mingw32.static.posix\bin/ld.exe: file34dc4266ea.o:file34dc4266ea:(.text$_ZN3tbb8internal26task_scheduler_observer_v3D0Ev[_ZN3tbb8internal26task_scheduler_observer_v3D0Ev]+0x1f): undefined reference to `tbb::internal::task_scheduler_observer_v3::observe(bool)'C:\rtools42\x86_64-w64-mingw32.static.posix\bin/ld.exe: f
Error in sink(type = "output") : invalid connection

Yeah, this is the exact issue I got as well - R4.2 , Rstan & Windows · Issue #1006 · stan-dev/rstan · GitHub

1 Like

The problem with RStan + R4.2 on Windows is due to unrespecting LOCAL_LIBS environment variable. As a workaround, after a failed compilation where LOCAL_LIBS is set correctly but not used:

Sys.setenv(PKG_LIBS = Sys.getenv("LOCAL_LIBS"))

Alternatively, you may add/create the required RStan plugin flags into file.path(Sys.getenv("HOME"), ".R", "Makevars.win").

This has been fixed in the development version of RStan by `rstan`: `plugin`: Fix environment variables · stan-dev/rstan@4d78f1d · GitHub.

4 Likes

When I fix my package (containing precompiled stan models) makevars.win with the following line, package building and functions using the precompiled models works fine:

PKG_LIBS = $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "cat(paste0(system.file('lib/x64', package = 'rstan', mustWork = TRUE),'/libStanServices.a'))") -L$(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "cat(system.file('libs/x64', package = 'StanHeaders', mustWork = TRUE))") -lStanheaders -L$(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "cat(system.file('lib/x64', package = 'RcppParallel', mustWork = TRUE))") -ltbb $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "RcppParallel::RcppParallelLibs()") $(shell "$(R_HOME)/bin$(R_ARCH_BIN)/Rscript" -e "StanHeaders:::LdFlags()")

However, when I try the supposed fix of:

Sys.setenv(PKG_LIBS = Sys.getenv("LOCAL_LIBS"))

or more conveniently for a package, putting this code before any compilation requiring code:

if(.Platform$OS.type=="windows" && R.Version()$major >=4 && R.Version()$minor >= 2 && 
    compareVersion(as.character(packageVersion('rstan')[[1]]),'2.25.0') == -1){
  
  Sys.setenv(PKG_LIBS=
      paste0('\"',system.file('lib/x64', package = 'rstan', mustWork = TRUE),'/libStanServices.a','\"', 
        ' -L','\"',system.file('libs/x64', package = 'StanHeaders', mustWork = TRUE),'\"',
        ' -lStanHeaders -L','\"',system.file('lib/x64', package = 'RcppParallel', mustWork = TRUE),'\"',
        ' -ltbb'))
}

Compilation of further models now succeeds (where before it would give a compile error) but now the R session crashes when I try to sample or optimize, in both 1 core and multicore cases. Any ideas? Updates in question are pushed to master of GitHub - cdriveraus/ctsem: Hierarchical continuous time state space modelling

1 Like

I’d avoid your hardcoded setting of PKG_LIBS for many reasons, especially linking to x64 libs with 32-bit version of R for example (that would cause a crash and should be replaced by Sys.getenv("R_ARCH")).

Have you tested it with RStan 2.26/2.29?

Well, I’m definitely open to better ideas – but hardcoded and working on some win/R4.2.x systems is better than not hardcoded and working on none. 32bit support is dropped for R 4.2 so I don’t think the R_ARCH check is needed. My software works fine in general with rstan 2.21 or 2.26, just not with the specific case of win / R4.2 / rstan 2.21. Which is unfortunately what many users will slowly be upgrading to.

If it works fine with RStan 2.26+, then it should get fixed in a minor update of RStan 2.21 on CRAN.

1 Like

The problem with RStan + R4.2 on Windows is due to unrespecting [LOCAL_LIBS] environment variable. As a workaround, after a failed compilation where LOCAL_LIBS is set correctly