1 # 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
# 41 "<stdin>"
using namespace std;
10 void* entry_pt( void* );
# 206 "<stdin>"
12 int main ( int argc, char * const argv[] ) {
cout << "PARSEC Benchmark Suite" << endl << flush;
srandom( 3 );
if( argc != 5 && argc != 6 ) {
cout << "Usage: " << argv[0] << " NTHREADS NSWAPS TEMP NETLIST [NSTEPS]" << endl;
exit( 1 );
}
int num_threads = atoi( argv[1] );
cout << "Threadcount: " << num_threads << endl;
# 236 "<stdin>"
int swaps_per_temp = atoi( argv[2] );
cout << swaps_per_temp << " swaps per temperature step" << endl;
int start_temp = atoi( argv[3] );
cout << "start temperature: " << start_temp << endl;
string filename( argv[4] );
cout << "netlist filename: " << filename << endl;
int number_temp_steps = -1;
if( argc == 6 ) {
number_temp_steps = atoi( argv[5] );
cout << "number of temperature steps: " << number_temp_steps << endl;
}
netlist my_netlist( filename );
annealer_thread a_thread( &my_netlist, num_threads, swaps_per_temp, start_temp, number_temp_steps );
# 282 "<stdin>"
std::vector<pthread_t> threads( num_threads );
void* thread_in = static_cast<void*>( &a_thread );
for( int i=0; i<num_threads; i++ ){
pthread_create( &threads[i], NULL, entry_pt, thread_in );
}
for ( int i=0; i<num_threads; i++ ){
pthread_join( threads[i], NULL );
}
# 298 "<stdin>"
cout << "Final routing is: " << my_netlist.total_routing_cost( ) << endl;
cout << "Terminated" << endl;
return 0;
}
# 341 "<stdin>"
using std::cout;
using std::endl;
84 void annealer_thread::Run( )
{
int accepted_good_moves=0;
int accepted_bad_moves=-1;
double T = _start_temp;
Rng rng;
long a_id;
long b_id;
netlist_elem* a = _netlist->get_random_element( &a_id, NO_MATCHING_ELEMENT, &rng );
netlist_elem* b = _netlist->get_random_element( &b_id, NO_MATCHING_ELEMENT, &rng );
int temp_steps_completed=0;
while( keep_going( temp_steps_completed, accepted_good_moves, accepted_bad_moves ) ){
T = T / 1.5;
accepted_good_moves = 0;
accepted_bad_moves = 0;
for ( int i = 0; i < _moves_per_thread_temp; i++ ){
a = b;
a_id = b_id;
b = _netlist->get_random_element( &b_id, a_id, &rng );
routing_cost_t delta_cost = calculate_delta_routing_cost( a, b );
move_decision_t is_good_move = accept_move( delta_cost, T, &rng );
if ( is_good_move == move_decision_accepted_bad ){
accepted_bad_moves++;
_netlist->swap_locations( a, b );
} else if ( is_good_move == move_decision_accepted_good ){
accepted_good_moves++;
_netlist->swap_locations( a, b );
} else if ( is_good_move == move_decision_rejected ){
}
}
temp_steps_completed++;
pthread_barrier_wait( &_barrier );
}
}
132 annealer_thread::move_decision_t annealer_thread::accept_move( routing_cost_t delta_cost, double T, Rng* rng )
{
if ( delta_cost < 0 ){
return move_decision_accepted_good;
} else {
double random_value = rng->drand( );
double boltzman = exp( - delta_cost/T );
if ( boltzman > random_value ){
return move_decision_accepted_bad;
} else {
return move_decision_rejected;
}
}
}
152 routing_cost_t annealer_thread::calculate_delta_routing_cost( netlist_elem* a, netlist_elem* b )
{
location_t* a_loc = a->present_loc.Get( );
location_t* b_loc = b->present_loc.Get( );
routing_cost_t delta_cost = a->swap_cost( a_loc, b_loc );
delta_cost += b->swap_cost( b_loc, a_loc );
return delta_cost;
}
166 bool annealer_thread::keep_going( int temp_steps_completed, int accepted_good_moves, int accepted_bad_moves )
{
bool rv;
if( _number_temp_steps == -1 ) {
rv = _keep_going_global_flag && ( accepted_good_moves > accepted_bad_moves );
if( !rv ) _keep_going_global_flag = false;
} else {
rv = temp_steps_completed < _number_temp_steps;
}
return rv;
}
# 484 "<stdin>"
182 class annealer_thread
{
public:
enum move_decision_t{
move_decision_accepted_good,
move_decision_accepted_bad,
move_decision_rejected
};
191 annealer_thread(
192 netlist* netlist,
int nthreads,
int swaps_per_temp,
int start_temp,
int number_temp_steps
)
:_netlist( netlist ),
_keep_going_global_flag( true ),
_moves_per_thread_temp( swaps_per_temp/nthreads ),
_start_temp( start_temp ),
_number_temp_steps( number_temp_steps )
{
assert( _netlist != NULL );
pthread_barrier_init( &_barrier, NULL, nthreads );
};
210 ~annealer_thread( ) {
pthread_barrier_destroy( &_barrier );
}
215 void Run( );
protected:
218 move_decision_t accept_move( routing_cost_t delta_cost, double T, Rng* rng );
219 routing_cost_t calculate_delta_routing_cost( netlist_elem* a, netlist_elem* b );
220 bool keep_going( int temp_steps_completed, int accepted_good_moves, int accepted_bad_moves );
protected:
223 netlist* _netlist;
224 bool _keep_going_global_flag;
int _moves_per_thread_temp;
int _start_temp;
int _number_temp_steps;
229 pthread_barrier_t _barrier;
};