uloop2() { CBOXPTR acellptr, bcellptr ; BBOXPTR ablckptr , bblckptr ; int botblk , topblk ; int flips ; int axcenter , bxcenter , bycenter ; int aorient , borient ; int bleft , bright ; int blk , pairflips ; int i , r , l , t ; int abin , bbin ; int firstTry , fds ; double temp , fp_ratio , percent_error ; attempts = 0 ; flips = 0 ; pairflips = 0 ; earlyRej = 0 ; P_limit = -1 ; windx = minxspan ; attmax = 2 * attprcel * numcells ; binpenCon = 0.0 ; fds = 0 ; if( estimate_feeds ) { fds = controlf( 1 ) ; } while( attempts < attmax ) { a = PICK_INT( 1 , numcells ) ; acellptr = carray[ a ] ; if( acellptr->cclass == -1 ) { continue ; } ablock = acellptr->cblock ; ablckptr = barray[ ablock ] ; axcenter = acellptr->cxcenter ; aorient = acellptr->corient ; abin = SetBin( axcenter ) ; cellaptr = binptr[ablock][abin]->cell ; for( i = 1 ; i <= *cellaptr ; i++ ) { if( cellaptr[i] == a ) { Apost = i ; break ; } } /* * select block for cell a to be placed in */ bblock = 0 ; firstTry = 0 ; if( (botblk = ablock - DELTA_B) < 1) { botblk = 1 ; } if( (topblk = ablock + DELTA_B) > numblock ) { topblk = numblock ; } for( i = 1 ; ; i++ ) { do { blk = XPICK_INT( botblk , topblk , firstTry ) ; bblckptr = barray[ blk ] ; } while( ablock == blk || ablckptr->bclass != bblckptr->bclass ) ; bleft = bblckptr->bxcenter + bblckptr->bleft ; bright = bblckptr->bxcenter + bblckptr->bright ; l = (bleft >= axcenter - windx) ? bleft : (axcenter-windx); r = (bright <= axcenter + windx) ? bright : (axcenter+windx); if( l > r ) { if( i == 1 ) { firstTry = blk ; continue ; } else if( i == 3 ) { if( r < bleft ) { l = r = bleft ; } else { l = r = bright ; } } else { firstTry = - ablock ; continue ; } } bblock = blk ; bycenter = bblckptr->bycenter ; if( bblock == ablock ) { bxcenter = XPICK_INT( l, r, axcenter ) ; } else { bxcenter = XPICK_INT( l, r, 0 ) ; } break ; } bbin = SetBin( bxcenter ) ; cellbptr = binptr[bblock][bbin]->cell ; if( *cellbptr == 0 ) { if( ablckptr->borient == 1 ) { if( bblckptr->borient == 1 ) { if( ucxx1( bxcenter, bycenter)){ flips++ ; } } else { /* bblckptr->borient == 2 */ if( ucxxo1( bxcenter,bycenter,(aorient == 0) ? 1 : 3 )){ flips++ ; } } } else { /* ablockptr->borient == 2 */ if( bblckptr->borient == 1 ) { if( ucxxo1( bxcenter, bycenter, (aorient == 1) ? 0 : 2)){ flips++ ; } } else { /* bblckptr->borient == 2 */ if( ucxx1( bxcenter, bycenter) ){ flips++ ; } } } } else { /* *cellbptr >= 1 */ Bpost = PICK_INT( 1 , *cellbptr ) ; b = cellbptr[ Bpost ] ; bcellptr = carray[b] ; bblock = bcellptr->cblock ; bblckptr = barray[ bblock ] ; if( bcellptr->cclass == -1 || a == b ) { continue ; } borient = bcellptr->corient ; if( ablckptr->borient == 1 ) { if( bblckptr->borient == 1 ) { t = ucxx2( ) ; if( t == 1 ) { pairflips++ ; } } else { /* bblock->orient == 2 */ t = ucxxo2( (aorient == 0) ? 1:3, (borient == 1) ? 0:2 ) ; if( t == 1 ) { pairflips++ ; } } } else { /* ablock->borient == 2 */ if( bblckptr->borient == 1 ) { t = ucxxo2( (aorient == 1) ? 0:2, (borient == 0) ? 1:3) ; if( t == 1 ) { pairflips++ ; } } else { /* bblock->borient == 2 */ t = ucxx2( ) ; if( t == 1 ) { pairflips++ ; } } } } attempts++ ; } temp = 100.0 * (double)(pairflips + flips) / (double)(attmax) ; if( pairflips > 0.0001 ) { fp_ratio = 100.0 * (double)flips/(double)pairflips ; } else { fp_ratio = 100.0 ; } fprintf(fpo,"%3d %3d %4d %8d %7d %5d 0.0 %4.1f %4.1f %4.1f %4.1f", iteration+1, (int)T, fds , funccost, penalty, P_limit, binpenCon, roLenCon, temp, fp_ratio); fprintf(fpo," %4.1f\n", 100.0*(double)earlyRej/(double)attmax ); fflush( fpo ) ; return ; }
void uloop() { FENCEBOXPTR fence ; CBOXPTR acellptr, bcellptr ; BBOXPTR ablckptr , bblckptr ; INT flips , rejects , do_single_cell_move , bit_class ; INT axcenter , bxcenter , bycenter ; INT aorient , borient ; INT blk , pairflips ; INT i , j , t , count , swaps, index, shift ; INT abin , bbin , fds , done , single_swap ; DOUBLE target_row_penalty ; DOUBLE target_bin_penalty ; DOUBLE temp , percent_error ; DOUBLE dCp, delta , gswap_ratio ; INT m1,m2, trials ; INT num_accepts , gate_switches , gate_attempts ; INT last_flips , delta_func , delta_time ; INT temp_timer, time_to_update ; /* keeps track of when to update T */ DOUBLE iter_time, accept_deviation, calc_acceptance_ratio() ; DOUBLE num_time, num_func ; DOUBLE calc_time_factor() ; /* commented out variables INT reset_T ; DOUBLE old_T ; */ attemptsG = 0 ; flips = 0 ; rejects = 0 ; pairflips = 0 ; earlyRejG = 0 ; Rej_errorG = 0 ; G( reset_heat_index() ) ; potential_errorsG = 0 ; error_countG = 0 ; if( !P_limit_setS || iterationG <= 0 ) { P_limitG = 999999; if( iterationG > 0 ) { P_limit_setS = TRUE ; } } else { if( wire_chgsG > 0 ) { mean_wire_chgG = total_wire_chgG / (DOUBLE) wire_chgsG ; if( iterationG > 1 ) { sigma_wire_chgG = sqrt( sigma_wire_chgG / (DOUBLE) wire_chgsG); } else { sigma_wire_chgG = 3.0 * mean_wire_chgG ; } } else { mean_wire_chgG = 0.0 ; sigma_wire_chgG = 0.0 ; } P_limitG = mean_wire_chgG + 3.0 * sigma_wire_chgG + TG ; if (P_limitG > 999999) P_limitG = 999999; } sigma_wire_chgG = 0.0 ; total_wire_chgG = 0.0 ; wire_chgsG = 0 ; m1 = m2 = 1; dCp = 0.0; fds = reconfig() ; avg_rowpenalS = 0.0 ; num_penalS = 0.0 ; if( iterationG < 0 ) { avg_timeG = 0.0 ; num_time = 0.0 ; avg_funcG = 0.0 ; num_func = 0.0 ; } /* number of moves before temperature update */ time_to_update = attmaxG / NUMTUPDATES ; if( time_to_update <= 14 ) { time_to_update = 14 ; } temp_timer = 0 ; /* initialize timer */ num_accepts = 0 ; last_flips = 0 ; gate_switches = 0 ; gate_attempts = 0 ; /* ------------------------------------------------------------------------ The back bone of the program the "while-loop" begins from here ... ------------------------------------------------------------------------ */ while( attemptsG < attmaxG ) { /* ------------- pick up a number at random --------------- */ aG = PICK_INT( 1 , numcellsG - extra_cellsG ) ; /* ------------- get the structure for cell# aG ------------- */ acellptr = carrayG[ aG ] ; ablockG = acellptr->cblock ; axcenter = acellptr->cxcenter ; /* ------------------------------------------------------------------------ If two cells have the same swap_group then parts of the cells are interchangable. Below we check if the cell#aG belongs to a swap_group ------------------------------------------------------------------------ */ if( acellptr->num_swap_group > 0 ) { INT sgroup; SGLISTPTR sglistptr; i = PICK_INT( 0 , acellptr->num_swap_group - 1 ) ; sglistptr = acellptr->swapgroups + i; sgroup = sglistptr->swap_group; trials = 0 ; /*--- number of max trials (heuristically)=50 ---*/ do { /* ----------------------------------------------------------------- pick_position picks up a new position for the cell#aG, it returns the bxcenter and blk where the cell could be moved ... -----------------------------------------------------------------*/ pick_position(&bxcenter,&blk,axcenter,ablockG,8.0); bbin = SetBin( bxcenter ) ; /* ----------------------------------------------------------------- the field "cell" in binptrG[blk][bbin]->cell contains a list of all the cells in that bin. But cell[0] contains the total number of cells in the bin (hard-coded) isn't it ... -----------------------------------------------------------------*/ cellbptrG = binptrG[blk][bbin]->cell ; if( *cellbptrG > 0 ) { if( Equal_Width_CellsG ){ BpostG = 1 ; } else { BpostG = PICK_INT( 1 , *cellbptrG ) ; } bG = cellbptrG[ BpostG ] ; bcellptr = carrayG[bG] ; } else { bG = 0 ; } if( bG != 0 && aG != bG ) { for (j = 0; j < bcellptr->num_swap_group; j++) { sglistptr = bcellptr->swapgroups + j; if (sglistptr->swap_group == sgroup) break; } if (j < bcellptr->num_swap_group) { break ; } else { trials++ ; } } else { trials++ ; } } while( trials <= 50 ) ; if( trials <= 50 ) { for( swaps = 1 ; swaps <= 4 ; swaps++ ) { /* -- gate_swap evaluates the proposed gate swaps --*/ gate_switches += gate_swap( 1, i, j ) ; gate_attempts++ ; } } sglistptr = acellptr->swapgroups + i; // If a cell has more than one pin group in the same // swap group, then it can permute pin groups within // itself. if( sglistptr->num_pin_group > 1 ) { for( swaps = 1 ; swaps <= 4 ; swaps++ ) { gate_swap( 0, i, j ) ; } } } if( acellptr->cclass < -1 ) { /*---- for rigid cells, continue ----*/ continue ; } ablckptr = barrayG[ ablockG ] ; aorient = acellptr->corient ; abin = SetBin( axcenter ) ; cellaptrG = binptrG[ablockG][abin]->cell ; if( Equal_Width_CellsG ){ ApostG = 1 ; } else { for( i = 1 ; i <= *cellaptrG ; i++ ) { if( cellaptrG[i] == aG ) { ApostG = i ; break ; } } } /* * select block for cell a to be placed in */ if( acellptr->fence == NULL ) { /* cclass -1 cells won't enter here */ bblockG = 0 ; for (i=0; i<10; i++) { pick_position(&bxcenter,&blk,axcenter,ablockG,1.0); bblckptr = barrayG[ blk ] ; /* if cell "a" can't legally enter this row, keep looking */ if( ablockG == blk || acellptr->cclass == 0 ) { /* cell "a" will remain in the same row, or: */ /* cell "a" can go anywhere it pleases */ break ; } else if( acellptr->cclass > 0 ) { /* it cannot go anywhere it pleases */ bit_class = 1 ; index = (bblckptr->bclass - 1) / 32 ; shift = bblckptr->bclass - 32 * index ; bit_class <<= (shift - 1) ; if( bit_class & acellptr->cbclass[index] ) { /* "a" is allowed in a row with this block_class */ break ; } /* else, keep searching for a legal row */ } } } else { /* * select block for cell a to be placed in */ bblockG = 0 ; for (i=0; i<10; i++) { fence = acellptr->fence ; if( fence->next_fence != NULL ) { count = 0 ; for( ; fence; fence = fence->next_fence){ count++ ; } j = PICK_INT( 1 , count ) ; count = 0 ; fence = acellptr->fence ; for( ; fence; fence = fence->next_fence ) { if( ++count == j ) { break ; } } } pick_fence_position(&bxcenter,&blk,fence) ; bblckptr = barrayG[ blk ] ; /* if cell "a" can't legally enter this row, keep looking */ if( ablockG == blk || acellptr->cclass <= 0 ) { /* cell "a" will remain in the same row, or: */ /* cell "a" can go anywhere it pleases */ break ; } else if( acellptr->cclass > 0 ) { /* it cannot go anywhere it pleases */ bit_class = 1 ; index = (bblckptr->bclass - 1) / 32 ; shift = bblckptr->bclass - 32 * index ; bit_class <<= (shift - 1) ; if( bit_class & acellptr->cbclass[index] ) { /* "a" is allowed in a row with this block_class */ break ; } /* else, keep searching for a legal row */ } } }/* end else -- acellptr->fence != NULL -- cclass -1 cells won't enter here */ if (i == 10) continue; /*-- get out of the while-loop --*/ /*------- Now get the target block's structure and target bin -------*/ bblockG = blk; bycenter = bblckptr->bycenter ; bbin = SetBin( bxcenter ) ; cellbptrG = binptrG[bblockG][bbin]->cell ; if( *cellbptrG > 0 ) { count = 0 ; get_b: if( Equal_Width_CellsG ){ BpostG = 1 ; } else { BpostG = PICK_INT( 1 , *cellbptrG ) ; } bG = cellbptrG[ BpostG ] ; if( aG == bG ) { continue ; } bcellptr = carrayG[bG] ; if( fences_existG ) { done = 0 ; if( (fence = bcellptr->fence) != NULL ) { while(1) { /*------- make sure cell aG's block is outside the block bG's fence -------*/ if( ablockG >= fence->min_block && ablockG <= fence->max_block && axcenter >= fence->min_xpos && axcenter <= fence->max_xpos ) { done = 1 ; break ; } else { fence = fence->next_fence ; if( fence == NULL ) { if( ++count < *cellbptrG ) { goto get_b ; } else { break ; } } } } if( !done ) { continue ; } } } if( bcellptr->cclass < -1 ) { do_single_cell_move = 1 ; } else if( ablockG != bblockG && bcellptr->cclass > 0 ) { bit_class = 1 ; index = (ablckptr->bclass - 1) / 32 ; shift = ablckptr->bclass - 32 * index ; bit_class <<= (shift - 1) ; if( !(bit_class & bcellptr->cbclass[index]) ) { /* "b" is not allowed in a row with this block_class */ continue ; } do_single_cell_move = 0 ; borient = bcellptr->corient ; } else { do_single_cell_move = 0 ; borient = bcellptr->corient ; } } else { do_single_cell_move = 1 ; } delta_func = funccostG ; delta_time = timingcostG ; if( do_single_cell_move ) { if( Equal_Width_CellsG ) { continue ; } /* reset_T = 0 ; if( acellptr->fence != NULL ) { if( ablockG < acellptr->fence->min_block || ablockG > acellptr->fence->max_block ) { reset_T = 1 ; old_T = T ; T = 1000000.0 ; } } */ if( ablckptr->borient == 1 ) { if( bblckptr->borient == 1 ) { t = ucxx1( bxcenter, bycenter) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } else { /* bblckptr->borient == 2 */ t = ucxxo1( bxcenter,bycenter,(aorient == 0) ? 1 : 3 ) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } } else { /* ablockGptr->borient == 2 */ if( bblckptr->borient == 1 ) { t = ucxxo1( bxcenter, bycenter, (aorient == 1) ? 0 : 2) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } else { /* bblckptr->borient == 2 */ t = ucxx1( bxcenter, bycenter) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ flips++ ; acc_cntS ++; } } } /* if( reset_T ) { T = old_T ; } */ } else { /* pairwise interchange */ if( ablckptr->borient == 1 ) { if( bblckptr->borient == 1 ) { t = ucxx2() ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } else { /* bblockG->orient == 2 */ t = ucxxo2( (aorient == 0) ? 1:3, (borient == 1) ? 0:2); if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 0) ? 2 : 0 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } } else { /* ablockG->borient == 2 */ if( bblckptr->borient == 1 ) { t = ucxxo2( (aorient == 1) ? 0:2, (borient == 0) ? 1:3); if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } else { /* bblockG->borient == 2 */ t = ucxx2( ) ; if( t != 1 ) { rejects++ ; if( rejects % 6 == 0 && acellptr->orflag != 0){ uc0( aG , (aorient == 1) ? 3 : 1 ); } } else { /* if( t == 1 ) */ pairflips++ ; acc_cntS ++; } } } } num_penalS += 1.0 ; avg_rowpenalS = (avg_rowpenalS * (num_penalS - 1.0) + (DOUBLE) rowpenalG) / num_penalS ; attemptsG++ ; /* draw the data */ G( check_graphics(FALSE) ) ; if (iterationG <= 0) { if( iterationG == 0 ) continue; /* calculate a running average of (delta) timing penalty */ delta_time = abs( delta_time - timingcostG ) ; if( delta_time != 0 ) { num_time += 1.0 ; avg_timeG = (avg_timeG * (num_time - 1.0) + (DOUBLE) delta_time) / num_time ; /* calculate a running average of (delta) wirelength penalty */ delta_func = abs( delta_func - funccostG ) ; num_func += 1.0 ; avg_funcG = (avg_funcG * (num_func - 1.0) + (DOUBLE) delta_func) / num_func ; } if (d_costG >= 0){ m1 ++; /* d_cost is the -ve of the actual d_cost */ } else { dCp -= d_costG; m2 ++; } temp = (INITRATIO * attemptsG - m1) / m2; if (temp <= 0.0) { TG *= 0.9; } else { TG = -dCp / (m2 * log(temp)); } continue; /* initialization phase */ } /* ----------------------------------------------------------------- Update temperature using negative feedback to control the acceptance ratio in accordance to curve fit schedule. Calc_acceptance_ratio returns desired acceptance ratio give the iterationG. The damped error term (deviation) is then applied to correct the temperature T. Update_window_size controls the range limiter. We avoid updating T during initialization, we use exact schedule to compute starting T. The temp_timer allows us to update temperature inside the inner loop of the annealing algorithm. We use counter to avoid use of mod function for speed. ------------------------------------------------------------------ */ num_accepts += pairflips + flips - last_flips ; last_flips = pairflips + flips ; if( ++temp_timer >= time_to_update || (attemptsG >= attmaxG && temp_timer >= 50) ) { ratioG = ((DOUBLE)(num_accepts)) / (DOUBLE) temp_timer ; temp_timer = 0 ; /* reset counter */ num_accepts = 0 ; iter_time = (DOUBLE) iterationG + (DOUBLE) attemptsG / (DOUBLE) attmaxG ; accept_deviation = (calc_acceptance_ratio( iter_time ) - ratioG ) ; if( (DOUBLE) iterationG < TURNOFFT ) { accept_deviation *= ACCEPTDAMPFACTOR ; } else { accept_deviation *= ACCEPTDAMPFACTOR2 ; } TG *= 1.0 + accept_deviation ; update_window_size( (DOUBLE) iterationG + (DOUBLE) attemptsG / (DOUBLE) attmaxG ) ; } } /* end of inner loop */ D( "uloop", check_cost() ; ) ;