Назад | Перейти на главную страницу

Параллельный 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 взят из HDF5.

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

Я выяснил, что это потому, что 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);
}

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