N臺機器中的每臺機器都將數據的專有部分作爲二進制文件。 (這些文件只是固定大小數據類型的數組)我可以使用MPI中的API讀取遠程文件嗎?
第i個proc是否可以在第j個過程中讀取數據文件的特定部分? (例如,第i個PROC從第j個PROC的文件的開頭讀4096個字節)。
看來MPI_File_*
操作要求來複制所有數據文件到每臺計算機的本地文件系統具有此功能除非我有分佈式並行文件系統。
N臺機器中的每臺機器都將數據的專有部分作爲二進制文件。 (這些文件只是固定大小數據類型的數組)我可以使用MPI中的API讀取遠程文件嗎?
第i個proc是否可以在第j個過程中讀取數據文件的特定部分? (例如,第i個PROC從第j個PROC的文件的開頭讀4096個字節)。
看來MPI_File_*
操作要求來複制所有數據文件到每臺計算機的本地文件系統具有此功能除非我有分佈式並行文件系統。
這可以通過單向MPI通信的方式進行模擬。從這裏,我會做出一些假設(其中一些你已經在你的問題確認):
r
將訪問名爲「/ tmp目錄/輸入r
」)所以這個想法是,每個進程在讀取模式下打開它自己的私有文件,存儲器映射它,然後將由mmap()
返回的內存地址公開到MPI內存窗口中。一旦完成,每個進程可以使用這個窗口來訪問它想要的各種文件的一部分。
這是它會是什麼樣子:
#include <stdio.h>
#include <mpi.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
int main(int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
// Open the local file
char fname[256];
snprintf(fname, 256, "/tmp/input%d", rank);
int fd = open(fname, O_RDONLY);
// And memory-map it
struct stat st;
fstat(fd, &st);
size_t len = st.st_size;
void *faddr = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0);
// Create a MPI memory window with the mapped files
MPI_Win win;
MPI_Win_create(faddr, len, 1, MPI_INFO_NULL, MPI_COMM_WORLD, &win);
// Each process reads two integers from the next process' private file
int next = (rank + 1) % size;
int values[2];
MPI_Win_lock(MPI_LOCK_EXCLUSIVE, next, 0, win);
MPI_Get(values, 2, MPI_INT, next, 0, 2, MPI_INT, win);
MPI_Win_unlock(next, win);
printf("Process %d read values %d and %d from process %d's private file\n",
rank, values[0], values[1], next);
// Cleaning up
MPI_Win_free(&win);
munmap(faddr, len);
close(fd);
MPI_Finalize();
return 0;
}
爲了測試起見,我創建了一個包含兩個整數的一些文件:添加當前進程的等級和其與10000我用這在Linux集羣(有幾個節點),結果是:
~> mpicc -std=c99 mpimap.c -o mpimap
~> mpirun -n 10 ./mpimap
Process 0 read values 1 and 10001 from process 1's private file
Process 1 read values 2 and 10002 from process 2's private file
Process 2 read values 3 and 10003 from process 3's private file
Process 3 read values 4 and 10004 from process 4's private file
Process 5 read values 6 and 10006 from process 6's private file
Process 6 read values 7 and 10007 from process 7's private file
Process 9 read values 0 and 10000 from process 0's private file
Process 4 read values 5 and 10005 from process 5's private file
Process 7 read values 8 and 10008 from process 8's private file
Process 8 read values 9 and 10009 from process 9's private file
正如你可以看到,它的工作原理和它也不需要讀取提前私人文件,也不需要有文件在共享文件sys上TEM。
感謝您的有趣解決方案!現在我有一個問題。我正在使用Infiniband的RDMA功能,它可能會繞過操作系統,甚至CPU直接訪問物理內存。我曾經在mmap地區使用MPI API,發現了一些可怕的錯誤(內核恐慌,http://unix.stackexchange.com/questions/263684/c-app-with-mmap-kills-kernel-kernel-panic-with-mmap )。知道與此相關的任何問題嗎? – syko
我之前沒有使用這種技術的經驗,所以我不能說它是否觸發某些內核/內核模塊上的錯誤。我可以告訴你的是,你可以嘗試(增強版本)你的集羣上的這個小代碼,看看你是否可以重現你的內核恐慌。如果是這樣,那麼你對你的U&L問題有一個微笑...... – Gilles
這可能不會如預期的那樣在RDMA網絡上工作,例如, IB。驅動程序通常會註冊整個緩衝區,這意味着它首先會默認其中的所有頁面,然後將其鎖定在物理內存中。因此,整個文件將被讀入,這會破壞使用'mmap()'的目的,並且如果文件大於物理內存,將導致段錯誤。 –
您定位的是哪種語言和操作系統? – Gilles