Dealing with Catalina

mac OS v10.14.6 Mojave with

clang++ --version
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.7.0

After commenting out everything in ~/.R/Makevars, I get

Error in throw_exception() : this is an exception

According to @ssp3nc3r if

Rcpp::sourceCpp(code = 
'
#include <Rcpp.h>
using namespace Rcpp; 

// [[Rcpp::export]]
int throw_exception() { 
  std::stringstream errmsg; errmsg << "this is an exception";
  throw std::domain_error(errmsg.str()); 
  return 0;
}
'
)

is compiled with Xcode’s clang++, then

throw_exception()

yields the expected

This is an exception

like @roualdes found.

But if any other package is loaded that has compiled C++ code such as dplyr, readr, etc., then

throw_exception()

yields the unexpected

c++ exception (unknown reason)

So, my conclusion is that this is a Rcpp and / or AT&T clang and / or Catalina issue rather than a RStan one, but it affects RStan a lot because Stan branches on exception type and doesn’t know what to do with “c++ exception (unknown reason)” and our previous approach to dealing with it in 2017 won’t work if the user happens to have loaded any of the 1000+ other packages that use Rcpp to compile C++ code.

Do you have any suggestions? I don’t think Anaconda is at issue here (although that often messes things up for other reasons) because @ssp3nc3r is just using a plain R and RStudio setup.

I still get “this is an exception” even after loading dplyr and readr in R or RStudio.

Sorry, all. This sounds frustrating. Thanks @bgoodri for all your help.

The example’s failure to correctly throw the exception after loading other packages was on Catalina, not Mojave. Testing on Mojave, the example correctly throws the exception whether or not other packages are loaded.

What happens if you do

Sys.setenv(PKG_LDFLAGS = "-static")

before

Rcpp::sourceCpp(code = 
'
#include <Rcpp.h>
using namespace Rcpp; 

// [[Rcpp::export]]
int throw_exception() { 
  std::stringstream errmsg; errmsg << "this is an exception";
  throw std::domain_error(errmsg.str()); 
  return 0;
}
'
)

throw_exception()

on Catalina when Apple’s clang++ is used?

No change in result. Without loading a package first, the correct error throws. Afterwards, it fails.

I added verbose = T in case its output helps:

Restarting R session...

> library(rstan)
Loading required package: StanHeaders
rstan (Version 2.19.9, GitRev: 2e1f913d3ca3)
For execution on a local, multicore CPU with excess RAM we recommend calling
options(mc.cores = parallel::detectCores()).
To avoid recompilation of unchanged Stan programs, we recommend calling
rstan_options(auto_write = TRUE)
> 
> Sys.setenv(PKG_LDFLAGS = "-static")
> 
> Rcpp::sourceCpp(code = 
+                   '
+ #include <Rcpp.h>
+ using namespace Rcpp; 
+ 
+ // [[Rcpp::export]]
+ int throw_exception() { 
+   std::stringstream errmsg; errmsg << "this is an exception";
+   throw std::domain_error(errmsg.str()); 
+   return 0;
+ }
+ ',
+ verbose = T
+ )

Generated extern "C" functions 
--------------------------------------------------------


#include <Rcpp.h>
// throw_exception
int throw_exception();
RcppExport SEXP sourceCpp_1_throw_exception() {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    rcpp_result_gen = Rcpp::wrap(throw_exception());
    return rcpp_result_gen;
END_RCPP
}

Generated R functions 
-------------------------------------------------------

`.sourceCpp_1_DLLInfo` <- dyn.load('/private/var/folders/lc/h55t9rqs08df0y000pnp61d40000gn/T/RtmpWD2Ye1/sourceCpp-x86_64-apple-darwin15.6.0-1.0.2/sourcecpp_3e041171732a/sourceCpp_2.so')

