C++ C++;MPI:无法发送任何内容

C++ C++;MPI:无法发送任何内容,c++,mpi,C++,Mpi,我尝试使用MPI对矩阵求和来完成此操作,我不知道为什么,但我无法使用MPI\u 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 ***

我尝试使用MPI对矩阵求和来完成此操作,我不知道为什么,但我无法使用
MPI\u 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;
}
#包括
#包括
#包括
#包括
#包括
#定义第10行
#定义冒号10
#定义主机0
使用名称空间std;
int main(int argc,char*argv[]){
int行;
int-averow=0;
int extra=0;
整数偏移量;
国际货币基金组织;
MPI_状态;
int矩阵[行][冒号];
int matrixB[行][冒号];
int matrixC[行][冒号];
for(int i=0;i<冒号;i++){
对于(int j=0;j对于(int dest=1;dest,代码中有多处错误:

  • dest
    i
    的循环必须是
    。否则,您的代码正试图发送到不存在的排名8
  • 在某些情况下,尽管没有任何
    DOUBLE
    数据,您仍在使用
    MPI\u DOUBLE
    数据类型。发送
    MPI\u INT
    和接收
    MPI\u DOUBLE
    也不起作用
  • MPI\u发送(&matrixA[offset][0],行*行,…
    ,应为
    行*冒号
  • MPI\u Send(&matrixB,冒号*冒号,…
    )应该是
    行*冒号
    ,也在相应的
    MPI\u Recv
  • 传输整个
    矩阵xb
    ,同时发送
    矩阵块
    ,从计算加法的角度来看也没有意义
  • 矩阵的第一个维度是行,第二个维度是列。但是,加法循环错误地混淆了这一点
  • 工作任务接收结果中的
    偏移量
    设置不正确
  • 我不确定我是否抓住了每一个实际错误,还有一些方面可以显著改进:

  • 有一个常量
    和一个变量
    具有不同的含义,这对于理解代码来说是极其重要的
  • 您的通信设置不必要地复杂。您可以在许多地方简化模式,例如,在本地计算
    偏移量
    ,而不是将其发送。但最重要的是,您应该使用集体操作。这不仅更易于推理,而且性能也更好
  • 在MPI中,主级通常参与计算
  • 不要气馁。初学者可能很难掌握MPI,而且构建(错误和低效)模式非常常见,这些模式可以通过集体轻松完成。我的建议是:

  • 从头开始,放弃当前尝试
  • 了解
    MPI\u Scatterv
    以及
    MPI\u Gatherv
    。在您的示例中,这些是您所需要的唯一通信功能。此外,不需要在主程序的通信路径周围设置单独的代码路径
  • 想想你的数据布局。每个列上矩阵的形状是什么。全局矩阵如何映射到局部矩阵
  • 使用能够清晰、简洁地描述其含义的变量名
  • 分步编写代码,仔细考虑每一行和每一个参数
  • 如果有效,请发布。如果无效或卡住,请发布新问题或更新。在这两种情况下,请随意在此处发布评论

  • 把C和C++都标记为一个问题总是不合适的。这是一个C++程序——即使在我看来它可能是一个C级程序,它有微小的变化——所以我删除了C标记。顺便说一下,<代码> CORONS <代码>应该是整个程序中的代码>列< /代码>。顺便说一下,我已经确认了这个问题。此时,程序会在错误消息之前打印,因为这表明在第一次调用
    MPI_Send
    时不会发生错误。您的问题之一是
    dest So….没有人知道这里的问题是什么….:(