You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mpi4py调用gather收集结构体列表后遍历触发类型错误问题

问题报错

使用mpi4py传输自定义结构体对象列表时,gather收集完成后根进程遍历返回对象触发类型错误,报错信息如下:

Traceback (most recent call last):
    File "Primary_secondary_co-sim.py", line 509, in <module>
    sm_clear_all(params, curr_pri_timestep, soln)
    File "/home/gridsan/jvineet9/vvc_sims/code/sm_clear_all.py", line 162, in sm_clear_all
    node_num = soln_node['node_num']
    TypeError: list indices must be integers or slices, not str
    Primary job  terminated normally, but 1 process returned
    a non-zero exit code. Per user-direction, the job has been aborted.
    ----------------------------------------------------------------- 

    mpirun detected that one or more processes exited with non-zero status, thus causing
    the job to be terminated. The first process to do so was:

    Process name: [[56840,1],1]
    Exit code:    1

复现信息

自定义结构体类定义:

class structtype:
    def __init__(self):
        pass

复现主逻辑:

from mpi4py import MPI
import os

data = [4,5]
num_SMOs = 5
solns_list = []

comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()

name = MPI.Get_processor_name()
pid = os.getpid()

idx = range(num_SMOs)
myidx = idx[rank:len(idx):size] 

for node in myidx:
    soln_node = structtype()
    # 给结构体赋值
    soln_node.node_num = node
    soln_node.XX = data
    solns_list.append(soln_node)

# 所有进程将本地solns_list发送到0号进程
solns_nodes_all = comm.gather(solns_list, root=0)

if rank == 0:
    for soln_node in solns_nodes_all: 
        node_num = soln_node.node_num
        data = soln_node.XX
错误原因

comm.gather的返回值仅在指定根进程上有效,返回结构为长度等于总进程数的列表,列表第i位的元素就是rank为i的进程传入的发送对象。
每个进程传入gather的发送对象是solns_list,本身是存储多个结构体实例的列表,因此根进程拿到的solns_nodes_all是两层嵌套列表:第一层按rank顺序存储每个进程发来的子列表,第二层子列表内才是单个结构体对象。原代码直接遍历第一层列表,取出的元素是子列表而非结构体实例,自然无法直接访问结构体属性。

修复方案

根进程处理gather返回值时,先遍历每个进程发来的子列表,再遍历子列表内的结构体对象即可,两种实现方式都可以:

  • 两层循环直接处理,无需额外存储
if rank == 0:
    for proc_soln_list in solns_nodes_all:
        for soln_node in proc_soln_list:
            node_num = soln_node.node_num
            data = soln_node.XX
            # 写入后续业务处理逻辑
  • 先展开嵌套列表得到一维的全量结构体列表,再做后续处理,如果需要按node_num排序可以在展开后追加排序逻辑
if rank == 0:
    all_soln_nodes = []
    for proc_soln_list in solns_nodes_all:
        all_soln_nodes.extend(proc_soln_list)
    # 如需按节点号排序,放开下一行注释
    # all_soln_nodes.sort(key=lambda x:x.node_num)
    for soln_node in all_soln_nodes:
        node_num = soln_node.node_num
        data = soln_node.XX
        # 写入后续业务处理逻辑

内容的提问来源于stack exchange,提问作者jvineet9

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:00:59