Совместное использование массивов numpy в многопроцессорном пуле Python

Я работаю над некоторым кодом, который выполняет довольно тяжелую численную работу над большим (десятком или сотней тысяч численных интегрирований )набора задач. К счастью,эти интеграции смущающе параллельны, поэтому легко использовать Pool.map (), чтобы разделить работу между несколькими ядрами.

Прямо сейчас у меня есть программа с этим базовым рабочим процессом:

#!/usr/bin/env python
from multiprocessing import Pool
from scipy import *
from my_parser import parse_numpy_array
from my_project import heavy_computation

#X is a global multidimensional numpy array
X = parse_numpy_array("input.dat")
param_1 = 0.0168
param_2 = 1.505

def do_work(arg):
  return heavy_computation(X, param_1, param_2, arg)

if __name__=='__main__':
  pool = Pool()
  arglist = linspace(0.0,1.0,100)
  results = Pool.map(do_work,arglist)
  #save results in a.npy file for analysis
  save("Results", [X,results])

Поскольку X, param _1 и param _2 жестко -закодированы и инициализированы одинаково для каждого процесса в пуле, все это работает нормально. Теперь, когда мой код работает, я хотел бы сделать так, чтобы имя файла, параметр _1 и параметр _2 вводились пользователем во время выполнения -, а не жестко -закодировано.

Следует отметить, что X, параметр _1 и параметр _2 не изменяются по мере выполнения работы. Поскольку я их не изменяю, я мог бы сделать что-то подобное в начале программы:

import sys
X = parse_numpy_array(sys.argv[1])
param_1 = float(sys.argv[2])
param_2 = float(sys.argv[3])

И это помогло бы, но, поскольку большинство пользователей этого кода запускают код с компьютеров Windows, я бы не стал использовать аргументы строки команды -.

То, что я действительно хотел бы сделать, это что-то вроде этого:

X, param_1, param_2 = None, None, None

def init(x,p1, p2)
  X = x
  param_1 = p1
  param_2 = p2

if __name__=='__main__':
  filename = raw_input("Filename> ")
  param_1 = float(raw_input("Parameter 1: "))
  param_2 = float(raw_input("Parameter 2: "))
  X = parse_numpy_array(filename)
  pool = Pool(initializer = init, initargs = (X, param_1, param_2,))
  arglist = linspace(0.0,1.0,100)
  results = Pool.map(do_work,arglist)
  #save results in a.npy file for analysis
  save("Results", [X,results])

Но, конечно, это не удается, и X/param _1/param _2 равны None, когда происходит вызов pool.map. Я новичок в многопроцессорной обработке, поэтому я не уверен, почему вызов инициализатора не работает. Есть ли способ сделать то, что я хочу сделать? Есть ли лучший способ сделать это вообще? Я также рассматривал использование общих данных, но, насколько я понимаю, документация работает только с ctypes, которые не включают массивы numpy. Любая помощь в этом будет принята с благодарностью.

7
задан rnorris 15 August 2012 в 01:53
поделиться