Использование Mpich (функции парного обмена)

Модератор: Модераторы разделов

Аватара пользователя
dey
Сообщения: 335
ОС: OpenSuse 11.1

Использование Mpich

Сообщение dey »

Проблема такая: есть задача вычисления сложной функции и запоминание результатов вычисления в массиве .
Когда выполняю эту задачу последовательно проблем не возникает, начинаю распараллеливать задачу результаты nan и такие сообщения

Код: Выделить всё

rank 3 in job 8  Kylix_36169   caused collective abort of all ranks
  exit status of rank 3: return code 1
[cli_1]: aborting job:
Fatal error in MPI_Send: Other MPI error, error stack:
MPI_Send(173).............................: MPI_Send(buf=0xbfde4660, count=24, MPI_LONG_DOUBLE, dest=0, tag=50, MPI_COMM_WORLD) failed


Вот собственно сам код

Код: Выделить всё

/*  Установка среды MPI*/
    double t1,t2;
    int numprocs,myid,tag=50;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs);//Получения числа запущенныъ процессов;
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);//Получение идентификатора процесса
//-----------------------------------------------------
MPI_Status status;

if (myid!=0)    {
for(i=myid;i<m;i+=numprocs)
    {
    zT[i]=kfl(Z,i,T);// разложения функции Z(t) в ряд zT из m многочленов Лежандра
}
MPI_Send(zT,m,MPI_LONG_DOUBLE,0,tag,MPI_COMM_WORLD);
}
else{
MPI_Recv(zT,m,MPI_LONG_DOUBLE,MPI_ANY_SOURCE,tag,MPI_COMM_WORLD,&status);
}
MPI_Finalize();


Вопрос как правильно распараллелить вычисление функции между n процессами и сохранить результат в общей области памяти?
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Спасибо сказали:
GPFault
Сообщения: 7

Re: Использование Mpich

Сообщение GPFault »

Похоже проблема в том, что MPI_Send вызывается много раз, а MPI_Recv всего один. Кроме того в приведённом коде в сообщении большая часть является мусором и затирает всё что там было раньше.

Нужно как-то так:

Код: Выделить всё

int getfirstindexforprocess(int myid, int totalelems, int totalprocs);//функция определяющая какая часть массива принадлежат процессу myid
//делит на равные куски с точностью до одного элемента. Там формула простая, но писать не буду - постоянно ошибаюсь в ней на этот самый один элемент

MPI_Status dummy;

if (myid!=0){
    int first=getfirstindexforprocess(myid,m,numprocs);
    int last=getfirstindexforprocess(myid,m,numprocs);
    for(i=first;i<last;++i){
        zT[i]=kfl(Z,i,T);
    }
    MPI_Send(zT+first,last-first,MPI_LONG_DOUBLE,0,0,MPI_COMM_WORLD);
}
else{
    int first=getfirstindexforprocess(myid,m,numprocs);
    int last=getfirstindexforprocess(myid,m,numprocs);
    //У нулевого процесса тоже есть своя часть вычислений
    for(i=first;i<last;++i){
        zT[i]=kfl(Z,i,T);
    }
    for (i=1;i<numprocs;++i){
        first=getfirstindexforprocess(i,m,numprocs);
        last=getfirstindexforprocess(i,m,numprocs);
        MPI_Recv(zT+first,last-first,MPI_LONG_DOUBLE,i,0,MPI_COMM_WORLD,&dummy);
    }
}
MPI_Finalize();

в коде возможны некоторые косяки (не компилировал), но по идее нужно как-то так
А воообще то что здесь реализовано на одних MPI_Send/Recv можно делать с помощью функции MPI_Gather
Спасибо сказали:
Аватара пользователя
dey
Сообщения: 335
ОС: OpenSuse 11.1

Re: Использование Mpich

Сообщение dey »

Благодарю за помощь !!!
Код заработал с небольшими изменениями

Код: Выделить всё

    int first=getfirstindexforprocess(myid,m,numprocs);//номер первого элемента
int last=getfirstindexforprocess(myid+1,m,numprocs)-1;//Номер последнего элемента


А функцию реализовал так :

Код: Выделить всё

int getfirstindexforprocess(int myid, int totalelems, int totalprocs){
//функция определяющая какая часть массива принадлежат процессу myid
avg=totalelems/totalprocs;//Кол-во элементов на процесс
int result=myid*avg;
cout<<"Среднее число "<<avg<<endl;
return result;
}


А по поводу MPI_Gather буду разбираться, судя по описанию она позволяет сократить код и цикличное выполнение MPI_Send/Recv
Еще раз спасибо
В сознательных действиях должен присутствовать существенный неалгоритмический компонент.
Roger Penrose,The Emperor's New Mind
Спасибо сказали: