Dask отложенный вызов функции с непереданными параметрами - PullRequest
0 голосов
/ 02 апреля 2020

Я пытаюсь лучше понять следующее поведение при использовании dask.delayed для вызова функции, которая зависит от параметров. Проблема возникает, когда параметры указываются в файле параметров, читаемом configparser. Вот полный пример:

файл параметров:

#zpar.ini: parameter file for configparser

[my pars]
my_zpar = 2.

синтаксический анализатор:

#zippy_parser
import configparser

def read(_rundir):

    global rundir
    rundir = _rundir

    cp = configparser.ConfigParser()
    cp.read(rundir + '/zpar.ini')

    #[my pars]
    global my_zpar
    my_zpar = cp['my pars'].getfloat('my_zpar')

и основной файл python:

# dask test with configparser
import dask
from dask.distributed import Client
import zippy_parser as zpar


def my_func(x, y):

    # print stuff
    print("parameter from main is: {}".format(main_par))
    print("parameter from configparser is: {}".format(zpar.my_zpar))

    # do stuff
    return x + y


if __name__ == '__main__':

    client = Client(n_workers = 4)

    #read parameters from input file
    rundir = '/path/to/parameter/file'
    zpar.read(rundir)

    #test zpar
    print("zpar is {}".format(zpar.my_zpar))

    #define parameter and call my_func
    main_par = 5.
    z = dask.delayed(my_func)(1., 2.)
    z.compute()

    client.close()

Первый оператор печати в my_fun c () выполняется просто отлично, но второй оператор печати вызывает исключение. Вывод:

zpar is 2.0
parameter from main is: 5.0
distributed.worker - WARNING -  Compute Failed
Function:  my_func
args:      (1.0, 2.0)
kwargs:    {}
Exception: AttributeError("module 'zippy_parser' has no attribute 'my_zpar'",)

Я новичок в DASK. Я полагаю, это как-то связано с сериализацией, которую я не понимаю. Может ли кто-нибудь просветить меня и / или указать на соответствующую документацию? Спасибо!

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Я постараюсь сохранить это краткое описание.

Когда функция сериализуется для отправки работникам, python также отправляет локальные переменные и функции, необходимые для функции (ее «замыкание»). Однако он хранит модули, на которые ссылается по имени, он не пытается сериализовать всю вашу среду выполнения. Это означает, что zippy_parser является импортированным в работнике, не десериализованным. Поскольку функция read никогда не вызывалась в работнике, переменная global никогда не инициализируется.

Таким образом, вы можете вызывать read в работниках как часть вашей функции или иным образом, но, вероятно, шаблон или установка глобальных переменных модуля с помощью функции невелики. Отложенный механизм Dask предпочитает функциональную чистоту, поэтому полученный вами результат не должен зависеть от текущего состояния среды выполнения.

(обратите внимание, что если вы создали клиента после вызова read в основном сценарии, рабочие может получить версию в памяти, в зависимости от того, как настроены подпроцессы для создания в вашей системе)

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

Я рекомендую вам явно указывать все параметры для ваших отложенных функций, а не полагаться на глобальное пространство имен.

...