【问题标题】:Signal: Segmentation fault (11) in MPI C++信号:MPI C++ 中的分段错误 (11)
【发布时间】:2016-05-08 13:50:37
【问题描述】:

我有一个代码,它计算 MPI 中整数的平均值:

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

// Average method
int compute_avg(int *array, int num_elements) {
    int sum = 0;
    int i;
    for (i = 0; i < num_elements; i++) {
    sum += array[i];
    }
    return sum / num_elements;
}

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

    if (argc != 2) {
    fprintf(stderr, "Usage: avg num_elements_per_proc\n");
    exit(1);
    }
    int num_elements_per_proc = atoi(argv[1]);

    MPI_Init(NULL, NULL);
    int world_rank;
    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
    int world_size;
    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

// Create array with integers
    int *nums = NULL;
    if (world_rank == 0) {

        for (int i =0; i<5; i++){
            nums[i] = i;
        }
    }


// Subtable from any processes
    int *sub_nums = (int *)malloc(sizeof(int) * num_elements_per_proc);
    assert(sub_nums != NULL);


// distribution numbers for all processes
    MPI_Scatter(nums, num_elements_per_proc, MPI_INT, sub_nums,
    num_elements_per_proc, MPI_INT, 0, MPI_COMM_WORLD);

// Count avg subtable
    int sub_avg = compute_avg(sub_nums, num_elements_per_proc);

// Collectiong averages
    int *sub_avgs = NULL;
    if (world_rank == 0) {
    sub_avgs = (int *)malloc(sizeof(int) * world_size);
    assert(sub_avgs != NULL);
    }
    MPI_Gather(&sub_avg, 1, MPI_INT, sub_avgs, 1, MPI_INT, 0, MPI_COMM_WORLD);


// Calculates the overall average
    if (world_rank == 0) {
    int avg = compute_avg(sub_avgs, world_size);
    printf("Avg of all elements is %d\n", avg);
// Obliczenie średniej na danych oryginalnych i wyświetlenie.
    int original_data_avg =
    compute_avg(nums, num_elements_per_proc * world_size);
    printf("Avg computed across original data is %d\n", original_data_avg);
}

// free memory
    if (world_rank == 0) {
    free(nums);
    free(sub_avgs);
    }
    free(sub_nums);
    MPI_Barrier(MPI_COMM_WORLD);
    MPI_Finalize();

return 0;
}

当我尝试运行这个 (mpirun -c 4 avg 4) 时,我得到了错误列表:

[mangeke-mpi-2431940:03372] * 处理接收到的信号 *

[mangeke-mpi-2431940:03372] 信号:分段错误 (11)

[mangeke-mpi-2431940:03372] 信号代码:地址未映射 (1)

[mangeke-mpi-2431940:03372] 地址失败:(nil)

[mangeke-mpi-2431940:03372] * 错误信息结束 *

我该如何解决这个问题?

【问题讨论】:

  • 错误发生在哪里?
  • 无论如何,如果 world_rank = 0 这将出现段错误,因为您将尝试将值分配给空指针
  • nums 在所有等级中被初始化为NULL,因此在紧随其后的循环中对其元素的任何分配都将因所有等级的分段错误而失败。

标签: c ubuntu mpi


【解决方案1】:

作为 Hristo cmets,nums 被初始化为 NULL。如果您探索使用调试器生成的核心文件,它会引发以下语句

核心是由 `./m 4' 生成的。程序以信号 SIGSEGV 终止, 分段故障。 #0 0x0000000000408809 in main (argc=2, argv=0x7ffd4fc87e68) at m.cxx:36 36 nums[i] = i;

如果您更改以下代码,如下所示,您将可以使其在没有段错误的情况下运行。

    ....

    // Create array with integers
    int nums[num_elements_per_proc]; // <<-- change here
    if (world_rank == 0) {

        for (int i =0; i<5; i++){
            nums[i] = i;
        }
    }

    ....
    // free memory
    if (world_rank == 0) {
    // free(nums);                   // <<-- change here, free not needed
    free(sub_avgs);
    }

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 2015-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-25
    • 2015-08-10
    • 2017-07-30
    • 2017-03-05
    相关资源
    最近更新 更多