Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Последовательное выполнение Openmpi  (Прочитано 1942 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн DartVolk

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Последовательное выполнение Openmpi
« : 25 Декабря 2010, 17:10:41 »
Здравствуйте!
Есть задачка распараллелить программу.
Для этого использую openmpi
Проблема в том, что при выполнении программы она выполняется последовательно, а не параллельно..

использую команды
 mpicc -w prog.c
mpirun -np 2 a.out  or mpiexec -np 2 a.out or mpiexec.gforked -np a.out or mpiexe.openmpi -np 2 a.out

Ни одна из перечисленных команд не выполняет приложение паралелльно...

Система Ubuntu 10.10 .Программы должны выполняться на локальной машине..

Помогите пожалуйста!

Оффлайн __v1tos

  • Участник
  • *
  • Сообщений: 105
  • Ubuntuu 10.10 x86-64
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #1 : 25 Декабря 2010, 17:48:43 »
Не могли бы вы показать Ваш код.

П,С, в мпиай программа и должна выполнятся последовательно, только указав число процессов вы можете заставить эти процессы выполнять только часть Вашей задачи, то есть добиться параллелизма
П,С, 2 (у меня с объяснениями не очень:)
AMD Phenom II 945, GA-MA790GPT-UD3H (HD 3300), 5 GiB ram

Оффлайн DartVolk

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #2 : 25 Декабря 2010, 18:48:54 »
А у меня не очень с данным кодом...стыдно показывать делал в спешке)
суть в том,что один поток у меня принимает массив а второй получает и пишет в файл.
так вот на убунте бывает так,что выполняет то один поток сначала, то второй...

*превозмогая стыд выкладывает код*

#include<stdio.h>
#include<stdlib.h>
#include<mpi.h>
//#include<iostream>
//#include<conio.h>

#define PR printf(" m,M,K   %i %i %i ",m,M,K);
#define NNN 100
/*
#define N 10
#define Nizn 10
#define nolX 0
#define nolY 0
#define nolZ 0

#define NX N
#define NY N
#define NZ N
*/
#define O Obnull(X);
#define V Vyvod1(X);
#define VV Vyvod2(X);




//#define V
void Vyvod1(int *X,int N)   
{ int i;
printf("vyvod :\n");
 for(i=0;i<N;i++) 
{
printf("%i",*(X+i));
}

}
void Vyvod2(int *X,int N)   
{ int i,j;
printf("vyvod :\n");
 for(i=0;i<N;i++)
for(j=0;j<N;j++)
{printf(" %i",*(X+i));
}

}
void Obnull(int *X,int N)
{int i;
for(i=0;i<N;i++) 
{*(X+i)=-1;
//printf("%i ",*(X+i));
}

}
void MyCaseBlock(int *X,int *Y,int *Z,int nolX,int nolY,int nolZ,\
int NX,int NY,int NZ)
{
/*
// nignia chast kuba po protiv chasovoi strelki
X[0]=nolX;  Y[0]=nolY;Z[0]=nolZ; 
X[1]=NX;Y[1]=nolY;Z[1]=nolZ;
X[2]=NX;Y[2]=NY;Z[2]=nolZ;
X[3]=NX;Y[3]=NY;Z[3]=nolZ;

//verxnia chast kuba protiv chasovoi strelki
X[4]=nolX;Y[4]=nolY;Z[4]=NZ;
X[5]=NX;Y[5]=nolY;Z[5]=NZ;
X[6]=NX;Y[6]=NX;Z[6]=nolZ;
X[7]=nolX;Y[7]=NY;Z[7]=NZ;
*/
*(X+0)=nolX;*(Y+0)=nolY;*(Z+0)=nolZ;
*(X+1)=NX; *(Y+1)=nolY;*(Z+1)=nolZ;
*(X+2)=NX; *(Y+2)=NY; *(Z+2)=nolZ;
*(X+3)=NX; *(Y+3)=NX; *(Z+3)=nolZ;
*(X+4)=nolX;*(Y+4)=nolY;*(Z+4)=NX;
*(X+5)=NX; *(Y+5)=nolY;*(Z+5)=NZ;
*(X+6)=NX; *(Y+6)=NX;  *(Z+6)=nolZ;
*(X+7)=nolX;*(Y+7)=NY; *(Z+7)=NX;
}
void FormatVyvod(int *X,int *CenterX,int *CenterY,int *CenterZ,\
int NX,int NY,int NZ,int N,int VarKub)
{int i=VarKub;int j=0;

CenterX[i]=NX/2;
CenterY[i]=NY/2;
CenterZ[i]=NZ/2;

}
static long int next=1;
void rand1(int seed)
{
next=seed;
}
int MyRand(int begin,int end)
{
rand1(begin);
static int j;

j=rand()%end+1;
return j;

}

