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

WSL2下运行mpi-sppy单边MPI测试脚本遇断言错误,锁逻辑存疑

mpi-sppy单边MPI测试脚本断言错误问题分析

环境与问题概述

  • 环境:Windows 11 + WSL2 Ubuntu 22.04,mpi4py==4.0.1,MPICH Version:4.0
  • 问题:运行mpi-sppy的单边MPI测试脚本时触发第49行断言错误,排查发现rank1的win.Lock(0)似乎在等待rank0的win.Lock(1)

相关代码片段

start = time.time()
if (rank == 0):
    buff[:] = 3. * np.ones(array_size, dtype='d')
    print(f"rank {rank} - {time.time()-start}: going to sleep")
    time.sleep(3)
    print(f"rank {rank} - {time.time()-start}: woke up")
    buff[:] = np.arange(array_size)

    print(f"rank {rank} - {time.time()-start}: ready for lock")
    win.Lock(1)
    print(f"rank {rank} - {time.time()-start}: locked")
    win.Put((buff, array_size, mpi.DOUBLE), target_rank=1)
    print(f"rank {rank} - {time.time()-start}: Put")
    win.Unlock(1)

elif (rank == 1):
    buff = np.ones(array_size, dtype='d')
    print(f"rank {rank} - {time.time()-start}: going to sleep")
    time.sleep(1)
    print(f"rank {rank} - {time.time()-start}: woke up")
    print(f"rank {rank} - {time.time()-start}: ready for lock")
    win.Lock(0)
    print(f"rank {rank} - {time.time()-start}: locked")
    win.Get((buff, array_size, mpi.DOUBLE), target_rank=0)
    print(f"rank {rank} - {time.time()-start}: Get")
    win.Unlock(0)

运行日志

rank 1 - 1.0728836059570312e-05: going to sleep
rank 0 - 0.00027298927307128906: going to sleep
rank 1 - 1.0001559257507324: woke up
rank 1 - 1.000209093093872: ready for lock
rank 0 - 3.000467300415039: woke up
rank 0 - 3.0005922317504883: ready for lock
rank 0 - 3.000704050064087: locked
rank 1 - 3.0007107257843018: locked
rank 0 - 3.002230405807495: Put
rank 1 - 3.002246618270874: Get

问题分析

  1. Lock操作逻辑说明
    win.Lock(target_rank)的作用是获取目标进程窗口的独占访问锁:rank0调用win.Lock(1)是锁定rank1的窗口,rank1调用win.Lock(0)是锁定rank0的窗口。这两个操作针对不同进程的窗口,本身不存在互相等待的逻辑,属于正常的MPI单边通信锁使用方式。

  2. 断言错误的根本原因
    从日志可见,rank1在rank0完成Put操作前就执行了Get:

  • rank1sleep1秒后就进入Lock(0)并执行Get,此时rank0还在sleep,buff仍是初始的3.0 * np.ones
  • rank0sleep3秒后才修改buff为np.arange(array_size)并执行Put,但此时rank1已经完成了Get操作

脚本的断言应该是检查rank1的buff是否等于rank0最终生成的数组,由于Get早于Put执行,导致断言失败,这属于测试脚本本身的逻辑错误,没有保证数据写入(Put)在读取(Get)之前完成。

修正建议

  • 调整sleep时间:让rank1的sleep时长大于3秒,确保rank0先完成Put再执行Get
  • 使用MPI同步原语:在rank1执行Get前添加MPI.Barrier(),等待rank0完成Put后再继续
  • 调整锁与操作顺序:让rank0先完成Put并释放锁,rank1再获取锁执行Get

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 12:29:51