Вызов MPI вызывает ошибку сегментации

Я написал программу для нахождения суммы элементов массива по MPI. И root, и worker находят сумму части, а worker в конце отправляет частичные суммы root. Когда я пытаюсь использовать массив статического размера, проблем не возникает. Но это дает ошибку сегментации, если я использую calloc. Исходный код приведен ниже:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#define tag1 1 /* send from root to workers */
#define tag2 2 /* send from workers to root */
#define root 0
#define n_data 12

int main(int argc, char *argv[]) 
{ 
    int total_sum, partial_sum;
    int my_id, i, n_procs, n_portion;

    MPI_Init(&argc, &argv);
    MPI_Status status;
    MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
    MPI_Comm_size(MPI_COMM_WORLD, &n_procs);
    n_portion=n_data/n_procs;

    int *array = (int *)calloc(n_data, sizeof(int));
    int *local  = (int *)calloc(n_portion, sizeof(int));

    if(my_id == root) { 

        /* initialize array */
        for(i = 0; i < n_data; i++) 
            array[i]=i;

        /* send a portion of the array to each worker */
        for(i= 1; i < n_procs; i++) 
            MPI_Send( &array[i*n_portion], n_portion, MPI_INT,i, tag1, MPI_COMM_WORLD); 

        /* calculate the sum of my portion */
        for(i = 0; i < n_portion; i++)
            total_sum += array[i];

        /* collect the partial sums from workers */
        for(i= 1; i < n_procs; i++) {
            MPI_Recv( &partial_sum, 1, MPI_INT, MPI_ANY_SOURCE,tag2, MPI_COMM_WORLD, &status);
            total_sum += partial_sum; 
        }

        printf("The total sum is: %d\n", total_sum);
    }
    else { /* I am a worker, receive data from root */

        MPI_Recv( &local, n_portion, MPI_INT, root, tag1, MPI_COMM_WORLD, &status);

        /* Calculate the sum of my portion of the array */
        partial_sum = 0;
        for(i = 0; i < n_portion; i++)
            partial_sum += local[i];

        /* send my partial sum to the root */
        MPI_Send( &partial_sum, 1, MPI_INT, root, tag2, MPI_COMM_WORLD);
    }

    MPI_Finalize(); 
    return 0;
}

Я сделал ошибку:

-bash-4.1$ mpirun -np 3 distApprox
--------------------------------------------------------------------------
mpirun noticed that process rank 2 with PID 110834 on node levrek1 exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

Спасибо за помощь.


person smtnkc    schedule 16.12.2015    source источник
comment
Каково значение n_portion?   -  person PaulMcKenzie    schedule 16.12.2015
comment
Вы пытались отладить код, в какой строке он получает ошибку сегментации? хорошо, calloc возвращает нулевой указатель, если он не может выделить код.   -  person rahul.deshmukhpatil    schedule 16.12.2015
comment
@PaulMcKenzie Я запустил 3 процесса, и у меня есть 12 элементов в массиве. Таким образом, 1_.   -  person smtnkc    schedule 16.12.2015
comment
@JoachimPileborg Но так и должно быть. Потому что я тоже использую root в качестве рабочего. если n_procs равно 2, корень будет вычислять одну половину массива, а worker1 будет вычислять другую половину.   -  person smtnkc    schedule 16.12.2015
comment
@samet - Вы предполагаете, что это будет 4, или вы проверили факт, что это соответствует 4? Ваш код не содержит проверки ошибок, поэтому до сих пор не ясно, действительно ли значение равно 4. Все, что у нас есть, это вызовы calloc с переменными, о которых мы понятия не имеем. Как насчет жесткого кодирования 4 вместо использования переменной? Если бы вы сделали это, у вас все еще была бы проблема?   -  person PaulMcKenzie    schedule 16.12.2015
comment
Вы не проверяете результат calloc(). Может быть, это терпит неудачу.   -  person John Zwinck    schedule 16.12.2015
comment
Примечание: вы забыли инициализировать total sum. Этот факт наводит меня на мысль, что вам нужно повысить уровень предупреждения. Добавьте -wall в командную строку вашего компилятора (при условии, что вы используете gcc).   -  person Klas Lindbäck    schedule 16.12.2015
comment
Спасибо за комментарии. У меня сейчас проблемы с сервером mpi. Я попробую все и дам отзыв через несколько минут.   -  person smtnkc    schedule 16.12.2015
comment
Разве не должно быть просто local вместо &local в вызове MPI_Recv?   -  person Martin Zabel    schedule 16.12.2015
comment
@PaulMcKenzie Та же проблема возникает, когда я жестко запрограммировал n_portion как 4. Итак, я инициализировал total_sum = 0, как указал Клас, и изменил &local на local, как указал Мартин. Оно работает! Спасибо.   -  person smtnkc    schedule 17.12.2015


Ответы (1)


Я бы сказал, что проблема заключается в MPI_Recv на рабочей стороне. Вы должны использовать «local» вместо «& local» в качестве буфера. MPI ожидает "начальный адрес приемного буфера" (см. стандарт MPI), который в случае динамических массивов является самой переменной массива.

MPI_Recv( local, n_portion, MPI_INT, root, tag1, MPI_COMM_WORLD, &status);

Вы также можете инициализировать 'total_sum' равным 0 в корне, и тогда ваш код должен работать.

Редактировать: только что увидел, что Мартин Забель уже указал на это в комментариях.

person Johannes    schedule 16.12.2015
comment
Спасибо! Идеальное решение. - person smtnkc; 17.12.2015