Exemple #1
0
static
void hpccg_alloc_and_fill( const int np ,
                           const int my_p ,
                           const int gbox[][2] ,
                           const int ghost ,
                           struct cgsolve_data * const data )
{
  int (*pbox)[3][2] = NULL ;
  int * map_local_ord = NULL;

  data->nRow = 0 ;
  data->A_pc = NULL ;
  data->A_ia = NULL ;
  data->A_a  = NULL ;

  data->np = np ;
  data->ip = my_p ;
  data->recv_pc = NULL  ;
  data->send_pc = NULL ;
  data->send_id = NULL ;

  box_partition_rcb( np, my_p,
                     (const int (*)[2]) gbox, ghost,
                     & pbox ,
                     & map_local_ord ,
                     & data->recv_pc ,
                     & data->send_pc ,
                     & data->send_id );

  {
    const int (* const my_box)[2] = (const int (*)[2]) pbox[my_p] ;
    const int bx = my_box[0][0] ;
    const int by = my_box[1][0] ;
    const int bz = my_box[2][0] ;
    const int nx = my_box[0][1] - bx ;
    const int ny = my_box[1][1] - by ;
    const int nz = my_box[2][1] - bz ;
    const int n = nx * ny * nz ;
    const int nnz = 27 * n ; /* Upper bound */
    int    * const pc = (int *)   malloc( sizeof(int) * ( n + 1 ) );
    int    * const ia = (int *)   malloc( sizeof(int) * nnz );
    MATRIX_SCALAR  * const a  = (MATRIX_SCALAR *) malloc( sizeof(MATRIX_SCALAR) * nnz );

    int irow = 0 ;
    int ipc  = 0 ;
    int ix , iy , iz ;
    int sx , sy , sz ;

    for ( iz = 0 ; iz < nz ; ++iz ) {
    for ( iy = 0 ; iy < ny ; ++iy ) {
    for ( ix = 0 ; ix < nx ; ++ix , ++irow ) {

      if ( irow != box_map_local( my_box, ghost, map_local_ord,ix,iy,iz) ) {
        fprintf(stderr,"P%d:  irow[%d] != box_map_local(%d,%d,%d) = %d\n",
                my_p,irow,ix,iy,iz,
                box_map_local( my_box, ghost, map_local_ord, ix, iy, iz) );
      }

      pc[ irow ] = ipc ;   /* Beginning of row coefficients */
      /* Diagonal term first */
      ia[ ipc ] = irow ;
      a[  ipc ] = 27.0f ;
      ++ipc ;

      /* Off-diagonal terms to follow */
      for ( sz = -1 ; sz <= 1 ; ++sz ) {
      for ( sy = -1 ; sy <= 1 ; ++sy ) {
      for ( sx = -1 ; sx <= 1 ; ++sx ) {
        const int dx = ix + sx ;
        const int dy = iy + sy ;
        const int dz = iz + sz ;
        const int global_x = dx + bx ;
        const int global_y = dy + by ;
        const int global_z = dz + bz ;

        if ( gbox[0][0] <= global_x && global_x < gbox[0][1] &&
             gbox[1][0] <= global_y && global_y < gbox[1][1] &&
             gbox[2][0] <= global_z && global_z < gbox[2][1] &&
             ! ( sz == 0 && sy == 0 && sx == 0 ) ) {
          /* 'icol' is mapped for communication */

          const int icol =
            box_map_local(my_box,ghost,map_local_ord,dx,dy,dz);

          if ( icol < 0 ) {
            fprintf(stderr,"P%d : bad column at local (%d,%d,%d) global(%d,%d,%d)\n",
                    my_p, dx,dy,dz,global_x,global_y,global_z);
            fflush(stderr);
            abort();
          }

          ia[ ipc ] = icol ;
          a[  ipc ] = -1.0f ;
          ++ipc ;
        }
      }
      }
      }
    }
    }
    }

    pc[irow] = ipc ;

    data->nRow = irow ;
    data->A_pc = pc ;
    data->A_ia = ia ;
    data->A_a  = a ;
  }

