PTHRead & MPI

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by Student[ka], 30 Nov 2010.

  1. Student[ka]

    Student[ka] New Member

    Joined:
    30 Nov 2010
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    Здравствуйте! Дана такая задачка следующего вида:
    q = max(3*MA+5*MB)
    где MA, MB – матриці размером NxM.
    Числа N та M задаются пользователем . Все элемент матрицы заполнить целыми числа в диапазоне [-5;5].
    Количество узлов 4. Написать паралельную программу с помощью модулей PTHRead & MPI.

    Code:
    #include <windows.h>
    #include <time.h>
    #include <mpi.h>
    #include <iostream>
    #define comm MPI_COMM_WORLD
    using namespace std;
    
    int i,j,Sum,k,Maxi,N,M, ;
    int MA[100][100],MB[100][100],MQ[100][100];
    static MPI_Status status;//статус процесса
    static int rank = 0, //номер активного процесса
         cluster_size = 4;//количество процессов
    static int tag_N = 3;
    static int tag_M = 4;
    
    
    int main(int argc, char *argv[])
    {
      
        
        MPI_Init(&argc, &argv);//инициализация MPI процесса
    	MPI_Comm_rank(comm, &rank);//получение номера процесса
    	MPI_Comm_size(comm, &cluster_size);//получение количества процессов
    
        if (rank == 0) {
              cout<<"Введите количество строк матрицы кратно 4 = ";
        cin>>N;
        cout<<'\n';
        cout<<"Введите количество столбцов матрицы кратно 4 = ";
        cin>>M;  
        system("cls");
    }
    MPI_Barrier(comm);
    
    if (rank == 0) {
             for(i=0;i<cluster_size;i++)
             { MPI_Send(&N, 1, MPI_LONG, i, tag_N, comm);
               MPI_Send(&M, 1, MPI_LONG, i, tag_M, comm);
             }
    	} else {
               MPI_Recv(&N, 1, MPI_LONG, 0, tag_N, comm, &status);
               MPI_Recv(&M, 1, MPI_LONG, 0, tag_M, comm, &status);
    }
    if (rank == 0) 
    {
     for (i=1;i<=N;i++)
     for (j=1;j<=M;j++)
     MA[i][j]=rand() %11-5;           
     
     for (i=1;i<=N;i++)
     for (j=1;j<=M;j++)
     MB[i][j]=rand() %11-5;        
    }          
    MPI_Barrier(comm);
    
    if(rank == 0) {
     for(k=1; k<cluster_size; ++k) {
    			MPI_Send(MA, N*M, MPI_INT, k, 0, comm);
    			MPI_Send(MB, N*M, MPI_INT, k, 1, comm);
    		}
    	} else {
    		MPI_Recv(MA, N*M, MPI_INT, 0, 0, comm, &status);
    		MPI_Recv(MB, N*M, MPI_INT, 0, 1, comm, &status);
    		}
    		
    if(rank == 0) {	
    	MPI_Barrier(comm);
         for (i=0;i<N/4;i++)
         for(j=0;j<M;j++)
      MQ[i][j]=3*MA[i][j]+5*MB[i][j];}       
      MPI_Barrier(comm);
     
     
     Maxi=MQ[1][1];
     for (i=1;i<=N;i++)
      for (j=1;j<=M;j++)
     if (MQ[i][j]>Maxi)
     Maxi=MQ[i][j];
        
             	   
       	   
       	   
      MPI_Finalize();
      
      cout<<"Матрица A"<<'\n';
      for (i=1;i<=N;i++)
      {
          for (j=1;j<=M;j++)
          cout<<MA[i][j]<<' ';
          cout<<'\n';
      }         
      cout<<'\n'; 
      cout<<"Матрица В"<<'\n';
      for (i=1;i<=N;i++)
      {
          for (j=1;j<=M;j++)
          cout<<MB[i][j]<<' ';
          cout<<'\n';
      }
      cout<<'\n';
     cout<<"Матрица Q"<<'\n';
      
      for (i=1;i<=N;i++)
      {
          for (j=1;j<=M;j++)
          cout<<MQ[i][j]<<' ';
          cout<<'\n'; 
      } 
         
           cout<<'\n';
    
    
     cout<<"Максимальный элемент="<<Maxi<<'\n';    
    cin.get();    
    cin.get();
        return 0;
    }

    Ну во второй программе, я все таки думаю, над использывать широковещатели.

    Вот в чем беда заключается... курсовая.. Помогите хоть чуточку, буду безумно благодарна.

    З.Ы. За написанные программы строго не ругайте, я язык вижу только 2-ой месяц.. а MPI и его синтаксис вторую ночь :)
     
    #1 Student[ka], 30 Nov 2010
    Last edited: 2 Dec 2010
  2. cheater_man

    cheater_man Member

    Joined:
    13 Nov 2009
    Messages:
    651
    Likes Received:
    44
    Reputations:
    7
    Под рукой библиотеки MPI нет, так что примерно будет так:
    Code:
    ...
    int main (int argc, char* argv)//параметры лучше конечно в 
    //main   передать, ну ладно пусть как есть
    if(rank==0)
    {
     //вводишь параметры
     //в for отправлешь всем сообщения
    }
    else
    {
      //принимаешь
    }
    
    Тут достаточно двух ф-ций MPI_Send и MPI_Recv
    так что никакого MPI_Barrier ненужно=)
    В общем-то задача элементарная...
    когда курсач писал очень помог сайт: http://mpi.deino.net
     
  3. bad_boy

    bad_boy Elder - Старейшина

    Joined:
    30 Dec 2004
    Messages:
    187
    Likes Received:
    33
    Reputations:
    3
    Не or а ||.
    mutex инициализировать надо,
    Code:
    pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
    //затем, в коде, в начале нужно вызвать
    pthread_mutex_init(&_mutex,0);
    ...
    //а в конце уничтожить
    pthread_mutex_destroy(&mutex);
    
    ЗЫ. Я пользуюст макросом:
    Code:
    #define CREATE_MODULE_MUTEX(_m) \
    	static pthread_mutex_t _m ##_mutex=PTHREAD_MUTEX_INITIALIZER;\
    	__inline void _m##_lock(){pthread_mutex_lock(&_m ##_mutex);}\
    	__inline void _m##_unlock(){pthread_mutex_unlock(&_m ##_mutex);}\
    	__inline void _m##_init(){pthread_mutex_init(&_m ##_mutex,0);}\
    	__inline void _m##_deinit(){pthread_mutex_destroy(&_m ##_mutex);}
    
    Пример использования
    Code:
    
    CREATE_MODULE_MUTEX(my_mutex)
    
    int a;
    void locked_increment(int* what)
    {
       my_mutex_lock();
       *what +=1;
       my_mutex_unlock();
    }
    
    int main()
    {
       my_mutex_init()
       locked_increment(&a);
       my_mutex_deinit();
       return 0;
    }
    
     
    #3 bad_boy, 30 Nov 2010
    Last edited: 30 Nov 2010
  4. Student[ka]

    Student[ka] New Member

    Joined:
    30 Nov 2010
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    Ооо спасибки за замечания, ща чёт попробуемс ... :)
     
  5. Student[ka]

    Student[ka] New Member

    Joined:
    30 Nov 2010
    Messages:
    3
    Likes Received:
    0
    Reputations:
    0
    Наверно все таки уничтожение мютекса надо было, видимо память забивалась и из-за этого иногда не инициализировалась половинка матрицы.. не успевало..
    Только осталось на MPI сделать.. вот может ктот еще идейку кинет - переделала вот таким образом, но без безрезультатно:(


    Code:
    #include <windows.h>
    #include <time.h>
    #include <mpi.h>
    #include <iostream>
    #define comm MPI_COMM_WORLD
    using namespace std;
    int i,j,k,N,M,a,b,rank,maxi;
    int MA[100][100],MB[100][100],MAX[100],MQ[100][100];
    static MPI_Status status;
     int  size=4;
     
     
     
    int main(int argc, char *argv[])
    {
      
        
        MPI_Init(&argc, &argv);
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
     
    if (rank == 0) { 
        cout<<"Ââåäèòå êîëè÷åñòâî ñòðîê ìàòðèöû êðàòíî 4 = ";
        cin>>N;
        cout<<'\n';
        cout<<"Ââåäèòå êîëè÷åñòâî ñòîëáöîâ ìàòðèöû = ";
        cin>>M;  
        system("cls");
        
             
              MPI_Bcast(&N,1,MPI_INT, 0, MPI_COMM_WORLD);
              MPI_Bcast(&M,1,MPI_INT, 0, MPI_COMM_WORLD);
               
               a=rank*N/size;
                 b=a+N/size; 
                 for (i=a;i<b;i++)
                 for (j=0;j<M;j++)
                 MA[i][j]=rand() %11-5;           
     
                 for (i=a;i<b;i++)
                 for (j=0;j<M;j++)
                 MB[i][j]=rand() %11-5;
     
                 for(i=a; i<=b; i++)
                      {
                          for(j=1; j<=M; j++)
                          {
                           MQ[i][j]=3*MA[i][j]+5*MB[i][j];
                          }     
                      }
            } else {
               MPI_Recv(&N, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
               MPI_Recv(&M, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
                 cout<<" - - ";
                 a=rank*N/size;
                 b=a+N/size;         
                
                 for (i=a;i<b;i++)
                 for (j=0;j<M;j++)
                 MA[i][j]=rand() %11-5;           
     
                 for (i=a;i<b;i++)
                 for (j=0;j<M;j++)
                 MB[i][j]=rand() %11-5;
     
                 for(i=a; i<b; i++)
                      {
                          for(j=0; j<M; j++)
                          {
                           MQ[i][j]=3*MA[i][j]+5*MB[i][j];
                          }     
                      }
    }   
           maxi=MQ[0][0];
           if (rank == 0) 
           for (i=0;i<N;i++)
           for (j=0;j<M;j++)
            if (maxi<MQ[i][j])
            maxi=MQ[i][j];
             
      MPI_Finalize();
      cout<<"Ìàòðèöà A"<<'\n';
      for (i=0;i<N;i++)
      {
          for (j=0;j<M;j++)
          cout<<MA[i][j]<<' ';
          cout<<'\n';
      }         
      cout<<'\n'; 
      cout<<"Ìàòðèöà Â"<<'\n';
      for (i=0;i<N;i++)
      {
          for (j=0;j<M;j++)
          cout<<MB[i][j]<<' ';
          cout<<'\n';
      }
      cout<<'\n';
     cout<<"Ìàòðèöà Q"<<'\n';
      
      for (i=0;i<N;i++)
      {
          for (j=0;j<M;j++)
          cout<<MQ[i][j]<<' ';
          cout<<'\n'; 
      } 
         
           cout<<'\n';
     
     cout<<"Ìàêñèìàëüíûé ýëåìåíò="<<maxi<<'\n';    
    cin.get();    
    cin.get();
        return 0;
    }
    
    
     
    #5 Student[ka], 1 Dec 2010
    Last edited: 2 Dec 2010