@@ -4,12 +4,12 @@ makeExpression <- local({
44 tmpl_expr_local <- future ::: bquote_compile(base :: local(.(expr )))
55
66 tmpl_expr_evaluate2 <- future ::: bquote_compile({
7- # # Evaluate future
8- future ::: evalFuture(expr = quote(.(expr )), stdout = .(stdout ), conditionClasses = .(conditionClasses ), split = .(split ), immediateConditions = .(immediateConditions ), immediateConditionClasses = .(immediateConditionClasses ), globals.onMissing = .(globals.onMissing ), globalenv = .(globalenv ), skip = .(skip ), packages = .(packages ), seed = .(seed ), strategiesR = .(strategiesR ), forwardOptions = .(forwardOptions ), mc.cores = .(mc.cores ))
7+ # # Evaluate future
8+ future ::: evalFuture(expr = quote(.(expr )), stdout = .(stdout ), conditionClasses = .(conditionClasses ), split = .(split ), immediateConditions = .(immediateConditions ), immediateConditionClasses = .(immediateConditionClasses ), globals = .( globals ), globals .onMissing = .(globals.onMissing ), globalenv = .(globalenv ), skip = .(skip ), packages = .(packages ), seed = .(seed ), strategiesR = .(strategiesR ), forwardOptions = .(forwardOptions ), mc.cores = .(mc.cores ))
99 })
1010
1111
12- function (expr , local = TRUE , immediateConditions = FALSE , stdout = TRUE , conditionClasses = NULL , split = FALSE , globals.onMissing = getOption(" future.globals.onMissing" , NULL ), globalenv = (getOption(" future.globalenv.onMisuse" , " ignore" ) != " ignore" ), enter = NULL , exit = NULL , version = " 1.8" , packages = NULL , seed = NULL , mc.cores = NULL ) {
12+ function (expr , local = TRUE , immediateConditions = FALSE , stdout = TRUE , conditionClasses = NULL , split = FALSE , globals = NULL , globals .onMissing = getOption(" future.globals.onMissing" , NULL ), globalenv = (getOption(" future.globalenv.onMisuse" , " ignore" ) != " ignore" ), enter = NULL , exit = NULL , version = " 1.8" , packages = NULL , seed = NULL , mc.cores = NULL ) {
1313 if (version != " 1.8" ) {
1414 stop(FutureError(" Internal error: Non-supported future expression version: " , version ))
1515 }
@@ -55,6 +55,22 @@ makeExpression <- local({
5555 packages <- unique(c(packages , pkgsS ))
5656 }
5757
58+ if (is.function(strategiesR )) {
59+ if (! inherits(strategiesR , " future" )) {
60+ stop(FutureError(sprintf(" Argument 'strategiesR' is a function, but does not inherit 'future': %s" , paste(sQuote(class(strategiesR )), collapse = " , " ))))
61+ }
62+ } else if (is.list(strategiesR )) {
63+ for (kk in seq_along(strategiesR )) {
64+ strategy <- strategiesR [[kk ]]
65+ if (! inherits(strategy , " future" )) {
66+ stop(FutureError(sprintf(" Element #%d of list 'strategiesR' is a function, but does not inherit 'future': %s" , kk , paste(sQuote(class(strategy )), collapse = " , " ))))
67+ }
68+ }
69+ } else if (is.character(strategiesR )) {
70+ } else {
71+ stop(FutureError(sprintf(" Unknown value of argument 'strategiesR': %s" , paste(sQuote(class(strategiesR )), collapse = " , " ))))
72+ }
73+
5874 forwardOptions <- list (
5975 # # Assert globals when future is created (or at run time)?
6076 future.globals.onMissing = globals.onMissing ,
@@ -82,7 +98,21 @@ makeExpression <- local({
8298
8399
84100
85- evalFuture <- function (expr , stdout = TRUE , conditionClasses = character (0L ), split = FALSE , immediateConditions = NULL , immediateConditionClasses = character (0L ), globals.onMissing = getOption(" future.globals.onMissing" , NULL ), globalenv = (getOption(" future.globalenv.onMisuse" , " ignore" ) != " ignore" ), skip = NULL , packages = NULL , seed = NULL , mc.cores = NULL , forwardOptions = NULL , strategiesR = future :: sequential , envir = parent.frame()) {
101+ logme <- function (expr , envir = parent.frame()) {
102+ expr <- substitute(expr )
103+ stdout <- utils :: capture.output(eval(expr , envir = envir ))
104+ stdout <- sprintf(" [evalFuture()] %s\n " , stdout )
105+ stdout <- paste(stdout , collapse = " " )
106+ cat(stdout , file = " callr.log" , append = TRUE )
107+ }
108+
109+ FutureEvalError <- function (... ) {
110+ ex <- FutureError(... )
111+ class(ex ) <- c(" FutureEvalError" , class(ex ))
112+ ex
113+ }
114+
115+ evalFuture <- function (expr , stdout = TRUE , conditionClasses = character (0L ), split = FALSE , immediateConditions = NULL , immediateConditionClasses = character (0L ), globals = NULL , globals.onMissing = getOption(" future.globals.onMissing" , NULL ), globalenv = (getOption(" future.globalenv.onMisuse" , " ignore" ) != " ignore" ), skip = NULL , packages = NULL , seed = NULL , mc.cores = NULL , forwardOptions = NULL , strategiesR = NULL , envir = parent.frame()) {
86116 stop_if_not(
87117 length(stdout ) == 1L && is.logical(stdout ),
88118 length(split ) == 1L && is.logical(split ) && ! is.na(split ),
@@ -91,11 +121,25 @@ evalFuture <- function(expr, stdout = TRUE, conditionClasses = character(0L), sp
91121 is.character(immediateConditionClasses ) && ! anyNA(immediateConditionClasses ) && all(nzchar(immediateConditionClasses )),
92122 length(globalenv ) == 1L && is.logical(globalenv ) && ! is.na(globalenv ),
93123 length(skip ) == 2L && is.integer(skip ) && ! anyNA(skip ) && all(skip > = 0L ),
94- ! is.null(strategiesR ),
95124 is.null(seed ) || is_lecyer_cmrg_seed(seed ) || (is.logical(seed ) && ! is.na(seed ) || ! seed ),
96125 is.null(mc.cores ) || (is.numeric(mc.cores ) && length(mc.cores ) == 1L && ! is.na(mc.cores ) && mc.cores > = 1 )
97126 )
98127
128+ if (is.function(strategiesR )) {
129+ if (! inherits(strategiesR , " future" )) {
130+ stop(FutureEvalError(sprintf(" Argument 'strategiesR' is a function, but does not inherit 'future': %s" , paste(sQuote(class(strategiesR )), collapse = " , " ))))
131+ }
132+ } else if (is.list(strategiesR )) {
133+ for (kk in seq_along(strategiesR )) {
134+ strategy <- strategiesR [[kk ]]
135+ if (! inherits(strategy , " future" )) {
136+ stop(FutureEvalError(sprintf(" Element #%d of list 'strategiesR' is a function, but does not inherit 'future': %s" , kk , paste(sQuote(class(strategy )), collapse = " , " ))))
137+ }
138+ }
139+ } else if (is.character(strategiesR )) {
140+ } else {
141+ stop(FutureEvalError(sprintf(" Unknown value of argument 'strategiesR': %s" , paste(sQuote(class(strategiesR )), collapse = " , " ))))
142+ }
99143
100144 # # Start time for future evaluation
101145 ... future.startTime <- Sys.time()
@@ -106,7 +150,7 @@ evalFuture <- function(expr, stdout = TRUE, conditionClasses = character(0L), sp
106150 # # -----------------------------------------------------------------
107151 # # Current working directory
108152 ... future.workdir <- getwd()
109-
153+
110154 # # mc.cores
111155 ... future.mc.cores.old <- getOption(" mc.cores" )
112156
@@ -326,6 +370,14 @@ evalFuture <- function(expr, stdout = TRUE, conditionClasses = character(0L), sp
326370 ... future.globalenv.names <- c(names(.GlobalEnv ), " ...future.value" , " ...future.globalenv.names" , " .Random.seed" )
327371 }
328372
373+ if (length(globals ) > 0 ) {
374+ base_attach <- base :: attach # # To please R CMD check
375+ base_attach(globals , pos = 2L , name = " future:globals" )
376+ on.exit({
377+ detach(name = " future:globals" )
378+ }, add = TRUE )
379+ }
380+
329381 # # Ignore, capture or discard standard output?
330382 if (is.na(stdout )) { # # stdout = NA
331383 # # Don't capture, but also don't block any output
@@ -354,9 +406,15 @@ evalFuture <- function(expr, stdout = TRUE, conditionClasses = character(0L), sp
354406 options(future.plan = NULL )
355407 Sys.unsetenv(" R_FUTURE_PLAN" )
356408
409+ # logme("future:plan() ...")
410+ # logme(utils::str(strategiesR))
411+ # logme(print(strategiesR))
412+
357413 # # Use the next-level-down ("popped") future strategy
358414 future :: plan(strategiesR , .cleanup = FALSE , .init = FALSE )
359-
415+
416+ # logme("future:plan() ... done")
417+
360418 # # Temporarily set R option 'mc.cores'?
361419 if (! is.null(mc.cores )) {
362420 options(mc.cores = mc.cores )
0 commit comments