gpt4 book ai didi

C++ MPI : could not sent anything

转载 作者:行者123 更新时间:2023-11-30 05:19:33 27 4
gpt4 key购买 nike

我尝试使用 MPI 对矩阵求和来执行此操作,我不知道为什么,但我无法使用 MPI_Send 发送任何类型的数据,但无论我在尝试什么我会收到一条错误消息吗:

Sending 3 rows to task 1 offset=0
Sending 3 rows to task 2 offset=3
Sending 2 rows to task 3 offset=6
Sending 2 rows to task 4 offset=8
*** An error occurred in MPI_Send
*** reported by process [1047527425,0]
*** on communicator MPI_COMM_WORLD
*** MPI_ERR_RANK: invalid rank
*** MPI_ERRORS_ARE_FATAL (processes in this communicator will now abort,
*** and potentially your MPI job)

这是我的代码:

# include <mpi.h>
# include <stdio.h>
# include <stdlib.h>
# include <time.h>
# include <vector>

#define ROWS 10
#define COLONS 10
#define MASTER 0

using namespace std;

int main(int argc, char *argv[]) {

int rows;

int averow=0;
int extra=0;
int offset;
int numprocs;
MPI_Status status;
int matrixA[ROWS][COLONS];
int matrixB[ROWS][COLONS];
int matrixC[ROWS][COLONS];

for (int i = 0; i < COLONS; i++) {
for (int j = 0; j < ROWS; j++) {
matrixA[i][j] = rand() % 10;
matrixB[i][j] = rand() % 10;
}
}
int my_id;

MPI_Init(&argc, &argv);
MPI_Comm_size( MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank( MPI_COMM_WORLD, &my_id);
if (my_id == MASTER) {

averow = ROWS / numprocs;
extra = ROWS % numprocs;
offset = 0;

/* Send matrix data to the worker tasks */
for (int dest = 1; dest <= numprocs; dest++) {
rows = (dest <= extra) ? averow + 1 : averow;
printf("Sending %d rows to task %d offset=%d\n", rows, dest, offset);
MPI_Send(&offset, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
MPI_Send(&rows, 1, MPI_INT, dest, 1, MPI_COMM_WORLD);
MPI_Send(&matrixA[offset][0], rows * ROWS, MPI_DOUBLE, dest, 1,
MPI_COMM_WORLD);
MPI_Send(&matrixB, COLONS * COLONS, MPI_INT, dest, 1,
MPI_COMM_WORLD);
offset = offset + rows;
}

/* Receive results from worker tasks */
for (int i = 1; i <= numprocs; i++) {
int source = i;
MPI_Recv(&offset, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
MPI_Recv(&rows, 1, MPI_INT, source, 2, MPI_COMM_WORLD, &status);
MPI_Recv(&matrixC[offset][0], rows * COLONS, MPI_INT, source, 2,
MPI_COMM_WORLD, &status);
printf("Received results from task %d\n", source);
}
}

if (my_id != MASTER) {
MPI_Recv(&offset, 1, MPI_INT, MASTER, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&rows, 1, MPI_INT, MASTER, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&matrixA, rows * COLONS, MPI_DOUBLE, MASTER, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&matrixB, COLONS * COLONS, MPI_DOUBLE, MASTER, 1,
MPI_COMM_WORLD, &status);

for (int k = 0; k < COLONS; k++) {
for (int i = 0; i < rows; i++) {
matrixC[k][i] = matrixA[k][i] + matrixB[k][i];
}
}
MPI_Send(&offset, 1, MPI_INT, MASTER, 2, MPI_COMM_WORLD);
MPI_Send(&rows, 1, MPI_INT, MASTER, 2, MPI_COMM_WORLD);
MPI_Send(&matrixC, rows * COLONS, MPI_DOUBLE, MASTER, 2,
MPI_COMM_WORLD);
}
MPI_Finalize();

return 0;
}

我在 8 个进程上运行这个程序。

伙计们,你们知道我做错了什么吗?因为我什么也看不见。

最佳答案

您的代码中存在多处错误:

  1. dest 的循环和 i必须是 < numprocs .否则,您的代码将尝试发送到不存在的排名 8!
  2. 有时您会使用 MPI_DOUBLE数据类型,尽管没有任何 double数据。发送 MPI_INT并收到 MPI_DOUBLE也不起作用。
  3. MPI_Send(&matrixA[offset][0], rows * ROWS, ... , 应该是 rows * COLONS .
  4. MPI_Send(&matrixB, COLONS * COLONS, ... , 应该是 ROWS * COLONS , 也在相应的 MPI_Recv 上.
  5. 转移整个matrixB同时发送 matrixA 的 block , 在计算加法时也没有意义。
  6. 矩阵的第一维是,第二维是。但是,您的加法循环错误地混合了这一点。
  7. rowsoffset在您的 Receive results from worker tasks 中设置不正确。

我不确定我是否捕捉到每一个实际错误,还有一些方面可以显着改进:

  1. 有一个常量 ROWS和一个变量 rows具有不同的含义对于轻松理解代码非常不利。
  2. 您的通信设置不必要地复杂。您可以在许多地方简化模式,例如计算 rowsoffset本地而不是四处发送。但最重要的是,你应该使用集体行动。这既更容易推理,也表现得更好。
  3. 在MPI中,master rank一般参与计算。

不要气馁。初学者可能很难掌握 MPI,而且构建(不正确且低效的)模式很常见,而这些模式可以通过集合轻松完成。我的建议是:

  1. 从头开始,放弃当前的尝试。
  2. 了解 MPI_Scatterv以及MPI_Gatherv .这些是您示例中唯一需要的通信功能。此外,也不需要围绕 master 的单独代码路径。
  3. 考虑您的数据布局。每个等级上的矩阵形状是什么。全局矩阵如何映射到局部矩阵。
  4. 使用明确且简洁地描述其含义的变量名称。
  5. 分步编写代码并仔细考虑每一行和参数。
  6. 如果有效,请将其发布到 Code Review .如果它不起作用或您遇到困难,请发布新问题或更新此问题。在这两种情况下,请随时在此处发表评论。

关于C++ MPI : could not sent anything,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41062560/

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