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
相关产品推荐
相关产品推荐

