Параллельное программирование в стандарте MPI. Баканов В.М - 60 стр.

UptoLike

Составители: 

- 60 -
printf(“%6.2f “, c[i][j]);
}
printf (“\n”);
}
/**************************** worker task ************************************/
if (taskid > MASTER)
{
MPI_Recv(&offset, 1, MPI_INT, MASTER, FROM_MASTER, M_C_W, &status);
MPI_Recv(&rows, 1, MPI_INT, MASTER, FROM_MASTER, M_C_W, &status);
MPI_Recv(&a, rows*NCA, MPI_DOUBLE, MASTER, FROM_MASTER,
M_C_W, &status);
MPI_Recv(&b, NCA*NCB, MPI_DOUBLE, MASTER, FROM_MASTER,
M_C_W, &status);
for (k=0; k<NCB; k++)
for (i=0; i<rows; i++)
{
c[i][k] = 0.0;
for (j=0; j<NCA; j++)
c[i][k] += a[i][j] * b[j][k];
}
MPI_Send(&a_offset, 1, MPI_INT, MASTER, FROM_WORKER, M_C_W);
MPI_Send(&a_rows, 1, MPI_INT, MASTER, FROM_WORKER, M_C_W);
MPI_Send(&c, a_rows*NCB, MPI_DOUBLE, MASTER, FROM_WORKER,
M_C_W);
}
MPI_Finalize();
} // end of MM_MPI_2.C program
Cтроки матрицы [A] распределяются между
numworkers
процессов по
rows
штуккаждому процессу
dest=1
÷
numworkers
посредством вызова функции
MPI_Send(&a[offset][0], rows*NCA, MPI_DOUBLE, dest, FROM_MASTER,
MPI_COMM_WORLD)
пересылаются
rows
строк (
rows=averow
, если
NRA
делится
на
numworkers
нацело и
rows=averow+1
в противном случае,
offset
номер
первой пересылаемой строки). Матрица [B] пересылается посредством
MPI_Send(&b, NCA*NCB, MPI_DOUBLE, dest, FROM_MASTER,
MPI_COMM_WORLD)
всем
numworkers
процессам целиком.
После получения процессами данных выполняется умножение посредст-
вом внешнего цикла по k=1
÷
NCA (т.е. по столбцам [A] и строкам [B] и внут-
реннего цикла по i=1
÷
rows (т.е. переданной части строк [A] и [C]):
for (k=0; k<NCB; k++)
for (i=0; i<rows; i++) // …на узле присутствует только rows строк матрицы [A]
{
c[i][k] = 0.0;
for (j=0; j<NCA; j++)
c[i][k] += a[i][j] * b[j][k];
}
                                            - 60 -

         printf(“%6.2f “, c[i][j]);
      }
     printf (“\n”);
}

/**************************** worker task ************************************/
  if (taskid > MASTER)
  {
     MPI_Recv(&offset, 1, MPI_INT, MASTER, FROM_MASTER, M_C_W, &status);
     MPI_Recv(&rows, 1, MPI_INT, MASTER, FROM_MASTER, M_C_W, &status);
     MPI_Recv(&a, rows*NCA, MPI_DOUBLE, MASTER, FROM_MASTER,
                                                               M_C_W, &status);
     MPI_Recv(&b, NCA*NCB, MPI_DOUBLE, MASTER, FROM_MASTER,
                                                               M_C_W, &status);

     for (k=0; k