При использовании 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);
}
Хотя программа может сообщать «прочитано ОК», но вывод шестнадцатеричного дампа показывает, что вывод усечен.