Skip to content

Commit 67f4e0c

Browse files
Backends: future.batchtools (>= 0.20.0) supports interrupts
1 parent ab2121f commit 67f4e0c

File tree

5 files changed

+87
-85
lines changed

5 files changed

+87
-85
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
Package: future
2-
Version: 1.67.0-9008
2+
Version: 1.67.0-9009
33
Title: Unified Parallel and Distributed Processing in R for Everyone
44
Depends:
55
R (>= 3.2.0)

README.md

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ The **future** package comes with built-in future backends that leverage the **p
154154
| **[future.callr]**<br> `callr` | 📶<br>♻️<br> | parallelly via transient **[callr]** background R sessions on current machine; all memory is returned when as each future is resolved
155155
| **[future.mirai]**<br> `mirai_multisession` | 📶<br>♻️<br> | parallelly via **[mirai]** background R sessions on current machine; low latency
156156
| **[future.mirai]**<br> `mirai_cluster` |♻️<br> | parallelly via **[mirai]** daemons running locally or remotely
157-
| **[future.batchtools]**<br> `batchtools_lsf`<br>`batchtools_openlava`<br>`batchtools_sge`<br>`batchtools_slurm`<br>`batchtools_torque` | 📶(soon)<br> ♻️(next) | parallelly on HPC job schedulers (Load Sharing Facility [LSF], OpenLava, TORQUE/PBS, Son/Sun/Oracle/Univa Grid Engine [SGE], Slurm) via **[batchtools]**; for long-running tasks; high latency |
157+
| **[future.batchtools]**<br> `batchtools_lsf`<br>`batchtools_openlava`<br>`batchtools_sge`<br>`batchtools_slurm`<br>`batchtools_torque` | 📶(soon)<br> ♻️<br> | parallelly on HPC job schedulers (Load Sharing Facility [LSF], OpenLava, TORQUE/PBS, Son/Sun/Oracle/Univa Grid Engine [SGE], Slurm) via **[batchtools]**; for long-running tasks; high latency |
158158

