Skip to content

Commit e664a76

Browse files
kevinusheyeddelbuettel
authored andcommitted
provide class for suspension of RNG synchronization (#862)
1 parent d1674cf commit e664a76

File tree

6 files changed

+50
-2
lines changed

6 files changed

+50
-2
lines changed

ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2018-06-06 Kevin Ushey <[email protected]>
2+
3+
* inst/include/Rcpp/RNGScope.h: Allow suspension of RNG synchronization
4+
* inst/include/Rcpp/routines.h: Idem
5+
* src/Rcpp_init.cpp: Idem
6+
* src/api.cpp: Idem
17

28
2018-06-02 Lionel Henry <[email protected]>
39

inst/NEWS.Rd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
\itemize{
1010
\item The random number \code{Generator} class no longer inhreits from
1111
\code{RNGScope} (Kevin in \ghpr{837} fixing \ghit{836}).
12+
\item A new class, \code{SuspendRNGSynchronizationScope}, can be created
13+
and used to ensure that calls to Rcpp functions do not attempt to call
14+
\code{::GetRNGstate()} or \code{::PutRNGstate()} for the duration of
15+
some code block.
1216
\item A spurious parenthesis was removed to please gcc8 (Dirk
1317
fixing \ghit{841})
1418
\item The optional \code{Timer} class header now undefines

inst/include/Rcpp/RNGScope.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@ class RNGScope{
3030
~RNGScope(){ internal::exitRNGScope(); }
3131
};
3232

33+
class SuspendRNGSynchronizationScope {
34+
public:
35+
SuspendRNGSynchronizationScope() { internal::beginSuspendRNGSynchronization(); }
36+
~SuspendRNGSynchronizationScope() { internal::endSuspendRNGSynchronization(); }
37+
};
38+
3339
} // namespace Rcpp
3440

3541
#endif

inst/include/Rcpp/routines.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ namespace Rcpp{
3131
namespace internal{
3232
unsigned long enterRNGScope();
3333
unsigned long exitRNGScope();
34+
unsigned long beginSuspendRNGSynchronization();
35+
unsigned long endSuspendRNGSynchronization();
3436
char* get_string_buffer();
3537
SEXP get_Rcpp_namespace();
3638
}
@@ -86,6 +88,18 @@ namespace Rcpp {
8688
return fun();
8789
}
8890

91+
inline attribute_hidden unsigned long beginSuspendRNGSynchronization(){
92+
typedef unsigned long (*Fun)(void);
93+
static Fun fun = GET_CALLABLE("beginSuspendRNGSynchronization");
94+
return fun();
95+
}
96+
97+
inline attribute_hidden unsigned long endSuspendRNGSynchronization(){
98+
typedef unsigned long (*Fun)(void);
99+
static Fun fun = GET_CALLABLE("endSuspendRNGSynchronization");
100+
return fun();
101+
}
102+
89103
inline attribute_hidden char* get_string_buffer(){
90104
typedef char* (*Fun)(void);
91105
static Fun fun = GET_CALLABLE("get_string_buffer");

src/Rcpp_init.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ void registerFunctions(){
9494
RCPP_REGISTER(demangle)
9595
RCPP_REGISTER(enterRNGScope)
9696
RCPP_REGISTER(exitRNGScope)
97+
RCPP_REGISTER(beginSuspendRNGSynchronization);
98+
RCPP_REGISTER(endSuspendRNGSynchronization);
9799
RCPP_REGISTER(get_Rcpp_namespace)
98100
RCPP_REGISTER(get_cache)
99101
RCPP_REGISTER(stack_trace)

src/api.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,18 +65,34 @@ namespace Rcpp {
6565

6666
namespace internal {
6767

68+
int rngSynchronizationSuspended = 0;
69+
6870
// [[Rcpp::register]]
6971
unsigned long enterRNGScope() {
70-
GetRNGstate();
72+
if (rngSynchronizationSuspended == 0)
73+
GetRNGstate();
7174
return 0;
7275
}
7376

7477
// [[Rcpp::register]]
7578
unsigned long exitRNGScope() {
76-
PutRNGstate();
79+
if (rngSynchronizationSuspended == 0)
80+
PutRNGstate();
7781
return 0;
7882
}
7983

84+
// [[Rcpp::register]]
85+
unsigned long beginSuspendRNGSynchronization() {
86+
++rngSynchronizationSuspended;
87+
return rngSynchronizationSuspended;
88+
}
89+
90+
// [[Rcpp::register]]
91+
unsigned long endSuspendRNGSynchronization() {
92+
--rngSynchronizationSuspended;
93+
return rngSynchronizationSuspended;
94+
}
95+
8096
// [[Rcpp::register]]
8197
char* get_string_buffer() {
8298
static char buffer[MAXELTSIZE];

0 commit comments

Comments
 (0)