在多处理中使用共享数组来保存值

时间:2017-09-12 13:36:36

标签: python numpy multiprocessing python-multiprocessing

我试图让python多处理工作来加速我编写的代码。代码如下所示:

from multiprocessing import Array, Pool
import numpy as np
#setting up shared memory array
global misfit
misfit = Array('d', np.empty((dim1,dim2,dim3,dim4)).flat)

#looping through some values
for i in xrange(0,1):
     #setting up pool
     pool = Pool()
     p = [pool.apply_async(self.testfunc,args=(somevals,j)) for j in xrange(0,1)]
     pool.close()
     pool.join()

self.testfunc的样子:

 def testfunc(self,somevals,j):
      #some calculations
      for k in xrange(0,1):
           #some calculations
           for mn in xrange(0,1):
                 #some more calculations
                 #save results
                 result = i*j*k*mn # example
                 misfit[i*j*k*mn] = result

我的问题是,当我运行它时,没有任何值保存在共享数组中,并且它仍然是空的。我知道这可能与全局变量有关,但在使用这种精确设置的简单程序中,值会保存到数组中。整个程序中的数组也非常大(4561920000值)。此外,如果我在池之外调用此函数,它将起作用并保存值。

所以我的问题是我在这里做错了什么?我是否错误地发送了共享阵列?

编辑:想象我添加了有效的代码:

from multiprocessing import Array, Pool
from numpy import empty, sin
from time import time
import numpy as np

def initarr():
  a = Array('d', empty((5, 50, 80)).flat)
  return a

def testfunc(i, j, k):
  count = (i*50*80) + (j*80) + k
  x = sin(k)
  a[count] = x
  y = np.fft.fft(np.exp(2j*np.pi*np.arange(50000)/50000))


def process(i):
  start = time()
  pool = Pool()
  for j in xrange(0, 50):
    p = [pool.apply_async(testfunc, args=(i, j, k)) for k in xrange(0, 80)]
  pool.close()
  pool.join()
  print time() - start


global a
a = initarr()

for i in xrange(0, 5):
   process(i)

1 个答案:

答案 0 :(得分:1)

好的,在我们IT部门的人员的帮助下,我终于有了一个适用的版本,所以对于将来查看这个问题的任何人,我都会发布一个解决方案。我还没有真正使用堆栈溢出,所以很抱歉,如果回答我自己的问题是不礼貌的话。

我们使用初始化函数实现了这个功能,但是我们必须确保初始化函数与Pool运行的函数在相同的文件(模块)中。所以在一个模块(misc)中我们有:

**misc.py**
def testfunc(self,somevals,j):
  #some calculations
  for k in xrange(0,len(krange)):
       #some calculations
       for mn in xrange(0,len(mnrange)):
             #some more calculations
             #save results
             loc = (i*len(jrange)*len(krange)*len(mnrange))+
                   (j*len(krange)*len(mnrange))+(k*len(mnrange))+mn
             result = i*j*k*mn # example
             misfit[loc] = result

def initpool(a):
    global misfit
    misfit = a

在主文件中我们有:

**main.py**
from multiprocessing import Array, Pool
from misc import initpool, testfunc
import numpy as np

#setting up shared memory array
misfit = Array('d', np.empty((dim1,dim2,dim3,dim4)).flat)

#looping through some values
for i in xrange(0,len(irange)):
     #setting up pool
     pool = Pool(initializer=initpool,initargs=(misfit,),processes=20)
     p = [pool.apply_async(testfunc,args=(somevals,j)) for j in xrange(0,len(jrange))]
     pool.close()
     pool.join()

print(misfit[0])

注意当我们最初设置数组时,它必须被命名为相同,就像你在initpool中设置的变量一样,至少从我测试它时开始。< / p>

这可能不是最好的方法,但它有效,希望其他人可能会找到它的用途!