Avoid recompiling the exact same Stan model with brms

FWIW tiflo’s script runs fine for me on High Sierra (10.13.6).

Some unsolicited advice, I would try running this using rscript and not within Rstudio. Calling Stan lots of times from within a single Rstudio instance has caused me a lot of pain in the past.

FWIW, after a few iterations it bombs out using RStudio. I ran it in the R console now and the same thing seems to happen:

 *** caught segfault ***
address 0x116f389c0, cause 'memory not mapped'

Traceback:
 1: .Call(list(name = "CppObject__finalize", address = <pointer: 0x600002b20060>,     dll = list(name = "Rcpp", path = "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/libs/Rcpp.so",         dynamicLookup = TRUE, handle = <pointer: 0x600001ca5ad0>,         info = <pointer: 0x106e2b360>), numParameters = 2L),     <pointer: 0x600001781c00>, .pointer)
 2: x$.self$finalize()
 3: (function (x) x$.self$finalize())(<environment>)

Segfaults make me suspect a complier version mismatch somewhere down the line, I ran into this when updating to R 3.5.3 the other day. The solution for me was to purge and reinstall my library: https://www.r-bloggers.com/how-to-remove-all-user-installed-packages-in-r/.

Every chance this is something else though.

Running the script on a computer cluster with CentOS 7 with R 3.5.1 and BRMS 2.8.0 yields no error.

I removed all packages, reinstalled rstan, tidyverse, magrittr, brms, bridgesampling, and tictoc. Same error.

I use Mojave 10.14.4, latest Xcode and my Makevars only contains:
CPPFLAGS="-isystem /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include"

Sorry @tiflo, not much more I can figure out from my side…

Have you tried configuring your Makevars following the guidelines on RStan?

> dotR <- file.path(Sys.getenv("HOME"), ".R")
> if (!file.exists(dotR)) dir.create(dotR)
> M <- file.path(dotR, ifelse(.Platform$OS.type == "windows", "Makevars.win", "Makevars"))
> if (!file.exists(M)) file.create(M)
> cat("\nCXX14FLAGS=-O3 -march=native -mtune=native",
>     if( grepl("^darwin", R.version$os)) "CXX14FLAGS += -arch x86_64 -ftemplate-depth-256" else 
>     if (.Platform$OS.type == "windows") "CXX11FLAGS=-O3 -march=native -mtune=native" else
>     "CXX14FLAGS += -fPIC",
>     file = M, sep = "\n", append = TRUE)

Sorry to be slow. I cranked my back and have limited mobility (R crashed me ;)).

I can add that I had completely reinstalled R, c++, and rstan recently. I’m running MacOS High Sierra 10.13.6 (17G65) on a MacPro (2.7 GHz 12-Core Intel Xeon E5, 64 GB 1866 MHz DDR3).

platform       x86_64-apple-darwin15.6.0   
arch           x86_64                      
os             darwin15.6.0                
system         x86_64, darwin15.6.0        
status                                     
major          3                           
minor          5.2                         
year           2018                        
month          12                          
day            20                          
svn rev        75870                       
language       R                           
version.string R version 3.5.2 (2018-12-20)
nickname       Eggshell Igloo            

Brm version 2.8.0, bridgesampling 0.6-0, rstan 2.18.2. Clang --version yields (not sure whether that’s relevant):

Apple LLVM version 10.0.0 (clang-1000.11.45.5)
Target: x86_64-apple-darwin17.7.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

I’ve now followed Pascal’s (@Pascal_J) suggestion and edited Makevars using the code from his post. Here’s the content of my Makevars file.

CXXFLAGS=-O3 -mtune=native -march=native -Wno-unused-variable -Wno-unused-function -Wno-macro-redefined

CC=clang

CXX=clang++ -arch x86_64 -ftemplate-depth-256

CXXFLAGS+=-flto -Wno-unused-local-typedefs

CXXFLAGS += -Wno-ignored-attributes -Wno-deprecated-declarations

CXX14FLAGS=-O3 -march=native -mtune=native

CXX14FLAGS += -arch x86_64 -ftemplate-depth-256

I then restarted R and R studio (not sure whether I also would need to restart the computer?). This still yields the same error (and at the same place in the script).

And here’s the output I get if I run the process in the R console. Pretty much the same as @torkar (thank you, btw):

 *** caught segfault ***
address 0x122a94b30, cause 'memory not mapped'

Traceback:
 1: .Call(list(name = "CppObject__finalize", address = <pointer: 0x624000226e60>,     dll = list(name = "Rcpp", path = "/Library/Frameworks/R.framework/Versions/3.5/Resources/library/Rcpp/libs/Rcpp.so",         dynamicLookup = TRUE, handle = <pointer: 0x6240001429f0>,         info = <pointer: 0x7fe0ca8ec100>), numParameters = 2L),     <pointer: 0x6140001e4500>, .pointer)
 2: x$.self$finalize()
 3: (function (x) x$.self$finalize())(<environment>)

I had a similar problem where I wanted to use the same model to run a simulation a 17000 times without recompilation. It always crashed after the 1000th run even when I used a different computer and OS.

My solution was to use rslurm to parallelise the R code and ran everything on our HPC.That worked perfectly. I didn’t have time to test it but maybe it would even work using other kinds of parallelisation or functions like lapply() instead of a for loop.

A quick example is:

library(brms)
library(rslurm)

df ← data.frame(x = rnorm(100), y= rnorm(100))

model ← brm(x ~ y, data = df)

test_func ← function(n) {
df ← data.frame(x = rnorm(n), y= rnorm(n))
fixef(update(model, newdata = df))
}

pars ← data.frame(n = rep(100, 1000))

n_nodes ← 4
cpus_per_node ← 24
sjob ← slurm_apply(test_func, pars, jobname = ‘test_brms’,
add_objects = c(“model”),
nodes = n_nodes, cpus_per_node = cpus_per_node, submit = FALSE)

2 Likes