我有以下问题,我正在尝试发送 2 种类型的数据,1 种 int 和 2 种字符,这是我程序的一部分
#define Send(send_data, count, type, dest, tag) MPI_Send(send_data, count, type, dest, tag, GROUP)
#define Recv(recv_data, count, type, source, tag) MPI_Recv(recv_data, count, type, source, tag, GROUP, &status)
#define Recv(recv_data, count, type, source, tag) MPI_Recv(recv_data, count, type, source, tag, GROUP, &status)
#define Pack(data_in, count_in, type, data_out, count_out, pos) MPI_Pack(data_in, count_in, type, data_out, count_out, pos, GROUP)
#define Unpack(data_out, count_out, pos, data_in, count_in, type) MPI_Unpack(data_out, count_out, pos, data_in, count_in, type, GROUP)
#define Pack_size(count, type, size) MPI_Pack_size(count, type, GROUP, size)
#define MASTER 0
if( rank == 0 ){
k1 = strlen(prog);
k2 = strlen(gamesspath);
for( i = 1; i < proc; i++ ){
Send(&k1, 1, INT, i, 1);
Send(&k2, 1, INT, i, 2);
}
}
else{
Recv(&k1, 1, INT, MASTER, 1);
Recv(&k2, 1, INT, MASTER, 2);
gamesspath = malloc( k2 * sizeof(char));
}
Pack_size(k1, CHAR, &size1);
Pack_size(k2, CHAR, &size2);
Pack_size(1, INT, &size3);
buffer_size = size1 + size2 + size3;
buffer = malloc( buffer_size * sizeof(char));
if( rank == MASTER ){
pos = 0;
Pack(prog, k1, CHAR, buffer, buffer_size, &pos);
Pack(gamesspath, k2, CHAR, buffer, buffer_size, &pos);
Pack(&nindiv, 1, INT, buffer, buffer_size, &pos);
}
Bcast(buffer, buffer_size, PACKED);
if( rank != MASTER ){
pos = 0;
Unpack(buffer, buffer_size, &pos, prog, k1, CHAR);
Unpack(buffer, buffer_size, &pos, gamesspath, k2, CHAR);
Unpack(buffer, buffer_size, &pos, &nindiv, 1, INT);
}
/*FIM DO ENVIO*/
printf("PROG = %s, GAMESSPATH = %s, NINDIV = %d - rank %d\n", prog, gamesspath, nindiv, rank);
但我得到以下结果
PROG = GAMESS, GAMESSPATH = /usr/local/gamess/rungms1, NINDIV = 10 - rank 1
PROG = GAMESS, GAMESSPATH = /usr/local/gamess/rungms, NINDIV = 10 - rank 0
我的问题在第 1 级的 GAMESSPATH 中,/usr/local/gamess/rungms1 排名 0,/usr/local/gamess/rungms
正如您注意到的那样,在排名 1 的 GAMESS PATH 末尾,出现数字 1, 但我找不到错误。
最佳答案
C 中的字符串以空字节结束。 strlen
返回不含空字节的字符串长度。因此,当您使用 MPI 发送字符串时,在接收方不是终止空字节,而是在末尾有一些垃圾数据。
一个简单的修复方法是将 strlen
返回的值加 1。如果长度值可能溢出,这确实有安全隐患。这可能不是科学代码中的问题,但需要注意。
此外,为什么需要打包缓冲区?看起来这些字符串是连续存储的。您实际上也不需要发送长度:只需告诉接收方接收最大缓冲区大小,并在发送方使用实际长度。
关于c - MPI_Bcast 发送字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10838540/