gpt4 book ai didi

c - 在 C 语言中使用 MPI_Reduce

转载 作者:行者123 更新时间:2023-12-02 00:35:32 25 4
gpt4 key购买 nike

我正在尝试使用 MPI 库用 C 语言编写程序。在我的程序中,我正在解决 TSP(但没有使用任何特殊算法......)。我的输入参数是int nCites , int xCoord[]int yCoord[] .我将它们捆绑成 Coordinates并使用 MPI_Bcast使它们对所有线程可用。

我的问题是:在计算完每个线程中所有路径的权重后,我想将它们缩减为一个结果,最好的一个。我试过使用 MPI_Reduce ,但是有些东西,这就是我感到困惑的地方,会导致段错误(仅在一个线程中,通常是 root )。

这是主要代码和结构:

typedef struct Coordinates_t {
int* x;
int* y;
int n;
} Coordinates;

typedef struct PathAndLength_t {
int* path;
int pathSize;
int length;
} PathAndLength;

void comparePaths(void* a, void* b, int* len, MPI_Datatype* dataType) {
...
}

int tsp_main(int nCites, int xCoord[], int yCoord[], int P[]){
int numOfProcs, rank;
if (MPI_Comm_size(MPI_COMM_WORLD, &numOfProcs))
throw "Error: MPI_Comm_size failed";
if (MPI_Comm_rank(MPI_COMM_WORLD, &rank))
throw "Error: MPI_Comm_rank failed";

Coordinates crds;
crds.x = xCoord;
crds.y = yCoord;
crds.n = nCites;

MPI_Datatype data;
createInDataType(&crds, &data);

if (MPI_Bcast(&crds, 1, data, 0, MPI_COMM_WORLD))
throw "Error: MPI_Comm_size failed";

...

PathAndLength* pal = (PathAndLength*)malloc(sizeof(PathAndLength));
pal->path = (int*)malloc(sizeof(int)*crds.n);

pal->length = min_length;
for (int i = 0; i < crds.n; ++i) {
(pal->path)[i] = min_path[i];
}
pal->pathSize = crds.n;
MPI_Datatype outDatatype;
MPI_Op op;

createOutDataType(pal, &outDatatype);

MPI_Op_create(&comparePaths, 1, &op);

PathAndLength* result = (PathAndLength*)malloc(sizeof(PathAndLength));
result->path = (int*)malloc(sizeof(int)*crds.n);
MPI_Reduce(pal, result, crds.n, outDatatype, op, 0, MPI_COMM_WORLD);

...

return result->length;
}

这些是 createOutDataTypecreateInDataType我在我的代码中使用:

void createInDataType(Coordinates* indata, MPI_Datatype* message_type_ptr) {
// Build a derived datatype
int block_lengths[3];
MPI_Aint displacements[3];
MPI_Aint addresses[4];
MPI_Datatype typelist[3];

// First specify the types
typelist[0] = typelist[1] = typelist[2] = MPI_INT;

// Specify the number of elements of each type
block_lengths[0] = block_lengths[1] = indata->n;
block_lengths[2] = 1;

// Calculate the displacements of the members relative to indata
MPI_Address(indata, &addresses[0]);
MPI_Address(indata->x, &addresses[1]);
MPI_Address(indata->y, &addresses[2]);
MPI_Address(&indata->n, &addresses[3]);
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];
displacements[2] = addresses[3] - addresses[0];

// Create the derived type
MPI_Type_struct(3, block_lengths, displacements, typelist, message_type_ptr);

// Commit it so that it can be used
MPI_Type_commit(message_type_ptr);
}

void createOutDataType(PathAndLength* outdata, MPI_Datatype* message_type_ptr) {
// Build a derived datatype
int block_lengths[2];
MPI_Aint displacements[2];
MPI_Aint addresses[3];
MPI_Datatype typelist[2];

// First specify the types
typelist[0] = MPI_INT;
typelist[1] = MPI_INT;

// Specify the number of elements of each type
block_lengths[0] = outdata->pathSize;
block_lengths[1] = 1;

// Calculate the displacements of the members relative to outdata
MPI_Address(outdata, &addresses[0]);
MPI_Address(outdata->path, &addresses[1]);
MPI_Address(&outdata->length, &addresses[2]);
displacements[0] = addresses[1] - addresses[0];
displacements[1] = addresses[2] - addresses[0];

// Create the derived type
MPI_Type_struct(2, block_lengths, displacements, typelist, message_type_ptr);

// Commit it so that it can be used
MPI_Type_commit(message_type_ptr);
}

很抱歉包含了这么多代码,但我无法确定什么是无关紧要的……
谢谢。

最佳答案

PathAndLength* result = (PathAndLength*)malloc(sizeof(PathAndLength));
result->path = (int*)malloc(sizeof(int)*crds.n);
MPI_Reduce(pal, result, crds.n, outDatatype, op, 0, MPI_COMM_WORLD);

您正在将 crds.n*outDatatype 接收到大小为 sizeof(PathAndLength) 的结果缓冲区中。你似乎有设计缺陷。

关于c - 在 C 语言中使用 MPI_Reduce,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4741865/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com