如何正确使用MPI_Gather?
How to use correctly MPI_Gather?
我读过有关 mpi 的文章,我对使用函数 MPI_Gather 很感兴趣。
现在我正在这样做,但它不起作用:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
char *funcion (char *a) {
sprintf(a, "asdfa%u", 2);
}
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
char *parcial = malloc(5*sizeof(char));
char *total;
if (rank == 0) {
total = malloc(15*sizeof(char));
parcial = "aaaaa";
}
else if (rank == 1) {
parcial = "bbbbb";
}
else if (rank == 2) {
parcial = "ccccc";
}
MPI_Gather(parcial,5,MPI_CHAR,total,15,MPI_CHAR,0,MPI_COMM_WORLD);
if (rank == 0) {
printf("%s",total);
}
MPI_Finalize();
}
它只打印 "aaaaa",而不是打印 "aaaaabbbbbccccc"。
我做错了什么?
recvcount
参数指定任何单个接收的元素数,而不是总数。因此你应该使用:
MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);
请注意,您对 C 中字符串的理解从根本上是错误的。
首先,每个 C-string 都需要一个额外的字节作为终止空字符。因此,您必须分配 6 / 16 个字节。但是,您不能发送那些空终止符,否则 master 中的字符串将简单地在第一个终止符处结束。但是您必须显式设置 total[15] = 0
才能正确终止字符串。
其次,parcial = "aaaaa"
不会将字符串复制到您的 malloc
内存中(由 strncpy
完成),而是将指针简单地分配给不同的(non-writable) 内存中存储 "aaaaa[=16=]"
的部分。
效果不错:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
char *funcion (char *a) {
sprintf(a, "asdfa%u", 2);
}
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
void *total;
void *parcial;
if (rank == 0) {
parcial = "aaaaa";
}
else if (rank == 1) {
parcial = "bbbbb";
}
else if (rank == 2) {
parcial = "ccccc";
}
MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);
if (rank == 0) {
printf("%s",(char*)total);
}
MPI_Finalize();
}
我读过有关 mpi 的文章,我对使用函数 MPI_Gather 很感兴趣。
现在我正在这样做,但它不起作用:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
char *funcion (char *a) {
sprintf(a, "asdfa%u", 2);
}
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
char *parcial = malloc(5*sizeof(char));
char *total;
if (rank == 0) {
total = malloc(15*sizeof(char));
parcial = "aaaaa";
}
else if (rank == 1) {
parcial = "bbbbb";
}
else if (rank == 2) {
parcial = "ccccc";
}
MPI_Gather(parcial,5,MPI_CHAR,total,15,MPI_CHAR,0,MPI_COMM_WORLD);
if (rank == 0) {
printf("%s",total);
}
MPI_Finalize();
}
它只打印 "aaaaa",而不是打印 "aaaaabbbbbccccc"。
我做错了什么?
recvcount
参数指定任何单个接收的元素数,而不是总数。因此你应该使用:
MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);
请注意,您对 C 中字符串的理解从根本上是错误的。
首先,每个 C-string 都需要一个额外的字节作为终止空字符。因此,您必须分配 6 / 16 个字节。但是,您不能发送那些空终止符,否则 master 中的字符串将简单地在第一个终止符处结束。但是您必须显式设置 total[15] = 0
才能正确终止字符串。
其次,parcial = "aaaaa"
不会将字符串复制到您的 malloc
内存中(由 strncpy
完成),而是将指针简单地分配给不同的(non-writable) 内存中存储 "aaaaa[=16=]"
的部分。
效果不错:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
char *funcion (char *a) {
sprintf(a, "asdfa%u", 2);
}
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
void *total;
void *parcial;
if (rank == 0) {
parcial = "aaaaa";
}
else if (rank == 1) {
parcial = "bbbbb";
}
else if (rank == 2) {
parcial = "ccccc";
}
MPI_Gather(parcial,5,MPI_CHAR,total,5,MPI_CHAR,0,MPI_COMM_WORLD);
if (rank == 0) {
printf("%s",(char*)total);
}
MPI_Finalize();
}