我是 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...),即使我在调用 MPI_Gather 之前明确将 Total[ii] 设置为零,它在接收缓冲区的开头总是有垃圾并设置障碍。是因为我实际上只有两个内核吗?但我读到 MPI 无论如何都会创建一个虚拟机。有没有办法清洁它并获得可靠的聚集?
添加:
我想,这个垃圾可能来自第零个线程。为什么在第 25 行之后它不归零?
最佳答案
摘自 MPI_Gather 的 MPI 手册页:
Each process (root process included) sends the contents of its send buffer to the root process.
因此,recv 缓冲区的前 15000 个元素 total
将包含根进程上的 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();
}
关于c - MPI_收集接收缓冲区中的垃圾 (MPI+C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50497163/