You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Will blockApply() be gaining a sink or BACKEND argument? This can be convenient when blockApply()-ing over a matrix-like object to create a normalised matrix-like object, for example.
FYI, this is what I'm currently using, but I'd prefer to retire this for an 'official' solution. It requires (and doesn't check) that the sink is the appropriate type and dimensions.
blockApplyWithRealization<-function(x, FUN, ..., grid=NULL, sink=NULL,
BPREDO=list(), BPPARAM= bpparam()) {
FUN<- match.fun(FUN)
grid<-DelayedArray:::.normarg_grid(grid, x)
nblock<- length(grid)
bplapply(seq_len(nblock), function(b) {
if (DelayedArray:::get_verbose_block_processing()) {
message("Processing block ", b, "/", nblock, " ... ",
appendLF=FALSE)
}
viewport<-grid[[b]]
block<-DelayedArray:::extract_block(x, viewport)
if (!is.array(block)) {
block<-DelayedArray:::.as_array_or_matrix(block)
}
attr(block, "from_grid") <-grid
attr(block, "block_id") <-bblock_ans<- FUN(block, ...)
# NOTE: This is the only part different from DelayedArray::blockApply()if (!is.null(sink)) {
write_block_to_sink(block_ans, sink, viewport)
block_ans<-NULL
}
if (DelayedArray:::get_verbose_block_processing()) {
message("OK")
}
},
BPREDO=BPREDO,
BPPARAM=BPPARAM)
}
This one has been patiently sitting in a corner for a while ;-)
blockApply() and family has matured a bit in the last 2 years, and now we have viewportApply() and viewportReduce() in addition to blockApply() and blockReduce().
viewportReduce() would be a better choice in general than blockApply(x, FUN, sink) for block-processing with on-the-fly writing to a realization sink. For your use case, it would look something like this:
library(DelayedArray)
## Normalization function:
my_powerful_normalization_algo <- function(m, shift=0) { m + shift }
## Block-processed version of the normalization function (we want to be as much
## backend-agnostic as we can, so no parallelization):
BLOCK_my_powerful_normalization_algo <- function(sink, m, shift=0, verbose=NA)
{
stopifnot(identical(dim(sink), dim(m)))
## By setting 'block.shape' to "first-dim-grows-first" we're guaranteed to be
## compatible with realization sinks that only support linear writing (e.g.
## TENxRealizationSink objects).
grid <- defaultAutoGrid(sink, block.shape="first-dim-grows-first")
## Define callback function to pass to viewportReduce().
FUN <- function(viewport, sink, shift) {
block <- read_block(m, viewport)
block <- my_powerful_normalization_algo(block, shift)
write_block(sink, viewport, block)
}
viewportReduce(FUN, grid, sink, shift=shift, verbose=verbose)
}
Let's try it:
library(TileDBArray)
## Matrix to normalize:
M <- writeTileDBArray(matrix(1:6000, nrow=50))
The major difference with the blockApply(x, FUN, sink) approach is that here we walk on a grid defined on the sink instead of on x. Turns out that for the particular normalization use case the transformation is isometric so x and the sink have the same geometry but this is not the case in general. For the general case, we want to walk on a grid defined on the sink. blockApply(x, FUN, sink) doesn't allow this.
Was never entirely happy with viewportReduce() as the primary tool for walking on a realization sink and filling it with data. Today I added sinkApply() in DelayedArray 0.17.11 as a slightly better tool for that. Name and interface are a little bit more intuitive, I hope. It's documented in ?sinkApply.
Yeah I realize this arrives kind of late. Oh well, maybe at some point when I've nothing else to do I'll replace blockApplyWithRealization() with sinkApply() in minfi and bsseq ;-)
Activity
PeteHaitch commentedon Mar 12, 2018
FYI, this is what I'm currently using, but I'd prefer to retire this for an 'official' solution. It requires (and doesn't check) that the
sinkis the appropriate type and dimensions.hpages commentedon Oct 2, 2020
Hi Pete,
This one has been patiently sitting in a corner for a while ;-)
blockApply()and family has matured a bit in the last 2 years, and now we haveviewportApply()andviewportReduce()in addition toblockApply()andblockReduce().viewportReduce()would be a better choice in general thanblockApply(x, FUN, sink)for block-processing with on-the-fly writing to a realization sink. For your use case, it would look something like this:Let's try it:
Create HDF5 realization sink:
Block process:
Close sink and coerce:
This is with DelayedArray 0.15.14.
The major difference with the
blockApply(x, FUN, sink)approach is that here we walk on a grid defined on the sink instead of onx. Turns out that for the particular normalization use case the transformation is isometric soxand thesinkhave the same geometry but this is not the case in general. For the general case, we want to walk on a grid defined on the sink.blockApply(x, FUN, sink)doesn't allow this.Hope this makes sense,
H.
hpages commentedon Apr 27, 2021
Hi @PeteHaitch ,
Was never entirely happy with
viewportReduce()as the primary tool for walking on a realization sink and filling it with data. Today I addedsinkApply()in DelayedArray 0.17.11 as a slightly better tool for that. Name and interface are a little bit more intuitive, I hope. It's documented in?sinkApply.H.
PeteHaitch commentedon Apr 27, 2021
Thanks, Herve. I'm not currently working on anything that requires this but it's good to have it there.
hpages commentedon Apr 27, 2021
Yeah I realize this arrives kind of late. Oh well, maybe at some point when I've nothing else to do I'll replace
blockApplyWithRealization()withsinkApply()in minfi and bsseq ;-)