我在编写将以特定模式编写的并行MPI I / O程序时遇到了麻烦。 我能够让进程0写整数0-9,进程1写整数10-19,进程2写整数20-29,等等。
proc 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
proc 1: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
proc 2: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
proc 3: [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
result: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20
这是完成此任务的代码:
int main(int argc, char *argv[]) {
// MPI_Finalize();
int i, rank, size, offset;
MPI_File fhw;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int N = size * 10;
int buf[N];
for ( i = 0; i < N; ++i ) {
buf[i] = rank * 10 + i;
}
offset = rank * (N/size) * sizeof(int);
MPI_File_open(MPI_COMM_WORLD, "datafile", MPI_MODE_CREATE|MPI_MODE_WRONLY,
MPI_INFO_NULL, &fhw);
printf("(%d) Writing to file...\n", rank);
printf("\nRank: (%d), Offset: %d\n", rank, offset);
MPI_File_write_at(fhw, offset, buf, (N/size), MPI_INT, &status);
MPI_File_close(&fhw);
MPI_Finalize();
return 0;
}
但是,我对如何产生以下结果感到困惑:
// starting out:
proc 0: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
proc 1: [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
proc 2: [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]
proc 3: [30, 31, 32, 33, 34, 35, 36, 37, 38, 39]
// proc 0 writes first 2 slots, then proc 1 writes next 2, etc.
result: [0, 1, 10, 11, 20, 21, 30, 31, 2, 3, 12, 13, 22, 23, ..., 8, 9, 18, 19, 28, 29, 38, 29]
在过去的几个小时中,我曾尝试使用MPI_File_set_view
来在线查找示例和文档,但无法正常使用。有人可以指引我正确的方向吗?
答案 0 :(得分:2)
如您所知,您需要设置一个视图...
然后在您的代码中出现一些小错误: 1)您真的需要每个进程的buf大于10的数字吗? 2)MPI_File_wite_at中的偏移量以字节为单位,但以元素数(相对于视图元素大小)为单位
因此要设置视图,您只需要一行:
jq '.resources[].entity.credentials | select(.["credhub-ref"])' file
然后,您可以使用MPI_File_write :-)进行完全相同的操作,并为每个进程设置不同的视图,只需替换视图并编写:
#include "mpi.h"
#include <cstdio>
int main(int argc, char *argv[]) {
// MPI_Finalize();
int i, rank, size, offset;
MPI_File fhw;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int N = 10;
int buf[N];
for ( i = 0; i < N; ++i ) {
buf[i] = rank * 10 + i;
}
offset = 10*rank;
MPI_File_open(MPI_COMM_WORLD,"datafile",MPI_MODE_CREATE|MPI_MODE_WRONLY,
MPI_INFO_NULL, &fhw);
printf("(%d) Writing to file...\n", rank);
printf("\nRank: (%d), Offset: %d\n", rank, offset);
MPI_File_set_view( fhw,0,MPI_INT, MPI_INT, "native", MPI_INFO_NULL ) ;
MPI_File_write_at(fhw, offset, buf, N, MPI_INT, &status);
MPI_File_close(&fhw);
MPI_Finalize();
return 0;
}
或简单地:
MPI_File_set_view(fhw,offset*sizeof(int),MPI_INT,MPI_INT,
"native",MPI_INFO_NULL ) ;
MPI_File_write_at(fhw, 0, buf, N, MPI_INT, &status);
注意:在视图中,偏移量以字节为单位,而在写操作中,偏移量以视图元素的大小为准。...可能有点令人困惑:-)
然后魔术:
您需要编写跨度为2 * size的2个整数的块,并且您有N / 2个这些块,因此您要创建一个类型:
MPI_File_set_view(fhw,offset*sizeof(int),MPI_INT,MPI_INT,
"native",MPI_INFO_NULL ) ;
MPI_File_write(fhw, buf, N, MPI_INT, &status);
并设置视图:
MPI_Type_vector(N/2, 2 , size*2, MPI_INT, &ftype);
MPI_Type_commit(&ftype);
然后,您必须考虑到在内存中您必须连续存储数据以适应您的视图,因此它必须为N / 2个块,因此您需要创建一个数据类型:
MPI_File_set_view( fhw, rank*2*sizeof(int), MPI_INT, ftype, "native", MPI_INFO_NULL ) ;
然后您就可以开始写了:
MPI_Type_contiguous(2, MPI_INT, &mtype);
MPI_Type_commit(&mtype);
因此整个代码将变为:
MPI_File_write(fhw, buf, N/2, mtype, &status);
MPI_File_close(&fhw);
答案 1 :(得分:1)
MPI文件视图确实有些复杂。按流程细分:
rank 0: 0 1 - - - - - - 2 3 - - - - - - 4 5
rank 1: - - 10 11 - - - - - - 12 13 - - - - - -
rank 2: - - - - 20 21 - - - - - -
rank 3: - - - - - - 30 31 - - - - - -
您有很多MPI数据类型可供选择。哪个合适?
在C语言中,VECTOR的原型是这样的:
int MPI_Type_vector(int count, int blocklength, int stride,
MPI_Datatype oldtype, MPI_Datatype *newtype)
在此示例中,您希望每个进程编写一个包含5个块的向量。每个块都有两个元素。每个块开始之间的跨度为2 * nprocs或8。“旧类型”为MPI_INT。
您已经在使用MPI_FILE_WRITE_AT。也许考虑使用MPI_FILE_WRITE_AT_ALL来利用库可能提供的所有集体I / O优化。