⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clog_sync.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 2 页
字号:
                               next_adj_rank, CLOG_SYNC_SLAVE_READY,                               MPI_COMM_WORLD, &status );                        /* Set recv_cnt to actual received count of double */                    PMPI_Get_count( &status, CLOG_TIME_MPI_TYPE, &recv_cnt );                    /* Send&Recv timestamp  */                    sync_time_start  = CLOG_Timer_get();                    PMPI_Send( &dummytime, 1, CLOG_TIME_MPI_TYPE,                               next_adj_rank, CLOG_SYNC_TIME_QUERY,                               MPI_COMM_WORLD );                    PMPI_Recv( &sync_time_esti, 1, CLOG_TIME_MPI_TYPE,                               next_adj_rank, CLOG_SYNC_TIME_ANSWER,                               MPI_COMM_WORLD, &status );                    sync_time_final  = CLOG_Timer_get();                    if (   (sync_time_final - sync_time_start)                         < gpofst_pairs[ gpofst_idx ] ) {                        gpofst_pairs[ gpofst_idx ]   = sync_time_final                                                     - sync_time_start;                        gpofst_pairs[ gpofst_idx+1 ] = 0.5 * ( sync_time_final                                                             + sync_time_start )                                                     - sync_time_esti;                    }                    best_gp     = gpofst_pairs[ gpofst_idx ];                    best_ofst   = gpofst_pairs[ gpofst_idx+1 ];                    gpofst_idx += 2;                    /* increment to include the recent exchanges */                    for ( ii = 0; ii < recv_cnt; ii += 2 ) {                        gpofst_pairs[ gpofst_idx+ii ]    += best_gp;                        gpofst_pairs[ gpofst_idx+ii+1 ]  += best_ofst;                    }                    gpofst_idx += recv_cnt; /* total increment = recv_cnt + 2 */                }            }            else { /* if ( rank_rem != 0 ) */                prev_adj_rank  = CLOG_Sync_ring_rank( sync->world_size,                                                      sync->root,                                                      sync->world_rank                                                    - rank_sep );                if ( prev_adj_rank >= 0 ) {                    /* Recv&Send ready message */                    PMPI_Recv( &dummytime, 0, CLOG_TIME_MPI_TYPE,                               prev_adj_rank, CLOG_SYNC_MASTER_READY,                               MPI_COMM_WORLD, &status );                        /* Send gpofst_pairs[ 0 ... gpofst_idx-1 ] */                    send_cnt    = gpofst_idx;                    gpofst_ptr  = gpofst_pairs;                    PMPI_Send( gpofst_ptr, send_cnt, CLOG_TIME_MPI_TYPE,                               prev_adj_rank, CLOG_SYNC_SLAVE_READY,                               MPI_COMM_WORLD );                    /* Recv&Send timestamp  */                    PMPI_Recv( &dummytime, 1, CLOG_TIME_MPI_TYPE,                               prev_adj_rank, CLOG_SYNC_TIME_QUERY,                               MPI_COMM_WORLD, &status );                    sync_time_esti  = CLOG_Timer_get();                    PMPI_Send( &sync_time_esti, 1, CLOG_TIME_MPI_TYPE,                               prev_adj_rank, CLOG_SYNC_TIME_ANSWER,                               MPI_COMM_WORLD );                    break;                }            }   /* endof if ( rank_rem == 0 ) */            rank_rem    = rank_quot & 1; /* rank_rem   = rank_quot % 2; */            rank_quot >>= 1;             /* rank_quot /= 2; */            rank_sep  <<= 1;             /* rank_sep  *= 2; */        }   /* endof while ( rank_sep < sync->world_size ) */    }   /* endof for ( idx < sync->frequency ) */    /* Compute the global time offset based on relative time offset. */    if ( sync->world_rank == sync->root ) {        for ( ii = 2*(sync->world_size-1); ii >= 2; ii -= 2 ) {            gpofst_pairs[ ii   ] = gpofst_pairs[ ii-2 ]; /* gap */            gpofst_pairs[ ii+1 ] = gpofst_pairs[ ii-1 ]; /* offset */        }        gpofst_pairs[ 0 ] = 0.0;        gpofst_pairs[ 1 ] = 0.0;    }    PMPI_Scatter( gpofst_pairs, 2, CLOG_TIME_MPI_TYPE,                  sync->best_gpofst, 2, CLOG_TIME_MPI_TYPE,                  sync->root, MPI_COMM_WORLD );    if ( gpofst_pairs != NULL )        FREE( gpofst_pairs );    return sync->best_gpofst[1];}/*    A scalable O(1), perfectly parallel, algorithm.    An alterating neighbor in a ring algorithm that does constant steps.    The algorithm is least accurate but perfectly parallel.*/static CLOG_Time_t CLOG_Sync_run_altngbr( CLOG_Sync_t *sync ){    int          prev_world_rank, next_world_rank;    int          ii, idx;    int          iorder, is_odd_rank;    CLOG_Time_t  dummytime;    CLOG_Time_t  sync_time_start, sync_time_final, sync_time_esti;    CLOG_Time_t  bestgap, bestshift;    CLOG_Time_t *gpofst_pairs, best_gpofst[2];    CLOG_Time_t  tmp_gp, tmp_ofst, sum_gp, sum_ofst;    MPI_Status   status;    dummytime    = 0.0;    bestshift    = 0.0;    /* Set neighbors' world rank */    prev_world_rank = sync->world_rank - 1;    if ( prev_world_rank < 0 )        prev_world_rank = sync->world_size - 1;    next_world_rank = sync->world_rank + 1;    if ( next_world_rank >= sync->world_size )        next_world_rank = 0;    PMPI_Barrier( MPI_COMM_WORLD );    PMPI_Barrier( MPI_COMM_WORLD ); /* approximate common starting point */    bestgap = CLOG_SYNC_LARGEST_GAP;    for ( idx = 0; idx < sync->frequency; idx++ ) {        for ( iorder  = sync->world_rank;              iorder <= sync->world_rank+1;              iorder++ ) {            is_odd_rank = iorder % 2;            if ( ! is_odd_rank ) {                /* Send&Recv ready message */                PMPI_Send( &dummytime, 0, CLOG_TIME_MPI_TYPE,                           next_world_rank, CLOG_SYNC_MASTER_READY,                           MPI_COMM_WORLD );                PMPI_Recv( &dummytime, 0, CLOG_TIME_MPI_TYPE,                           next_world_rank, CLOG_SYNC_SLAVE_READY,                           MPI_COMM_WORLD, &status );                /* Send&Recv timestamp  */                sync_time_start  = CLOG_Timer_get();                PMPI_Send( &dummytime, 1, CLOG_TIME_MPI_TYPE,                           next_world_rank, CLOG_SYNC_TIME_QUERY,                           MPI_COMM_WORLD );                PMPI_Recv( &sync_time_esti, 1, CLOG_TIME_MPI_TYPE,                           next_world_rank, CLOG_SYNC_TIME_ANSWER,                           MPI_COMM_WORLD, &status );                sync_time_final  = CLOG_Timer_get();                if ( (sync_time_final - sync_time_start) < bestgap ) {                    bestgap   = sync_time_final - sync_time_start;                    bestshift = 0.5 * (sync_time_final + sync_time_start)                              - sync_time_esti;                }            }            else {                /* Recv&Send ready message */                PMPI_Recv( &dummytime, 0, CLOG_TIME_MPI_TYPE,                           prev_world_rank, CLOG_SYNC_MASTER_READY,                           MPI_COMM_WORLD, &status );                PMPI_Send( &dummytime, 0, CLOG_TIME_MPI_TYPE,                           prev_world_rank, CLOG_SYNC_SLAVE_READY,                           MPI_COMM_WORLD );                /* Recv&Send timestamp  */                PMPI_Recv( &dummytime, 1, CLOG_TIME_MPI_TYPE,                           prev_world_rank, CLOG_SYNC_TIME_QUERY,                           MPI_COMM_WORLD, &status );                sync_time_esti  = CLOG_Timer_get();                PMPI_Send( &sync_time_esti, 1, CLOG_TIME_MPI_TYPE,                           prev_world_rank, CLOG_SYNC_TIME_ANSWER,                           MPI_COMM_WORLD );            }        }    }   /* endof for ( idx < sync->frequency ) */    best_gpofst[0]  = bestgap;    best_gpofst[1]  = bestshift;    if ( sync->root != 0 ) {        /* Poor man implementation of MPI_Scan when root =\= 0 */        gpofst_pairs = NULL;        if ( sync->world_rank == sync->root )            gpofst_pairs = (CLOG_Time_t *) MALLOC( 2 * sync->world_size                                                 * sizeof(CLOG_Time_t) );        PMPI_Gather( best_gpofst, 2, CLOG_TIME_MPI_TYPE,                     gpofst_pairs, 2, CLOG_TIME_MPI_TYPE,                     sync->root, MPI_COMM_WORLD );        if ( sync->world_rank == sync->root ) {            sum_gp    = gpofst_pairs[2*sync->root];            sum_ofst  = gpofst_pairs[2*sync->root+1];            gpofst_pairs[2*sync->root]    = 0.0;            gpofst_pairs[2*sync->root+1]  = 0.0;            for ( ii = sync->root+1; ii < sync->world_size; ii++ ) {                tmp_gp                = gpofst_pairs[2*ii];                tmp_ofst              = gpofst_pairs[2*ii+1];                gpofst_pairs[2*ii]    = sum_gp;                gpofst_pairs[2*ii+1]  = sum_ofst;                sum_gp               += tmp_gp;                sum_ofst             += tmp_ofst;            }            for ( ii = 0; ii < sync->root; ii++ ) {                tmp_gp                = gpofst_pairs[2*ii];                tmp_ofst              = gpofst_pairs[2*ii+1];                gpofst_pairs[2*ii]    = sum_gp;                gpofst_pairs[2*ii+1]  = sum_ofst;                sum_gp               += tmp_gp;                sum_ofst             += tmp_ofst;            }        }        PMPI_Scatter( gpofst_pairs, 2, CLOG_TIME_MPI_TYPE,                      sync->best_gpofst, 2, CLOG_TIME_MPI_TYPE,                      sync->root, MPI_COMM_WORLD );        if ( sync->world_rank == sync->root )            FREE( gpofst_pairs );    }    else {  /* root == 0 */        PMPI_Send( best_gpofst, 2, CLOG_TIME_MPI_TYPE,                   next_world_rank, CLOG_SYNC_TIME_QUERY,                   MPI_COMM_WORLD );        PMPI_Recv( best_gpofst, 2, CLOG_TIME_MPI_TYPE,                   prev_world_rank, CLOG_SYNC_TIME_QUERY,                   MPI_COMM_WORLD, &status );        if ( sync->world_rank == 0 ) {            best_gpofst[0] = 0.0;            best_gpofst[1] = 0.0;        }        PMPI_Scan( best_gpofst, sync->best_gpofst, 2, CLOG_TIME_MPI_TYPE,                   MPI_SUM, MPI_COMM_WORLD );    }    return sync->best_gpofst[1];}/*@      CLOG_Sync_run - synchronize clocks with selected algorithm through                      MPE_SYNC_ALGORITHMInout Parameters:+ sync            - CLOG_Sync_t contains local best_gpofst[2] to be filled inReturn value:   local time offset after synchronization@*/CLOG_Time_t CLOG_Sync_run( CLOG_Sync_t *sync ){    switch ( sync->algorithm_ID ) {        case CLOG_SYNC_AGRM_DEFAULT:            if ( sync->world_size > 16 )                return CLOG_Sync_run_bitree( sync );            else                return CLOG_Sync_run_seq( sync );        case CLOG_SYNC_AGRM_SEQ:            return CLOG_Sync_run_seq( sync );        case CLOG_SYNC_AGRM_BITREE:            return CLOG_Sync_run_bitree( sync );        case CLOG_SYNC_AGRM_ALTNGBR:            return CLOG_Sync_run_altngbr( sync );        default:            if ( sync->world_rank == 0 ) {                fprintf( stderr, __FILE__":CLOG_Sync_run() - \n"                                 "Unknown MPE_SYNC_ALGORITHM ID = %d."                                 "Assume default synchronization mechanism.\n",                                 sync->algorithm_ID );                fflush( stderr );            }            if ( sync->world_size > 16 )                return CLOG_Sync_run_bitree( sync );            else                return CLOG_Sync_run_seq( sync );    }}char *CLOG_Sync_print_type( const CLOG_Sync_t *sync ){    switch ( sync->algorithm_ID ) {        case CLOG_SYNC_AGRM_DEFAULT:            return "Default";        case CLOG_SYNC_AGRM_SEQ:            return "Seq";        case CLOG_SYNC_AGRM_BITREE:            return "BiTree";        case CLOG_SYNC_AGRM_ALTNGBR:            return "AltNgbr";        default:            return "Unknown(assume Default)";    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -