Giter VIP home page Giter VIP logo

Comments (9)

coatless avatar coatless commented on August 20, 2024 2

@osorensen from what I remember, there is no way to enable openmp on mac for RcppArmadillo as its underlying installation configuration does a hard check against whether you have the Apple LLVM being used. (regardless of whether you do the cran trick.)

RcppArmadillo/configure.ac

Lines 118 to 123 in 2277661

apple_compiler=$($CXX --version 2>&1 | grep -i -c -e 'apple llvm')
if test x"${apple_compiler}" = x"1"; then
AC_MSG_RESULT([found])
AC_MSG_WARN([OpenMP unavailable and turned off.])
can_use_openmp="no"

So, you would need to use the homebrew'd R version to be able to switch to gcc. Then, that should probably yield similar output. The alternative here is to just use Rcpp data types to avoid battling OpenMP flags as you've adopted.

from rcpparmadillo.

osorensen avatar osorensen commented on August 20, 2024 1

Wanted to post an update here in case someone else has the same issue. I am on an M1 Mac using mac OS 14.2.1. After first installing gcc with brew install gcc I created a file ~/.R/Makevars with the following content:

CXX=/opt/homebrew/bin/g++-13
CXX17=/opt/homebrew/bin/g++-13

This makes sure that my C++ code is compiled with gcc and not clang.

After this change, the results on mac OS are identical to the results on Windows.

from rcpparmadillo.

eddelbuettel avatar eddelbuettel commented on August 20, 2024

Howdy, and thanks for filing a ticket! And such a detailed one. The same code should, as you surmise, generate identical code on both platforms. I am sure we can drill into this.

I was about to scratch my head on this but I may have spotted the 'smoking gun' thanks to your verbose code output. I am not sure if you noticed or not but on Windows your compilation is using OpenMP whereas on the macOS machine it is not. (Looong story of why, in short complain to Cupertino, not us.) On my Linux machine I also have OpenMP and I get results that are identical to your Windows results.

