Параллельный 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)

Client 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 тип 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 взят из HDF5.

См. Абзац "==> Sample_mpio.c <==" в https://support.hdfgroup.org/ftp/HDF5/current/src/unpacked/release_docs/INSTALL_parallel

0
задан 24 June 2019 в 11:21
1 ответ

Я выяснил, что это потому, что NFSv4 по умолчанию имеет значение «ac». Таким образом, когда ранг 0 в MPI создал файл, другие процессы начали его открывать через несколько миллисекунд. Клиент 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);
}

Хотя программа может сообщать "прочитано ОК", но шестнадцатеричный дамп вывод показывает, что вывод усечен.

0
ответ дан 23 November 2019 в 23:18

Теги

Похожие вопросы