void FileTest(FILE *fp,int rank)
{

fp=fopen("mytest.txt","a");
fprintf(fp,"zapisyvaem koordinaty tsentra kruga v fail v formate: Nomer kuba, X,Y,Z \t X,Y,Z ...; \n");
fprintf(fp,"Write  Process %d\n",rank);
fclose(fp);
}
/* vvod-vyvod v fail
zapisyvaem koordinaty tsentra kruga v fail v formate: Nomer kuba, X,Y,Z \t X,Y,Z ...;
*/
void FileIO(FILE *fp,int *CenterX,int *CenterY,int *CenterZ,int N,int Number)
{int i=0;
static int FirstNum;
fp=fopen("mytest.txt","a");
//intf("\nN=%i ",N);
//fprintf(fp,"zapisyvaem koordinaty tsentra kruga v fail v formate: Nomer kuba, X,Y,Z \t X,Y,Z ...; \n");
for(i=0;i<NNN;i++)
{
if(CenterX[i]!=-1 || CenterY[i]!=-1||CenterZ[i]!=-1)
{
fprintf(fp,"%i \t %i %i %i \n",Number,CenterX[i],CenterY[i],CenterZ[i]);
}
}
fclose(fp);
}



int DelenieKub(int VarKub,int *CenterX,int *CenterY,int *CenterZ,\
int *X,int *Y,int *Z ,float *AbsNumber,\
int NX, int NY, int NZ,int N)
{int cent;
int CentX[N],CentY[N],CentZ[N];
for(cent=0;cent<N;cent++)
{
CentX[cent]=CenterX[cent];CentY[cent]=CenterY[cent];CentZ[cent]=CenterZ[cent];
//printf("\nCentX=%i",CentX[cent]);
}

static int flag=1;
static int nolX;
static int nolY;
static int nolZ;
static int NXX;NXX=NX;
static int NYY;NYY=NY;
static int NZZ;NZZ=NZ;

switch(VarKub)
{
flag++;

//vychisliaem koordinaty kybov 1-8
case 1:
NXX=NXX/2;
nolX=0;
nolY=0;nolZ=0;

MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);

case 4:nolX=0;nolY=0;nolZ=0;NX=NX/2;NY=NY;NZ=NZ/2;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CentX,CentY,CentZ,NXX,NYY,NZZ,N,VarKub);

case 2:nolX=NX/2;nolY=0;nolZ=0;NX=NX;NY=NY/2;NZ=NZ/2;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);

case 3: nolX=NX/2;nolY=NY/2;nolZ=0;  NX=NX;NY=NY;NZ=NZ/2;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);


case 5: nolX=0;nolY=0;nolZ=NZ/2; NX=NX/2;NY=NY/2;NZ=NZ;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);

case 6: nolX=NX/2;nolY=0;nolZ=NZ/2; NX=NX;NY=NY/2;NZ=NZ;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);

case 7: nolX=NX/2;nolY=NY/2;nolZ=NZ/2; NX=NX;NY=NY;NZ=NZ;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);


case 8: nolX=N/2;nolY=N/2;nolZ=N/2; NX=N;NY=N;NZ=N;
MyCaseBlock(X,Y,Z,nolX,nolY,nolZ,NXX,NYY,NZZ);
FormatVyvod(X,CenterX,CenterY,CenterZ,NXX,NYY,NZZ,N,VarKub);


}
//RecordNumber(VarKub,AbsNumber,N);
// printf("DelenieKub CenterX %i \n",CenterX[4]);
for(cent=0;cent<N;cent++)
{
//CentX[cent]=CenterX[cent];CentY[cent]=CenterY[cent];CentZ[cent]=CenterZ[cent];
// printf("\n!!!CentX=%i",CentX[cent]);
}
return VarKub;
}





void RecordNumber(int Number,float *AbsNumber,int N)
{int i=0;

*(AbsNumber+i)=Number;

}
void FindNoll(float *AbsNumber,float *NollX,float *NollY,float *NollZ)
{


}

