Вот код, который я написал для аналогичного случая, и вы можете использовать его в качестве руководства.
do {
iter++;
MPI_Irecv(&old[1][0], 1, myHelloVector, nbrs[LEFT], 2, MPI_COMM_WORLD, \
&requestFourR[LEFT]);
MPI_Irecv(&old[1][chunkSize[1]+1], 1, myHelloVector, nbrs[RIGHT], 1, \
MPI_COMM_WORLD, &requestFourR[RIGHT]);
MPI_Irecv(&old[0][1], chunkSize[1], MPI_FLOAT, nbrs[UP], 4, \
MPI_COMM_WORLD, &requestFourR[UP]);
MPI_Irecv(&old[chunkSize[0]+1][1], chunkSize[1], MPI_FLOAT, \
nbrs[DOWN], 3, MPI_COMM_WORLD, &requestFourR[DOWN]);
MPI_Issend(&old[1][1], 1, myHelloVector, nbrs[LEFT], 1, \
MPI_COMM_WORLD, &requestFourS[LEFT]);
MPI_Issend(&old[1][chunkSize[1]], 1, myHelloVector, nbrs[RIGHT], 2, \
MPI_COMM_WORLD, &requestFourS[RIGHT]);
MPI_Issend(&old[1][1], chunkSize[1], MPI_FLOAT, nbrs[UP], 3, \
MPI_COMM_WORLD, &requestFourS[UP]);
MPI_Issend(&old[chunkSize[0]][1], chunkSize[1], MPI_FLOAT, nbrs[DOWN], 4, \
MPI_COMM_WORLD, &requestFourS[DOWN]);
calImage(old, new, edge, chunkSize[ROWS], chunkSize[COLS]);
for (itr = 0; itr < 4; itr++) {
MPI_Waitany(4, &requestFourR[0], &index, &status);
switch ( index ) { /* status.MPI_TAG) */
case 0: /* RIGHT */
j = 1;
for (i = 2; i < chunkSize[0]; i++) {
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+ \
old[i][j+1] - edge[i][j]);
}
break;
case 1: /* LEFT */
j = chunkSize[1];
for (i = 2; i < chunkSize[0]; i++) {
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+ \
old[i][j+1] - edge[i][j]);
}
break;
case 2: /* DOWN */
i = 1;
for (j = 2; j < chunkSize[1]; j++) {
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+ \
old[i][j+1] - edge[i][j]);
}
break;
case 3: /* UP */
i = chunkSize[0];
for (j = 2; j < chunkSize[1]; j++) {
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+ \
old[i][j+1] - edge[i][j]);
}
break;
}
}
i = 1; j = 1;
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+old[i][j+1] - \
edge[i][j]);
i = 1; j = chunkSize[1];
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+old[i][j+1] - \
edge[i][j]);
i = chunkSize[0]; j = 1;
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+old[i][j+1] - \
edge[i][j]);
i = chunkSize[0]; j = chunkSize[1];
new[i][j] = 0.25f*(old[i-1][j]+old[i+1][j]+old[i][j-1]+old[i][j+1] - \
edge[i][j]);
MPI_Waitall(4, requestFourS, statusS);
temp = old;
old = new;
new = temp;
} while(your_stopping_condition);
Функция calImage() выполняет вычисления, которые не зависят от операции замены ореола.
void calImage(float **image, float **newImage, float **edge, \
int rows, int cols) {
int i, j;
for (i = 2; i < rows; i++) {
for (j = 2; j < cols; j++) {
newImage[i][j] = 0.25f * (image[i-1][j] \
+ image[i+1][j] \
+ image[i][j-1] \
+ image[i][j+1] \
- edge[i][j]);
}
}
}
person
Angelos
schedule
01.07.2016
DMDACreate2d()
a> создает распределенный массив. Например, см. этот пример о неоднородном лапласиане. Распределенные массивы очень распространены в программах MPI. Действительно, он ограничивает объем обмена данными между узлами и обеспечивает хороший баланс между занимаемой памятью и процессорным временем между процессами. - person francis   schedule 22.06.2016