demo/mandelbrot.R

library(progressr)
library(future)
library(graphics)

p <- function(...) NULL

plot_what_is_done <- function(counts) {
  done <- 0L
  
  for (kk in seq_along(counts)) {
    f <- counts[[kk]]

    ## Already plotted?
    if (!inherits(f, "Future")) {
      done <- done + 1L
      next
    }

    ## Not resolved?
    ## NOTE: This will block, if all workers are busy!
    if (runif(1) < 0.8*(1-(done/length(counts))) || !resolved(f)) next

    message(sprintf("Plotting tile #%d of %d ...", kk, n))
    counts[[kk]] <- value(f)
    screen(kk)
    plot(counts[[kk]])

    done <- done + 1L
  }
  
  counts
}


## Options
region <- getOption("future.demo.mandelbrot.region", 1L)
if (!is.list(region)) {
  if (region == 1L) {
    region <- list(xmid = -0.75, ymid = 0.0, side = 3.0)
  } else if (region == 2L) {
    region <- list(xmid = 0.283, ymid = -0.0095, side = 0.00026)
  } else if (region == 3L) {
    region <- list(xmid = 0.282989, ymid = -0.01, side = 3e-8)
  }
}
nrow <- getOption("future.demo.mandelbrot.nrow", 5L)
resolution <- getOption("future.demo.mandelbrot.resolution", 1024L)
delay <- getOption("future.demo.mandelbrot.delay", interactive())
if (isTRUE(delay)) {
  delay <- function(counts) Sys.sleep(runif(1L, min=0.5, max=5))
} else if (!is.function(delay)) {
  delay <- function(counts) {}
}

## Generate Mandelbrot tiles to be computed
Cs <- mandelbrot_tiles(xmid = region$xmid, ymid = region$ymid,
                       side = region$side, nrow = nrow,
                       resolution = resolution)
message("Tiles: ", paste(dim(Cs), collapse = " by "))		       
if (interactive()) {
  dev.new()
  plot.new()
  split.screen(dim(Cs))
  for (ii in seq_along(Cs)) {
    screen(ii)
    par(mar = c(0, 0, 0, 0))
    text(x = 1 / 2, y = 1 / 2, sprintf("Future #%d\nunresolved", ii), cex = 2)
  }
} else {
  split.screen(dim(Cs))
}

## Create all Mandelbrot tiles via lazy futures
n <- length(Cs)
message(sprintf("* Creating %d Mandelbrot tiles", n))
with_progress({
  p <- progressor(along = Cs)
  counts <- lapply(seq_along(Cs), FUN=function(ii) {
    C <- Cs[[ii]]
    future({
      message(sprintf("Calculating tile #%d of %d ...", ii, n), appendLF = FALSE)
      fit <- mandelbrot(C)
  
      ## Emulate slowness
      delay(fit)
  
      p(sprintf("Tile #%d (PID %d)", ii, Sys.getpid()))
      
      message(" done")
      fit
    }, lazy = TRUE)
  })
  str(counts)

  pp <- 0L
  while (any(sapply(counts, FUN = inherits, "Future"))) {
    counts <- plot_what_is_done(counts)
  }
})

  


close.screen()


message("SUGGESTION: Try to rerun this demo after changing strategy for how futures are resolved, e.g. plan(multisession).\n")

Try the progressr package in your browser

Any scripts or data that you put into this service are public.

progressr documentation built on Aug. 11, 2023, 1:07 a.m.