// !!!! Perevesti vse tipy dannyx to float
int main(int argc, char *argv[])
{
/////////////////////////////////////////
int numprocs, rank, namelen,numprocs1,rank1;        // MPI
char processor_name[MPI_MAX_PROCESSOR_NAME],processor_name1[MPI_MAX_PROCESSOR_NAME];

/////////////////////////////////////////
//printf("hi!");
char str='d';
int i,j,k,m=20,K,M;int N=100;
//static int Nizn;static int nolX;static int nolY;static int nolZ;static int NX;static int NY;static int NZ;
int Nizn,nolx,nolY,nolZ,NX,NY,NZ;

int CenterX[N]; int CenterY[N]; int CenterZ[N];
float NollX[N],NollY[N],NollZ[N]; // koordinaty nuleu kubov v absolutmon znachenii
float AbsNumber[N];   // zapis Number posle kagdogo vyzova funktsii DelenieKub
//FILE *fp;   
int X[N];
int Y[N];
int Z[N];
int VarKub;
//O(X,N);
//O(Y,N);
//O(Z,N);
Obnull(X,N);
Obnull(Y,N);
Obnull(Z,N);
Obnull(CenterX,N);
Obnull(CenterY,N);
Obnull(CenterZ,N);

//printf("Vvedite m,M,K: \n");
//scanf("%i %i %i",&m,&M,&K);
//scanf("%i",&m);
//PR;
VarKub=1;
int Abs1[N];
int Parallel[N],Destination[N];
int Number=0;
// pravilo vychislenia nomera kuba- protiv chasovoi strelki/
// snachala niz ,zatem verx

//test Myrand
//float test;
//printf("test= %i \n");

/*
for(i=0;i<8;i++)
{
test=MyRand(1,8);
printf("%i \n",test);
}
*/
int tag=50,dest,source;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Status status;
MPI_Get_processor_name(processor_name, &namelen);
printf("Process %d on %s out of %d\n", rank, processor_name, numprocs);

//VarKub=(int)test;
NX=N/2;NY=N/2;NZ=N/2; //test
VarKub++;


if(0==rank)
{
FILE *fp;
printf("!!rabotaet Potok %i \n",rank);
for(dest=0;dest<numprocs-1;dest++)
printf("hi\n");
//for(i=0;i<m;i++)
{
VarKub++;
NX=NX/2;NY=NY/2;NZ=NZ/2;
Number=DelenieKub(VarKub,CenterX,CenterY,CenterZ,X,Y,Z,AbsNumber,NX,NY,NZ,N);
//MPI_Send(Parallel,0,MPI_INT,0,224,MPI_COMM_WORLD);
int j;
for(j=0;j<N;j++)
{
Parallel[j]=CenterX[j];
}
MPI_Send(Parallel,N,MPI_INT,dest,tag,MPI_COMM_WORLD);
printf("MPI_SEND at process %i\n",rank);
FileTest(fp,rank);
FileIO(fp,CenterX,CenterY,CenterZ,m,Number);
printf("FileIO.....\n");
RecordNumber(Number,AbsNumber,N);
Abs1[i]=Number;
//printf("absNumber %i \n",Abs1[i]);
//printf("Number %i \n",Number);    // error!
int jj;
for(jj=0;jj<m;jj++)
{
printf("Parallel= %i\n",Parallel[jj]);
}
printf("End of Parallel\n");
}

}


if(1==rank)
{ FILE *fp;
printf("!!raboraet Potok %i \n",rank);
for(source=0;source<numprocs-1;source++)
printf("hi\n");
//for(i=0;i<m;i++)
//{
VarKub++;
NX=NX/2;NY=NY/2;NZ=NZ/2;
//fork();

//Number=DelenieKub(VarKub,CenterX,CenterY,CenterZ,X,Y,Z,AbsNumber,NX,NY,NZ,N);
//Parallel[i]=CenterX[i];
//MPI_Recv(Parallel,0,MPI_INT,0,224,MPI_COMM_WORLD);
MPI_Recv(Parallel,N,MPI_INT,source,tag,MPI_COMM_WORLD,&status);
printf("MPI_RECV at process %i",rank);

RecordNumber(Number,AbsNumber,N);
Abs1[i]=Number;
//printf("absNumber %i \n",Abs1[i]);
//printf("Number %i \n",Number);    // error!

//printf("Parallel=%i \n ",Parallel[i]);

//}

}

//printf("%i ",CenterX[0]);

MPI_Finalize();
//Vyvod1(X[N],N);
return 0;
}

Смотрите на функцию main .

Суть программы вкратце- есть куб, есть его точки.
мы в кажом цикле случайно выбираем число, затем делим куб на 8 частей и в нем выбираем новый куб(0-7 это и есть то число)
и так далее.
находим центры кубов и записываем в файл.
Вот собственно и все.

Распараллеливание вижу так- поток посылает массив точек, а второй поток принимает и пишет  в файл.
в результате получается файлик с данными.

Прога висит на том,что выполняет только один поток...

> П,С, в мпиай программа и должна выполнятся последовательно, только указав число процессов вы можете заставить эти процессы выполнять только часть Вашей задачи, то есть добиться параллелизма

