You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

MPI并行计算1-1000求和遇除零错误:MyNode与Nodes为何为0?

MPI代码整数除零错误排查:MyNode与Nodes为何均为0?

你遇到的这个问题是典型的MPI API调用用法错误导致的,咱们一步步拆解原因:

首先看你贴出的代码里这两行关键错误:

MyNode = MPI_Comm_rank(MPI_COMM_WORLD, &MyNode);
Nodes = MPI_Comm_size(MPI_COMM_WORLD, &Nodes);

错误原因分析

MPI的MPI_Comm_rankMPI_Comm_size这两个函数的返回值不是进程rank或者进程总数,而是错误码(成功时返回0)。正确的用法是通过函数的第二个参数(指针类型)来获取实际的rank值和进程数量。

你的代码里犯了两个致命错误:

  • 把函数的返回值(成功时为0)直接赋值给了MyNodeNodes,导致这两个变量都被设置为0
  • 虽然你把MyNodeNodes的地址传给了函数,但此时变量本身已经被赋值为返回值的0,不过更关键的是,你完全误解了这两个函数的返回值含义,这才是核心问题

Nodes为0时,后续计算1000 * MyNode / Nodes就变成了0 / 0,自然触发Integer division by zero错误。

修正后的代码

把这两行错误的API调用改成正确的写法即可:

// 正确获取当前进程的rank
MPI_Comm_rank(MPI_COMM_WORLD, &MyNode);
// 正确获取总进程数
MPI_Comm_size(MPI_COMM_WORLD, &Nodes);

另外,你的main函数参数也有问题:int main(int* argc, char** argv[])应该改成int main(int argc, char** argv)(符合C++标准,同时适配MPI_Init的参数要求),不过这个不是导致当前错误的直接原因,但最好一并修正。

完整修正后的代码如下:

#include <iostream>
#include <stdio.h>
#include <mpi.h>
static int MyNode, Nodes;
using namespace std;

int main(int argc, char** argv) {
    MPI_Init(&argc, &argv);
    // 修正MPI API调用方式
    MPI_Comm_rank(MPI_COMM_WORLD, &MyNode);
    MPI_Comm_size(MPI_COMM_WORLD, &Nodes);
    MPI_Status status;
    int sum = 0;
    int accum = 0;
    int FIndex = 1000 * MyNode / Nodes + 1;
    int LIndex = 1000 * (MyNode + 1) / Nodes;
    for (int I = FIndex; I <= LIndex; I = I + 1) sum += I;
    
    if (MyNode != 0)
        MPI_Send(&sum, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
    else
        for (int J = 1; J < Nodes; J = J + 1) {
            MPI_Recv(&accum, 1, MPI_INT, J, 1, MPI_COMM_WORLD, &status);
            sum += accum;
        }
    
    if (MyNode == 0) {
        cout << "Total Nodes is " << Nodes << ".The sum from 1 to 1000 is: " << sum << endl;
    }
    MPI_Finalize();
    return 0;
}

额外说明

  • MPI函数的返回值通常用来检查调用是否成功,比如你可以这样写来捕获错误:
    int err = MPI_Comm_rank(MPI_COMM_WORLD, &MyNode);
    if (err != MPI_SUCCESS) {
        // 处理错误逻辑
    }
    
  • 运行MPI程序时,要确保用mpiexec或者mpirun指定正确的进程数,比如mpiexec -n 4 ./your_program来用4个进程运行。

内容的提问来源于stack exchange,提问作者hian cuei

火山引擎 最新活动