向工作人员发送具有特定大小的数组
Posted
技术标签:
【中文标题】向工作人员发送具有特定大小的数组【英文标题】:Send an array with specific size to workers 【发布时间】:2020-08-28 13:19:02 【问题描述】:我想向我的 8 个工人发送一个大小为 336 的拆分部分的数组。我希望工人 0-8 的尺寸为 12、18、30、36、48、54、66 和 72。所以添加 6,然后添加 12 和 6,依此类推……至此,我能够剪切数组分成 10 个。
这是我想出的:
from mpi4py import MPI
comm = MPI.COMM_WORLD
rank = comm.Get_rank()
size = comm.Get_size()
v=np.random.rand(100,1) #array
if rank == 0:
# Process to send data to the different processes. Just send evenly chunks to the processes.
for i in range(1, size):
v_splitted=[np.array_split(v, 10)[i-1]]
comm.send(v_splitted, dest=i, tag=i)
# worker processes
else:
# each worker process receives data from master process
data = comm.recv(source=0, tag=rank)
我如何确保每个工人都获得所需的尺寸?
【问题讨论】:
您需要什么帮助?拆分数组v
,还是向每个工作人员发送其工作负载?
【参考方案1】:
您可以使用 itertools 和 zip 中的累积来构建切片列表。然后用它把你的数组分解成所需大小的块:
from itertools import accumulate
sizes = [12,18,30,36,48,54,66,72] # or [*accumulate([12,6]*4)]
breaks = [*accumulate(sizes)]
slices = [slice(s,e) for s,e in zip([0]+breaks,breaks)]
v = list(range(336))
for i,chunk in enumerate(slices):
print(len(v[chunk]),":",*v[chunk][:3],"...",*v[chunk][-3:])
# comm.send(v[chunk], dest=i, tag=i)
输出:
12 : 0 1 2 ... 9 10 11
18 : 12 13 14 ... 27 28 29
30 : 30 31 32 ... 57 58 59
36 : 60 61 62 ... 93 94 95
48 : 96 97 98 ... 141 142 143
54 : 144 145 146 ... 195 196 197
66 : 198 199 200 ... 261 262 263
72 : 264 265 266 ... 333 334 335
工作原理
breaks
列表包含在每个块结束时处理的累计项目数:
[12, 30, 60, 96, 144, 198, 264, 336]
这些数字对应于代表每个数据块的索引范围的末尾。要获得这些范围的开始,我们只需将每个结束值与前一个块的结束值配对(第一个块从零开始):
starts (s): [0] [12, 30, 60, 96, 144, 198, 264, 336]
ends (e): [12, 30, 60, 96, 144, 198, 264, 336]
ranges: (0,12), (12,30), (30,60) ... (264,336)
这是slices
变量将包含的内容,除了为了方便以后使用,它返回一个 slice() 对象列表而不是 range() 对象列表。切片对象可以直接用作包含数据的列表或数组的下标(例如v[slice]
)。 zip() 函数在这里用于创建一对结束值,其中前一个结束(即开始)是通过用一个额外的条目(零)偏移中断来获得的
【讨论】:
谢谢阿兰,还有一个问题,slices = [slice(s,e) for s,e in zip([0]+breaks,breaks)] 这一行有什么作用?以上是关于向工作人员发送具有特定大小的数组的主要内容,如果未能解决你的问题,请参考以下文章