PDA

View Full Version : سوال: برنامه نویسی mpi به زبان C++‎



bahar-danaei
دوشنبه 10 تیر 1392, 15:37 عصر
با سلام و احترام
امیدوارم که سوالم را جای مناسبی مطرح کرده باشم.
برنامه موازی حل معادله خطی به روش حذف گوسی با mpi به زبان C++‎ در ubuntu 12 را تا حدی نوشته ام.در واقع می خواهم مرحله بالا مثلثی کردن ماتریس را به صورت پارالل انجام دهم که به مشکلی برخورد کردم.
روش کار به این صورت است که master سطر i که pivot می باشد را به slaveها می دهد.سپس تمامی سطرهای بعد از i را بین slaveها تقسیم می کند تا آنها با توجه به سطر pivot مقادیر را برای سطرهایی که در اختیار دارند محاسبه کنند و آنها را به master باز گردانند . سپس i یکی اضافه می شود.
مشکل این است که برنامه فقط به ازای i=0 اجرا می شود و هنگامی که i=1 ، مستر پس از ارسال سطرها به slaveها منتظر دریافت از slave می ماند . در واقع slaveها فقط یکبار اجرا می شوند!!!!!!!!!!!!
از راهنمایی تان نهایت سپاس را دارم.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "mpi.h"
#define n 4
#define MASTER_TO_SLAVE_TAG 1 //tag for messages sent from master to slaves
#define SLAVE_TO_MASTER_TAG 4 //tag for messages sent from slaves to master
#define MASTER_TO_SLAVE_TAG_NULL 1000
#define Bcast_TAG 20


void MakeAb();
void PrintArray();
int rank; //process rank
int size; //number of processes
int i, j, k,h,pivot,c; //helper variables
int ANY_SRC;
double start_time; //hold start time
double end_time; // hold end time
int low_bound;
int upper_bound;
int portion;
int count=0;

MPI_Status status; // store status of a MPI_Recv
MPI_Request request; //capture request of a MPI_Isend


double A[n][n];
double b[n];
double A_null[n];




int main( int argc, char *argv[] )
{
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (rank == 0)
{
MakeAb();
PrintArray();
for(i=0;i<n;i++)
A_null[i]=0;
start_time = MPI_Wtime();


for(i=0;i<n-1;i++)
{
count=0;
portion =ceil((n-i-1) / (size - 1));
if (portion==0)
portion=1;
for(j=1;j<size;j++)
{
low_bound = j * portion+i;
upper_bound = low_bound + portion;
if(upper_bound>n)
upper_bound=n;
if(low_bound<n)
{
MPI_Isend(&i,1, MPI_INT, j, MASTER_TO_SLAVE_TAG , MPI_COMM_WORLD, &request);
MPI_Isend(&A[i], n, MPI_DOUBLE, j, MASTER_TO_SLAVE_TAG+1, MPI_COMM_WORLD, &request);
MPI_Isend(&low_bound, 1, MPI_INT, j, MASTER_TO_SLAVE_TAG+2, MPI_COMM_WORLD, &request);
MPI_Isend(&upper_bound, 1, MPI_INT, j, MASTER_TO_SLAVE_TAG + 3, MPI_COMM_WORLD, &request);
for(k=low_bound,c=4;k<upper_bound;k++,C++‎)
MPI_Isend(A[k],n, MPI_DOUBLE,j,MASTER_TO_SLAVE_TAG+c,MPI_COMM_WORLD, &request);
count++;

}
else
{
MPI_Isend(&i,1, MPI_INT, j, MASTER_TO_SLAVE_TAG_NULL , MPI_COMM_WORLD, &request);

}
}
for (j=1;j<=count;j++)
{

MPI_Recv(&low_bound, 1, MPI_INT,j , SLAVE_TO_MASTER_TAG, MPI_COMM_WORLD, &status);
MPI_Recv(&upper_bound, 1, MPI_INT,j , SLAVE_TO_MASTER_TAG + 1, MPI_COMM_WORLD, &status);
for(k=low_bound,c=2;k<upper_bound;k++,C++‎)
MPI_Recv(&A[k],n,MPI_DOUBLE,j, SLAVE_TO_MASTER_TAG +c, MPI_COMM_WORLD, &status);

}
}
}







if (rank > 0)
{

MPI_Recv(&pivot, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG , MPI_COMM_WORLD, &status);
if (!(MASTER_TO_SLAVE_TAG==MASTER_TO_SLAVE_TAG_NULL))
{
MPI_Recv(&A[pivot], n, MPI_DOUBLE, 0, MASTER_TO_SLAVE_TAG+1, MPI_COMM_WORLD, &status);
MPI_Recv(&low_bound, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG+2, MPI_COMM_WORLD, &status);
MPI_Recv(&upper_bound, 1, MPI_INT, 0, MASTER_TO_SLAVE_TAG + +3, MPI_COMM_WORLD, &status);
for(k=low_bound,c=4;k<upper_bound;k++,C++‎)
{
MPI_Recv(&A[k],n , MPI_DOUBLE, 0,MASTER_TO_SLAVE_TAG + c,MPI_COMM_WORLD, &status);
for(i=0;i<n;i++)
A[k][i]+=A[pivot][i]*(-A[k][pivot]/A[pivot][pivot]) ;
}

MPI_Isend(&low_bound, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG , MPI_COMM_WORLD, &request);
MPI_Isend(&upper_bound, 1, MPI_INT, 0, SLAVE_TO_MASTER_TAG +1, MPI_COMM_WORLD, &request);
for(k=low_bound,c=2;k<upper_bound;k++,C++‎)
MPI_Isend(A[k],n,MPI_DOUBLE,0,SLAVE_TO_MASTER_TAG +c, MPI_COMM_WORLD, &request);

}

}

if (rank == 0)
{
end_time = MPI_Wtime();
printf("\nRunning Time = %f\n\n", end_time - start_time);
PrintArray();
}

MPI_Finalize(); //finalize MPI operations
return 0;
}





void MakeAb()
{

A[0][0]=6;
A[0][1]=-2;
A[0][2]=2;
A[0][3]=4;
A[1][0]=12;
A[1][1]=-8;
A[1][2]=6;
A[1][3]=10;
A[2][0]=3;
A[2][1]=-13;
A[2][2]=9;
A[2][3]=3;
A[3][0]=-6;
A[3][1]=4;
A[3][2]=1;
A[3][3]=-18;
b[0]=16;
b[1]=26;
b[2]=-19;
b[3]=-34;
}


void PrintArray()
{
int i,j;
for( i = 0; i < n;i++ )
{
for(j=0;j<n;j++)
printf( "%f ",A[i][j]);
printf( " | %f ",b[i]);
printf("\n");
}
}