并行 MPI_File_open 在 NFSv4 上失败但在 NFSv3 上运行

并行 MPI_File_open 在 NFSv4 上失败但在 NFSv3 上运行

当使用 NFSv4 时,我的客户报告他们的 MPI 程序有时会报告文件无法打开或找不到文件的错误。

我编写了一个示例 MPI-IO 程序,并确认如果计算节点上的 MPI 进程尝试访问从 NFS 共享的同一个文件,该程序将失败。经过多次检查,结果发现将 NFS 挂载从 v4.1 更改为 v3 可以消除此问题。

我仍然想使用 NFSv4,因为它安全并且可能提高速度。所以我想知道我应该添加哪些参数才能使其工作。

操作系统:CentOS 7.6 更新至最新版本,nfs-utils 1.3.0,内核 3.10.0-957.12.2

服务器导出:

/home 10.0.214.0/24(rw,no_subtree_check,no_root_squash)

客户端 fstab:

ib-orion-io1:/home /home nfs defaults,rdma,port=20049,nodev,nosuid 0 2

NFSv4 客户端挂载:

ib-orion-io1:/home on /home type nfs4 (rw,nosuid,nodev,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=rdma,port=20049,timeo=600,retrans=2,sec=sys,clientaddr=10.0.214.11,local_lock=none,addr=10.0.214.5)

NFSv3 客户端挂载

ib-orion-io1:/home on /home type nfs (rw,nosuid,nodev,relatime,vers=3,rsize=1048576,wsize=1048576,namlen=255,hard,proto=rdma,port=20049,timeo=600,retrans=2,sec=sys,mountaddr=10.0.214.5,mountvers=3,mountproto=tcp,local_lock=none,addr=10.0.214.5)

NFSv4 客户端上显示错误

Testing simple MPIO program with 112 processes accessing file tttestfile
    (Filename can be specified via program argument)
Proc 0: hostname=node001
Proc 0: MPI_File_open failed (Other I/O error , error stack:
ADIO_OPEN(219): open failed on a remote node)
Proc 66: MPI_File_open failed (File does not exist, error stack:
ADIOI_UFS_OPEN(39): File tttestfile does not exist)
Proc 1: MPI_File_open failed (Other I/O error , error stack:
ADIO_OPEN(219): open failed on a remote node)
Proc 84: MPI_File_open failed (File does not exist, error stack:
ADIOI_UFS_OPEN(39): File tttestfile does not exist)

示例并行 MPI 文件 IO 程序取自 HDF5。

参见“==>Sample_mpio.c<==" 段落 https://support.hdfgroup.org/ftp/HDF5/current/src/unpacked/release_docs/INSTALL_parallel

答案1

我发现这是因为 NFSv4 默认为“ac”。因此,当 MPI 中的等级 0 创建文件时,其他进程在几毫秒后开始打开它。NFS 客户端返回缓存信息,然后出现“文件未找到”的情况。

当添加“noac”选项时,一切又变得顺利了。

编辑:写入仍然有错误。我稍后会尝试使用 NFSv3。示例代码:

#include <mpi.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

int main(int argc, char *argv[])
{
    char hostname[16];
    char readhost[16];
    int  mpi_size, mpi_rank;
    MPI_File fh;
    char *filename = "./mpirw.data";

    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &mpi_size);
    MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank);
    gethostname(hostname, 16);

    if (mpi_rank == 0)
    {
        MPI_File_open(MPI_COMM_SELF, filename,
                MPI_MODE_CREATE | MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
        printf("%d@%s created file\n", mpi_rank, hostname);
        MPI_File_close(&fh);
    }

    MPI_Barrier(MPI_COMM_WORLD);

    MPI_File_open(MPI_COMM_WORLD, filename,
            MPI_MODE_RDWR, MPI_INFO_NULL, &fh);
    printf("%d@%s opened file\n", mpi_rank, hostname);
    MPI_Status status;
    int count = strlen(hostname);
    MPI_File_write_at(fh, mpi_rank * 16,
            hostname, count + 1, MPI_CHAR, &status);
    printf("%d@%s wrote OK\n", mpi_rank, hostname);
    MPI_Barrier(MPI_COMM_WORLD);

    if (mpi_rank == 0)
        MPI_File_write_at(fh, mpi_size * 16, "\n", 1, MPI_CHAR,  &status);

    MPI_File_read_at(fh, mpi_rank * 16,
            readhost, count + 1, MPI_CHAR, &status);
    if (strcmp(hostname, readhost) != 0)
        printf("%d@%s read ERROR, got %s\n", mpi_rank, hostname, readhost);
    else
        printf("%d@%s read OK, got %s\n", mpi_rank, hostname, readhost);

    MPI_File_close(&fh);
}

尽管程序可能会报告“read OK”,但是 hexdump 输出显示输出被截断。

相关内容