2012-08-26 71 views
1

我有這個串行代碼,我試圖使用MPI轉換爲並行。但我似乎無法讓MPI_Scatter()函數正常工作而不會崩潰。該函數遍歷一個名爲cells的數組,並修改一些值。MPI_Scatter()error

以下是原始串行代碼:

int accelerate_flow(const t_param params, t_speed* cells, int* obstacles) 
{ 
    register int ii,jj;  /* generic counters */ 
    register float w1,w2; /* weighting factors */ 
    /* compute weighting factors */ 
    w1 = params.density * params.accel * oneover9; 
    w2 = params.density * params.accel * oneover36; 

    int i; 

    /* modify the first column of the grid */ 
    jj=0; 

    for(ii=0;ii<params.ny;ii++) 
    { 

     if(!obstacles[ii*params.nx] && (cells[ii*params.nx].speeds[3] > w1 && 
      cells[ii*params.nx].speeds[6] > w2 && cells[ii*params.nx].speeds[7] > w2)) 
     { 
      /* increase 'east-side' densities */ 
      cells[ii*params.nx].speeds[1] += w1; 
      cells[ii*params.nx].speeds[5] += w2; 
      cells[ii*params.nx].speeds[8] += w2; 
     /* decrease 'west-side' densities */ 
     cells[ii*params.nx].speeds[3] -= w1; 
     cells[ii*params.nx].speeds[6] -= w2; 
     cells[ii*params.nx].speeds[7] -= w2; 
     } 
    } 

return EXIT_SUCCESS; 

} 

這裏是我在使用MPI嘗試:

int accelerate_flow(const t_param params, t_speed* cells, int* obstacles, int myrank, int ntasks) 
{ 
    register int ii,jj = 0;;  /* generic counters */ 
    register float w1,w2; /* weighting factors */ 
    int recvSize; 
    int cellsSendTag = 123, cellsRecvTag = 321; 
    int size = params.ny/ntasks, i; 
    MPI_Request* cellsSend, *cellsRecieve; 
    MPI_Status *status; 

    /* compute weighting factors */ 
    w1 = params.density * params.accel * oneover9; 
    w2 = params.density * params.accel * oneover36; 

    t_speed* recvCells = (t_speed*)malloc(size*sizeof(t_speed)*params.nx); 

    MPI_Scatter(cells, sizeof(t_speed)*params.nx*params.ny, MPI_BYTE, recvCells, 
     size*sizeof(t_speed)*params.nx, MPI_BYTE, 0, MPI_COMM_WORLD); 

    for(ii= 0;ii < size;ii++) 
    { 
     if(!obstacles[ii*params.nx] && (recvCells[ii*params.nx].speeds[3] > w1 && 
      recvCells[ii*params.nx].speeds[6] > w2 && recvCells[ii*params.nx].speeds[7] > w2)) 
     { 

      /* increase 'east-side' densities */ 
      recvCells[ii*params.nx].speeds[1] += w1; 
      recvCells[ii*params.nx].speeds[5] += w2; 
      recvCells[ii*params.nx].speeds[8] += w2; 
      /* decrease 'west-side' densities */ 
      recvCells[ii*params.nx].speeds[3] -= w1; 
      recvCells[ii*params.nx].speeds[6] -= w2; 
      recvCells[ii*params.nx].speeds[7] -= w2; 
     } 
    } 

MPI_Gather(recvCells, size*sizeof(t_speed)*params.nx, MPI_BYTE, cells, params.ny*sizeof(t_speed)*params.nx, MPI_BYTE, 0, MPI_COMM_WORLD); 

return EXIT_SUCCESS; 

} 

這裏是t_speed結構:

typedef struct { 
float speeds[NSPEEDS]; 
} t_speed; 

params.nx = 300params.ny = 200

將不勝感激任何幫助。謝謝。

回答

2

MPI_Scatter的第一個計數參數是發送到每個進程,而不是總數的元素數。在這裏,發送計數和接收計數將是相同的,並且將是nx * ny/ntasks;所以你必須像

int count=params.nx*params.ny/ntasks; 

MPI_Scatter(cells, sizeof(t_speed)*count, MPI_BYTE, 
      recvCells,sizeof(t_speed)*count, MPI_BYTE, 0, MPI_COMM_WORLD); 

注意,當ntasks整除NX * NY這隻會工作,否則你將不得不使用Scatterv

+0

非常感謝,它只是一個簡單的大小錯誤與分散和收集。 – wybourn