Использование dask для распараллеливания l oop во вложенных циклах - PullRequest
0 голосов
/ 03 апреля 2020

Я только учусь использовать dask и читаю на этом форуме много тем, связанных с Dask и циклами. Но мне все еще неясно, как применить эти решения к моей проблеме. Я работаю с климатическими данными, которые являются функциями (время, глубина, местоположение). Координата «местоположение» - это линейный индекс, так что каждое значение соответствует уникальному (долгота, широта). Ниже я показываю основную часть того, что я пытаюсь сделать, предполагая, что var1 и var2 - две входные переменные. Я хочу распараллелить параметр местоположения 'nxy', поскольку мои вычисления могут выполняться одновременно в разных местах.

for loc in range(0,nxy):           # nxy = total no. of locations
    for it in range(0,ntimes):    

       out1 = expression1 involving ( var1(loc), var2(it,loc) )
       out2 = expression2 involving ( var1(loc), var2(it,loc) )
       # <a dozen more output variables>

Мои вопросы:

(i) Множество примеров, иллюстрирующих использование ' задержано 'показать что-то вроде "отложено (функция) (аргумент)". В моем случае у меня не слишком много (если есть) функций, но много выражений. Если «delayed» работает только на уровне функций, я должен преобразовать каждое выражение в функцию и добавить «delayed» впереди?

(ii) Должен ли я обернуть все для l oop, показанного выше внутри функции, а затем вызвать эту функцию с помощью «задерживается»? Я пытался сделать что-то подобное, но, возможно, не делал это правильно, так как я не получил никакого ускорения по сравнению с без использования dask. Вот что я сделал:

def test_dask(n):
 for loc in range(0,n):
   # same code as before
 return var1  # just returning one variable for now

var1=delayed(tast_dask)(nxy)
var1.compute()

Спасибо за вашу помощь.

1 Ответ

0 голосов
/ 04 апреля 2020

Каждая задержанная задача добавляет около 1 мс накладных расходов. Поэтому, если ваше выражение медленное (возможно, вы вызываете какую-то другую дорогую функцию), тогда да, dask.delayed может подойти. Если нет, то вы, вероятно, должны искать в другом месте.

В частности, похоже, что вы просто перебираете пару массивов и работаете элемент за элементом. Пожалуйста, обратите внимание, что Python очень медленно в этом. Возможно, вы вообще не захотите использовать Dask, но вместо этого попробуйте один из следующих подходов:

  1. Найдите какой-нибудь умный способ переписать ваши вычисления с помощью Numpy выражений
  2. Использовать Numba

Кроме того, учитывая используемые вами термины, такие как широта / долгота / глубина, возможно, Xarray - хороший проект для вас.

...