Skip to content

Commit 5ade080

Browse files
Merge branch 'develop' of github.com:HenrikBengtsson/future.batchtools into develop
2 parents 0ab8038 + cac629f commit 5ade080

24 files changed

+340
-134
lines changed

.github/workflows/R-CMD-check.yaml

Lines changed: 40 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,35 @@ name: R-CMD-check
44

55
jobs:
66
R-CMD-check:
7+
if: "! contains(github.event.head_commit.message, '[ci skip]')"
8+
79
runs-on: ${{ matrix.config.os }}
10+
811
name: ${{ matrix.config.os }} (${{ matrix.config.r }})
9-
if: "! contains(github.event.head_commit.message, '[ci skip]')"
10-
12+
1113
strategy:
1214
fail-fast: false
1315
matrix:
1416
config:
15-
- { os: windows-latest, r: '3.5'}
16-
- { os: windows-latest, r: '3.6'}
17-
- { os: macOS-latest, r: '3.5'}
18-
- { os: macOS-latest, r: '3.6'}
19-
- { os: macOS-latest, r: 'devel'}
20-
- { os: ubuntu-16.04, r: '3.2', cran: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"}
21-
- { os: ubuntu-16.04, r: '3.3', cran: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"}
22-
- { os: ubuntu-16.04, r: '3.4', cran: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"}
23-
- { os: ubuntu-16.04, r: '3.5', cran: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"}
24-
- { os: ubuntu-16.04, r: '3.6', cran: "https://demo.rstudiopm.com/all/__linux__/xenial/latest"}
17+
- {os: windows-latest, r: 'devel'}
18+
#2020-09-23# - {os: windows-latest, r: 'release'}
19+
- {os: macOS-latest, r: 'devel'}
20+
- {os: macOS-latest, r: 'release'}
21+
- {os: ubuntu-20.04, r: 'devel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
22+
- {os: ubuntu-20.04, r: 'release', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
23+
- {os: ubuntu-20.04, r: 'oldrel', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
24+
- {os: ubuntu-20.04, r: '3.5', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
25+
- {os: ubuntu-20.04, r: '3.4', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
26+
- {os: ubuntu-20.04, r: '3.3', rspm: "https://packagemanager.rstudio.com/cran/__linux__/xenial/latest"}
2527

2628
env:
2729
R_REMOTES_NO_ERRORS_FROM_WARNINGS: true
28-
CRAN: ${{ matrix.config.cran }}
29-
30+
R_FUTURE_RNG_ONMISUSE: error
31+
RSPM: ${{ matrix.config.rspm }}
32+
GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
3033

3134
steps:
32-
- uses: actions/checkout@v1
35+
- uses: actions/checkout@v2
3336

3437
- uses: r-lib/actions/setup-r@master
3538
with:
@@ -38,15 +41,19 @@ jobs:
3841
- uses: r-lib/actions/setup-pandoc@master
3942

4043
- name: Query dependencies
41-
run: Rscript -e "install.packages('remotes')" -e "saveRDS(remotes::dev_package_deps(dependencies = TRUE), 'depends.Rds', version = 2)"
44+
run: |
45+
install.packages('remotes')
46+
saveRDS(remotes::dev_package_deps(dependencies = TRUE), ".github/depends.Rds", version = 2)
47+
writeLines(sprintf("R-%i.%i", getRversion()$major, getRversion()$minor), ".github/R-version")
48+
shell: Rscript {0}
4249

4350
- name: Cache R packages
4451
if: runner.os != 'Windows'
4552
uses: actions/cache@v1
4653
with:
4754
path: ${{ env.R_LIBS_USER }}
48-
key: ${{ runner.os }}-r-${{ matrix.config.r }}-${{ hashFiles('depends.Rds') }}
49-
restore-keys: ${{ runner.os }}-r-${{ matrix.config.r }}-
55+
key: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-${{ hashFiles('.github/depends.Rds') }}
56+
restore-keys: ${{ runner.os }}-${{ hashFiles('.github/R-version') }}-1-
5057

5158
- name: Install system dependencies
5259
if: runner.os == 'Linux'
@@ -59,20 +66,27 @@ jobs:
5966
6067
- name: Install dependencies
6168
run: |
62-
Rscript -e "library(remotes)" -e "update(readRDS('depends.Rds'))" -e "remotes::install_cran('rcmdcheck')"
63-
Rscript -e "install.packages('.', type = 'source', repos = NULL)"
69+
remotes::install_deps(dependencies = TRUE)
70+
remotes::install_cran("rcmdcheck")
71+
install.packages(".", repos=NULL, type="source") ## needed by parallel workers
72+
shell: Rscript {0}
73+
74+
- name: Session info
75+
run: |
76+
options(width = 100)
77+
pkgs <- installed.packages()[, "Package"]
78+
sessioninfo::session_info(pkgs, include_base = TRUE)
79+
shell: Rscript {0}
6480

6581
- name: Check
66-
run: Rscript -e "rcmdcheck::rcmdcheck(args = '--no-manual', error_on = 'warning', check_dir = 'check')"
82+
env:
83+
_R_CHECK_CRAN_INCOMING_REMOTE_: false
84+
run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check")
85+
shell: Rscript {0}
6786

6887
- name: Upload check results
6988
if: failure()
7089
uses: actions/upload-artifact@master
7190
with:
7291
name: ${{ runner.os }}-r${{ matrix.config.r }}-results
7392
path: check
74-
75-
- name: Test coverage
76-
if: matrix.config.os == 'ubuntu-16.04' && matrix.config.r == '3.6-HIDE'
77-
run: |
78-
Rscript -e "install.packages('covr')" -e 'covr::codecov(token = "${{secrets.CODECOV_TOKEN}}")'

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@
2020
revdep/data.sqlite
2121
revdep/checks/*
2222
revdep/library/*
23+
.github/

DESCRIPTION

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Package: future.batchtools
2-
Version: 0.9.0
2+
Version: 0.9.0-9000
33
Depends:
44
R (>= 3.2.0),
5-
future (>= 1.14.0)
5+
future (>= 1.17.0)
66
Imports:
7-
batchtools (>= 0.9.11),
7+
batchtools (>= 0.9.13),
88
utils
99
Suggests:
1010
future.apply,

Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
include .make/Makefile
22

3+
spelling:
4+
$(R_SCRIPT) -e "spelling::spell_check_files(c('NEWS', dir('vignettes', pattern='[.]rsp', full.names=TRUE)), ignore=readLines('inst/WORDLIST', warn=FALSE))"
5+
36
future.tests/%:
47
$(R_SCRIPT) -e "future.tests::check" --args --test-plan=$*
58

69
future.tests: future.tests/future.batchtools\:\:batchtools_local
10+
11+
spelling:
12+
$(R_SCRIPT) -e "spelling::spell_check_package()"
13+
$(R_SCRIPT) -e "spelling::spell_check_files(c('NEWS', dir('vignettes', pattern='[.]rsp', full.names=TRUE)), ignore=readLines('inst/WORDLIST', warn=FALSE))"

NEWS

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
Package: future.batchtools
22
==========================
33

4+
Version: 0.9.0-9000 [2020-10-13]
5+
6+
DOCUMENTATION:
7+
8+
* Document option 'future.delete' and clarify option 'future.cache.path'
9+
in help("future.batchtools.options").
10+
11+
BUG FIXES:
12+
13+
* If run() was called twice for a BatchtoolsFuture, it would not produce
14+
a FutureError but only a regular non-classed error.
15+
16+
417
Version: 0.9.0 [2020-04-14]
518

619
SIGNIFICANT CHANGES:
@@ -27,7 +40,7 @@ NEW FEATURES:
2740
available on all workers on a shared file system, e.g. plan(batchtools_nnn,
2841
registry = list(work.dir = "~")).
2942

30-
* It is possible to control if and how batchtools should use file compressions
43+
* It is possible to control if and how batchtools should use file compression
3144
for exported globals and results by specifying batchtools registry parameter
3245
'compress'. For example, to turn off file compression, use
3346
plan(batchtools_nnn, registry = list(compress = FALSE)).
@@ -112,8 +125,8 @@ BUG FIXES:
112125
* A bug was introduced in future.batchtools 0.7.0 that could result in "Error
113126
in readLog(id, reg = reg) : Log file for job with id 1 not available" when
114127
using one of the batchtools backends. It occurred when the value was
115-
queried. It was observered using 'batchtools_torque' but not when using
116-
'batchools_local'. This bug was missed because the 0.7.0 release was not
128+
queried. It was observed using 'batchtools_torque' but not when using
129+
'batchtools_local'. This bug was missed because the 0.7.0 release was not
117130
tested on an TORQUE/PBS HPC scheduler as it should have.
118131

119132

R/BatchtoolsFuture-class.R

Lines changed: 48 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,9 @@
1919
#' @param label (optional) Label of the future (where applicable, becomes the
2020
#' job name for most job schedulers).
2121
#'
22-
#' @param resources (optional) A named list passed to the batchtools template
23-
#' (available as variable `resources`).
22+
#' @param resources (optional) A named list passed to the \pkg{batchtools}
23+
#' template (available as variable `resources`). See Section 'Resources'
24+
#' in [batchtools::submitJobs()] more details.
2425
#'
2526
#' @param workers (optional) The maximum number of workers the batchtools
2627
#' backend may use at any time. Interactive and "local" backends can only
@@ -48,7 +49,6 @@
4849
#'
4950
#' @export
5051
#' @importFrom future Future getGlobalsAndPackages
51-
#' @importFrom batchtools submitJobs
5252
#' @keywords internal
5353
BatchtoolsFuture <- function(expr = NULL, envir = parent.frame(),
5454
substitute = TRUE,
@@ -63,7 +63,48 @@ BatchtoolsFuture <- function(expr = NULL, envir = parent.frame(),
6363
...) {
6464
if (substitute) expr <- substitute(expr)
6565

66-
if (!is.null(label)) label <- as.character(label)
66+
## Record globals
67+
gp <- getGlobalsAndPackages(expr, envir = envir, globals = globals)
68+
69+
future <- Future(expr = gp$expr, envir = envir, substitute = FALSE,
70+
globals = gp$globals,
71+
packages = unique(c(packages, gp$packages)),
72+
label = label,
73+
...)
74+
75+
future <- as_BatchtoolsFuture(future,
76+
resources = resources,
77+
workers = workers,
78+
finalize = finalize,
79+
conf.file = conf.file,
80+
cluster.functions = cluster.functions,
81+
registry = registry)
82+
83+
future
84+
}
85+
86+
87+
## Helper function to create a BatchtoolsFuture from a vanilla Future
88+
#' @importFrom utils file_test
89+
as_BatchtoolsFuture <- function(future,
90+
resources = list(),
91+
workers = NULL,
92+
finalize = getOption("future.finalize", TRUE),
93+
conf.file = findConfFile(),
94+
cluster.functions = NULL,
95+
registry = list(),
96+
...) {
97+
if (is.function(workers)) workers <- workers()
98+
if (!is.null(workers)) {
99+
stop_if_not(length(workers) >= 1)
100+
if (is.numeric(workers)) {
101+
stop_if_not(!anyNA(workers), all(workers >= 1))
102+
} else {
103+
stop("Argument 'workers' should be either a numeric or a function: ",
104+
mode(workers))
105+
}
106+
}
107+
future$workers <- workers
67108

68109
if (!is.null(cluster.functions)) {
69110
stop_if_not(is.list(cluster.functions))
@@ -79,35 +120,13 @@ BatchtoolsFuture <- function(expr = NULL, envir = parent.frame(),
79120
}
80121
}
81122

82-
if (is.function(workers)) workers <- workers()
83-
if (!is.null(workers)) {
84-
stop_if_not(length(workers) >= 1)
85-
if (is.numeric(workers)) {
86-
stop_if_not(!anyNA(workers), all(workers >= 1))
87-
} else {
88-
stop("Argument 'workers' should be either a numeric or a function: ",
89-
mode(workers))
90-
}
91-
}
92-
93123
stop_if_not(is.list(registry))
94124
if (length(registry) > 0L) {
95125
stopifnot(!is.null(names(registry)), all(nzchar(names(registry))))
96126
}
97127

98128
stop_if_not(is.list(resources))
99129

100-
## Record globals
101-
gp <- getGlobalsAndPackages(expr, envir = envir, globals = globals)
102-
103-
future <- Future(expr = gp$expr, envir = envir, substitute = FALSE,
104-
workers = workers, label = label,
105-
version = "1.8", .callResult = TRUE,
106-
...)
107-
108-
future$globals <- gp$globals
109-
future$packages <- unique(c(packages, gp$packages))
110-
111130
## Create batchtools registry
112131
reg <- temp_registry(
113132
label = future$label,
@@ -342,13 +361,14 @@ result.BatchtoolsFuture <- function(future, cleanup = TRUE, ...) {
342361

343362

344363
#' @importFrom future run getExpression
345-
#' @importFrom batchtools batchExport batchMap saveRegistry setJobNames
364+
#' @importFrom batchtools batchExport batchMap saveRegistry setJobNames submitJobs
346365
#' @export
347366
run.BatchtoolsFuture <- function(future, ...) {
348367
if (future$state != "created") {
349368
label <- future$label
350369
if (is.null(label)) label <- "<none>"
351-
stop(sprintf("A future ('%s') can only be launched once.", label))
370+
msg <- sprintf("A future ('%s') can only be launched once.", label)
371+
stop(FutureError(msg, future = future))
352372
}
353373

354374
## Assert that the process that created the future is

R/options.R

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,37 @@
2828
#' This option controls how many lines are displayed.
2929
#' (Default: `48L`)}
3030
#'
31-
#' \item{\option{future.cache.path} / \env{R_FUTURE_CACHE_PATH}}{
31+
#' \item{\option{future.cache.path} / \env{R_FUTURE_CACHE_PATH}:}{
3232
#' (character string)
3333
#' An absolute or relative path specifying the root folder in which
3434
#' \pkg{batchtools} registry folders are stored.
35-
#' (Default: `.future`)}
35+
#' This folder needs to be accessible from all hosts ("workers").
36+
#' Specifically, it must _not_ be a folder that is only local to the
37+
#' machine such as `file.path(tempdir(), ".future"` if an job scheduler
38+
#' on a HPC environment is used.
39+
#' (Default: `.future` in the current working directory)}
40+
#'
41+
#' \item{\option{future.delete}:}{(logical)
42+
#' Controls whether or not the future's \pkg{batchtools} registry folder
43+
#' is deleted after the future result has been collected.
44+
#' If TRUE, it is always deleted.
45+
#' If FALSE, it is never deleted.
46+
#' If not set or NULL, the it is deleted, unless running in non-interactive
47+
#' mode and the batchtools job failed or expired, which helps to
48+
#' troubleshoot when running in batch mode.
49+
#' (Default: NULL (not set))}
3650
#' }
3751
#'
52+
#' @examples
53+
#' # Set an R option:
54+
#' options(future.cache.path = "/cluster-wide/folder/.future")
55+
#'
56+
#' # Set an environment variable:
57+
#' Sys.setenv(R_FUTURE_RNG_ONMISUSE = "/cluster-wide/folder/.future")
58+
#'
3859
#' @aliases
3960
#' future.cache.path
61+
#' future.delete
4062
#' future.batchtools.expiration.tail
4163
#' future.batchtools.output
4264
#' future.batchtools.workers

R/resources_OP.R

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
#'
66
#' @param fassignment The future assignment, e.g.
77
#' \code{x \%<-\% \{ expr \}}.
8-
#' @param tweaks A named list (or vector) of resource
9-
#' batchtools parameters that should be changed relative to
10-
#' the current strategy.
8+
#' @param tweaks A named list (or vector) of resource \pkg{batchtools}
9+
#' parameters (see Section 'Resources' in [batchtools::submitJobs()])
10+
#' that should be changed relative to the current strategy.
1111
#'
1212
#' @export
1313
#' @importFrom future plan tweak

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,10 @@ library("future")
4545
library("listenv")
4646
## The first level of futures should be submitted to the
4747
## cluster using batchtools. The second level of futures
48-
## should be using multiprocessing, where the number of
48+
## should be using multisession, where the number of
4949
## parallel processes is automatically decided based on
5050
## what the cluster grants to each compute node.
51-
plan(list(batchtools_torque, multiprocess))
51+
plan(list(batchtools_torque, multisession))
5252

5353
## Find all samples (one FASTQ file per sample)
5454
fqs <- dir(pattern = "[.]fastq$")
@@ -77,11 +77,11 @@ bams <- as.list(bams)
7777
```
7878
Note that a user who do not have access to a cluster could use the same script processing samples sequentially and chromosomes in parallel on a single machine using:
7979
```r
80-
plan(list(sequential, multiprocess))
80+
plan(list(sequential, multisession))
8181
```
8282
or samples in parallel and chromosomes sequentially using:
8383
```r
84-
plan(list(multiprocess, sequential))
84+
plan(list(multisession, sequential))
8585
```
8686

8787
For an introduction as well as full details on how to use futures,
@@ -157,10 +157,10 @@ To specify the `resources` argument at the same time as using nested future stra
157157
```r
158158
plan(list(
159159
tweak(batchtools_torque, resources = list(nodes = "1:ppn=12", vmem = "5gb")),
160-
multiprocess
160+
multisession
161161
))
162162
```
163-
causes the first level of futures to be submitted via the TORQUE job scheduler requesting 12 cores and 5 GiB of memory per job. The second level of futures will be evaluated using multiprocessing using the 12 cores given to each job by the scheduler.
163+
causes the first level of futures to be submitted via the TORQUE job scheduler requesting 12 cores and 5 GiB of memory per job. The second level of futures will be evaluated using multisession using the 12 cores given to each job by the scheduler.
164164
165165
A similar filename format is used for the other types of job schedulers supported. For instance, for Slurm the template file should be named `./batchtools.slurm.tmpl` or `~/.batchtools.slurm.tmpl` in order for
166166
```r

0 commit comments

Comments
 (0)