2015-11-18 22 views
0

我試圖根據隨機生成的數組生成一個隨機生成的數組,並稍微隨機地對其進行更改,並將每個變體發送到另一個處理器。這是我到目前爲止的代碼:如何發送MPI中的2D陣列,每個處理器都有變化

#include "stdio.h" 
#include "stdlib.h" 
#include "mpi.h" 
#include "math.h" 

int main(int argc, char **argv) { 

    int N = 32; 
    int dim = 3; 
    float a = 10.0; 
    int size, rank, i, j, k, q; 
    float **C; 
    float rijx, rijy, rijz, rij, Vij, E=0; 
    float stepsize = 0.05; 

    double Start_time, End_time, Elapse_time; 
    MPI_Status status; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &size); 
    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    C = (float **)malloc(N * sizeof(float*)); // 32 particles 

    for (i = 0; i < N; i++) { 
    C[i]=(float *)malloc(dim*sizeof(float)); // x, y, z 
    } 

    MPI_Barrier(MPI_COMM_WORLD); 

    if(rank == 0) { 
    Start_time = MPI_Wtime(); 
    } 

    if (rank == 0) { 
    for(i = 0; i < N; i++) { 
    for(j = 0; j < dim; j++) { 
     C[i][j] = (float)rand()/(float)(RAND_MAX/a); 
     //printf("%f\n",C[i][j]); 
    } 
    } 
    } 

// this is to generate some slight variations in the array 

    float** randomsteps(float **matrix) { 
for(i = 0; i < N; i = i+(rand()%(32/size))) { 
    for (j = 0; j < dim; j++) { 
     if(i%2 == 0) { 
     C[i][j] = C[i][j]+stepsize; 
      if(C[i][j] > 10) { 
      C[i][j] = C[i][j] - 10; 
      } 
     } else { 
     C[i][j] = C[i][j]-stepsize; 
     if(C[i][j] < 0) { 
      C[i][j] = C[i][j] + 10; 
     } 
     } 
    } 
} 
return C; 
    } 


// and here I try to send the array 
    if(rank == 0) { 
    for(i=0; i<size; i++) { 
    C = randomsteps(C); 

    MPI_Send(&C, N*3, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD); 
    } 
    } 

    if(rank != 0) { 
    for(i=0; i<size; i++) { 
     MPI_Recv(&C, N*3, MPI_FLOAT, 0, 10+i, MPI_COMM_WORLD, &status); 
    } 
    } 

MPI_Barrier(MPI_COMM_WORLD); 

    MPI_Finalize(); 

    return 0; 
} 

與代碼一個明顯的問題是,產生的隨機數的方法是有點幼稚(它讓我每次運行程序時相同的值)。這是我可以在以後工作的。

現在,我只是想知道 - 我發送和接收數組的方式有什麼問題?我在使用MPI發送和接收數據時最好格式化數據時遇到了很多麻煩。我將如何去解決這部分代碼?

在此先感謝您的幫助!

+3

您只能使用。 MPI_Send/MPI_Recv移動連續內存塊。你的「二維數組」是一個指針數組,而不是一塊連續的內存 – talonmies

+0

如何使它連續?我正在查看[this](http://www.just4tech.com/2013/10/matrix-multiplication-in-mpi.html)程序以供參考,但我不確定在嘗試修改代碼爲我的程序.. – Chylomicron

+1

使用一個malloc調用來分配整個矩陣,而不是每行一個 – talonmies

回答

1

這裏的問題是所有MPI調用都期望內存是連續的。你的記憶在給定的行內只是連續的,你所說的二維數組實際上是一個指針數組。指針不可移植,因此嘗試向另一個進程發送或廣播指針數組毫無意義,而MPI本身不支持深度複製,所以這種方法不起作用。

但是,如果你改變你的陣列分配是這樣的:

float** C; 
    float* C_buff; 
    C = (float**)malloc(N * sizeof(float*)); // 32 particles 
    C_buff = (float*)malloc(N * dim * sizeof(float)); // buffer for particles 

    float* p = &C_buff[0]; 
    for (i = 0; i < N; i++) { 
    C[i]=p; 
    p+= dim*sizeof(float)); 
    } 

[免責聲明:寫在瀏覽器中,沒有經過測試,使用風險自擔]

使C_buff代表連​​續內存對於你的二維數組,並且CC_buff連續分配中包含指向內存的行指針,那麼你可以使用你現有的代碼進行初始化,但是這樣做是這樣的:

MPI_Send(&C_buff[0][0], N*DIM, MPI_FLOAT, i, 10+i, MPI_COMM_WORLD); 

即。使用C_buff進行MPI呼叫,它應該可以工作。

相關問題