MPI_Gather 接收缓冲区中的垃圾 (MPI+C)
MPI_Gather junk in receiving buffer (MPI+C)
我是 MPI 的新手,正在尝试在多个线程上并行化代码。我需要将一大块数据传回主线程,并且无法清理我在 MPI_Gather 之后得到的内存垃圾。这是示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank, world_size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
double *total=NULL;
double parcial[15000];
int W=world_size*15000;
if (rank == 0) {
total=malloc(sizeof(double) * world_size*15000);
}
else if (rank != 0) {
for(int i=0; i<15000; i++)parcial[i] = rank*i*0.1;
}
MPI_Barrier(MPI_COMM_WORLD);
if(rank==0) for(int ii=0; ii<W; ii++)total[ii]=0.;
MPI_Gather(parcial,15000,MPI_DOUBLE,total,15000,MPI_DOUBLE,0,MPI_COMM_WORLD);
if (rank == 0) {
int N=world_size*15000;
for(int i=0; i<N; i++) printf("%f ", total[i]);
}
free(total);
MPI_Finalize();
}
如果你 运行 多线程代码(我试过 3,4,5...),它总是在接收缓冲区的开头有垃圾,即使我明确地把 total[ii ] 在调用 MPI_Gather 之前归零并设置障碍。是因为我身体上只有两个内核吗?但我读过 MPI 无论如何都会创建一个虚拟机。有没有办法清理它并获得可靠的收集?
加法:
我想,这个垃圾可能来自 zero-th 线程。为什么它在第 25 行之后不归零?
摘自 MPI_Gather 的 MPI 手册页:
Each process (root process included) sends the contents of its
send buffer to the root process.
因此,接收缓冲区 total
的前 15000 个元素将包含根进程上 parcial
的元素。这在您的代码中被单元化了。
编辑:@Gilles 评论说 MPI_IN_PLACE
可用于避免对根进程进行初始化。这是一个显示其效果的示例:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int *in_place_total = calloc(sizeof(int), size);
int *total = calloc(sizeof(int), size);
int sendval = rank-5000;
MPI_Gather(&sendval, 1, MPI_INT,
total, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
assert(total[0] == -5000);
if (rank)
MPI_Gather(&sendval, 1, MPI_INT,
in_place_total, 1, MPI_INT, 0, MPI_COMM_WORLD);
else
MPI_Gather(MPI_IN_PLACE, 1, MPI_INT,
in_place_total, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
assert(in_place_total[0] == 0);
free(total);
free(in_place_total);
MPI_Finalize();
}
我是 MPI 的新手,正在尝试在多个线程上并行化代码。我需要将一大块数据传回主线程,并且无法清理我在 MPI_Gather 之后得到的内存垃圾。这是示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mpi.h>
int main (int argc, char *argv[]) {
MPI_Init(&argc, &argv);
int rank, world_size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
double *total=NULL;
double parcial[15000];
int W=world_size*15000;
if (rank == 0) {
total=malloc(sizeof(double) * world_size*15000);
}
else if (rank != 0) {
for(int i=0; i<15000; i++)parcial[i] = rank*i*0.1;
}
MPI_Barrier(MPI_COMM_WORLD);
if(rank==0) for(int ii=0; ii<W; ii++)total[ii]=0.;
MPI_Gather(parcial,15000,MPI_DOUBLE,total,15000,MPI_DOUBLE,0,MPI_COMM_WORLD);
if (rank == 0) {
int N=world_size*15000;
for(int i=0; i<N; i++) printf("%f ", total[i]);
}
free(total);
MPI_Finalize();
}
如果你 运行 多线程代码(我试过 3,4,5...),它总是在接收缓冲区的开头有垃圾,即使我明确地把 total[ii ] 在调用 MPI_Gather 之前归零并设置障碍。是因为我身体上只有两个内核吗?但我读过 MPI 无论如何都会创建一个虚拟机。有没有办法清理它并获得可靠的收集?
加法:
我想,这个垃圾可能来自 zero-th 线程。为什么它在第 25 行之后不归零?
摘自 MPI_Gather 的 MPI 手册页:
Each process (root process included) sends the contents of its send buffer to the root process.
因此,接收缓冲区 total
的前 15000 个元素将包含根进程上 parcial
的元素。这在您的代码中被单元化了。
编辑:@Gilles 评论说 MPI_IN_PLACE
可用于避免对根进程进行初始化。这是一个显示其效果的示例:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int *in_place_total = calloc(sizeof(int), size);
int *total = calloc(sizeof(int), size);
int sendval = rank-5000;
MPI_Gather(&sendval, 1, MPI_INT,
total, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
assert(total[0] == -5000);
if (rank)
MPI_Gather(&sendval, 1, MPI_INT,
in_place_total, 1, MPI_INT, 0, MPI_COMM_WORLD);
else
MPI_Gather(MPI_IN_PLACE, 1, MPI_INT,
in_place_total, 1, MPI_INT, 0, MPI_COMM_WORLD);
if (rank == 0)
assert(in_place_total[0] == 0);
free(total);
free(in_place_total);
MPI_Finalize();
}