2013-04-22 111 views
2

我需要從一個進程發送一個矩陣列並從另一個進程接收它。我嘗試運行下面的程序,但我得到了一個奇怪的結果(至少我認爲是這樣);只有矩陣的第一個元素被複制,並且一些矩陣元素意外改變。MPI - 發送和接收列

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <math.h> 
#include "mpi.h" 

void swap(int* a,int* b){ 
    int temp; 
    temp=*a; 
    *a=*b; 
    *b=temp; 
} 
void print_matrix(double** A,int n){ 
    int i,j; 
    for(i=0;i<n;i++){ 
     for(j=0;j<n;j++){ 
      printf("%f ",A[i][j]); 
     } 
     printf("\n"); 
    } 
} 

int main(int argc, char *argv[]){ 
    int i,j,k,l,n,myid,p,maxp; 
    double **A; 
    MPI_Datatype col_type; 
    MPI_Status status; 

    n=3; 
    A=malloc(n*sizeof(double*)); /*allocating memory */ 
    for(i=0;i<n;i++) 
     A[i]=malloc(n*sizeof(double)); 

    A[0][0]=-1; 
    A[0][1]=2; 
    A[0][2]=-1; 
    A[1][0]=2; 
    A[1][1]=-1; 
    A[1][2]=0; 
    A[2][0]=1; 
    A[2][1]=7; 
    A[2][2]=-3; 

    MPI_Init(&argc,&argv); 

    MPI_Type_vector(n, 1, n, MPI_DOUBLE,&col_type); 
    MPI_Type_commit(&col_type); 
    MPI_Comm_size(MPI_COMM_WORLD,&p); 
    MPI_Comm_rank(MPI_COMM_WORLD,&myid); 

    if(myid==0){ 
     printf("Starting Method with p=%d\n",p); 
     print_matrix(A,n); 
    } 
    if(myid==0){ 
      maxp=2; 
      A[0][0]=-43; 
      A[1][0]=-33; 
      A[2][0]=-23; 
      printf("BEFORE SENDING\n"); 
      print_matrix(A,n); 
      for(l=0;l<p;l++) 
       if(l!=myid){ 
        MPI_Send(&A[0][0], 1, col_type,l,0,MPI_COMM_WORLD); 
        MPI_Send(&maxp,1,MPI_INT,l,1,MPI_COMM_WORLD); 
       } 
      printf("AFTER SENDING\n"); 
      print_matrix(A,n); 
    } 
    else{ 
      //receive(k) 
      printf("BEFORE RECIEVING\n"); 
      print_matrix(A,n); 
      MPI_Recv(&A[0][1],1,col_type,0,0,MPI_COMM_WORLD,&status); 
      MPI_Recv(&maxp,1,MPI_INT,0,1,MPI_COMM_WORLD,&status); 
      printf("Just Recieved\n"); 
      print_matrix(A,n); 
    } 

    MPI_Finalize(); 
} 

回答

5

問題是與你的配置:

A=malloc(n*sizeof(double*)); /*allocating memory */ 
for(i=0;i<n;i++) 
    A[i]=malloc(n*sizeof(double)); 

這是完全正常的,但它不一定分配N * N雙打的連續陣列;它分配n個n個數組的n個數組,並且這些數組可以相對於彼此分散在整個內存中。其中(除了潛在的緩存問題)也沒什麼關係,只不過當你定義這樣一列:

MPI_Type_vector(n, 1, n, MPI_DOUBLE,&col_type); 

例如,N雙打,每一個爲n的前一個雙打的時候,你假設所有的數據都是在一個大塊中佈置的。

上最容易改變的是你的配置,以確保它是所有連續和順序(這是幾乎總是你想要的科學計算):

A=malloc(n*sizeof(double*));  /*allocating pointers */ 
A[0] = malloc(n*n*sizeof(double)); /* allocating data */ 
for(i=1;i<n;i++) 
    A[i]=&(A[0][i*n]); 

/* ... */ 

free(A[0]); 
free(A); 
+0

我分配它像這樣,它行得通。謝謝! – 2013-04-22 17:26:28

+1

This:'A [i] =&(A [0] [i * n]);'很聰明,從來沒有想到過,謝謝! – FreeNickname 2013-12-25 18:22:23