Monte Carlo simulations provide a powerful computational approach to address a wide variety of problems in several domains, such as physical sciences, engineering, computational biology and finance. The independent-samples and large-scale nature of Monte Carlo simulations make the corresponding computation suited for parallel execution, at least in theory. In practice, pseudo-random number generators (RNGs) are intrinsically sequential. This often prevents having a parallel Monte Carlo algorithm that is *playing fair*, meaning that results are independent of the architecture, parallelization techniques and number of parallel processes.

**rTRNG** is an R package for advanced parallel Random Number Generation in R. It relies on **TRNG** (Tina’s Random Number Generator), a state-of-the-art C++ pseudo-random number generator library for sequential and parallel Monte Carlo simulations. In particular, *parallel* random number engines provided by TRNG can be manipulated by `jump`

and `split`

operations. These allow to `jump`

ahead by an arbitrary number of steps and to `split`

a sequence into any desired sub-sequence(s), thus enabling techniques such as *block-splitting* and *leapfrogging* suitable to parallel algorithms.

Package **rTRNG** provides the R users with access to the functionality of the underlying TRNG C++ library, both in R and as part of other projects combining R with C++.

The TRNG.Random functionality (see `?TRNG.Random`

) provides a base-R-like access to TRNG random number engines by setting and manipulating the current engine in use.

```
library(rTRNG)
TRNGkind("yarn2")
TRNGseed(117)
TRNGjump(5) # advance by 5 the internal state
TRNGsplit(3, 2) # subsequence: one element every 3 starting from the 2nd
```

Random variates from the current engine are then generated using functions `r<dist>_trng`

, e.g. `runif_trng`

for the uniform distribution.

```
<- runif_trng(10)
x
x## [1] 0.9085960 0.8689441 0.3540530 0.7378240 0.0052939 0.5866284 0.6862086
## [8] 0.7088267 0.6622958 0.8182121
```

Random number engines can be explicitly created and manipulated using reference objects from a number of classes (see `?TRNG.Engine`

), e.g. `yarn2`

.

```
<- yarn2$new()
rng $seed(117)
rng# alternative: rng <- yarn2$new(117)
$jump(5)
rng$split(3, 2) rng
```

The engine object is then passed as `engine`

argument of any `r<dist>_trng`

function.

```
<- runif_trng(10, engine = rng)
x
x## [1] 0.9085960 0.8689441 0.3540530 0.7378240 0.0052939 0.5866284 0.6862086
## [8] 0.7088267 0.6622958 0.8182121
```

The parallel nature of TRNG random number engines allows *fair-playing* multi-threaded generation of random variates, with guaranteed equivalence to a purely-sequential generation. Parallel generation is available in `r<dist>_trng`

with argument `parallelGrain > 0`

and relies on `RcppParallel`

, where the number of parallel threads is controlled via `RcppParallel::setThreadOptions`

.

```
TRNGseed(117)
::setThreadOptions(numThreads = 2)
RcppParallel<- runif_trng(1e5, parallelGrain = 100)
x_parallel TRNGseed(117)
<- runif_trng(1e5)
x_serial identical(x_serial, x_parallel)
## [1] TRUE
```

C++ code using the C++ TRNG library and headers shipped with **rTRNG** can easily be compiled, specifying the `Rcpp::depends`

attribute that allows `Rcpp::sourceCpp`

to link correctly against the library. Moreover, `Rcpp::plugins(cpp11)`

is needed to enforce the C++11 standard required by TRNG >= 4.22.

```
// [[Rcpp::depends(rTRNG)]]
// TRNG >= 4.22 requires C++11
// [[Rcpp::plugins(cpp11)]]
#include <Rcpp.h>
#include <trng/yarn2.hpp>
#include <trng/uniform_dist.hpp>
using namespace Rcpp;
using namespace trng;
// [[Rcpp::export]]
NumericVector exampleCpp() {
yarn2 rng;117);
rng.seed(// alternative: yarn2 rng(117);
5);
rng.jump(3, 1); // note the C++ 0-based index for the subsequence
rng.split(10);
NumericVector x(0, 1);
uniform_dist<> unif(for (unsigned int i = 0; i < 10; i++) {
x[i] = unif(rng);
}return x;
}/*** R
exampleCpp()
*/
```

```
## [1] 0.9085960 0.8689441 0.3540530 0.7378240 0.0052939 0.5866284 0.6862086
## [8] 0.7088267 0.6622958 0.8182121
```

Creating an R package with C++ code using the TRNG library and headers through **rTRNG** is achieved by

- adding
`Imports: rTRNG`

and`LinkingTo: rTRNG`

to the DESCRIPTION file - importing one symbol in the NAMESPACE:
`importFrom(rTRNG, TRNG.Version)`

- enforcing compilation using C++11 in Makevars[.win] via
`CXX_STD = CXX11`

- setting the relevant linker flags in Makevars[.win] via
`rTRNG::LdFlags()`

- Makevars:
`PKG_LIBS += $(shell ${R_HOME}/bin/Rscript -e "rTRNG::LdFlags()")`

- Makevars.win:
`PKG_LIBS += $(shell "${R_HOME}/bin${R_ARCH_BIN}/Rscript.exe" -e "rTRNG::LdFlags()")`

- Makevars:

C++ code using the TRNG library (sourced via `Rcpp::sourceCpp`

or part of an R package) might fail on certain systems due to issues with building and linking against **rTRNG**. This is typically the case for **macOS**, and can generally be checked by running

`::check_rTRNG_linking() rTRNG`