我需要从一个进程发送一个矩阵列,然后从另一个进程接收它。我尝试运行以下程序,但是我得到了一个奇怪的结果(至少我是这么认为的);仅复制矩阵的第一个元素,并且一些矩阵元素意外更改。
#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();
}
答案 0 :(得分: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);