Ex7 Code
Ex7 Code
c Page 2 of 6
start4 = MPI_Wtime();
void Setup_grid(GRID_INFO_T* grid); fprintf(fp, "%d\n", ma);
void Read_matrix(char* prompt, float block[], int m, int n, GRID_INFO_T* grid); fprintf(fp, "%d\n", nb);
float *parallel_Fox(float block_A[], float block_B[], int ma, int nb, int na,
int mb, GRID_INFO_T* grid); for (i = 0; i < ma * nb; i++)
{
MPI_Init(&argc, &argv); fprintf(fp, "%f\n", mat_C[i]);
MPI_Comm_rank(MPI_COMM_WORLD, &rank); }
Setup_grid(&grid); finish4 = MPI_Wtime();
int n_bar; {
int i, j, k, h, x; dest = l + i * grid->q;
int l; MPI_Send(temp + l * n_bar * m_bar, n_bar * m_bar, MPI_FLOAT, dest, 0 ,
int q, dest; grid->comm);
MPI_Status status; }
}
m_bar = m / grid->q; }
n_bar = n / grid->q; }
int old_rank;
count = ma * na / grid->p; int dimensions[2];
int wrap_around[2];
// determine which block should be broadcasted in step(0....grid.q-1) in each int coordinates[2];
row int free_coords[2];
if (grid->my_rank == grid->my_row * grid->q + (grid->my_row + step) % grid->q)
{ /* Set up Global Grid Information */
memcpy(new_block, block_A, count * sizeof(float)); MPI_Comm_size(MPI_COMM_WORLD, &(grid->p));
} MPI_Comm_rank(MPI_COMM_WORLD, &old_rank);
max_step = grid->q; void rearrange_result(float *block_C, float *res, int ma, int nb, GRID_INFO_T*
res = (float*)calloc(ma * nb / grid->p, sizeof(float)); grid)
pieces_res = (float*)malloc(ma * nb / grid->p * sizeof(float)); {
new_block = (float*)calloc(na * ma / grid->p, sizeof(float)); float *buff;
mat_C = (float*)malloc(ma * nb * sizeof(float)); int i, j, k;
int nb_bar, ma_bar;
for (i = 0; i < max_step; i++)
{ ma_bar = ma / grid->q;
row_broadcast(block_A, new_block, na, ma, i, grid); nb_bar = nb / grid->q;
pieces_res = local_dot(new_block, block_B, ma, nb, na, grid); buff = (float*)malloc(ma_bar * nb * sizeof(float));
column_circular_shift(block_B, mb, nb, grid);
for (i = 0; i < ma_bar; i++) // rearrange the entries in each row of grid
for (j = 0; j < ma * nb / grid->p; j++) processes
{ {
res[j] = res[j] + pieces_res[j]; // update local result MPI_Gather(block_C + i * nb_bar, nb_bar, MPI_FLOAT, buff + i * nb, nb_bar,
} MPI_FLOAT, 0, grid->row_comm);
} }
rearrange_result(res, mat_C, ma, nb, grid); // arrange entries to a nomal order // gather the ordered entries from first column to the grid prosses in proc.0
MPI_Gather(buff, ma_bar * nb, MPI_FLOAT, res, ma_bar * nb, MPI_FLOAT, 0, grid-
free(res); >col_comm);
free(pieces_res);
free(new_block); free(buff);
}
return mat_C;
}