Mengatasi Memori di MPI_Gather C

Saya mencoba meneruskan data ke MPI_Gather. Saya mengalokasikan memori sebagai berikut:

float *phie, *phitemp;
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);

phitemp=(float *) malloc(20*sizeof(float));
if (rank==1) phie=(float *) malloc(itermax*20*size*sizeof(float));

dan kemudian dapatkan semua proses untuk mengirim data ke peringkat 1 menggunakan MPI_Gather() seperti di bawah ini:

for (iter=0;iter<itermax;iter++) {    
   MPI_Gather((float *) phitemp, 20, MPI_FLOAT, (float *) (phie+iter*20*size*sizeof(float)), 20, MPI_FLOAT, 1, MPI_COMM_WORLD);
   iter=0;

}

Saya mendapatkan pesan kesalahan yang menunjukkan saya tidak mengalokasikan memori dengan tepat.


person Marta    schedule 01.02.2017    source sumber
comment
Menambahkan pertanyaan saya. Saya menggunakan variabel iter untuk memindahkan alamat buffer penerimaan di MPI_Gather(). iter mungkin memiliki nilai berbeda di prosesor yang berbeda. Yang mana yang digunakan dalam fungsi MPI_Gather? Yang untuk prosesor yang menerima data? Jika ya, bagaimana saya bisa memastikan prosesor yang berbeda menunggunya?   -  person Marta    schedule 01.02.2017
comment
Harap tambahkan kata-kata yang tepat dari pesan kesalahan spesifik ke pertanyaan Anda!   -  person Zulan    schedule 01.02.2017
comment
Jika Anda menambahkan pertanyaan lagi, silakan gunakan fungsi edit dan masukkan pertanyaan tambahan di badan pertanyaan.   -  person Zulan    schedule 01.02.2017


Jawaban (1)


Aritmatika penunjuk dilakukan berdasarkan ukuran kata yang ditunjuk penunjuk. Karena phie adalah float *, sizeof(float) di phie+iter*20*size*sizeof(float) mubazir dan Anda keluar dari memori yang valid.

Hapus sizeof(float), atau lebih baik ubah ke pengindeksan array yang lebih jelas: &(phie[iter * 20 * size])

Anda juga harus menghapus semua gips penunjuk, semuanya mubazir dan dapat menyembunyikan masalah. Anda sebaiknya hanya melakukan transmisi ketika Anda tahu bahwa Anda membutuhkannya.

Mengenai pertanyaan tambahan Anda: Parameter recvbuf dari MPI_Gather hanya signifikan pada proses root. Oleh karena itu, hanya iter dari proses root yang penting. Namun demikian karena semua proses Anda melewati putaran yang sama saat menjalankan MPI_Gather, dan mereka tidak dapat mendahului satu sama lain, mereka akan selalu memiliki iter yang sama selama pengumpulan yang cocok.

person Zulan    schedule 01.02.2017
comment
Terima kasih. Saya telah memperbaikinya, tetapi kesalahannya masih ada. - person Marta; 02.02.2017
comment
Jika MPI_Gather tidak mengizinkan proses untuk saling mendahului, bagaimana cara memasukkan baris output sebelum perintah MPI_Gather printf(iter: %d, processor: %d sebelum MPI_Gather.\n, iter, rank); berikan keluaran ini? iter: 0, prosesor: 0 sebelum MPI_Gather. iter: 0, prosesor: 1 sebelum MPI_Gather. iter: 0, prosesor: 2 sebelum MPI_Gather. iter: 0, prosesor: 3 sebelum MPI_Gather. iter: 1, prosesor: 0 sebelum MPI_Gather. iter: 1, prosesor: 1 sebelum MPI_Gather. iter: 2, prosesor: 1 sebelum MPI_Gather. iter: 3, prosesor: 1 sebelum MPI_Gather. iter: 4, prosesor: 1 sebelum MPI_Gathe - person Marta; 02.02.2017
comment
Harap edit contoh minimal yang dapat direproduksi yang telah diperbaiki (baca halaman itu dengan cermat) ke dalam pertanyaan Anda untuk upaya debugging lebih lanjut. - person Zulan; 02.02.2017
comment
Operasi-operasi tersebut tidak dapat mendahului satu sama lain, yang berarti hanya akan cocok secara berurutan. Namun aliran kontrol di peringkat belum tentu sinkron - MPI_Gather tidak berarti adanya penghalang. Juga tidak ada jaminan apa pun tentang bagaimana stdout dari peringkat yang berbeda digabungkan. - person Zulan; 02.02.2017
comment
Itu adalah bug kecil yang telah saya perbaiki. Terima kasih atas klarifikasi Anda sebelumnya: itulah masalah utama yang saya hadapi. - person Marta; 02.02.2017