в том то и дело,что я пишу команду на 2 процесса, а в результате выполняется только один..
Процессор в системе один, ядро тоже одно.

Оффлайн __v1tos

  • Участник
  • *
  • Сообщений: 105
  • Ubuntuu 10.10 x86-64
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #3 : 25 Декабря 2010, 19:14:53 »
По моему, у Вас  процесс 2 (ранк=1) принимает данные (хотя должен отправлять), а процесс 1 отправляет (процесс 1 пишет резултат в файл, правильно?).

Лично я воспринимаю параллельность так: оба процесса делят куб на части и что то там делают (нужно их синхронизавать, что бы они не выполняли одной работы), затем все процессы отправляют результаты главному процессу, который и пишет в файл.
AMD Phenom II 945, GA-MA790GPT-UD3H (HD 3300), 5 GiB ram

Оффлайн DartVolk

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #4 : 25 Декабря 2010, 21:27:42 »
mpirun -np 2 a.out
Process 0 on mylaptop out of 1
!!raboraet Potok 0
Process 0 on mylaptop out of 1
!!raboraet Potok 0


Вот что выводит консоль...
получается она запускает поток 3 раза подряд, а не три разных потока.Вот в чем проблема:(

Оффлайн __v1tos

  • Участник
  • *
  • Сообщений: 105
  • Ubuntuu 10.10 x86-64
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #5 : 25 Декабря 2010, 22:09:48 »
Хз. Наверное нужно попробовать на двуядерной машине. Хотя у меня все работало, 4 процесса на одноядерной машине запускалось все ок.
Попробуйте простую программку запустить, в программке сделайте вывод MPI_Comm_size при пр=2

Пользователь решил продолжить мысль 25 Декабря 2010, 22:25:59:
У меня на 4-х ядерном 10 процессов спок. запускаются.
Вы с настройками ни чего не делали?
« Последнее редактирование: 25 Декабря 2010, 22:25:59 от __v1tos »
AMD Phenom II 945, GA-MA790GPT-UD3H (HD 3300), 5 GiB ram

Оффлайн DartVolk

  • Автор темы
  • Участник
  • *
  • Сообщений: 101
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #6 : 25 Декабря 2010, 22:37:48 »
нет ничего. установил openmpi и все.
самое обидное, что год назад у меня таки все запускалось!(система была 9.10) ..
а вот сейчас ничегошеньки не выходит.

Запустил стандартную программу .Вывод тот же.То есть выводится в один поток.
Перестанавливал openmpi-bin ..все тоже самое
Hello world: processor 0 of 1
That is all for now!
Hello world: processor 0 of 1
That is all for now!


#include < mpi.h>   /* PROVIDES THE BASIC MPI DEFINITION AND TYPES */
#include < stdio.h>

int main(int argc, char **argv) {
 
  int my_rank;
  int partner;
  int size, i,t;
  char greeting[100];
  MPI_Status stat;
 
  MPI_Init(&argc, &argv); /*START MPI */
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); /*DETERMINE RANK OF THIS PROCESSOR*/
  MPI_Comm_size(MPI_COMM_WORLD, &size); /*DETERMINE TOTAL NUMBER OF PROCESSORS*/
 
 
  sprintf(greeting, "Hello world: processor %d of %d\n", my_rank, size);
 
  /* adding a silly conditional statement like the
     following graphically illustrates "blocking" and
     flow control during program execution
     
     if (my_rank == 1) for (i=0; i<1000000000; i++) t=i;
     
  */
 
  if (my_rank ==0) {
    fputs(greeting, stdout);
    for (partner = 1; partner < size; partner++){
     
      MPI_Recv(greeting, sizeof(greeting), MPI_BYTE, partner, 1, MPI_COMM_WORLD, &stat);
      fputs (greeting, stdout);
     
    }
  }
  else {
    MPI_Send(greeting, strlen(greeting)+1, MPI_BYTE, 0,1,MPI_COMM_WORLD);
  }
 
 
 
  if (my_rank == 0) printf("That is all for now!\n");
  MPI_Finalize();  /* EXIT MPI */
 
}

Оффлайн __v1tos

  • Участник
  • *
  • Сообщений: 105
  • Ubuntuu 10.10 x86-64
    • Просмотр профиля
Re: Последовательное выполнение Openmpi
« Ответ #7 : 26 Декабря 2010, 11:36:14 »
Нашел на http://www.open-mpi.org/   
(Нажмите, чтобы показать/скрыть)

Попробуйте     mpirun -np 10 --host localhost имя_программы
AMD Phenom II 945, GA-MA790GPT-UD3H (HD 3300), 5 GiB ram

 

Страница сгенерирована за 0.021 секунд. Запросов: 22.