So in some sense we could argue that your two setups are in fact not identical: One permits for parallel execution, the other does not. If you really wanted to nail down identical results for this setup you may have to look into either adding OpenMP to your macOS setup (and I forget if that is easy or hard as I am on a different platform) or force the alternate implentation to forgo OpenMP (and I think there are optional #define variables you can set).

from rcpparmadillo.

osorensen avatar osorensen commented on August 20, 2024

Thanks for the quick response. Here are the results of a couple of things I tried.

I went into etc\x64\Makeconf on Windows and commented out the four lines related to OpenMP. Here is the relevant part of the file.

#SHLIB_OPENMP_CFLAGS = -fopenmp
#SHLIB_OPENMP_CXXFLAGS = -fopenmp
#SHLIB_OPENMP_FCFLAGS = -fopenmp
#SHLIB_OPENMP_FFLAGS = -fopenmp

Next, running Rcpp::sourceCpp("test.cpp", verbose = TRUE) on Windows gives identical output as before, and is not the same as on Mac. Here is the verbose output, where the are no -fopenmp anywhere:

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

// test
arma::uvec test();
RcppExport SEXP sourceCpp_1_test() {
BEGIN_RCPP
    Rcpp::RObject rcpp_result_gen;
    Rcpp::RNGScope rcpp_rngScope_gen;
    rcpp_result_gen = Rcpp::wrap(test());
    return rcpp_result_gen;
END_RCPP
}

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

`.sourceCpp_1_DLLInfo` <- dyn.load('C:/Users/oyste/AppData/Local/Temp/RtmpKMJ3QY/sourceCpp-x86_64-w64-mingw32-1.0.11.6/sourcecpp_490c3f9376d1/sourceCpp_2.dll')

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

rm(`.sourceCpp_1_DLLInfo`)

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

DIR: C:/Users/oyste/AppData/Local/Temp/RtmpKMJ3QY/sourceCpp-x86_64-w64-mingw32-1.0.11.6/sourcecpp_490c3f9376d1

C:/PROGRA~1/R/R-43~1.2/bin/x64/R CMD SHLIB -o "sourceCpp_2.dll" "test.cpp" 
using C++ compiler: 'G__~1.EXE (GCC) 12.3.0'
using C++11
g++  -std=gnu++11 -I"C:/PROGRA~1/R/R-43~1.2/include" -DNDEBUG -I../inst/include   -I"C:/Users/oyste/AppData/Local/R/win-library/4.3/Rcpp/include" -I"C:/Users/oyste/AppData/Local/R/win-library/4.3/RcppArmadillo/include" -I"C:/Users/oyste/AppData/Local/R/win-library/4.3/testthat/include" -I"C:/Users/oyste/Documents/BayesMallows/work-docs" -I"C:/Users/oyste/Documents/BayesMallows/inst/include"   -I"C:/rtools43/x86_64-w64-mingw32.static.posix/include"     -O2 -Wall  -mfpmath=sse -msse2 -mstackrealign  -c test.cpp -o test.o
g++ -shared -s -static-libgcc -o sourceCpp_2.dll tmp.def test.o -LC:/PROGRA~1/R/R-43~1.2/bin/x64 -lRlapack -LC:/PROGRA~1/R/R-43~1.2/bin/x64 -lRblas -lgfortran -lm -lquadmath -LC:/rtools43/x86_64-w64-mingw32.static.posix/lib/x64 -LC:/rtools43/x86_64-w64-mingw32.static.posix/lib -LC:/PROGRA~1/R/R-43~1.2/bin/x64 -lR

I also tried what is described here for enabling OpenMP on macOS. It seemingly compiled on Mac with -fopenmp, but the results were still the same as before.

from rcpparmadillo.

osorensen avatar osorensen commented on August 20, 2024

Finally, Rcpp::sample does give identical output across platforms, so in my case a solution seems to be to convert the arma vectors to Rcpp vectors and work with them instead.

The following code:

#include <Rcpp.h>

// [[Rcpp::export]]
Rcpp::IntegerVector test() {
  Rcpp::NumericVector probs(20, .05);
  Rcpp::IntegerVector inds(20);
  for(size_t i{}; i < 20; i++) inds(i) = i;
  return Rcpp::sample(inds, inds.size(), true, probs);
}

/*** R
set.seed(3)
test()
*/

Returns on both Mac and Windows:

> test()
 [1]  4 17  8  7 13 13  3  6 12 13 11 11 11 12 18 17  3 15 18  6

which also happens to be the same as Rcpp::RcppArmadillo::sample() returned on Windows.

from rcpparmadillo.

osorensen avatar osorensen commented on August 20, 2024

Thanks @coatless. From what I can tell, this seems to be the case both for RcppArmadilloExtensions as well as for the random number generating functions provided by Armadillo.

Here is an example with the arma::shuffle() function, which caused trouble in unit testing on my part.

#include <RcppArmadillo.h>
// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
arma::ivec test(int size) {
  arma::ivec inds = arma::regspace<arma::ivec>(0, size - 1);
  return arma::shuffle(inds);
}

/*** R
set.seed(1)
apply(sapply(1:1000, function(i) test(100)), 1, mean)
*/

With a lower number of replications or a lower argument to test(), the outputs were identical, although I did not explore it very extensively.

Mac OS

Returns

  [1] 49.074 48.727 50.330 49.968 50.084 49.594 48.305 49.971 49.395 49.389 49.081 46.842 49.795 49.839 49.005 50.672 49.905 48.596
 [19] 49.098 48.104 50.785 49.354 49.896 49.514 50.969 49.265 50.980 50.066 49.246 49.207 50.174 49.441 48.751 51.817 49.472 50.349
 [37] 47.793 49.500 49.303 50.138 48.515 50.944 49.940 49.712 49.385 49.487 49.125 50.438 50.172 48.529 50.886 49.160 50.534 48.480
 [55] 49.009 50.127 50.308 50.230 51.442 46.912 50.178 49.366 49.233 48.055 49.150 49.996 47.745 50.436 49.037 49.126 48.241 49.642
 [73] 48.950 49.248 49.598 48.758 49.154 49.784 50.409 49.060 51.287 51.046 51.709 48.915 49.544 48.929 49.682 51.286 49.362 49.857
 [91] 49.773 47.853 47.884 48.432 49.137 48.385 50.730 49.186 48.837 47.871

Windows

Returns

[1] 49.032 48.769 50.335 49.963 50.084 49.552 48.365 49.953 49.395 49.422 49.051 46.785 49.789 49.899 49.005
 [16] 50.672 49.905 48.596 49.055 48.147 50.861 49.278 49.896 49.393 51.131 49.233 50.971 50.066 49.246 49.229
 [31] 50.216 49.377 48.751 51.817 49.472 50.357 47.785 49.500 49.282 50.123 48.551 50.971 49.922 49.749 49.339
 [46] 49.430 49.267 50.315 50.197 48.545 50.883 49.166 50.528 48.480 48.978 50.198 50.268 50.209 51.506 46.957
 [61] 50.062 49.294 49.336 48.052 49.158 49.988 47.742 50.439 49.037 49.170 48.197 49.580 48.942 49.277 49.639
 [76] 48.758 49.154 49.784 50.409 49.060 51.287 50.996 51.759 48.915 49.611 48.855 49.703 51.209 49.379 49.903
 [91] 49.773 47.853 47.884 48.457 49.112 48.388 50.691 49.194 48.857 47.879

from rcpparmadillo.

eddelbuettel avatar eddelbuettel commented on August 20, 2024

Finally, Rcpp::sample does give identical output across platforms, so in my case a solution seems to be to convert the arma vectors to Rcpp vectors and work with them instead.

I was about to suggest something along those line. The use of parallel code was likely coming from the vector creation so should be easy to circumvent.

I had also poked into the header and it seems we have no explicit switch to turn off OpenMP (as we had no need yet) as @coatless alluded to. So yes, your best bet is probably to work with the (newer, anyway) sample() than the older contributed extension if you desire identical results.

Can this be closed then as nothing really actionable has come up?

from rcpparmadillo.

osorensen avatar osorensen commented on August 20, 2024

Can this be closed then as nothing really actionable has come up?

Sure, and thanks again for helping.

from rcpparmadillo.

eddelbuettel avatar eddelbuettel commented on August 20, 2024

Sure thing!

from rcpparmadillo.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.