Exemplo n.º 1
0
static void box_partition_maps( 
  const int np ,
  const int my_p ,
  const int pbox[][3][2] ,
  const int ghost ,
  int ** map_local_id ,
  int ** map_recv_pc ,
  int ** map_send_pc ,
  int ** map_send_id )
{
  const int (*my_box)[2] = pbox[my_p] ;

  const int my_ix = my_box[0][0] ;
  const int my_iy = my_box[1][0] ;
  const int my_iz = my_box[2][0] ;
  const int my_nx = my_box[0][1] - my_box[0][0] ;
  const int my_ny = my_box[1][1] - my_box[1][0] ;
  const int my_nz = my_box[2][1] - my_box[2][0] ;

  const int my_use_nx = 2 * ghost + my_nx ;
  const int my_use_ny = 2 * ghost + my_ny ;
  const int my_use_nz = 2 * ghost + my_nz ;

  const int id_length = my_use_nx * my_use_ny * my_use_nz ;

  int * local_id  = (int *) malloc( id_length * sizeof(int) );
  int * recv_pc   = (int *) malloc( ( np + 1 ) * sizeof(int) );
  int * send_pc   = (int *) malloc( ( np + 1 ) * sizeof(int) );

  int * send_id  = NULL ;
  int   send_id_size = 0 ;

  int iLocal , iSend ;
  int i ;

  int my_use_box[3][2] ;

  my_use_box[0][0] = my_box[0][0] - ghost ;
  my_use_box[0][1] = my_box[0][1] + ghost ;
  my_use_box[1][0] = my_box[1][0] - ghost ;
  my_use_box[1][1] = my_box[1][1] + ghost ;
  my_use_box[2][0] = my_box[2][0] - ghost ;
  my_use_box[2][1] = my_box[2][1] + ghost ;

  for ( i = 0 ; i < id_length ; ++i ) { local_id[i] = -1 ; }

  iSend = 0 ;
  iLocal = 0 ;

  /* The vector space is partitioned by processors */

  for ( i = 0 ; i < np ; ++i ) {
    const int ip = ( i + my_p ) % np ;
    recv_pc[i] = iLocal ;
    send_pc[i] = iSend ;

    if ( ! box_disjoint( (const int (*)[2]) my_use_box , pbox[ip] ) ) {
      const int p_ix = pbox[ip][0][0] ;
      const int p_iy = pbox[ip][1][0] ;
      const int p_iz = pbox[ip][2][0] ;
      const int p_ex = pbox[ip][0][1] ;
      const int p_ey = pbox[ip][1][1] ;
      const int p_ez = pbox[ip][2][1] ;

      int local_x , local_y , local_z ;

      /* Run the span of global cells that my processor uses */

      for ( local_z = -ghost ; local_z < my_nz + ghost ; ++local_z ) {
      for ( local_y = -ghost ; local_y < my_ny + ghost ; ++local_y ) {
      for ( local_x = -ghost ; local_x < my_nx + ghost ; ++local_x ) {

        const int global_z = local_z + my_iz ;
        const int global_y = local_y + my_iy ;
        const int global_x = local_x + my_ix ;

        const int entry = 
          box_map_local_entry(my_box,ghost,local_x,local_y,local_z);

        if ( entry < 0 ) { abort(); }

        if ( p_iz <= global_z && global_z < p_ez &&
             p_iy <= global_y && global_y < p_ey &&
             p_ix <= global_x && global_x < p_ex ) {

          /* This ordinal is owned by processor 'ip' */

          local_id[ entry ] = iLocal++ ;

#if defined(DEBUG_PRINT)
if ( my_p != ip ) {
  fprintf(stdout,"  (%d,%d,%d) : P%d recv at local %d from P%d\n",
                  global_x,global_y,global_z,my_p,local_id[entry],ip);
  fflush(stdout);
}
#endif
        }

        /* If in my ownership and used by the other processor */
        if ( my_p != ip &&
             /* In my ownership: */
             ( 0 <= local_z && local_z < my_nz &&
               0 <= local_y && local_y < my_ny &&
               0 <= local_x && local_x < my_nx ) &&
             /* In other processors usage: */
             ( p_iz - ghost <= global_z && global_z < p_ez + ghost &&
               p_iy - ghost <= global_y && global_y < p_ey + ghost &&
               p_ix - ghost <= global_x && global_x < p_ex + ghost ) ) {

          resize_int( & send_id , & send_id_size , (iSend + 1) );
          send_id[ iSend ] = local_id[ entry ] ;
          ++iSend ;

#if defined(DEBUG_PRINT)
{
  fprintf(stdout,"  (%d,%d,%d) : P%d send at local %d to P%d\n",
                  global_x,global_y,global_z,my_p,local_id[entry],ip);
  fflush(stdout);
}
#endif
        }
      }
    }
    }
    }
  }
  recv_pc[np] = iLocal ;
  send_pc[np] = iSend ;

  *map_local_id  = local_id ;
  *map_recv_pc   = recv_pc ;
  *map_send_pc   = send_pc ;
  *map_send_id   = send_id ;
}
Exemplo n.º 2
0
void box_partition_map( 
  const int np ,
  const int my_p ,
  const int gbox[3][2] ,
  const int pbox[][3][2] ,
  const int ghost ,

  int    map_use_box[3][2] ,
  int    map_local_id[] ,
  int *  map_count_interior ,
  int *  map_count_owns ,
  int *  map_count_uses ,
  int ** map_recv_pc ,
  int ** map_send_pc ,
  int ** map_send_id )
{
  int * recv_pc = (int *) malloc( ( np + 1 ) * sizeof(int) );
  int * send_pc = (int *) malloc( ( np + 1 ) * sizeof(int) );

  int   id_length = 0 ;

  int * send_id  = NULL ;
  int   send_id_size = 0 ;

  int own_length , use_length , int_length ;
  int count_interior , count_parallel ;
  int iSend ;
  int g_ix , g_iy , g_iz ;
  int i ;

  int my_int_box[3][2] ;

  global_to_use_box( gbox , pbox[my_p] , ghost , my_int_box , map_use_box );

  own_length = ( pbox[my_p][0][1] - pbox[my_p][0][0] ) *
               ( pbox[my_p][1][1] - pbox[my_p][1][0] ) *
               ( pbox[my_p][2][1] - pbox[my_p][2][0] );

  use_length = ( map_use_box[0][1] - map_use_box[0][0] ) *
               ( map_use_box[1][1] - map_use_box[1][0] ) *
               ( map_use_box[2][1] - map_use_box[2][0] );

  int_length = ( my_int_box[0][1] - my_int_box[0][0] ) *
               ( my_int_box[1][1] - my_int_box[1][0] ) *
               ( my_int_box[2][1] - my_int_box[2][0] );

  for ( i = 0 ; i < id_length ; ++i ) { map_local_id[i] = -1 ; }

  /* Fill in locally owned portion: { interior , parallel } */

  count_interior = 0 ;
  count_parallel = int_length ;

  for ( g_iz = pbox[my_p][2][0] ; g_iz < pbox[my_p][2][1] ; ++g_iz ) {
  for ( g_iy = pbox[my_p][1][0] ; g_iy < pbox[my_p][1][1] ; ++g_iy ) {
  for ( g_ix = pbox[my_p][0][0] ; g_ix < pbox[my_p][0][1] ; ++g_ix ) {

    const int local =
      map_global_to_use_box( (BoxInput) map_use_box, g_ix, g_iy, g_iz );

    if ( local < 0 ) { 
      abort();
    }

    if ( my_int_box[2][0] <= g_iz && g_iz < my_int_box[2][1] &&
         my_int_box[1][0] <= g_iy && g_iy < my_int_box[1][1] &&
         my_int_box[0][0] <= g_ix && g_ix < my_int_box[0][1] ) {
      /* Interior */
      map_local_id[ local ] = count_interior++ ;
    }
    else {
      /* Parallel */
      map_local_id[ local ] = count_parallel++ ;
    }
  }
  }
  }

  if ( count_interior != int_length ) { abort(); }
  if ( count_parallel != own_length ) { abort(); }

  /* Fill in off-process received portion: { ( i + my_p ) % np } */

  recv_pc[0] = count_parallel ;
  recv_pc[1] = count_parallel ;
  send_pc[0] = 0 ;
  send_pc[1] = 0 ;
  iSend = 0 ;

  for ( i = 1 ; i < np ; ++i ) {
    const int ip = ( i + my_p ) % np ;
    int recv_box[3][2] ;
    int send_box[3][2] ;
    int other_int_box[3][2] ;
    int other_use_box[3][2] ;

    /* Received portions */

    if ( box_intersect( (BoxInput) map_use_box , (BoxInput) pbox[ip] , recv_box ) ) {

      for ( g_iz = recv_box[2][0] ; g_iz < recv_box[2][1] ; ++g_iz ) {
      for ( g_iy = recv_box[1][0] ; g_iy < recv_box[1][1] ; ++g_iy ) {
      for ( g_ix = recv_box[0][0] ; g_ix < recv_box[0][1] ; ++g_ix ) {

        const int local = map_global_to_use_box( (BoxInput) map_use_box, g_ix, g_iy, g_iz );

        map_local_id[ local ] = count_parallel++ ;
      }
      }
      }
    }
    recv_pc[i+1] = count_parallel ;

    /* Sent items */

    global_to_use_box( gbox, pbox[ip], ghost, other_int_box, other_use_box );

    if ( box_intersect( (BoxInput) other_use_box , (BoxInput) pbox[my_p] , send_box ) ) {

      int nSend = ( send_box[0][1] - send_box[0][0] ) *
                  ( send_box[1][1] - send_box[1][0] ) *
                  ( send_box[2][1] - send_box[2][0] );

      resize_int( & send_id , & send_id_size , (iSend + nSend ) );

      for ( g_iz = send_box[2][0] ; g_iz < send_box[2][1] ; ++g_iz ) {
      for ( g_iy = send_box[1][0] ; g_iy < send_box[1][1] ; ++g_iy ) {
      for ( g_ix = send_box[0][0] ; g_ix < send_box[0][1] ; ++g_ix ) {

        const int local = map_global_to_use_box( (BoxInput) map_use_box, g_ix, g_iy, g_iz );

        if ( map_local_id[ local ] < count_interior ) { abort(); }

        send_id[ iSend ] = map_local_id[ local ] ;
        ++iSend ;
      }
      }
      }
    }
    send_pc[i+1] = iSend ;
  }

  if ( count_parallel != use_length ) { abort(); }

  *map_count_interior = int_length ;
  *map_count_owns     = own_length ;
  *map_count_uses     = use_length ;
  *map_recv_pc        = recv_pc ;
  *map_send_pc        = send_pc ;
  *map_send_id        = send_id ;
}