throw_exception <- Rcpp:::sourceCppFunction(function() {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_throw_exception')

rm(`.sourceCpp_1_DLLInfo`)

Building shared library
--------------------------------------------------------

DIR: /private/var/folders/lc/h55t9rqs08df0y000pnp61d40000gn/T/RtmpWD2Ye1/sourceCpp-x86_64-apple-darwin15.6.0-1.0.2/sourcecpp_3e041171732a

/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB -o 'sourceCpp_2.so'  'file3e0418632ce.cpp'  
clang++ -std=gnu++11 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I"/Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rcpp/include" -I"/private/var/folders/lc/h55t9rqs08df0y000pnp61d40000gn/T/RtmpWD2Ye1/sourceCpp-x86_64-apple-darwin15.6.0-1.0.2" -isysroot /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk -I/usr/local/include  -fPIC  -Wall -g -O2  -c file3e0418632ce.cpp -o file3e0418632ce.o
clang++ -std=gnu++11 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/usr/local/lib -o sourceCpp_2.so file3e0418632ce.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
> 
> throw_exception()
Error in throw_exception() : c++ exception (unknown reason)

It didn’t take. Maybe try it with

Sys.setenv(PKG_LDLIBS = “-static”)

instead of

Sys.setenv(PKG_LDFLAGS = “-static”)

This is not working for me when I run:

example(stan_model, run.dontrun = TRUE)

This is the resulting error I get at the end of it:

Error in compileCode(f, code, language = language, verbose = verbose) :
Compilation ERROR, function(s)/method(s) not created! In file included from file5cb6aa88d5a.cpp:8:
In file included from /Users/lukemansillo/Library/R/3.6/library/StanHeaders/include/src/stan/model/model_header.hpp:4:
In file included from /Users/lukemansillo/Library/R/3.6/library/StanHeaders/include/stan/math.hpp:4:
In file included from /Users/lukemansillo/Library/R/3.6/library/StanHeaders/include/stan/math/rev/mat.hpp:4:
In file included from /Users/lukemansillo/Library/R/3.6/library/StanHeaders/include/stan/math/rev/core.hpp:5:
In file included from /Users/lukemansillo/Library/R/3.6/library/StanHeaders/include/stan/math/rev/core/build_vari_array.hpp:4:
In file included from /Users/lukemansillo/Library/R/3.6/library/StanHeaders/include/stan/math/prim/mat/fun/Eigen.hpp:4:
In file included from /Library/Frameworks/R.framework/Versions/3.6/Resources/library/RcppEigen/include/Eigen/Dense:1:
In file included from /Library/Frameworks/R.framework/Versions/3.6/Resources/library/Rc

Does anyone with Catalina want to try a clang++ from the LLVM website

http://releases.llvm.org/

as opposed to the one from CRAN?

@bgoodri, any particular version of clang++ you want us to install?

For what it’s worth, I’ve found that while the RStan setup using the mainline Anaconda packages doesn’t work on my Mac, RStan via conda-forge does, at least for me. I suspect that has to do with conda-forge using more up-to-date compilers.

Bear in mind, though, that this is with an older version of MacOS, so I don’t know if that’s relevant for Catalina. That said, one could, say, install Miniconda, create a Conda environment with the conda-forge RStan package and relevant dependencies, and delete the installation if it doesn’t work. It would be interesting to see if that worked.

Let’s try clang-7.

I have not recompiled RStan, Rcpp, etc. Just tell me what to do and I’ll do it.

@bgoodri, I take my data and run:

library(rstan)
library(brms)
post ← stan(model_code = make_stancode(y ~ 1 + (1 | algorithm), data = df),
data = make_standata(y ~ 1 + (1 | algorithm), data = df),
verbose = TRUE)

Using (d/l binary from llvm):

system(“clang++ --version”)
clang version 8.0.0 (tags/RELEASE_800/final)
Target: x86_64-apple-darwin19.0.0
Thread model: posix
InstalledDir: /Users/torkarr/Downloads/clang+llvm-8.0.0-x86_64-apple-darwin/bin

Results in:

Chain 1: Iteration: 1 / 2000 [ 0%] (Warmup)
[1] “Error in sampler$call_sampler(args_list[[i]]) : "
[2] " c++ exception (unknown reason)”

Using (Coatless):

system(“clang++ --version”)
clang version 7.0.0 (tags/RELEASE_700/final)
Target: x86_64-apple-darwin19.0.0
Thread model: posix
InstalledDir: /usr/local/clang7/bin

Results in:

Chain 2: Iteration: 1 / 2000 [ 0%] (Warmup)
[1] “Error in sampler$call_sampler(args_list[[i]]) : "
[2] " c++ exception (unknown reason)”

Using (Xcode):

system(“clang++ --version”)
Apple clang version 11.0.0 (clang-1100.0.33.8)
Target: x86_64-apple-darwin19.0.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Results in:

Chain 2: Iteration: 1 / 2000 [ 0%] (Warmup)
[1] “Error in sampler$call_sampler(args_list[[i]]) : "
[2] " c++ exception (unknown reason)”

I’m not really sure there is a work around for this.

I think we’re seeing an exception get thrown cross-translation unit. This seems to error more with clang than gcc. Details: https://github.com/RcppCore/Rcpp/issues/972

I’ve asked Kevin to take a look.

I suspect this is caused by an incompatibility in the versions of libc++ shipped by Apple versus that shipped with R (and used by the Clang 7 toolchain used to build R).

In particular, if I inspect the library compiled by Stan, I see:

kevinushey@Kevins-MacBook-Pro:/var/folders/b4/2422hswx71z8mgwtv4rhxchr0000gn/T/RtmpLIAtcW
$ otool -L filed1635bbe64b.so
filed1635bbe64b.so:
        filed1635bbe64b.so (compatibility version 0.0.0, current version 0.0.0)
        /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libR.dylib (compatibility version 3.6.0, current version 3.6.1)
        /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation (compatibility version 150.0.0, current version 1670.10.0)
        /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 800.6.0)
        /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1281.0.0)

