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 ;
}
Esempio n. 2
0
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() ;
) ;