  free( map_local_ord );
  free( pbox );
}
Exemple #2
0
static void test_maps( const int root_box[][2] , const int np )
{
  const int ghost = 1 ;
  const int nx_global = root_box[0][1] - root_box[0][0] ;
  const int ny_global = root_box[1][1] - root_box[1][0] ;
  int ieq , i , j ;
  int (*pbox)[3][2] ;
  int **local_values ;
  int **map_local_id ;
  int **map_recv_pc ;
  int **map_send_pc ;
  int **map_send_id ;
  
  pbox = (int (*)[3][2]) malloc( sizeof(int) * np * 3 * 2 );

  box_partition( 0 , np , 2 , root_box , pbox );

  local_values = (int **) malloc( sizeof(int*) * np );
  map_local_id = (int **) malloc( sizeof(int*) * np );
  map_recv_pc  = (int **) malloc( sizeof(int*) * np );
  map_send_pc  = (int **) malloc( sizeof(int*) * np );
  map_send_id  = (int **) malloc( sizeof(int*) * np );

  /* Set each local value to the global equation number */

  for ( ieq = i = 0 ; i < np ; ++i ) {
    const int (*mybox)[2] = (const int (*)[2]) pbox[i] ;
    const int nx = mybox[0][1] - mybox[0][0] ;
    const int ny = mybox[1][1] - mybox[1][0] ;
    const int nz = mybox[2][1] - mybox[2][0] ;
    int ix , iy , iz ;

    /* Generate the partition maps for this rank */
    box_partition_maps( np , i , (const int (*)[3][2]) pbox , ghost ,
                        & map_local_id[i] , & map_recv_pc[i] , 
                        & map_send_pc[i] , & map_send_id[i] );

    local_values[i] = (int *) malloc( sizeof(int) * map_recv_pc[i][np] );

    for ( iz = -ghost ; iz < nz + ghost ; ++iz ) {
    for ( iy = -ghost ; iy < ny + ghost ; ++iy ) {
    for ( ix = -ghost ; ix < nx + ghost ; ++ix ) {
      const int ieq = box_map_local(mybox,ghost,map_local_id[i],ix,iy,iz);

      if ( 0 <= ieq ) {
        const int ix_global = ix + mybox[0][0] ;
        const int iy_global = iy + mybox[1][0] ;
        const int iz_global = iz + mybox[2][0] ;

        if ( root_box[0][0] <= ix_global && ix_global < root_box[0][1] &&
             root_box[1][0] <= iy_global && iy_global < root_box[1][1] &&
             root_box[2][0] <= iz_global && iz_global < root_box[2][1] ) {

          local_values[i][ ieq ] = ix_global +
                                   iy_global * nx_global +
                                   iz_global * nx_global * ny_global ;
        }
        else {
          local_values[i][ ieq ] = -1 ;
        }
      }
    }
    }
    }
  }

  /* Pair-wise compare the local values */
  /* i  == receiving processor rank */
  /* ip == sending   processor rank */
  /* j  == receiving processor data entry for message from 'ip' */
  /* jp == sending   processor data entry for message to   'i' */

  for ( i = 0 ; i < np ; ++i ) {
    for ( j = 1 ; j < np ; ++j ) {
      const int ip = ( i + j ) % np ;
      const int jp = ( i + np - ip ) % np ;
      const int nrecv = map_recv_pc[i] [j+1]  - map_recv_pc[i] [j] ;
      const int nsend = map_send_pc[ip][jp+1] - map_send_pc[ip][jp] ;
      int k ;
      if ( nrecv != nsend ) {
        fprintf(stderr,"P%d recv %d from P%d\n",i,nrecv,ip);
        fprintf(stderr,"P%d send %d to   P%d\n",ip,nsend,i);
        abort();
      }
      for ( k = 0 ; k < nrecv ; ++k ) {
        const int irecv = map_recv_pc[i][j] + k ;
        const int isend = map_send_pc[ip][jp] + k ;
        const int val_irecv = local_values[i][irecv] ;
        const int val_isend = local_values[ip][ map_send_id[ip][isend] ] ;
        if ( val_irecv != val_isend ) {
          fprintf(stderr,"P%d recv[%d] = %d , from P%d\n",i,k,val_irecv,ip);
          fprintf(stderr,"P%d send[%d] = %d , to   P%d\n",ip,k,val_isend,i);
          abort();
        }
      }
    }
  }

  for ( i = 0 ; i < np ; ++i ) {
    free( map_local_id[i] );
    free( map_recv_pc[i] );
    free( map_send_pc[i] );
    free( map_send_id[i] );
    free( local_values[i] );
  }
  free( map_send_id );
  free( map_send_pc );
  free( map_recv_pc );
  free( map_local_id );
  free( local_values );
  free( pbox );
}