2013-04-08 2 views
1

Ну, я делаю домашнюю работу с использованием MPI + C. На самом деле я написал небольшой код программирования 3.2 из книги Питера Пачеко «Введение в параллельное программирование». Кажется, что код работает для 3 или 5 процессов ... но когда я пытаюсь выполнить более 6 процессов, программа прерывается.Ошибка в идентификаторе ранга с использованием MPI_Reduce

Я использую очень «плохой» подход к отладке, который должен помещать некоторые printfs для отслеживания там, где возникают проблемы. Используя этот «метод», я обнаружил, что после MPI_Reduce происходит какое-то странное поведение, и моя программа запутывается по идентификаторам рангов, в частности, ранг 0 исчезает и появляется очень большой (и ошибочный) ранг.

Мой код ниже, и после этого, я отправляю выход на 3 и 9 процессов ... Я бегу с

mpiexec -n X ./name_of_program 

где X представляет собой число процессов.

Мой код:

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

int main(void) 
{ 
MPI_Init(NULL,NULL); 

long long int local_toss=0, local_num_tosses=-1, local_tosses_in_circle=0, global_tosses_in_circle=0; 

double local_x=0.0,local_y=0.0,pi_estimate=0.0; 

int comm_sz, my_rank; 

MPI_Comm_size(MPI_COMM_WORLD, &comm_sz); 
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);   

if (my_rank == 0) { 
    printf("\nEnter the number of dart tosses: "); 
    fflush(stdout); 
    scanf("%lld",&local_num_tosses); 
    fflush(stdout); 
} 

// 
MPI_Barrier(MPI_COMM_WORLD); 

    MPI_Bcast(&local_num_tosses, 1, MPI_LONG_LONG_INT, 0, MPI_COMM_WORLD); 

    MPI_Barrier(MPI_COMM_WORLD); 

    srand(rand()); //tried to improve randomness here! 

for (local_toss=0;local_toss<local_num_tosses;local_toss++) { 
    local_x = (-1) + (double)rand()/(RAND_MAX/2); 
    local_y = (-1) + (double)rand()/(RAND_MAX/2); 

    if ((local_x*local_x + local_y*local_y) <= 1) {local_tosses_in_circle++;} 
} 


MPI_Barrier(MPI_COMM_WORLD); 

MPI_Reduce 
(
    &local_tosses_in_circle, 
    &global_tosses_in_circle, 
    comm_sz, 
    MPI_LONG_LONG_INT, 
    MPI_SUM, 
    0, 
    MPI_COMM_WORLD 
); 

printf("\n\nDEBUG: myrank = %d, comm_size = %d",my_rank,comm_sz); 
fflush(stdout); 

    MPI_Barrier(MPI_COMM_WORLD); 

if (my_rank == 0) { 
    pi_estimate = ((double)(4*global_tosses_in_circle))/((double) comm_sz*local_num_tosses); 
    printf("\nPi estimate = %1.5lf \n",pi_estimate); 
    fflush(stdout); 
} 

MPI_Finalize(); 
    return 0; 
} 

Теперь, 2 выхода:

(I) в течение 3 процессов:

Enter the number of dart tosses: 1000000 

DEBUG: myrank = 0, comm_size = 3 

DEBUG: myrank = 1, comm_size = 3 

DEBUG: myrank = 2, comm_size = 3 
Pi estimate = 3.14296 

(II) За 9 процессов: (заметим, что \ п выход странный, иногда он не работает)

 Enter the number of dart tosses: 10000000 


     DEBUG: myrank = 1, comm_size = 9 
     DEBUG: myrank = 7, comm_size = 9 


     DEBUG: myrank = 3, comm_size = 9 
     DEBUG: myrank = 2, comm_size = 9DEBUG: myrank = 5, comm_size = 9 
     DEBUG: myrank = 8, comm_size = 9 



     DEBUG: myrank = 6, comm_size = 9 

     DEBUG: myrank = 4, comm_size = 9DEBUG: myrank = -3532887, comm_size = 141598939[PC:06511] *** Process received signal *** 
     [PC:06511] Signal: Segmentation fault (11) 
     [PC:06511] Signal code: (128) 
     [PC:06511] Failing at address: (nil) 
     -------------------------------------------------------------------------- 
     mpiexec noticed that process rank 0 with PID 6511 on node PC exited on signal 11 (Segmentation fault). 
     -------------------------------------------------------------------------- 

ответ

1

Это работает для меня, когда третий аргумент MPI_Reduce является 1, не comm_size (так как число элементов в каждом буфере 1):

MPI_Reduce 
(
    &local_tosses_in_circle, 
    &global_tosses_in_circle, 
    1, //instead of comm_size 
    MPI_LONG_LONG_INT, 
    MPI_SUM, 
    0, 
    MPI_COMM_WORLD 
); 

При увеличении числа процессов, MPI_Reduce перезаписывает другие вещи в стек функции, например my_rank и comm_sz, и развращает данные.

Кроме того, я не думаю, что вам нужны какие-либо из заявлений MPI_Barrier. MPI_Reduce и MPI_Bcast блокируют в любом случае.

Я не стал бы беспокоиться о новостях. Их не хватает, но в каком-то другом месте на выходе, вероятно, потому, что многие процессы одновременно записываются в stdout.

Кстати: Отладка с использованием printf 's очень распространена.

+0

Очень красивый Рафаэль, спасибо большое! Это решило мою проблему! Фактически, третий аргумент MPI_Reduce - это размер данных. Если это не вектор, то правильное значение - 1 ... действительно! Я чувствую себя немым :-(lol О барьере, я думаю, что то же самое, что и вы ... но посмотрите на [это] (http://stackoverflow.com/questions/9284419/is-mpi-reduce -blocking-or-a-natural-барьер) Stack Overflow post .. это действительно запутанно! – guipy

+1

Я вижу, откуда происходит публикация пива. Я, вероятно, займусь этим и отвечу вам иногда. Если вы не выполняете MPI_Reduce в петля, как пиво упоминает, сбросить MPI_Barrier, безусловно, хорошо. –

+0

Большое спасибо Рафаэлю за усилия, которые мне помогают! Большое спасибо! – guipy

Смежные вопросы