使用MPI_Send发送矩阵的多个列

时间:2013-10-19 15:19:51

标签: c mpi matrix-multiplication

我正在尝试将多个“B”矩阵列发送到处理器0的不同处理器。我正在尝试发送使用MPI_Send但它不起作用。有人可以帮助我吗?

例如:方阵B的大小为7。 这样就应该分发。

处理器0:3列

处理器1:2列

处理器2:2列

#include <stdlib.h>
#include <mpi.h>
#include <stdio.h>
#define ERR_BADORDER    255
#define TAG_INIT      31337
#define TAG_RESULT       42
#define DISP_MAXORDER    12

int mm(double *A, double *B, double *C, int n, int n1);
int rc(int rt,int rank, int size);
int main(int argc, char *argv[]) {
double *A, *B, *C,t,tt;
int n = 0, n0, n1, n2, i,ss,sts;
int rank = 0, size = 1,prev,next,k,z,jcol,ix=0,m,j;
MPI_Datatype column;
MPI_Request reqs[4];
MPI_Status stats[2];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (!rank) {
    if (argc > 1) {
        n = atoi(argv[1]);
    }
    }
MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
 if (!n) {
    MPI_Finalize();
    return 0;
}
n1  = rc(n, rank,size);
n0  = n * n1;  
n2     = n * n;   
A = (double *) malloc(sizeof(double) * (rank ? n0 : n2));
B = (double *) malloc(sizeof(double) *   n2 );       
C = (double *) malloc(sizeof(double) * (rank ? n0 : n2));
if (!rank) {
    for (i=0; i<n2; i++) {
        A[i] = 1.0;
        B[i] = 1.0;
    }
}
t = MPI_Wtime();
if (!rank) {
    ss = n0;
    for (i=1; i<size; i++) {
        sts = n * rc(n, i, size);
        MPI_Send(A + ss, sts, MPI_DOUBLE, i, TAG_INIT,
                 MPI_COMM_WORLD);
        ss += sts;
    }
}
else {
    MPI_Recv(A, n0, MPI_DOUBLE, 0, TAG_INIT, MPI_COMM_WORLD,
             MPI_STATUS_IGNORE);
}
MPI_Type_vector(n,1,n,MPI_DOUBLE, &column);
MPI_Type_commit(&column);

if (!rank) {

  for (i=1; i<size; i++) {

      for(m=0;m<=i-1;m++)
        ix+=rc(n,m,size);         
       ss=rc(n,i,size);        
        for(j=ix;j<ss+ix;j++)
      MPI_Send(&B[j], 1, column, i, TAG_INIT, MPI_COMM_WORLD);
       /*  MPI_Send(&B[i+(n-1)*n], 1, column, i, TAG_INIT,
                 MPI_COMM_WORLD);*/
    }
}
else {
        printf("hello");
    MPI_Recv(B, n, MPI_DOUBLE, 0, TAG_INIT, MPI_COMM_WORLD,
             MPI_STATUS_IGNORE);
}
for (i=0; i<n0; i++) {
   printf("Processor: %d and matrix  %lf \n ",rank, B[i]); 
} 

for (i=0; i<n0; i++) {
    C[i] = 0.0;
}  
MPI_Finalize();
return 0;
}
int rc(int rt, int rank, int size) {  
return (rt / size) + (rt % size > rank);
}

1 个答案:

答案 0 :(得分:0)

请不要用两三个字母来调用这些值,因为我无法理解你想做什么。 您可以通过不同方式解决问题。 当n = 7且我有3个进程时,我向每个进程发送2列不同于主进程0.我希望这对你有所帮助。最好的问候。

#include <stdlib.h>
#include <mpi.h>
#include <stdio.h>
#define ERR_BADORDER    255
#define TAG_INIT      31337
#define TAG_RESULT       42
#define DISP_MAXORDER    12

int main(int argc, char *argv[]) {
    double *B;
    int n = 0;
    int rank , size;
    int i; 
    int columnToSend;
    MPI_Datatype column;
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    if (!rank)printf ("rank = %d , size = %d\n", rank, size);
    if (!rank) {
        if (argc > 1) {
            n = atoi(argv[1]);
        }

    }
    MPI_Bcast(&n, 1, MPI_INT, 0, MPI_COMM_WORLD);
    if (!n) {
        printf ("n = %d!!\n", n);
        MPI_Finalize();
        return 0;
    }

    int offset = n%size;
    int gap = n/size;
    if (!rank)printf ("n = %d, offset = %d , gap = %d\n", n, offset, gap);

    MPI_Type_vector(n,gap,n,MPI_DOUBLE, &column);
    MPI_Type_commit(&column);
    B = (double *) malloc(sizeof(double) *  n*n );
    for (i = 0 ; i < n * n ; i++) {
            B[i] = -1.0;
    }

    if (!rank) {
        for (i = 0 ; i < n * n ; i++) {
            B[i] = i;//<----- I put i instead one
        }
      for (i=1; i < size; i++) {
          columnToSend = gap *i + offset;
          printf ("columnToSend = %d to i = %d \n", columnToSend, i);
          MPI_Send(&B[columnToSend], 1, column, i, TAG_INIT, MPI_COMM_WORLD);

        }
    }
    if (rank)  {
        printf ("in rank = %d n*gap = %d \n", rank, n*gap);
        MPI_Recv(B, n*gap, MPI_DOUBLE, 0, TAG_INIT, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
        for (i=0; i < n*gap; i++) {
            printf("Processor: %d and matrix  %lf \n ",rank, B[i]); 
        }
    }

    MPI_Finalize();
    return 0;
}