【发布时间】:2017-05-04 16:18:53
【问题描述】:
概述:我正在测试我使用 MPI_Type_create_struct() 创建的数据类型是否正确,因此会发送正确的值。我无法将存储在数组中的值传输到其他处理器。我认为这可能是每个结构绑定中数组的内存地址以及存储在用于创建数据类型 mpibound 的数组 indices[] 中的偏移量的问题。
问题: 我正在开发一个使用 MPI 的程序,我的最终目标是使用 MPI_Gatherv() 从下面声明的称为 bound 的结构数组中收集值。
struct bound {
int n;
char* name;
double* lat;
double* lon;
};
我创建了一个测试程序来确保我正确使用了 MPI_Type_create_struct()。我调用 MPI_Type_create_struct() 的函数写在下面。
void CreateBoundType (struct bound a_bound) {
int blocklens[4]; /*Block Lengths of data in structure*/
MPI_Datatype old_types[4]; /*Data types of data in structure*/
MPI_Aint indices[4]; /*Byte displacement of each piece of data*/
MPI_Aint addr1, addr2, addr3, addr4, baseaddr;
/*Set block lengths*/
blocklens[0] = 1;
blocklens[1] = 10;
blocklens[2] = NPT_MAX;
blocklens[3] = NPT_MAX;
/*Set Data Types*/
old_types[0] = MPI_INT;
old_types[1] = MPI_CHAR;
old_types[2] = MPI_DOUBLE;
old_types[3] = MPI_DOUBLE;
/*Set byte displacement for each piece of data in structure*/
/*!!!!!I expect that the following 8 lines cause my problem!!!!!!*/
MPI_Get_address ( &a_bound, &baseaddr);
MPI_Get_address ( &a_bound.num_pts, &addr1);
MPI_Get_address ( a_bound.label, &addr2);
MPI_Get_address ( a_bound.lat, &addr3);
MPI_Get_address ( a_bound.lon, &addr4);
indices[0] = addr1 - baseaddr;
indices[1] = addr2 - baseaddr;
indices[2] = addr3 - baseaddr;
indices[3] = addr4 - baseaddr;
/*Create structure type in MPI so that we can transfer boundaries between nodes*/
MPI_Type_create_struct(4,blocklens,indices,old_types,&mpibound);
MPI_Type_commit(&mpibound);
return;
}
当我尝试使用我创建的数据类型(它是一个全局变量,mpibound)时,在调用 MPI_Bcast() 时,存储在我使用的缓冲区结构的一部分的数组中的值不会更新,但是整数值 n(n 是数组的长度)在所有处理器上都会发生变化。因此,我认为我的问题与用于定义 mpibound 的偏移量(索引 [4])有关。
下面我编写了一个主函数,显示了我如何调用这个函数并设置结构。 (我省略了对 MPI_Init 和其他此类函数的调用,以使其尽可能短)
int main (int argc, char **argv) {
/*Initialise MPI etc*/...
/*Create structure to broadcast*/
struct bound my_bound;
my_bound.name = strdup(string);
my_bound.lat = malloc(NPT_MAX*sizeof(double));
my_bound.lon = malloc(NPT_MAX*sizeof(double));
if(rank == 0) {
my_bound.n = 5;
my_bound.lat[0] = 2.6;
my_bound.lon[0] = 4.2;
}
/*Call the function that creates the type mpibound*/
CreateBoundType(my_bound);
/*Create buffer to be used in a Broadcast from the root processor (rank 0)*/
struct bound *buff = malloc(sizeof(struct bound));
buff->lat = malloc(NPT_MAX*sizeof(double));
buff->lon = malloc(NPT_MAX*sizeof(double));
buff = &my_bound;
/*Cast values in buffer from proc 0 to all others*/
MPI_Bcast(buff,1,mpibound,0,MPI_COMM_WORLD);
/*Print values and checks, free memory etc*/...
return(EXIT_SUCCESS);
}
在调用 MPi_Bcast 之后放置一些打印语句表明,在秩 >0 的 procs 上,n 的值从秩 0 更新为该广播,但 lat 和 lon 数组的第一个元素仍为 0。
如果你能帮助我,我非常感谢它已经为此苦苦挣扎了几天!我尽量保持简短,这是我能够创建的最佳版本。
感谢阅读!
【问题讨论】:
-
您的代码毫无意义。您为这两个数组分配了两个结构和一些内存,但随后您通过执行
buff = &my_bound完全丢弃了第二个数组的内存。无论如何,请准备一个适当的minimal reproducible example 以及更具体的预期输出和实际输出。 -
我支持@Zulan 的评论。你的代码充满了错误,我认为这不仅仅是一个 MPI 问题,它是你在这里错过的对 C 的基本理解。一旦你的 C 基础扎实了,你就可以通过尝试解决 MPI 来开始升级,但如果你想用 MPI + C 编程,C 语言绝对是先决条件。
标签: c arrays struct malloc mpi