Problem compling rstan models on Mac M1 with clang 13.0.0

Since a recent reinstall of my compiler toolchain I encounter a strange error that prevents me from compiling any models with rstan as well as compiling rstan itself.

For example

install.packages("rstan", repos = c("https://mc-stan.org/r-packages/", getOption("repos")))

(or any attempt to compile an rstan model with any precompiled version of rstan) gives me

error: unknown target CPU 'vortex'
note: valid target CPU values are: i386, i486, winchip-c6, winchip2, c3, i586, pentium, pentium-mmx, pentiumpro, i686, pentium2, pentium3, pentium3m, pentium-m, c3-2, yonah, pentium4, pentium4m, prescott, nocona, core2, penryn, bonnell, atom, silvermont, slm, goldmont, goldmont-plus, tremont, nehalem, corei7, westmere, sandybridge, corei7-avx, ivybridge, core-avx-i, haswell, core-avx2, broadwell, skylake, skylake-avx512, skx, cascadelake, cooperlake, cannonlake, icelake-client, icelake-server, tigerlake, sapphirerapids, alderlake, knl, knm, lakemont, k6, k6-2, k6-3, athlon, athlon-tbird, athlon-xp, athlon-mp, athlon-4, k8, athlon64, athlon-fx, opteron, k8-sse3, athlon64-sse3, opteron-sse3, amdfam10, barcelona, btver1, btver2, bdver1, bdver2, bdver3, bdver4, znver1, znver2, znver3, x86-64, geode
make: *** [Module.o] Error 1

So CPU target “vortex” does not seem to be recognized as valid CPU target by clang 13.0.0. I couldn’t find much about this “vortex” target but what I found pointed to some (outdated?) aliases of arm64 type processors, which are the ones used in my mac.

This is my setup:

  • MacOS Monterey 12.1
  • M1 Max Chip
  • R 4.1.2 binary for Mac M1 (arm64) from https://cran.r-project.org/
  • The current version of CommanLineTools, with clang 13.0.0:
clang --version
Apple clang version 13.0.0 (clang-1300.0.27.3)
Target: arm64-apple-darwin21.2.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

I can compile and run cmdstanr models normally, with cmdstan build with the compiler above, so Stan itself does not seem to be broken.

Any suggestions would be highly appreciated!

That’s definitely an odd one!

Can you try compiling c++ through both R CMD SHLIB and Rcpp? I’m wondering which stage is introducing the error:

system('touch foo.cpp')
system('R CMD SHLIB foo.cpp')

and

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

  // [[Rcpp::export]]
  int fibonacci(const int x) {
    if (x == 0) return(0);
    if (x == 1) return(1);
    return (fibonacci(x - 1)) + fibonacci(x - 2);
  }'
,verbose=T)
1 Like

Thanks for coming back to me so quickly! Below is my reprex and output of R:

> sink("foo.cpp")
> cat('
+   int fibonacci(const int x) {
+ 
+     if (x == 0) return(0);
+ 
+     if (x == 1) return(1);
+ 
+     return (fibonacci(x - 1)) + fibonacci(x - 2);
+ 
+   }')
> sink()
> system('touch foo.cpp')
> system('R CMD SHLIB foo.cpp')
clang++ -arch arm64 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c foo.cpp -o foo.o
clang++ -arch arm64 -std=gnu++14 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/opt/R/arm64/lib -o foo.so foo.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation
> Rcpp::sourceCpp(code='
+ 
+   #include <Rcpp.h>
+ 
+ 
+ 
+   // [[Rcpp::export]]
+ 
+   int fibonacci(const int x) {
+ 
+     if (x == 0) return(0);
+ 
+     if (x == 1) return(1);
+ 
+     return (fibonacci(x - 1)) + fibonacci(x - 2);
+ 
+   }',
+   verbose=T)

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


#include <Rcpp.h>
#ifdef RCPP_USE_GLOBAL_ROSTREAM
Rcpp::Rostream<true>&  Rcpp::Rcout = Rcpp::Rcpp_cout_get();
Rcpp::Rostream<false>& Rcpp::Rcerr = Rcpp::Rcpp_cerr_get();
#endif

// fibonacci
int fibonacci(const int x);
RcppExport SEXP sourceCpp_1_fibonacci(SEXP xSEXP) {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    Rcpp::traits::input_parameter< const int >::type x(xSEXP);
    rcpp_result_gen = Rcpp::wrap(fibonacci(x));
    return rcpp_result_gen;
END_RCPP
}

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

`.sourceCpp_1_DLLInfo` <- dyn.load('/private/var/folders/yx/cyjlcbj51cv_vnkyryldf39c0000gn/T/RtmpAuCVZW/sourceCpp-aarch64-apple-darwin20-1.0.8/sourcecpp_4546393b59c3/sourceCpp_2.so')

fibonacci <- Rcpp:::sourceCppFunction(function(x) {}, FALSE, `.sourceCpp_1_DLLInfo`, 'sourceCpp_1_fibonacci')

rm(`.sourceCpp_1_DLLInfo`)

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

DIR: /private/var/folders/yx/cyjlcbj51cv_vnkyryldf39c0000gn/T/RtmpAuCVZW/sourceCpp-aarch64-apple-darwin20-1.0.8/sourcecpp_4546393b59c3

/Library/Frameworks/R.framework/Resources/bin/R CMD SHLIB -o 'sourceCpp_2.so' 'file454664230d41.cpp' 
clang++ -arch arm64 -std=gnu++14 -I"/Library/Frameworks/R.framework/Resources/include" -DNDEBUG   -I"/Library/Frameworks/R.framework/Versions/4.1-arm64/Resources/library/Rcpp/include" -I"/private/var/folders/yx/cyjlcbj51cv_vnkyryldf39c0000gn/T/RtmpAuCVZW/sourceCpp-aarch64-apple-darwin20-1.0.8" -I/opt/R/arm64/include   -fPIC  -falign-functions=64 -Wall -g -O2  -c file454664230d41.cpp -o file454664230d41.o
clang++ -arch arm64 -std=gnu++14 -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/Library/Frameworks/R.framework/Resources/lib -L/opt/R/arm64/lib -o sourceCpp_2.so file454664230d41.o -F/Library/Frameworks/R.framework/.. -framework R -Wl,-framework -Wl,CoreFoundation

So everything seems to run without issues from what I can see.

The plot thickens! So likely something related to rstan's compiler flags then. Can you try the example model and post the output? That should show what flags stan is using and where:

example(stan_model,package="rstan",run.dontrun=T,verbose=T)

I have found the problem after you suggested that in may be the compiler flags. In my Makevars I had

CXX14FLAGS = -O3 -mtune=native 
CXX14FLAGS += -arch x86_64 -ftemplate-depth-256

I don’t know where I got the second line from, perhaps an old Stan discourse post about M1 Macs? In any case, commenting out the second line fixes the problem!

2 Likes

Phew, glad it was something simple!

Me too! I am just confused that It did work before with -arch x86_64 on my M1 Mac and only refused to work after some update on the system side.

Thank you very much for your help!

1 Like