void matrix_multiply_DivConq( int A[][], int B[][]){
     
     if(A_SIZE== 1){ 
       C[0][0] =  A[0][0] * B[0][0];
     
     }else{
       divide_matrix();
       //divide matrix
       //conquer
       C_up_left = matrix_multiply_DivConq( A_up_left, B_up_left)+
                   matrix_multiply_DivConq( A_up_right, B_down_left);

       C_up_right = matrix_multiply_DivConq( A_up_left, B_up_right)+
                   matrix_multiply_DivConq( A_up_right, B_down_right);
       
       C_down_left = matrix_multiply_DivConq( A_down_left, B_up_left)+
                   matrix_multiply_DivConq( A_down_right, B_down_left);

       C_down_right = matrix_multiply_DivConq( A_down_left, B_up_right)+
                   matrix_multiply_DivConq( A_down_right, B_down_right);
            
     
     return C[][];
}

void matrix_multiply_normal( int A[][], int B[][], int C[][]){
     int rowA = 0;
     int columnA = 0;
     int rowB = 0;
     int columnB = 0;
     int value = 0;

     if(MATRIX_SIZE== 1){
    
       C[0][0] =  A[0][0] * B[0][0];
     }
       

     
     }else{
Esempio n. 2
0
int main(int argc, char **argv) {

 
  int rank, M, j,i, *d_graph;
  int *local_matrix, *row_matrix, *col_matrix, *res_matrix, *rowIds, *colIds;
  int P, N, q, p_row, p_col;
  double start, finish;
  MPI_Status status;
 
  MPI_Init(&argc, &argv);
  MPI_Comm_size(MPI_COMM_WORLD, &P);
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);

  //INPUT HANDLED BY THE ROOT PROCESSOR
  if (rank == ROOT){
    scanf("%d", &N);  
    q = check_fox_conditions(P,N);

    //Check's if the fox's conditions are met
    if(q == 0){
      MPI_Abort(MPI_COMM_WORLD, 0);
      return 1; //error
    }  

    d_graph = (int*)malloc((N*N) * sizeof(int));

    for(i=0; i < N; i++){
      for(j=0; j < N; j++){
	scanf("%d", &d_graph[GET_MTRX_POS(i,j,N)]);
	if (d_graph[GET_MTRX_POS(i,j,N)] == 0 && i != j) {
	  d_graph[GET_MTRX_POS(i,j,N)] = INF;
	}
      }
    }



    MPI_Bcast(&q, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);

    if(q > 1)
      divide_matrix( d_graph, N, q); 
      
  }
  else{
    MPI_Bcast(&q, 1, MPI_INT, 0, MPI_COMM_WORLD);
    MPI_Bcast(&N, 1, MPI_INT, 0, MPI_COMM_WORLD);
  }
  //---------------COMMON------------------
   
  int lngth = N / q;


  local_matrix = (int*)malloc((lngth*lngth) * sizeof(int));
  row_matrix   = (int*)malloc((lngth*lngth) * sizeof(int));
  col_matrix   = (int*)malloc((lngth*lngth) * sizeof(int));
  res_matrix   = (int*)malloc((lngth*lngth) * sizeof(int));
  
  if(q>1)
    chnkd_MPI_Recv(local_matrix, lngth*lngth, MPI_INT, 0);
  else
    local_matrix = d_graph;
    
  p_row = ( rank / q );
  p_col = ( rank % q );
    
  //CREATE COMMUNICATORS 
  MPI_Group MPI_GROUP_WORLD;
  MPI_Comm_group(MPI_COMM_WORLD, &MPI_GROUP_WORLD);
  MPI_Group row_group, col_group;
  MPI_Comm row_comm, col_comm, grid_comm;
  int tmp_row, tmp_col, proc;
  int row_process_ranks[q], col_process_ranks[q];
    
  for(proc = 0; proc < q; proc++){   
    row_process_ranks[proc] = (p_row * q) + proc;
    col_process_ranks[proc] = ((p_col + proc*q) %(q*q));
  }    
  radixsort(col_process_ranks, q);
  radixsort(row_process_ranks, q);

  MPI_Group_incl(MPI_GROUP_WORLD, q, row_process_ranks, &row_group);  
  MPI_Group_incl(MPI_GROUP_WORLD, q, col_process_ranks, &col_group);  
     
  MPI_Comm_create(MPI_COMM_WORLD, row_group, &row_comm);  
  MPI_Comm_create(MPI_COMM_WORLD, col_group, &col_comm);  

  if ((rank / q) == (rank % q)) {
      memcpy(row_matrix, local_matrix, (lngth*lngth) * sizeof(int));
  }
  int ln,d,flag;
  int step, rotation_src, rotation_dest, src;
  int count = 0;
  memcpy(res_matrix, local_matrix, (lngth*lngth) * sizeof(int));
  rotation_src = (p_row + 1) % q;
  rotation_dest = ((p_row - 1) + q) % q;
  ln = (lngth*q) << 1;
  start = MPI_Wtime();  

  for (d = 2; d < ln; d = d << 1) {
    memcpy(col_matrix, local_matrix, (lngth*lngth) * sizeof(int));
    for ( step = 0;  step < q;  step++) {
      src = (p_row +  step) % q;
      count++;
      if (src == p_col) {
	MPI_Bcast(local_matrix, lngth*lngth, MPI_INT, src, row_comm);
	floyd_warshall( local_matrix, col_matrix, res_matrix, lngth);
      } else {
	MPI_Bcast(row_matrix, lngth*lngth, MPI_INT, src, row_comm);
	floyd_warshall( row_matrix, col_matrix, res_matrix, lngth);
      }  
      if( step < q-1) 
        MPI_Sendrecv_replace(col_matrix, lngth*lngth, MPI_INT, rotation_dest, STD_TAG,rotation_src, STD_TAG, col_comm, MPI_STATUS_IGNORE);
  	
    }
    memcpy(local_matrix, res_matrix, (lngth*lngth) * sizeof(int));
  }
  
  
  int *sol;
  sol = malloc(N*N*sizeof(int));  
  
  MPI_Gather(res_matrix, lngth*lngth, MPI_INT, sol,  lngth*lngth, MPI_INT, 0, MPI_COMM_WORLD);
  
  if (rank == 0) {
    finish = MPI_Wtime();
    printf("Tempo de execução %f\n",finish - start);
  }
 
  if (rank == 0) {
    int row, col, pos_x, pos_y, pos, tmp_y, tmp_x;

    for (i = 0; i < P; i++) {
      pos_x = i / q;
      pos_y = i % q;
      pos = i * lngth*lngth;

      for (row = 0; row < lngth; row++) {
	for (col = 0; col < lngth; col++) {
          tmp_x = GET_MTRX_POS(pos_x,row,lngth);
          tmp_y = GET_MTRX_POS(pos_y,col,lngth);
          
	  if (sol[GET_MTRX_POS(row,col,lngth) + pos] == INF)
	    d_graph[GET_MTRX_POS(tmp_x,tmp_y,N)] = 0;
	  else
	    d_graph[GET_MTRX_POS(tmp_x,tmp_y,N)] = sol[GET_MTRX_POS(row,col,lngth) + pos];
	}
      }
    }
    prints_matrix(d_graph,N);
  }
  
  MPI_Finalize();
  return 0;
}