Note the usage of /usr/lib/libc++.1.dylib.

But if you look at the library actually loaded by the R session, I see (when run in RStudio):

$ lsof -p `pgrep -x rsession` | grep libc++
rsession 53603 kevinushey  txt      REG                1,8   216576            26186544 /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libc++abi.1.dylib
rsession 53603 kevinushey  txt      REG                1,8   845100            26186543 /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libc++.1.dylib

And note that a copy of libc++.1.dylib as provided with R was loaded instead.

This occurs regardless of whether you’re using the built-in Apple compiler, or the LLVM compiler toolchain provided by R. I suspect some extra flags need to be passed in during compilation to ensure that the compiled shared object uses the same standard library as R does.

As a side note, it’s possible to change the library used post-hoc; e.g.

install_name_tool -change \
    /usr/lib/libc++.1.dylib \
    /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libc++.1.dylib \
    /path/to/object.so

would hopefully work. That’s something rstan could potentially do to fix up the compiled object post-hoc.

@kevinushey, so it’s somehow connected to this: Error in rstan

I won’t have the time to check thoroughly but simply removing .R/Makevars makes the bug go away. If I put .R/Makevars back, the bug is there. At least for the example, which I provided, it’s consistently so.

Thanks @kevinushey . We have been using your hack in rstan and related packages


but I guess we need to target /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libc++.1.dylib, at least for R 3.6 . Is it similar for R 3.5 etc. but with a different directory?

Someone experiencing this issue please try the improved fix_Mac function upthread

R 3.5.x also bundles libc++, fortunately with the same name:

$ realpath libc++.1.dylib
/Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libc++.1.dylib

For newer releases of R, I think you can generally assume that if R is bundling libc++, it will be at that location within the lib folder. E.g.:

rhome <- normalizePath(R.home())
libcpp <- file.path(rhome, "lib/libc++.1.dylib")
if (file.exists(libcpp)) { ... }

As an aside, if I understand correctly, that function works the other way around – preferring usage of the system C++ standard library, as opposed to the one bundled with R?

I think as long as all packages are using the same standard library things should work, but I wonder if that should be the other way around (force usage of the R-bundled libc++). There are probably reasons to prefer one approach over the other, though.