具有动态数组的结构的mpi_聚集

具有动态数组的结构的mpi_聚集,mpi,Mpi,我有一个结构: typedef struct { double distance; int* path; } tour; 然后我尝试从所有流程中收集结果: MPI_Gather(&best, sizeof(tour), MPI_BEST, all_best, sizeof(tour)*proc_count, MPI_BEST, 0, MPI_COMM_WORLD); 收集我的根后,看到所有的_最好只包含一个普通元素,其他元素中包含垃圾。 最好的类型是tour* MPI_最佳

我有一个结构:

typedef struct 
{ 
double distance;
int* path;
} tour;
然后我尝试从所有流程中收集结果:

   MPI_Gather(&best, sizeof(tour), MPI_BEST, all_best, sizeof(tour)*proc_count, MPI_BEST, 0, MPI_COMM_WORLD);
收集我的根后,看到所有的_最好只包含一个普通元素,其他元素中包含垃圾。 最好的类型是tour*

MPI_最佳初始化:

 void ACO_Build_best(tour *tour,int city_count, MPI_Datatype *mpi_type /*out*/)
 {
int block_lengths[2];
MPI_Aint displacements[2];
MPI_Datatype typelist[2];
MPI_Aint start_address;
MPI_Aint address;

block_lengths[0] = 1;
block_lengths[1] = city_count;

typelist[0] = MPI_DOUBLE;
typelist[1] = MPI_INT;

MPI_Address(&(tour->distance), &displacements[0]);
MPI_Address(&(tour->path), &displacements[1]);

displacements[1] = displacements[1] - displacements[0];
displacements[0] = 0;

MPI_Type_struct(2, block_lengths, displacements, typelist, mpi_type);
MPI_Type_commit(mpi_type);
}

欢迎任何想法。

除了将不正确的长度传递给
MPI\u聚集
之外,MPI实际上并不跟随指针到指针。使用这种结构化类型,您将发送
distance
的值和
path
指针的值(本质上是一个地址,当发送到其他进程时没有意义)。如果假定
distance
基本上给出了
path
中的元素数量,那么您可以通过组合
MPI\u-Gather
MPI\u-Gatherv
来实现您的目标:

首先,收集长度:

int计数[proc_计数];
MPI_聚集(&best->距离,1,MPI_INT,计数,1,MPI_INT,0,MPI_COMM_WORLD);
现在已使用正确的长度填充了
计数
,您可以继续并使用
MPI\u Gatherv
接收所有路径:

int disps[proc_count];
disps[0]=0;
对于(int i=1;i路径,最佳->距离,MPI_INT,
所有路径、计数、显示、MPI_INT、0、MPI_COMM_WORLD);
现在,您可以在
所有路径
中连接所有路径。您可以通过在
所有路径中从位置
disps[i]
开始的
计数[i]
元素来检查或提取单个路径。或者,您甚至可以构建一组
tour
结构,并让它们使用已分配和填充的路径存储:

tour*all_best=malloc(proc_count*sizeof(tour));
对于(int i=0;i
或者,您可以复制这些段:

for(int i=0;i
编辑:因为我忽略了
tour
结构的定义,所以上面的代码实际上适用于:

struct
{
整数距离;
int*路径;
}

其中
distance
包含
path
中有效元素的数量。这与您的情况不同,但如果没有有关如何分配路径(和大小)的一些信息,则很难给出具体的解决方案。

除了将不正确的长度传递给
MPI\u聚集
,MPI实际上并不跟随指针指向指针。使用这种结构化类型,您将发送
distance
的值和
path
指针的值(本质上是一个地址,当发送到其他进程时没有意义)。如果假定
distance
基本上给出了
path
中的元素数量,那么您可以通过组合
MPI\u-Gather
MPI\u-Gatherv
来实现您的目标:

首先,收集长度:

int计数[proc_计数];
MPI_聚集(&best->距离,1,MPI_INT,计数,1,MPI_INT,0,MPI_COMM_WORLD);
现在已使用正确的长度填充了
计数
,您可以继续并使用
MPI\u Gatherv
接收所有路径:

int disps[proc_count];
disps[0]=0;
对于(int i=1;i路径,最佳->距离,MPI_INT,
所有路径、计数、显示、MPI_INT、0、MPI_COMM_WORLD);
现在,您可以在
所有路径
中连接所有路径。您可以通过在
所有路径中从位置
disps[i]
开始的
计数[i]
元素来检查或提取单个路径。或者,您甚至可以构建一组
tour
结构,并让它们使用已分配和填充的路径存储:

tour*all_best=malloc(proc_count*sizeof(tour));
对于(int i=0;i
或者,您可以复制这些段:

for(int i=0;i
编辑:因为我忽略了
tour
结构的定义,所以上面的代码实际上适用于:

struct
{
整数距离;
int*路径;
}

其中
distance
包含
path
中有效元素的数量。这与您的情况不同,但是没有关于如何分配(和大小)tour.path
的一些信息,很难给出具体的解决方案。

您确定计数[0]和所有路径[0]将来自同一个元素吗?@T\T,
MPI\u聚集[v]
按进程的级别对接收到的块进行排序,因此
计数[0]
始终是秩
0
所有路径中的元素数[0]
将是从秩
0
开始的路径中的第一项。但是现在我看到
距离
不是整数,所以事情变得更复杂。您能告诉我如何分配
巡更路径吗?我已将距离的类型更改为int。您的回答很有帮助。谢谢。是吗