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

实现缓冲版MPI_Get时触发errno 14报错问题求助

问题描述

尝试实现缓冲版本的MPI_Get,实现单进程仅需从另一进程获取数据时,无需执行全局fence同步操作。程序运行时抛出报错:

Read -1, expected 40, errno = 14

运行环境为OpenMPI 4.1.2,通过mpirun -n 2启动,复现代码如下:

#include <mpi.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>

void *ptr;
static MPI_Win win;

void setup(size_t maxmem)
{
    if ((ptr = mmap (NULL, maxmem, PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))
        == (void *)(intptr_t)-1) {
        MPI_Abort(MPI_COMM_WORLD, 1);
    }

   MPI_Win_create (ptr, maxmem, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
}

void bufferedGet(void *origin, size_t count,
    size_t owner_rank, size_t offset)
{
    MPI_Win_lock (MPI_LOCK_SHARED, owner_rank, 0, win);
    MPI_Get (origin, count, MPI_BYTE, owner_rank,
                       offset, count,
                       MPI_BYTE, win);
    MPI_Win_unlock (owner_rank, win);
}

int main(int argc, char **argv)
{
    MPI_Init(&argc, &argv);

    size_t size = 409600;
    setup(size);

    void *result = malloc(10);

    bufferedGet(result, 10, 0, 1);

    free(result);
    MPI_Win_free(&win);
    munmap(ptr, size);

    MPI_Finalize();
}
问题根因

报错里的errno=14对应系统错误码EFAULT,代表访问了非法内存地址,核心问题出在内存窗口的权限配置上:

  • 调用mmap创建窗口挂载的内存时,仅传入了PROT_WRITE写权限,没有开启读权限。MPI RMA层在目标进程侧读取窗口内存数据时,需要内存具备可读权限,无读权限的内存访问直接触发访问错误,最终抛出读失败的报错。
  • 选择的MPI_Win_lock/MPI_Win_unlock同步逻辑本身没有问题,这组API属于MPI RMA的被动目标同步模式,本身就只需要发起方和目标方参与,不需要全局fence同步,完全匹配设计目标。
  • 额外说明:当前用MAP_PRIVATE创建匿名私有映射仅做Get操作是可以正常运行的,但如果后续要支持Put/Accumulate等写操作,写时复制的私有映射会导致目标进程无法感知其他进程写入的数据,需要替换为MAP_SHARED标志。
修复方法

修改mmap调用的权限参数,新增读权限即可,修改后的mmap代码如下:

if ((ptr = mmap (NULL, maxmem, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0))
    == (void *)(intptr_t)-1) {
    MPI_Abort(MPI_COMM_WORLD, 1);
}

修改后重新编译运行即可正常执行,不需要额外添加全局fence操作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:03:19