Skip to content

Commit f4237b5

Browse files
committed
allow customization of RcppParallel backend at runtime
1 parent b216ba2 commit f4237b5

File tree

6 files changed

+121
-32
lines changed

6 files changed

+121
-32
lines changed

R/hooks.R

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,6 @@ mallocDllInfo <- NULL
2525
# load the package library
2626
library.dynam("RcppParallel", pkgname, libname)
2727

28-
# set default thread options
29-
numThreads <- "auto"
30-
numThreadsEnv <- Sys.getenv("RCPP_PARALLEL_NUM_THREADS", unset = NA)
31-
if (!is.na(numThreadsEnv))
32-
setThreadOptions(numThreads = as.integer(numThreadsEnv))
33-
else
34-
setThreadOptions(numThreads = "auto")
3528
}
3629

3730
.onUnload <- function(libpath) {

inst/NEWS

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
RcppParallel 4.4.5 (UNRELEASED)
1+
RcppParallel 5.0.0 (UNRELEASED)
22
------------------------------------------------------------------------
3+
* RcppParallel backend can now be customized with RCPP_PARALLEL_BACKEND
4+
environment variable (supported values are 'tbb' and 'tinythread')
35
* Fixed issue when compiling RcppParallel on macOS Catalina
46
* Fixed issue when compiling RcppParallel with Rtools40
57

inst/include/RcppParallel.h

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,44 +10,53 @@
1010
// compatibility with CRAN packages not previously configured
1111
// to link to TBB in Makevars.win)
1212
#ifndef RCPP_PARALLEL_USE_TBB
13-
#if defined(__APPLE__) || defined(__gnu_linux__) || ((defined(__sun) && defined(__SVR4) && !defined(__sparc)))
14-
#define RCPP_PARALLEL_USE_TBB 1
15-
#include "RcppParallel/TBB.h"
16-
#else
17-
#define RCPP_PARALLEL_USE_TBB 0
18-
#endif
13+
# if defined(__APPLE__) || defined(__gnu_linux__) || (defined(__sun) && defined(__SVR4) && !defined(__sparc))
14+
# define RCPP_PARALLEL_USE_TBB 1
15+
# else
16+
# define RCPP_PARALLEL_USE_TBB 0
17+
# endif
1918
#endif
2019

2120
#if RCPP_PARALLEL_USE_TBB
22-
#include "RcppParallel/TBB.h"
21+
# include "RcppParallel/TBB.h"
2322
#endif
2423

24+
#include "RcppParallel/Backend.h"
25+
2526
#include "RcppParallel/RVector.h"
2627
#include "RcppParallel/RMatrix.h"
2728

2829
namespace RcppParallel {
2930

30-
inline void parallelFor(std::size_t begin, std::size_t end,
31-
Worker& worker, std::size_t grainSize = 1) {
32-
31+
inline void parallelFor(std::size_t begin,
32+
std::size_t end,
33+
Worker& worker,
34+
std::size_t grainSize = 1)
35+
{
3336
#if RCPP_PARALLEL_USE_TBB
34-
tbbParallelFor(begin, end, worker, grainSize);
37+
if (internal::backend() == internal::BACKEND_TBB)
38+
tbbParallelFor(begin, end, worker, grainSize);
39+
else
40+
ttParallelFor(begin, end, worker, grainSize);
3541
#else
3642
ttParallelFor(begin, end, worker, grainSize);
3743
#endif
38-
3944
}
4045

4146
template <typename Reducer>
42-
inline void parallelReduce(std::size_t begin, std::size_t end,
43-
Reducer& reducer, std::size_t grainSize = 1) {
44-
47+
inline void parallelReduce(std::size_t begin,
48+
std::size_t end,
49+
Reducer& reducer,
50+
std::size_t grainSize = 1)
51+
{
4552
#if RCPP_PARALLEL_USE_TBB
46-
tbbParallelReduce(begin, end, reducer, grainSize);
53+
if (internal::backend() == internal::BACKEND_TBB)
54+
tbbParallelReduce(begin, end, reducer, grainSize);
55+
else
56+
ttParallelReduce(begin, end, reducer, grainSize);
4757
#else
4858
ttParallelReduce(begin, end, reducer, grainSize);
4959
#endif
50-
5160
}
5261

5362
} // namespace RcppParallel
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
2+
#ifndef __RCPP_PARALLEL_BACKEND__
3+
#define __RCPP_PARALLEL_BACKEND__
4+
5+
#include <cstdlib>
6+
#include <cstring>
7+
8+
extern "C" {
9+
void REprintf(const char*, ...);
10+
}
11+
12+
namespace RcppParallel {
13+
namespace internal {
14+
15+
enum backend_type {
16+
BACKEND_TBB,
17+
BACKEND_TINYTHREAD
18+
};
19+
20+
#if RCPP_PARALLEL_USE_TBB
21+
22+
inline backend_type defaultBackend()
23+
{
24+
return BACKEND_TBB;
25+
}
26+
27+
#else
28+
29+
inline backend_type defaultBackend()
30+
{
31+
return BACKEND_TINYTHREAD;
32+
}
33+
34+
#endif
35+
36+
37+
38+
inline const char* backendToString(backend_type backend)
39+
{
40+
switch (backend)
41+
{
42+
case BACKEND_TBB: return "tbb";
43+
case BACKEND_TINYTHREAD: return "tinythread";
44+
}
45+
}
46+
47+
inline backend_type backend()
48+
{
49+
const char* requestedBackend = std::getenv("RCPP_PARALLEL_BACKEND");
50+
if (requestedBackend == NULL)
51+
{
52+
return defaultBackend();
53+
}
54+
else if (std::strcmp(requestedBackend, "tbb") == 0)
55+
{
56+
#if RCPP_PARALLEL_USE_TBB
57+
return BACKEND_TBB;
58+
#else
59+
REprintf("tbb backend is not available; using tinythread instead\n");
60+
return BACKEND_TINYTHREAD;
61+
#endif
62+
}
63+
else if (strcmp(requestedBackend, "tinythread") == 0)
64+
{
65+
return BACKEND_TINYTHREAD;
66+
}
67+
else
68+
{
69+
const char* fmt = "unknown parallel backend '%s'; using '%s' instead\n";
70+
REprintf(fmt, requestedBackend, backendToString(defaultBackend()));
71+
return defaultBackend();
72+
}
73+
}
74+
75+
} // namespace internal
76+
} // namespace RcppParallel
77+
78+
#endif /* __RCPP_PARALLEL_BACKEND__ */

inst/include/RcppParallel/TinyThread.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22
#define __RCPP_PARALLEL_TINYTHREAD__
33

44
#include <cstdlib>
5+
#include <cstdio>
56

67
#include "Common.h"
78

89
#include <tthread/tinythread.h>
910

10-
#include <stdio.h>
1111

1212
#include <vector>
1313

tests/doRUnit.R

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,21 @@
1-
stopifnot(require(RUnit, quietly=TRUE))
2-
stopifnot(require(Rcpp, quietly=TRUE))
3-
stopifnot(require(RcppParallel, quietly=TRUE))
1+
stopifnot(require(RUnit, quietly = TRUE))
2+
stopifnot(require(Rcpp, quietly = TRUE))
3+
stopifnot(require(RcppParallel, quietly = TRUE))
44

55
## Set a seed to make the test deterministic
66
set.seed(42)
77

8+
# Don't use TBB
9+
Sys.setenv(RCPP_PARALLEL_BACKEND = "tinythread")
10+
811
## Define tests
9-
suite <- defineTestSuite(name="RcppParallel Unit Tests",
10-
dirs=system.file("tests", package = "RcppParallel"))
12+
suite <- defineTestSuite(
13+
name = "RcppParallel Unit Tests",
14+
dirs = system.file("tests", package = "RcppParallel")
15+
)
1116

1217
## Based on practice in Rcpp to avoid some test failures
13-
Sys.setenv("R_TESTS"="")
18+
Sys.setenv("R_TESTS" = "")
1419

1520
## Run tests
1621
tests <- runTestSuite(suite)
@@ -22,9 +27,11 @@ printTextProtocol(tests)
2227
if (getErrors(tests)$nFail > 0) {
2328
stop("TEST FAILED!")
2429
}
30+
2531
if (getErrors(tests)$nErr > 0) {
2632
stop("TEST HAD ERRORS!")
2733
}
34+
2835
if (getErrors(tests)$nTestFunc < 1) {
2936
stop("NO TEST FUNCTIONS RUN!")
3037
}

0 commit comments

Comments
 (0)