Calloc MPI Menyebabkan Kesalahan Segmentasi

Saya menulis sebuah program untuk menemukan jumlah elemen array dengan MPI. Root dan pekerja menemukan jumlah sebagian dan pekerja mengirimkan sebagian jumlah ke root pada akhirnya. Ketika saya mencoba dengan array berukuran statis tidak ada masalah. Tapi itu memberikan kesalahan segmentasi jika saya menggunakan calloc. Kode sumber diberikan di bawah ini:

#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;
}

Kesalahan yang saya ambil adalah:

-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).
--------------------------------------------------------------------------

Terimakasih atas bantuannya.


person smtnkc    schedule 16.12.2015    source sumber
comment
Berapa nilai n_portion?   -  person PaulMcKenzie    schedule 16.12.2015
comment
apakah Anda mencoba men-debug kode, pada baris mana ia mendapat kesalahan segmentasi? well calloc mengembalikan pointer nol jika tidak dapat mengalokasikan kode.   -  person rahul.deshmukhpatil    schedule 16.12.2015
comment
@PaulMcKenzie Saya menjalankan 3 proses dan saya memiliki 12 elemen dalam array. Jadi n_portion = 4.   -  person smtnkc    schedule 16.12.2015
comment
@JoachimPileborg Tapi, seharusnya seperti itu. Karena saya juga menggunakan root sebagai pekerja. jika n_procs adalah 2 root akan menghitung separuh array dan worker1 akan menghitung separuh lainnya.   -  person smtnkc    schedule 16.12.2015
comment
@samet - Apakah Anda berasumsi itu akan menjadi 4, atau apakah Anda memverifikasi fakta bahwa adalah 4? Kode Anda tidak mengandung pemeriksaan kesalahan, itulah sebabnya masih belum jelas apakah nilainya benar-benar 4. Yang kami miliki hanyalah panggilan ke calloc dengan variabel yang kami tidak tahu apa itu. Bagaimana dengan hard-coding 4 daripada menggunakan variabel? Jika Anda melakukan hal tersebut, apakah Anda masih mengalami masalah tersebut?   -  person PaulMcKenzie    schedule 16.12.2015
comment
Anda tidak memeriksa hasil calloc(). Mungkin itu gagal.   -  person John Zwinck    schedule 16.12.2015
comment
Catatan tambahan: Anda lupa menginisialisasi total sum. Fakta ini membuat saya percaya bahwa Anda perlu menaikkan tingkat peringatan Anda. Tambahkan -wall ke baris perintah kompiler Anda (dengan asumsi Anda menggunakan gcc).   -  person Klas Lindbäck    schedule 16.12.2015
comment
Terima kasih atas komentarnya. Saya mengalami masalah dengan server mpi untuk saat ini. Saya akan mencoba semuanya dan memberikan masukan dalam beberapa menit.   -  person smtnkc    schedule 16.12.2015
comment
Bukankah seharusnya hanya local dari pada &local dalam panggilan MPI_Recv ?   -  person Martin Zabel    schedule 16.12.2015
comment
@PaulMcKenzie Masalah yang sama terjadi ketika saya mengkodekan n_portion sebagai 4. Jadi, saya menginisialisasi total_sum = 0 seperti yang ditunjukkan Klas, dan mengubah &local menjadi local seperti yang ditunjukkan Martin. Berhasil! Terima kasih.   -  person smtnkc    schedule 17.12.2015


Jawaban (1)


Menurut saya masalahnya terletak pada MPI_Recv di sisi pekerja. Anda harus menggunakan 'lokal' bukan '&lokal' sebagai buffer. MPI mengharapkan "alamat awal buffer penerimaan" (lihat standar MPI), yang dalam kasus array dinamis adalah variabel array itu sendiri.

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

Anda mungkin juga ingin menginisialisasi 'total_sum' ke 0 di root dan kemudian kode Anda akan dijalankan.

Sunting: Baru saja melihat Martin Zabel sudah menunjukkan hal ini di komentar

person Johannes    schedule 16.12.2015
comment
Terima kasih! Solusi sempurna. - person smtnkc; 17.12.2015