-
Notifications
You must be signed in to change notification settings - Fork 31
Open
Description
I've discovered a case where BatchtoolsParam behaves differently from other backends. Consider the following reprex:
library(BiocParallel)
library(iterators)
library(assertthat)
library(testthat)
## Convert a foreach iterator into a BiocParallel iterator
makeIter <- function(it) {
f <- function() {
tryCatch(it$nextElem(), error = function(e) {
if (e$message == "StopIteration") {
NULL
} else {
stop(e)
}
})
}
f
}
## Example non-error usage of makeIter
bpiterate(
makeIter(icount(10)),
sqrt,
BPPARAM = SerialParam()
)
#> [[1]]
#> [1] 1
#>
#> [[2]]
#> [1] 1.414214
#>
#> [[3]]
#> [1] 1.732051
#>
#> [[4]]
#> [1] 2
#>
#> [[5]]
#> [1] 2.236068
#>
#> [[6]]
#> [1] 2.44949
#>
#> [[7]]
#> [1] 2.645751
#>
#> [[8]]
#> [1] 2.828427
#>
#> [[9]]
#> [1] 3
#>
#> [[10]]
#> [1] 3.162278
## Correctly throws the error
expect_error(bpiterate(
makeIter(iterators::icount(10)),
function(x) stop("This function always throws an error"),
BPPARAM = SerialParam()
))
## Correctly throws the error
expect_error(bpiterate(
makeIter(iterators::icount(10)),
function(x) stop("This function always throws an error"),
BPPARAM = MulticoreParam(workers = 2)
))
## Correctly throws the error
expect_error(bpiterate(
makeIter(iterators::icount(10)),
function(x) stop("This function always throws an error"),
BPPARAM = SnowParam(workers = 2)
))
## Does not throw the error, but collects in attr(,"errors")
resList <- bpiterate(
makeIter(iterators::icount(10)),
function(x) stop("This function always throws an error"),
BPPARAM = BatchtoolsParam(cluster = "socket", workers = 2)
)
#> Submitting 10 jobs in 2 chunks using cluster functions 'Socket' ...
print(resList)
#> [[1]]
#> NULL
#>
#> [[2]]
#> NULL
#>
#> [[3]]
#> NULL
#>
#> [[4]]
#> NULL
#>
#> [[5]]
#> NULL
#>
#> [[6]]
#> NULL
#>
#> [[7]]
#> NULL
#>
#> [[8]]
#> NULL
#>
#> [[9]]
#> NULL
#>
#> [[10]]
#> NULL
#>
#> attr(,"errors")
#> attr(,"errors")$`10`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`1`
#> <remote_error in FUN(...): This function always throws an error>
#> traceback() available as 'attr(x, "traceback")'
#>
#> attr(,"errors")$`2`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`3`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`4`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`5`
#> <remote_error in FUN(...): This function always throws an error>
#> traceback() available as 'attr(x, "traceback")'
#>
#> attr(,"errors")$`6`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`7`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`8`
#> <unevaluated_error: not evaluated due to previous error>
#>
#> attr(,"errors")$`9`
#> <unevaluated_error: not evaluated due to previous error>
## This assertion fails
assert_that(!any(bpok(resList)))
#> Error: !any(bpok(resList)) is not TRUE
## This assertion passes
assert_that(!any(bpok(attr(resList, "errors"))))
#> [1] TRUE
Created on 2023-07-07 with reprex v2.0.2
With any other backend (SerialParam, MulticoreParam, SnowParam), the bpiterate
call throws an error (verified here by calling expect_error
). However, BatchtoolsParam does not throw an error and instead returns a list with all NULL elements and an attribute "errors" containing the errors thrown during iteration. Furthermore, bpok
says this object is totally fine. I would expect BatchtoolsParam to behave the same as the other backends here.
Metadata
Metadata
Assignees
Labels
No labels