You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于MPI_Scatter计算10000个整数和出现运行错误问题求助

MPI 10进程求和程序报错修复方案

核心错误原因

你程序运行报错的核心是两个低级的参数和索引错误,以及PBS脚本的资源配置冲突:

  • MPI_Scatter 参数配置错误
    MPI_Scatter接口的第二个参数是根进程给每个接收进程发送的元素个数,不是全局数组的总元素数。你当前填写的10000会导致0号进程尝试从intArray读取10*10000=100000个元素,远超过数组实际的10000长度,直接触发内存越界。
  • 子数组访问越界
    你已经通过MPI_Scatter将每个进程负责的1000个元素拷贝到了长度为1000的subIntArray数组中,该数组的合法索引范围是0~999。但你遍历的时候用start = rank * 1000作为起始下标,rank≥1的进程会直接访问subIntArray[1000]及以上的非法地址,触发段错误,也就是你遇到的follower进程崩溃问题。
  • PBS脚本资源参数冲突
    你同时指定了#PBS -l nodes=2和#PBS -l select=5两个冲突的资源申请参数,会导致集群调度器分配的资源不符合预期,建议改为#PBS -l select=2:ncpus=5,刚好申请10个CPU核心匹配你的10进程需求。

修复后的代码

#include <mpi.h>
#include <stdio.h>
#include <string.h>

int main()
{
        int rank, nodes;
        MPI_Init(NULL, NULL);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        MPI_Comm_size(MPI_COMM_WORLD, &nodes);
        MPI_Status status;

        int intArray[10000];
        int subIntArray[1000];

        if(rank == 0) {
                FILE *fp = fopen("./lab7.csv", "r");
                int i = 0;
                int num;
                if (!fp) {
                        printf("Can't open file\n");
                        // 新增异常退出逻辑,避免其他进程永久等待
                        MPI_Abort(MPI_COMM_WORLD, 1);
                } else {
                        while (fscanf(fp, "%d", &num) > 0)
                        {
                                intArray[i] = num;
                                i++;
                        }
                        fclose(fp);
                }
        }

        // 修正Scatter的发送个数参数
        MPI_Scatter(intArray, 1000, MPI_INT, subIntArray, 1000, MPI_INT, 0, MPI_COMM_WORLD);

        int ans = 0;
        int total = 0;

        // 修正子数组索引,直接遍历0~999即可
        for(int i = 0; i < 1000; i++) {
                ans = ans + subIntArray[i];
        }

        if(rank != 0) {
                MPI_Ssend(&ans, 1, MPI_INT, 0, 0, MPI_COMM_WORLD);
        } else {
                total = ans;
                for(int j = 1; j < 10; j++) {
                        MPI_Recv(&ans, 1, MPI_INT, j, 0, MPI_COMM_WORLD, &status);
                        total += ans;
                }
                printf("Total is %d\n", total);
        }

        MPI_Finalize();
        return 0;
}

优化建议

你可以用MPI_Reduce接口代替手动的send/recv逻辑,代码更简洁也不容易出错,替换逻辑如下:

// 删去原来的if(rank!=0)发送和else接收的所有代码,直接调用以下接口即可
MPI_Reduce(&ans, &total, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
if(rank == 0) {
    printf("Total is %d\n", total);
}

内容的提问来源于stack exchange,提问作者anjana kumari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 10:54:03