Я пытаюсь использовать параллельную среду IPython, и до сих пор она выглядит великолепно, но я столкнулся с проблемой. Допустим, что у меня есть функция, определенная в библиотеке
def func(a,b):
...
который я использую, когда хочу оценить одно значение a и кучу значений b.
[func(myA, b) for b in myLongList]
Очевидно, что реальная функция сложнее, но суть дела в том, что она принимает несколько параметров, и я хотел бы отобразить только одну из них. Проблема в том, что map, @dview.parallel и т.д. Отображают все аргументы.
Итак, скажем, я хочу получить ответ на func (myA, myLongList). Очевидный способ сделать это - карри, либо w/functools.partial, либо как
dview.map_sync(lambda b: func(myA, b), myLongList)
Однако это не работает правильно на удаленных компьютерах. Причина в том, что когда выражение лямбда маринуется, значение myA не включается и вместо этого используется значение myA из локальной области на удаленной машине. Когда закрытие замачивается, переменные, которые они закрывают, не делают.
Два способа, которые я могу придумать, чтобы это сделать, это на самом деле работать, чтобы вручную создавать списки для каждого аргумента и иметь работу над всеми аргументами,
dview.map_sync(func, [myA]*len(myLongList), myLongList)
или для ужасного использования данных в качестве аргументов по умолчанию для функции, заставляющей ее замачиваться:
# Can't use a lambda here b/c lambdas don't use default arguments :(
def parallelFunc(b, myA = myA):
return func(myA, b)
dview.map_sync(parallelFunc, myLongList)
Действительно, все это кажется ужасно искаженным, когда реальная функция принимает множество параметров и сложнее. Есть ли какой-то идиоматический способ сделать это? Что-то вроде
@parallel(mapOver='b')
def bigLongFn(a, b):
...
но, насколько я знаю, ничего подобного "mapOver" не существует. Я, вероятно, имею представление о том, как его реализовать... это просто очень простая операция, в которой должна существовать поддержка, поэтому я хочу проверить, не хватает ли я чего-то.