Вложенный furrr::future_map?

Есть ли способ настроить furrr::future_mapчто позволило бы использовать вложенный вариант использования? Рассмотрим следующий код:

library(furrr)
library(tictoc)

# The problem is easier to reason about if you take N
# smaller than your number of cores, and M big.
N = 2 
M = 100

plan(sequential)
tic()
x = future_map(1:N, function(i){
  furrr::future_map(1:M,function(j){
    Sys.sleep(1/M)
    return(1)
  })
})
toc() # 2sec + overhead

plan(multiprocess)
tic()
x = future_map(1:N, function(i){
  furrr::future_map(1:M,function(j){
    Sys.sleep(1/M)
    return(1)
  })
})
toc() # one sec + overhead !!

Первый должен занять чуть больше 2 секунд. Хорошо. Но даже на машине с тысячей ядер, есть ли способ сделать так, чтобы вторая занимала менее 1 секунды?

Мой пример использования следующий: выполнение некоторых подзадач занимает больше времени, чем выполнение других, а когда некоторые из них завершены, некоторые ядра свободны для дальнейшего устранения более длительных задач.

Но Furrr не делает этого по умолчанию, и задачи, выполняемые lnger, выполняются только на одном ядре. Проблема эквивалентна той, которая отображается в приведенном выше коде: есть ли способ, чтобы furrr повторно отправлял внутренние задачи, если некоторые ядра свободны?

Это просто невозможно сделать, или я пропустил параметр для вызова furrr / future?

1 ответ

В A Future for R: Future Topologies , упомянутом user4341440 , вы можете использовать future::tweakв future::plan. Там элементы списка показывают глубину. Поэтому, если вы предоставляете два плана, распараллеливание также выполняется во вложенном furrr::future_mapнапример:

      future::plan(
      list(
        future::tweak(
          future::multiprocess, 
          workers = 2), 
        future::tweak(
          future::multiprocess,
          workers = 4)
        )
      )

Пример работает с 8 ядрами, так как каждый из двух первых воркеров получает 4 дополнительных воркера.

Другие вопросы по тегам