[英]How to scatter and gather a list of python of objects in mpi4py
我有一個100,000個python 對象的列表,我希望將它們分散在mpi4py
。
當我嘗試使用8個處理器時,我得到:
SystemError:負大小傳遞給PyBytes_FromStringAndSize
在散射。
當我嘗試使用64個處理器時,我遇到了同樣的錯誤,但是卻越來越多。
當我嘗試從列表中制作對象數組並使用Gather和Scatter時,出現一個錯誤,該錯誤基本上表明該數組的dtype不能是對象。
有什么辦法可以使它正常工作嗎? 還是我可以使用MPI以外的其他工具?
我正在8節點,64 ppn的計算機上運行此程序。
使用散點圖和聚集,示例了一個將numpy數組拆分為100000項的示例。
import numpy as np
from mpi4py import MPI
from pprint import pprint
comm = MPI.COMM_WORLD
pprint("-" * 78)
pprint(" Running on %d cores" % comm.size)
pprint("-" * 78)
N = 100000
my_N = N // 8
if comm.rank == 0:
A = np.arange(N, dtype=np.float64)
else:
A = np.empty(N, dtype=np.float64)
my_A = np.empty(my_N, dtype=np.float64)
# Scatter data
comm.Scatter([A, MPI.DOUBLE], [my_A, MPI.DOUBLE])
pprint("After Scatter:")
for r in range(comm.size):
if comm.rank == r:
print("[%d] %s" % (comm.rank, len(my_A)))
comm.Barrier()
# Allgather data into A
comm.Allgather([my_A, MPI.DOUBLE], [A, MPI.DOUBLE])
pprint("After Allgather:")
for r in range(comm.size):
if comm.rank == r:
print("[%d] %s" % (comm.rank, len(A)))
comm.Barrier()
您也可以在這里和這里檢查scatterv
和gatherv
,更多示例 。
我不確定這是否是答案,也不確定您是否還在尋找答案,但是...
因此,您有100,000個python 對象 。 如果這些對象是常規數據(數據集),而不是某個類的實例,則將數據作為json字符串傳遞。 像這樣:
#!/usr/bin/env python
import json
import numpy as np
from mpi4py import MPI
comm = MPI.COMM_WORLD
if comm.rank == 0:
tasks = [
json.dumps( { 'a':1,'x':2,'b':3 } ),
json.dumps( { 'a':3,'x':1,'b':2 } ),
json.dumps( { 'a':2,'x':3,'b':1 } )
]
else:
tasks = None
# Scatter paramters arrays
unit = comm.scatter(tasks, root=0)
p = json.loads(unit)
print "-"*18
print("-- I'm rank %d in %d size task" % (comm.rank,comm.size) )
print("-- My paramters are: {}".format(p))
print "-"*18
comm.Barrier()
calc = p['a']*p['x']**2+p['b']
# gather results
result = comm.gather(calc, root=0)
# do something with result
if comm.rank == 0:
print "the result is ", result
else:
result = None
請注意,如果您只有8個節點/核心,則必須在tasks
列表中創建8條記錄,並依次分散和收集所有100,000個數據集。 如果所有數據集都在ALLDATA
列表中,則代碼可能如下所示:
def calc(a=0,x=0,b=0):
return a*x**2+b
if comm.rank == 0: collector = []
for xset in zip(*(iter(ALLDATA),) * comm.size):
task = [ json.dumps(s) for s in xset ]
comm.Barrier()
unit = comm.scatter(task if comm.rank == 0 else None, root=0)
p = json.loads(unit)
res = json.dumps( calc(**p) )
totres = comm.gather(res, root=0)
if comm.rank == 0:
collector += [ json.loads(x) for x in totres ]
if comm.rank == 0:
print "the result is ", collector
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.