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

Repast4py跨Rank创建幽灵代理报KeyError:0的问题及解决

在Repast4py中跨MPI Rank共享OrderBook代理的问题与解决

问题详情

我需要实现一个能在所有MPI Rank间共享的OrderBook代理:

  • 最初计划用mpi4py的收发操作实现共享,后来根据Repast4py文档,尝试通过self.context.synchronize(restore_orderbook)让各Rank创建该代理的幽灵副本
  • 实际运行时触发KeyError: 0报错,报错栈显示错误出现在调用self.context.agents(OrderBook.TYPE)时
  • 即使尝试使用request_agents函数,Rank 0创建的代理也无法复制到其他Rank作为幽灵代理
  • 预期效果:Rank 0创建OrderBook,Rank1、2、3生成其幽灵副本,并在step函数中按分支逻辑打印订单

相关文件与运行信息

测试代码 test2.py

from repast4py import core, schedule
import mpi4py.MPI as MPI

class OrderBook(core.Agent):
    TYPE = 1
    def __init__(self, aid, rank):
        super().__init__(aid, rank)
        self.orders = []
    
    def save(self):
        return (self.orders,)
    
    def step(self, model):
        if MPI.COMM_WORLD.rank == 0:
            self.orders.append("new order")
            print(f"Rank 0 added order: {self.orders}")
        else:
            # 原错误代码:尝试遍历本地代理
            # for book in model.context.agents(OrderBook.TYPE):
            #     print(f"Rank {MPI.COMM_WORLD.rank} sees orders: {book.orders}")
            # 修复后代码
            b = model.context.ghost_agent((1,0,0))
            print(f"Rank {MPI.COMM_WORLD.rank} sees orders: {b.orders}")

def restore_orderbook(aid, rank, data):
    book = OrderBook(aid, rank)
    book.orders = data[0]
    return book

class TestModel:
    def __init__(self, comm):
        self.context = core.SharedContext(comm)
        self.rank = comm.Get_rank()
        if self.rank == 0:
            # 创建OrderBook代理,ID为(1,0,0)
            book = OrderBook((1,0,0), 0)
            self.context.add(book)
        self.scheduler = schedule.DefaultScheduler(comm)
        self.scheduler.schedule_repeating_event(1, 1, self.step)
    
    def step(self):
        self.context.synchronize(restore_orderbook)
        for agent in self.context.agents(OrderBook.TYPE):
            agent.step(self)

if __name__ == "__main__":
    comm = MPI.COMM_WORLD
    model = TestModel(comm)
    model.scheduler.run(3)

配置文件 test.yaml

repast4py:
  schedule:
    stop_at: 3

运行命令

mpiexec -n 4 python test2.py test.yaml

报错栈

Traceback (most recent call last):
  File "test2.py", line 45, in <module>
    model.scheduler.run(3)
  File "/path/to/repast4py/schedule.py", line XXX, in run
    self.execute()
  File "/path/to/repast4py/schedule.py", line XXX, in execute
    evt()
  File "test2.py", line 39, in step
    for agent in self.context.agents(OrderBook.TYPE):
  File "/path/to/repast4py/core/context.py", line XXX, in agents
    yield from self._local_agents[type_id].values()
KeyError: 0

解决方案

将原本尝试遍历本地代理的代码替换为直接通过代理ID获取幽灵代理:

原错误代码:

for book in model.context.agents(OrderBook.TYPE):
    print(f"Rank {MPI.COMM_WORLD.rank} sees orders: {book.orders}")

修复后代码:

b = model.context.ghost_agent((1,0,0))
print(f"Rank {MPI.COMM_WORLD.rank} sees orders: {b.orders}")

通过这种方式,非0 Rank可以直接获取到Rank 0创建的OrderBook幽灵代理,实现跨Rank的共享访问,符合预期的打印逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 15:35:12