Using C++ execution header in R package

101 Views Asked by At

I am developing an R package containing C++ code, and I would like to use the standard library header "execution". As C++17 is the default on CRAN now, this seems to be fine. However, this header is not yet implemented in Apple Clang, and from what I can tell from the R for macOS Developer website, C++ code in R packages on macOS will be compiled using Apple's toolchain.

Hence, my question is: Let's say I have a function similar to the one below, computing the set difference in parallel. Would this cause the package build to fail for macOS on CRAN?

#include <RcppArmadillo.h>
#include <execution>
using namespace arma;

// [[Rcpp::export]]
vec setdiff(const vec& x, const vec& y) {
  vec xs = sort(x);
  vec ys = sort(y);

  std::vector<double> diff;
  std::set_difference(
    std::execution::par,
    xs.begin(), xs.end(), ys.begin(), ys.end(),
    std::inserter(diff, diff.begin()));

  return conv_to<vec>::from(diff);
}

/*** R
setdiff(1:10, 3)
*/


On my own M1 Mac, I can make this compile by adding the following lines to ~/.R/Makevars, thus making sure I use g++ and not Apply clang.

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

There are 2 best solutions below

0
Øystein S On

I tried something similar to what @SymbolixAU suggested in a comment.

I created a package named anRpackage with the following files:

  • DESCRIPTION
Package: anRpackage
Type: Package
Title: What the package does (short line)
Version: 1.0
Date: 2024-01-09
Author: Who wrote it
Maintainer: Who to complain to <[email protected]>
Description: More about what it does (maybe more than one line). One more 
  sentence.
License: GPL-3
Imports: Rcpp
LinkingTo: Rcpp, RcppArmadillo
RoxygenNote: 7.2.3
Encoding: UTF-8
  • src/setdiff.cpp
#include "RcppArmadillo.h"
#include <execution>
using namespace arma;

// [[Rcpp::depends(RcppArmadillo)]]


// [[Rcpp::export]]
arma::vec setdiff_par(const arma::vec& x, const arma::vec& y) {
  vec xs = sort(x);
  vec ys = sort(y);
  
  std::vector<double> diff;
  std::set_difference(
    std::execution::par,
    xs.begin(), xs.end(), ys.begin(), ys.end(),
    std::inserter(diff, diff.begin()));
  
  return conv_to<vec>::from(diff);
}
  • src/Makevars and src/Makevars.win
PKG_CXXFLAGS = $(SHLIB_OPENMP_CXXFLAGS)
PKG_LIBS = $(SHLIB_OPENMP_CXXFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(FLIBS)
  • An R directory containing the auto-generated RcppExports.R.

Submitting to win-builder, devtools::check_win_devel(), it succeeded. Instead submitting to R Mac Builder, the build failed.

0
Ada Lovelace On

You are having an issue with a particular compiler and implementation of C++17 which is different from having an issue with C++17 'per se'.

Writing R Extensions is IIRC pretty clear about 'as provided by the compiler'. In this case, the C++17 feature you desire is offered by recent g++ version (including on macOS) but not on the (prescribed by the CRAN macOS maintainer) clang++ version you are faced with on macOS.

There is no path for you to use this on macOS at CRAN until the toolchain updates.