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 ; }
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 ; }