我使用mpi4py在几个过程中拆分一些计算。基本上我只计算一些凸壳的体积,我用tvtk和mayavi创建。
只有第一个proc导入这些库:
...
if rank==0:
from tvtk.api import tvtk
from mayavi Import mlab
...
mlab.figure(size=(1024,768),bgcolor=(1,1,1))
...
然后,我尝试在所有过程中共享对象mlab和tvtk:
for i in range(comm.Get_size()):
comm.send(mlab,dest=i)
comm.send(tvtk,dest=i)
....
以下步骤看起来像......
Points=local_data
ug=tvtk.UnstructuredGrid(Points=Points)
...
dataname="Data %s " % rank
ds=mlab.pipeline.add_dataset(ug,name=dataname)
delaunay=mlab.pipeline.delaunay3d(ds,name=dataname)
... calc volume...
然而,显然它不可能发送实例/类(或者mlab和tvtk),因为我总是得到以下错误:
comm.send(mlab,dest=i)
File "Comm.pyx", line 753, in mpi4py.MPI.Comm.send (src/mpi4py.MPI.c:53848)
File "pickled.pxi", line 122, in mpi4py.MPI.PyMPI_send (src/mpi4py.MPI.c:20409)
File "pickled.pxi", line 39, in mpi4py.MPI._p_Pickle.dump (src/mpi4py.MPI.c:19503)
cPickle.PicklingError: Can't pickle <type 'module'>: attribute lookup __builtin__.module failed
有没有办法在所有过程中“共享”实例mlab和tvtk?
编辑:简短的例子;你能让这个工作吗?
from mpi4py import MPI
comm=MPI.COMM_WORLD
size=comm.Get_size()
rank=comm.Get_rank()
if rank==0:
from tvtk.api import tvtk
from mayavi import mlab
if __name__=='__main__':
if rank==0:
for i in range(size):
comm.send(mlab,dest=i)
comm.send(tvtk,dest=i)
else:
local_mlab=comm.recv(mlab,source=0)
local_tvtk=comm.recv(tvtk,source=0)
答案 0 :(得分:2)
我想以下情况可能适合你的情况
from mpi4py import MPI
MPI._p_pickle.dumps = dill.dumps
MPI._p_pickle.loads = dill.loads
答案 1 :(得分:0)
我认为问题在于你不能以这种方式发送包,你可以在所有正在运行的实例上导入它们,并在需要的地方使用它们,这似乎可以让你做你想做的事情
然而,这不会共享任何全局模块数据,这可能是您尝试执行的操作,因此这需要您单独发送它,我建议使用:
global_data = None
if rank == 0:
global_data = {'value_of_interest': mlab.some_parameter}
global_data = MPI.COMM_WORLD.bcast(global_data, root=0)