Вложенный 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 дополнительных воркера.