N台机器中的每台机器都有一个独有的数据部分作为二进制文件。 (这些文件只是固定大小数据类型的数组)
第i个proc可以在第j个proc中读取数据文件的特定部分吗? (例如,第i个proc从第j个proc中的文件开头读取4096个字节。)
似乎MPI_File_*
操作需要将所有数据文件复制到每台机器的本地文件系统中以具有此功能,除非我有分布式并行文件系统。
答案 0 :(得分:1)
这可以通过单侧MPI通信来模拟这种情况。从这里开始,我将做出一些假设(其中一些已在您的问题中确认过):
r
将访问名为“/ tmp / input r
”的文件<) LI>
因此,我们的想法是每个进程在读取模式下打开自己的私有文件,内存映射它,然后将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
正如您所看到的,它既有效又无需提前读取私有文件,也不需要将文件放在共享文件系统上。