159159
📶: futures relay progress updates in real-time, e.g. **[progressr]**<br>
160160
♻️: futures are interruptible and restartable; * disabled by default<br>
@@ -209,7 +209,7 @@ Sequential futures are the default unless otherwise specified. They were design
209209
> plan(sequential)
210210
> pid <- Sys.getpid()
211211
> pid
212-
[1] 1399790
212+
[1] 1287562
213213
> a %<-% {
214214
+ pid <- Sys.getpid()
215215
+ cat("Future 'a' ...\n")
@@ -227,14 +227,14 @@ Sequential futures are the default unless otherwise specified. They were design
227227
Future 'a' ...
228228
> b
229229
Future 'b' ...
230-
[1] 1399790
230+
[1] 1287562
231231
> c
232232
Future 'c' ...
233233
[1] 6.28
234234
> a
235235
[1] 3.14
236236
> pid
237-
[1] 1399790
237+
[1] 1287562
238238
```
239239

240240
Since eager sequential evaluation is taking place, each of the three futures is resolved instantaneously in the moment it is created. Note also how `pid` in the calling environment, which was assigned the process ID of the current process, is neither overwritten nor removed. This is because futures are evaluated in a local environment. Since synchronous (uni-)processing is used, future `b` is resolved by the main R process (still in a local environment), which is why the value of `b` and `pid` are the same.
@@ -253,7 +253,7 @@ We start with multisession futures because they are supported by all operating s
253253
> plan(multisession, workers = 2)
254254
> pid <- Sys.getpid()
255255
> pid
256-
[1] 1399790
256+
[1] 1287562
257257
> a %<-% {
258258
+ pid <- Sys.getpid()
259259
+ cat("Future 'a' ...\n")
@@ -271,14 +271,14 @@ We start with multisession futures because they are supported by all operating s
271271
Future 'a' ...
272272
> b
273273
Future 'b' ...
274-
[1] 1399841
274+
[1] 1287626
275275
> c
276276
Future 'c' ...
277277
[1] 6.28
278278
> a
279279
[1] 3.14
280280
> pid
281-
[1] 1399790
281+
[1] 1287562
282282
```
283283

284284
The first thing we observe is that the values of `a`, `c` and `pid` are the same as previously. However, we notice that `b` is different from before. This is because future `b` is evaluated in a different R process and therefore it returns a different process ID.
@@ -318,7 +318,7 @@ Cluster futures evaluate expressions on an ad-hoc cluster (as implemented by the
318318
> plan(cluster, workers = c("n1", "n2", "n3"))
319319
> pid <- Sys.getpid()
320320
> pid
321-
[1] 1399790
321+
[1] 1287562
322322
> a %<-% {
323323
+ pid <- Sys.getpid()
324324
+ cat("Future 'a' ...\n")
@@ -336,14 +336,14 @@ Cluster futures evaluate expressions on an ad-hoc cluster (as implemented by the
336336
Future 'a' ...
337337
> b
338338
Future 'b' ...
339-
[1] 1399937
339+
[1] 1287729
340340
> c
341341
Future 'c' ...
342342
[1] 6.28
343343
> a
344344
[1] 3.14
345345
> pid
346-
[1] 1399790
346+
[1] 1287562
347347
```
348348

349349
Any types of clusters that `parallel::makeCluster()` creates can be used for cluster futures. For instance, the above cluster can be explicitly set up as:
@@ -394,24 +394,24 @@ For instance, here is an example of two "top" futures (`a` and `b`) that uses mu
394394
+ c(b.pid = Sys.getpid(), b1.pid = b1, b2.pid = b2)
395395
+ }
396396
> pid
397-
[1] 1399790
397+
[1] 1287562
398398
> a
399399
Future 'a' ...
400-
[1] 1400059
400+
[1] 1287860
401401
> b
402402
Future 'b' ...
403403
Future 'b1' ...
404404
Future 'b2' ...
405405
b.pid b1.pid b2.pid
406-
1400058 1400058 1400058
406+
1287859 1287859 1287859
407407
```
408408

409409
By inspection the process IDs, we see that there are in total three different processes involved for resolving the futures. There is the main R process
410-
(pid 1399790),
410+
(pid 1287562),
411411
and there are the two processes used by `a`
412-
(pid 1400059)
412+
(pid 1287860)
413413
and `b`
414-
(pid 1400058).
414+
(pid 1287859).
415415
However, the two futures (`b1` and `b2`) that is nested by `b` are evaluated by the same R process as `b`. This is because nested futures use sequential evaluation unless otherwise specified. There are a few reasons for this, but the main reason is that it protects us from spawning off a large number of background processes by mistake, e.g. via recursive calls.
416416

417417

@@ -428,16 +428,16 @@ We would actually get the same behavior if we try with multiple levels of multis
428428
> plan(list(multisession, multisession))
429429
[...]
430430
> pid
431-
[1] 1399790
431+
[1] 1287562
432432
> a
433433
Future 'a' ...
434-
[1] 1400155
434+
[1] 1287962
435435
> b
436436
Future 'b' ...
437437
Future 'b1' ...
438438
Future 'b2' ...
439439
b.pid b1.pid b2.pid
440-
1400154 1400154 1400154
440+
1287963 1287963 1287963
441441
```
442442

443443
The second multisession backend will default to single, sequential
@@ -452,22 +452,22 @@ Continuing, if we start off with the sequential backend and then use the multise
452452
> plan(list(sequential, multisession))
453453
[...]
454454
> pid
455-
[1] 1399790
455+
[1] 1287562
456456
> a
457457
Future 'a' ...
458-
[1] 1399790
458+
[1] 1287562
459459
> b
460460
Future 'b' ...
461461
Future 'b1' ...
462462
Future 'b2' ...
463463
b.pid b1.pid b2.pid
464-
1399790 1400250 1400251
464+
1287562 1288080 1288081
465465
```
466466

467467
which clearly show that `a` and `b` are resolved in the calling
468-
process (pid 1399790) whereas the two nested futures (`b1` and
469-
`b2`) are resolved in two separate R processes (pids 1400250 and
470-
1400251).
468+
process (pid 1287562) whereas the two nested futures (`b1` and
469+
`b2`) are resolved in two separate R processes (pids 1288080 and
470+
1288081).
471471

472472

473473

@@ -478,24 +478,24 @@ Having said this, it is indeed possible to use nested multisession backend that
478478
+ workers = 2)))
479479
[...]
480480
> pid
481-
[1] 1399790
481+
[1] 1287562
482482
> a
483483
Future 'a' ...
484-
[1] 1400346
484+
[1] 1288184
485485
> b
486486
Future 'b' ...
487487
Future 'b1' ...
488488
Future 'b2' ...
489489
b.pid b1.pid b2.pid
490-
1400345 1400561 1400560
490+
1288185 1288314 1288315
491491
```
492492

493493
First, we see that both `a` and `b` are resolved in different processes
494-
(pids 1400346 and 1400345)
494+
(pids 1288184 and 1288185)
495495
than the calling process
496-
(pid 1399790).
496+
(pid 1287562).
497497
Second, the two nested futures (`b1` and `b2`) are resolved in yet two other R processes
498-
(pids 1400561 and 1400560).
498+
(pids 1288314 and 1288315).
499499

500500

501501
For more details on working with nested futures and different future backends at each level, see Vignette '[A Future for R: Future Topologies]'.
@@ -532,11 +532,12 @@ Waiting for 'a' to be resolved ...
532532
8
533533
9
534534
10
535+
11
535536
> cat("Waiting for 'a' to be resolved ... DONE\n")
536537
Waiting for 'a' to be resolved ... DONE
537538
> a
538539
Future 'a' ...done
539-
[1] 1400685
540+
[1] 1288421
540541
```
541542

542543

@@ -604,9 +605,9 @@ There is one limitation with implicit futures that does not exist for explicit o
604605
> v <- lapply(f, FUN = value)
605606
> str(v)
606607
List of 3
607-
$ : int 1400783
608-
$ : int 1400784
609-
$ : int 1400783
608+
$ : int 1288542
609+
$ : int 1288543
610+
$ : int 1288543
610611
```
611612

612613
This is _not_ possible to do when using implicit futures. This is because the `%<-%` assignment operator _cannot_ be used in all cases where the regular `<-` assignment operator can be used. It can only be used to assign future values to _environments_ (including the calling environment) much like how `assign(name, value, envir)` works. However, we can assign implicit futures to environments using _named indices_, e.g.
@@ -622,9 +623,9 @@ This is _not_ possible to do when using implicit futures. This is because the `
622623
> v <- as.list(v)
623624
> str(v)
624625
List of 3
625-
$ a: int 1400783
626-
$ b: int 1400784
627-
$ c: int 1400783
626+
$ a: int 1288542
627+
$ b: int 1288543
628+
$ c: int 1288542
628629
```
629630

630631
Here `as.list(v)` blocks until all futures in the environment `v` have been resolved. Then their values are collected and returned as a regular list.
@@ -643,9 +644,9 @@ If _numeric indices_ are required, then _list environments_ can be used. List e
643644
> v <- as.list(v)
644645
> str(v)
645646
List of 3
646-
$ : int 1400783
647-
$ : int 1400784
648-
$ : int 1400783
647+
$ : int 1288542
648+
$ : int 1288543
649+
$ : int 1288542
649650
```
650651

651652
As previously, `as.list(v)` blocks until all futures are resolved.

inst/vignettes-static/future-1-overview.md.rsp.rsp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ The **future** package comes with built-in future backends that leverage the **p
155155
| **[future.callr]**<br> `callr` | 📶<br>♻️<br> | parallelly via transient **[callr]** background R sessions on current machine; all memory is returned when as each future is resolved
156156
| **[future.mirai]**<br> `mirai_multisession` | 📶<br>♻️<br> | parallelly via **[mirai]** background R sessions on current machine; low latency
157157
| **[future.mirai]**<br> `mirai_cluster` |♻️<br> | parallelly via **[mirai]** daemons running locally or remotely
158-
| **[future.batchtools]**<br> `batchtools_lsf`<br>`batchtools_openlava`<br>`batchtools_sge`<br>`batchtools_slurm`<br>`batchtools_torque` | 📶(soon)<br> ♻️(next) | parallelly on HPC job schedulers (Load Sharing Facility [LSF], OpenLava, TORQUE/PBS, Son/Sun/Oracle/Univa Grid Engine [SGE], Slurm) via **[batchtools]**; for long-running tasks; high latency |
158+
| **[future.batchtools]**<br> `batchtools_lsf`<br>`batchtools_openlava`<br>`batchtools_sge`<br>`batchtools_slurm`<br>`batchtools_torque` | 📶(soon)<br> ♻️<br> | parallelly on HPC job schedulers (Load Sharing Facility [LSF], OpenLava, TORQUE/PBS, Son/Sun/Oracle/Univa Grid Engine [SGE], Slurm) via **[batchtools]**; for long-running tasks; high latency |
159159

160160
📶: futures relay progress updates in real-time, e.g. **[progressr]**<br>
161161
♻️: futures are interruptible and restartable; * disabled by default<br>

0 commit comments

Comments
 (0)