[mpich-discuss] help required

Mohammad Zulqurnain prodigiousguy at hotmail.com
Fri Aug 5 18:41:37 CDT 2011





//---------------------------------------------------------------------------#include <vector>#include <string>#include <fstream>#include <iostream.h>#include <map>#include <cstdio>#include <cstring>#include <climits>#include <sys/time.h>#include <sys/resource.h>#include <vector>#include <cassert>#include <stack>#include <algorithm>#include <cmath>#include "mpi.h"
//--------------------------fplan.h--------------------------------using namespace std;
struct Pin{  int mod;  int net;  int x,y;    // relative position  int ax,ay;  // absolute position  Pin(int x_=-1,int y_=-1){ x=x_,y=y_; }};typedef vector<Pin> Pins;typedef Pin* Pin_p;typedef vector<Pin_p> Net;typedef vector<Net > Nets;
enum Module_Type { MT_Hard, MT_Soft, MT_Reclinear, MT_Buffer };
struct Module{  int id;  char name[20];  int width,height;  int x,y;  int area;  Pins pins;  Module_Type type;};typedef vector<Module> Modules;
struct Module_Info{  bool rotate, flip;  int x,y;  int rx,ry;};
typedef vector<Module_Info> Modules_Info;
class FPlan{  public:        int rank;    int Size;  FPlan(const Modules& modules,const Modules_Info& modules_info)    {        int rank = MPI::COMM_WORLD.Get_rank();    int Size = MPI::COMM_WORLD.Get_size();    }  int sendModule_Info(int proc, int tag);  int receiveModule_Info(int proc, int tag);  int sendModule(int proc, int tag);  int receiveModule(int proc, int tag);    FPlan(float calpha);    void read(char*);    virtual void init()		=0;    virtual void packing();    virtual void perturb()	=0;        virtual void keep_sol()	=0;    virtual void keep_best()	=0;    virtual void recover()	=0;    virtual void recover_best() =0;    virtual double getCost();    
    int    size()         { return modules_N; }    double getTotalArea() { return TotalArea; }    double getArea()      { return Area;      }    int    getWireLength(){ return WireLength;}    double getWidth()     { return Width;     }    double getHeight()    { return Height;    }    float  getDeadSpace();
    // information    void list_information();    void show_modules();        void normalize_cost(int);      protected:    void clear();    double calcWireLength();    void scaleIOPad(); 
    double Area;    double Width,Height;    int WireLength;    double TotalArea;        int modules_N;        Modules modules;    Module  root_module;    Modules_Info modules_info;        Nets network;    double norm_area, norm_wire;    float cost_alpha;    vector<vector<int> > connection;      private:    void read_dimension(Module&);    void read_IO_list(Module&,bool parent);    void read_network();    void create_network();   
    map<string,int> net_table;    string filename; };int FPlan::sendModule_Info(int proc, int tag) {

     int blockcounts[6] = {1,1,1,1,1,1};//count of the blocks of the subsequent type     MPI_Datatype types[6];//number of the types used in the mpi struct     MPI_Aint     displs[6];//record of the displacement from the beginning of a particular type block     MPI_Datatype FPlan_Module_Info;// name of the mpi structure object
     // initialize types and displs with addresses of items     MPI_Address( &modules_info[0].rotate, &displs[0] );     MPI_Address( &modules_info[0].flip, &displs[1] );     MPI_Address( &modules_info[0].x, &displs[2] );     MPI_Address( &modules_info[0].y, &displs[3] );     MPI_Address( &modules_info[0].rx, &displs[4] );     MPI_Address( &modules_info[0].ry, &displs[5] );
     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_INT;     types[2] = MPI_INT;       types[3] = MPI_INT;     types[4] = MPI_INT ;     types[5] = MPI_INT ;

    for (int i = 5; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 6, blockcounts, displs, types, &FPlan_Module_Info );    //use the structure in mpi    MPI_Type_commit( &FPlan_Module_Info );
    // send the mpi structure    MPI_Send(&modules_info, modules_N, FPlan_Module_Info , proc, tag, MPI_COMM_WORLD);

    return 1;}
// A function for defining a structure for MPI to collect the node/state object through out the processesint FPlan::receiveModule_Info(int proc, int tag) {




     int blockcounts[6] = {1,1,1,1,1,1};//count of the blocks of the subsequent type     MPI_Datatype types[6];//number of the types used in the mpi struct     MPI_Aint     displs[6];//record of the displacement from the beginning of a particular type block     MPI_Datatype FPlan_Module_Info;// name of the mpi structure object       MPI_Status status;     // initialize types and displs with addresses of items     MPI_Address( &modules_info[0].rotate, &displs[0] );     MPI_Address( &modules_info[0].flip, &displs[1] );     MPI_Address( &modules_info[0].x, &displs[2] );     MPI_Address( &modules_info[0].y, &displs[3] );     MPI_Address( &modules_info[0].rx, &displs[4] );     MPI_Address( &modules_info[0].ry, &displs[5] );
     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_INT;     types[2] = MPI_INT;       types[3] = MPI_INT;     types[4] = MPI_INT ;     types[5] = MPI_INT ;

    for (int i = 5; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 6, blockcounts, displs, types, &FPlan_Module_Info );    //use the structure in mpi    MPI_Type_commit( &FPlan_Module_Info );
    // send the mpi structure

       MPI_Recv(&modules_info,modules_N, FPlan_Module_Info , proc, tag, MPI_COMM_WORLD, &status);
    return 1;}int FPlan::sendModule(int proc, int tag) {

     int blockcounts[8] = {1,20,1,1,1,1,1,1};//count of the blocks of the subsequent type     MPI_Datatype types[8];//number of the types used in the mpi struct     MPI_Aint     displs[8];//record of the displacement from the beginning of a particular type block     MPI_Datatype FPlan_Module;// name of the mpi structure object
     // initialize types and displs with addresses of items     MPI_Address( &modules[0].id, &displs[0] );     MPI_Address( &modules[0].name[20], &displs[1] );     MPI_Address( &modules[0].width, &displs[2] );     MPI_Address( &modules[0].height, &displs[3] );     MPI_Address( &modules[0].x, &displs[4] );     MPI_Address( &modules[0].y, &displs[5] );     MPI_Address( &modules[0].area, &displs[6] );     MPI_Address( &modules[0].type, &displs[7] );     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_CHAR;     types[2] = MPI_INT;       types[3] = MPI_INT;     types[4] = MPI_INT ;     types[5] = MPI_INT ;     types[6] = MPI_INT ;      types[7] = MPI_INT ;
    for (int i = 7; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 8, blockcounts, displs, types, &FPlan_Module );    //use the structure in mpi    MPI_Type_commit( &FPlan_Module );
    // send the mpi structure    MPI_Send(&modules,modules_N, FPlan_Module, proc, tag, MPI_COMM_WORLD);

    return 1;} /*struct Module{  int id;           //id of the module  char name[20];    //name of the module  int width,height; //height and width of the module  int x,y;          //coordinate of the module  int area;         //total area of the module  Pins pins;        //array of pins contained in a module  Module_Type type; //type of the module};*/// A function for defining a structure for MPI to collect the node/state object through out the processesint FPlan::receiveModule(int proc, int tag) {


      int blockcounts[8] = {1,20,1,1,1,1,1,1};//count of the blocks of the subsequent type     MPI_Datatype types[8];//number of the types used in the mpi struct     MPI_Aint     displs[8];//record of the displacement from the beginning of a particular type block     MPI_Datatype FPlan_Module;// name of the mpi structure object         MPI_Status status;     // initialize types and displs with addresses of items   MPI_Address( &modules[0].id, &displs[0] );     MPI_Address( &modules[0].name[20], &displs[1] );     MPI_Address( &modules[0].width, &displs[2] );     MPI_Address( &modules[0].height, &displs[3] );     MPI_Address( &modules[0].x, &displs[4] );     MPI_Address( &modules[0].y, &displs[5] );     MPI_Address( &modules[0].area, &displs[6] );     MPI_Address( &modules[0].type, &displs[7] );     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_CHAR;     types[2] = MPI_INT;       types[3] = MPI_INT;     types[4] = MPI_INT ;     types[5] = MPI_INT ;     t
 ypes[6] = MPI_INT ;      types[7] = MPI_INT ;
    for (int i = 7; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 8, blockcounts, displs, types, &FPlan_Module );    //use the structure in mpi    MPI_Type_commit( &FPlan_Module );
    // send the mpi structure

       MPI_Recv(&modules, modules_N, FPlan_Module, proc, tag, MPI_COMM_WORLD, &status);
    return 1;}
void error(char *msg,char *msg2="");bool rand_bool();float rand_01();double seconds();      //---------------------------------------------------------------------------
extern float init_avg;extern float avg_ratio;extern float lamda;
double SA_Floorplan(FPlan &fp, int k, int local=0, float term_T=0.1);double Random_Floorplan(FPlan &fp,int times);//---------------------------------------------------------------------------//--------------------------------fplan.cpp---------------------------------//// Project: B*-trees floorplanning// Advisor: Yao-Wen Chang  <ywchang at cis.nctu.edu.tw>// Authors: Jer-Ming Hsu   <barz at cis.nctu.edu.tw>// 	    Hsun-Cheng Lee <gis88526 at cis.nctu.edu.tw>// Sponsor: Arcadia Inc.// Date:    7/19/2000 ~
//---------------------------------------------------------------------------

char line[100],t1[40],t2[40];ifstream fs;
FPlan::FPlan(float calpha=1){      int rank = MPI::COMM_WORLD.Get_rank();    int Size = MPI::COMM_WORLD.Get_size();  norm_area= 1;  norm_wire= 1;  cost_alpha=calpha;}
void FPlan::packing(){  if(cost_alpha!=1)     calcWireLength();}
void FPlan::clear(){  Area = 0;   WireLength = 0;}
double FPlan::getCost(){  if(cost_alpha==1)     return cost_alpha*(Area/norm_area);  else if(cost_alpha < 1e-4)     return (WireLength/norm_wire);  else     return cost_alpha*(Area/norm_area)+(1-cost_alpha)*(WireLength/norm_wire);}
float FPlan::getDeadSpace(){  return 100*(Area-TotalArea)/float(Area);}
void FPlan::normalize_cost(int t){  norm_area=norm_wire=0;
  for(int i=0; i < t; i++){    perturb();    packing();    norm_area += Area;    norm_wire += WireLength;  }    norm_area /= t;  norm_wire /= t;  printf("normalize area=%.0f, wire=%.0f\n", norm_area, norm_wire);}
//---------------------------------------------------------------------------//   Read//---------------------------------------------------------------------------
char* tail(char *str){    str[strlen(str)-1]=0;    return str;}
void FPlan::read(char *file){  filename = file;   fs.open(file);  if(fs==NULL)    error("unable to open file: %s",file);
  bool final=false;  Module dummy_mod;  for(int i=0; !fs.eof(); i++){    // modules    modules.push_back(dummy_mod);	// new module    Module &mod = modules.back();    mod.id = i;    mod.pins.clear();
    fs >> t1 >> t2;    tail(t2);			// remove ";"    strcpy(mod.name,t2);
    fs >> t1 >> t2;    if(!strcmp(t2,"PARENT;"))	final= true;        // dimension    read_dimension(mod);        read_IO_list(mod,final);
    // network    if(final){      read_network();      break;    }  }
  root_module = modules.back();  modules.pop_back();		// exclude the parent module  modules_N = modules.size();    modules_info.resize(modules_N);  modules.resize(modules_N);
  create_network();
  TotalArea = 0;  for(int i=0; i < modules_N; i++)    TotalArea += modules[i].area;
}
void FPlan::read_dimension(Module &mod){    fs >> t1;    int min_x=INT_MAX,min_y=INT_MAX,max_x=INT_MIN,max_y=INT_MIN;    int tx,ty;    for(int i=0; i < 4;i++){      fs >> tx >> ty;       min_x=min(min_x,tx); max_x=max(max_x,tx);      min_y=min(min_y,ty); max_y=max(max_y,ty);    }
    mod.x      = min_x;    mod.y      = min_y;    mod.width  = max_x - min_x;    mod.height = max_y - min_y;    mod.area   = mod.width * mod.height;    fs >> t1 >> t2;}
void FPlan::read_IO_list(Module &mod,bool parent=false){    // IO list    while(!fs.eof()){      Pin p;      fs.getline(line,100);      if(strlen(line)==0) continue;      sscanf(line,"%s %*s %d %d",t1,&p.x,&p.y);
      if(!strcmp(t1,"ENDIOLIST;"))	break;
      if(parent){ // IO pad is network       // make unique net id        net_table.insert(make_pair(string(t1),net_table.size()));        p.net = net_table[t1];      }
      p.mod = mod.id;      p.x -= mod.x;  p.y -= mod.y;	// shift to origin
      mod.pins.push_back(p);    }    fs.getline(line,100);}
void FPlan::read_network(){    while(!fs.eof()){      bool end=false;      int n=0;      fs >> t1 >> t2;      if(!strcmp(t1,"ENDNETWORK;"))        break;      // determine which module interconnection by name      int m_id;      for(m_id=0; m_id < modules.size(); m_id++)        if(!strcmp(modules[m_id].name,t2))   	  break;      if(m_id== modules.size()) 	error("can't find suitable module name!");              while(!fs.eof()){        fs >> t1;        if(t1[strlen(t1)-1]==';'){ 	  tail(t1);          end=true;        }
        // make unique net id        net_table.insert(make_pair(string(t1),net_table.size()));        modules[m_id].pins[n++].net = net_table[t1];        if(end) break;      }    }}
//---------------------------------------------------------------------------//   Wire Length Estimate//---------------------------------------------------------------------------
void FPlan::create_network(){  network.resize(net_table.size());
  for(int i=0; i < modules_N; i++){    for(int j=0; j < modules[i].pins.size(); j++){      Pin &p = modules[i].pins[j];      network[p.net].push_back(&p);    }  }
  for(int j=0; j < root_module.pins.size(); j++){    Pin &p = root_module.pins[j];    network[p.net].push_back(&p);  }
  connection.resize(modules_N+1);  for(int i=0; i < modules_N+1; i++){    connection[i].resize(modules_N+1);    fill(connection[i].begin(), connection[i].end(), 0);  }
  for(int i=0; i < network.size(); i++){    for(int j=0; j < network[i].size()-1; j++){      int p= network[i][j]->mod;      for(int k=j+1 ; k < network[i].size(); k++){        int q= network[i][k]->mod;        connection[p][q]++;        connection[q][p]++;         }    }  }}

void FPlan::scaleIOPad(){  float px = Width/float(root_module.width);  float py = Height/float(root_module.height);      for(int i=0; i < root_module.pins.size(); i++){    Pin &p = root_module.pins[i];    p.ax = int(px * p.x);    p.ay = int(py * p.y);
  }}
double FPlan::calcWireLength(){
  scaleIOPad();  WireLength=0;  // compute absolute position  for(int i=0; i < modules_N; i++){    int mx= modules_info[i].x, my= modules_info[i].y;    bool rotate= modules_info[i].rotate;    int w= modules[i].width;
    for(int j=0; j < modules[i].pins.size(); j++){      Pin &p = modules[i].pins[j];
      if(!rotate){        p.ax= p.x+mx, p.ay= p.y+my;      }      else{ // Y' = W - X, X' = Y	p.ax= p.y+mx, p.ay= (w-p.x)+my;      }    }  }
  for(int i=0; i < network.size(); i++)  {    int max_x= INT_MIN, max_y= INT_MIN;    int min_x= INT_MAX, min_y= INT_MAX;
    assert(network[i].size() > 0);    for(int j=0; j < network[i].size(); j++)    {      Pin &p = *network[i][j];      max_x= max(max_x, p.ax), max_y= max(max_y, p.ay);      min_x= min(min_x, p.ax), min_y= min(min_y, p.ay);    }//    printf("%d %d %d %d\n",max_x,min_x,max_y,min_y);    WireLength += (max_x-min_x)+(max_y-min_y);  }  return WireLength;}
//---------------------------------------------------------------------------//   Modules Information//---------------------------------------------------------------------------
string query_map(map<string,int> M,int value){  for(map<string,int>::iterator p=M.begin(); p != M.end(); p++){    if(p->second == value)      return p->first;  }  return "";}
void FPlan::show_modules(){  for(int i=0; i < modules.size();i++){    cout << "Module: " << modules[i].name << endl;    cout << "  Width = " << modules[i].width<< endl;    cout << "  Height= " << modules[i].height << endl;    cout << "  Area  = " << modules[i].area << endl;//    cout << modules[i].pins.size() << " Pins:\n";//    for(int j=0; j < modules[i].pins.size(); j++){//      cout << query_map(net_table,modules[i].pins[j].net) << " ";//      cout << modules[i].pins[j].x << " " << modules[i].pins[j].y << endl;//    }  }}
void FPlan::list_information(){
  string info = filename + ".info";     ofstream of(info.c_str());    of << modules_N << " " << Width << " " << Height << endl;  for(int i=0; i < modules_N; i++){    of << modules_info[i].x  << " " << modules_info[i].rx  << " ";    of << modules_info[i].y << " " << modules_info[i].ry << endl;  }  of << endl;
  calcWireLength();   int x,y,rx,ry;  for(int i=0; i < network.size(); i++){    assert(network[i].size()>0);    x = network[i][0]->ax;    y = network[i][0]->ay;        for(int j=1; j < network[i].size(); j++){      rx = network[i][j]->ax;      ry = network[i][j]->ay;      of << x << " " << y << " " << rx << " " << ry << endl;      x = rx, y = ry;    }  }
  cout << "Num of Module  = " << modules_N << endl;  cout << "Height         = " << Height*1e-3 << endl;  cout << "Width          = " << Width*1e-3 << endl;  cout << "Area           = " << Area*1e-6 << endl;  cout << "Wire Length    = " << calcWireLength()*1e-3 << endl;  cout << "Total Area     = " << TotalArea*1e-6 << endl;  printf( "Dead Space     = %.2f\n", getDeadSpace());}
//---------------------------------------------------------------------------//   Auxilliary Functions//---------------------------------------------------------------------------
void error(char *msg,char *msg2){  printf(msg,msg2);  cout << endl;  throw 1;}
bool rand_bool(){  return bool(rand()%2);}
float rand_01(){  return float(rand()%10000)/10000;}
double seconds(){   rusage time;   getrusage(RUSAGE_SELF,&time);   return (double)(1.0*time.ru_utime.tv_sec+0.000001*time.ru_utime.tv_usec);}//--------------------------------------sa.h----------------------------------//float init_avg = 0.00001;int hill_climb_stage = 7;float avg_ratio=150;float lamda=1.3;
double mean(vector<double> &chain){  double sum=0;  for(int i=0; i < chain.size();i++)     sum+= chain[i];  return sum/chain.size();}
double std_var(vector<double> &chain){  double m = mean(chain);  double sum=0;  double var;  int N= chain.size();
  for(int i=0; i < N;i++)     sum += (chain[i]-m)*(chain[i]-m);
  var = sqrt(sum/(N-1));  printf("  m=%.4f ,v=%.4f\n",m,var);
  return var;}
/* Simulated Annealing B*Tree Floorplan   k: factor of the number of permutation in one temperature   local: local search iterations   termT: terminating temperature*/
//----------------------sa.cpp--------------------------------//double SA_Floorplan(FPlan &fp, int k, int local, float term_T){  int MT,uphill,reject;  double pre_cost,best,cost;  float d_cost,reject_rate;    int N = k * fp.size();  float P=0.9;  float T,actual_T=1;  double avg=init_avg;  float conv_rate = 1;  double time=seconds(); 
  double estimate_avg = 0.08 / avg_ratio;  cout << "Estimate Average Delta Cost = " << estimate_avg << endl;
  if(local==0)    avg = estimate_avg;
  T = avg / log(P);      // get inital solution  fp.packing();  fp.keep_sol();    fp.keep_best();  pre_cost =  best = fp.getCost();    int good_num=0,bad_num=0;  double total_cost=0;  int count=0;  ofstream of("/tmp/btree_debug");
  do{   count++;   total_cost = 0;   MT=uphill=reject=0;   printf("Iteration %d, T= %.2f\n", count,  actual_T);      vector<double> chain;     for(; uphill < N && MT < 2*N; MT++){       fp.perturb();       fp.packing();       cost = fp.getCost();        d_cost = cost - pre_cost;       float p = exp(d_cost/T);       
       chain.push_back(cost);
       if(d_cost <=0 || rand_01() < p ){         fp.keep_sol();         pre_cost = cost;
         if(d_cost > 0){                  uphill++, bad_num++;           of << d_cost << ": " << p << endl;         }else  if(d_cost < 0)  good_num++;
         // keep best solution         if(cost < best){           fp.keep_best();           best = cost;           printf("   ==>  Cost= %f, Area= %.6f, ", best, fp.getArea()*1e-6);           printf("Wire= %.3f\n", fp.getWireLength()*1e-3);             assert(fp.getArea() >= fp.getTotalArea());           time = seconds();           }       }       else{         reject++;         fp.recover();       }   }//   cout << T << endl;   double sv = std_var(chain);   float r_t = exp(lamda*T/sv);   T = r_t*T;

   // After apply local-search, start to use normal SA   if(count == local){     T = estimate_avg/ log(P);     T *= pow(0.9,local);		// smothing the annealing schedule     actual_T = exp(estimate_avg/T);   }   if(count > local){     actual_T = exp(estimate_avg/T);     conv_rate = 0.95;   }
   reject_rate = float(reject)/MT;   printf("  T= %.2f, r= %.2f, reject= %.2f\n\n", actual_T, r_t, reject_rate);
  }while(reject_rate < conv_rate && actual_T > term_T);
  if(reject_rate >= conv_rate)    cout << "\n  Convergent!\n";  else if(actual_T <= term_T)    cout << "\n Cooling Enough!\n";
  printf("\n good = %d, bad=%d\n\n", good_num, bad_num);
  fp.recover_best();  fp.packing();  return time; }
double Random_Floorplan(FPlan &fp,int times){  int N =times,t=0;  double total_cost=0,pre_cost,cost,best;
  fp.packing();  pre_cost = best = fp.getCost();
 do{  for(int i=0; i < N;i++){    fp.perturb();    fp.packing();      cost = fp.getCost();    if(cost-pre_cost > 0){      t++;      total_cost += cost-pre_cost;      pre_cost = cost;    }
    if(cost < best){      fp.keep_best();      best = cost;      cout << "==> Cost=" << best << endl;    }  }	 }while(total_cost==0);
  fp.recover_best();  fp.packing();
  total_cost /= t;  return total_cost;}//------------------------------------Btree------------------------------------//// Project: B*-trees floorplanning// Advisor: Yao-Wen Chang  <ywchang at cis.nctu.edu.tw>// Authors: Jer-Ming Hsu   <barz at cis.nctu.edu.tw>// 	    Hsun-Cheng Lee <gis88526 at cis.nctu.edu.tw>// Sponsor: Arcadia Inc.// Date:    7/19/2000 ~
const int NIL = -1;typedef bool DIR;const bool LEFT=0, RIGHT=1;
struct Node{  int id,parent,left,right;  int rotate,flip;  int isleaf(){ return (left==NIL && right==NIL); }}; struct Contour{  int front,back;};
class B_Tree : public FPlan{  public:  int sendcontour(int proc, int tag);  int receivecontour(int proc, int tag);  int sendNode(int proc, int tag);  int receiveNode(int proc, int tag);     B_Tree(const B_Tree& obj,int i):FPlan(obj.modules,obj.modules_info)    {         nodes[i].id=obj.nodes[i].id;      nodes[i].parent=obj.nodes[i].parent;      nodes[i].left=obj.nodes[i].left;      nodes[i].right=obj.nodes[i].right;      nodes[i].flip=obj.nodes[i].flip;
    		 contour[i].front=obj.contour[i].front;          contour[i].back=obj.contour[i].back;          	modules[i].id=obj.modules[i].id;         modules[i].name[20]=obj.modules[i].name[20];         modules[i].width=obj.modules[i].width;         modules[i].height=obj.modules[i].height;         modules[i].x=obj.modules[i].x;         modules[i].y=obj.modules[i].y;         modules[i].area=obj.modules[i].area;         modules[i].pins=obj.modules[i].pins;          modules[i].type=obj.modules[i].type;     		modules_info[i].rotate=obj.modules_info[i].rotate;         modules_info[i].flip=obj.modules_info[i].flip;         modules_info[i].x=obj.modules_info[i].x;         modules_info[i].y=obj.modules_info[i].y;         modules_info[i].rx=obj.modules_info[i].rx;         modules_info[i].ry=obj.modules_info[i].ry;
    }    B_Tree(float calpha=1) :FPlan(calpha)    {
     }    virtual void init();    virtual void packing();    virtual void perturb();    virtual void keep_sol();    virtual void keep_best();        virtual void recover();    virtual void recover_best();
    // debuging    void testing();      protected:        void show_tree();      int place_module(int mod,int abut,bool is_left=true);    bool legal();    void clear();        // Auxilary function    void wire_nodes(int parent,int child,DIR edge);    int child(int node,DIR d);    bool legal_tree(int p,int n,int &num);    void add_changed_nodes(int n);      // SA permutating operation    void swap_node(Node &n1, Node &n2);    void insert_node(Node &parent,Node &node);    void delete_node(Node &node);        bool delete_node2(Node &node,DIR pull);    void insert_node2(Node &parent,Node &node,                     DIR edge,DIR push,bool fold=false);
    int contour_root;    vector<Contour> contour;    int nodes_root;    vector<Node> nodes;   
   private:            struct Solution{      int nodes_root;      vector<Node> nodes;      double cost;      Solution() { cost = 1; }      void clear() { cost = 1, nodes.clear(); }    };      void get_solution(Solution &sol);    void recover(Solution &sol);    void recover_partial();
    Solution best_sol, last_sol;    // for partial recover    vector<Node> changed_nodes;    int changed_root;    };
int B_Tree::sendcontour(int proc, int tag) {

     int blockcounts[2] = {1,1};//count of the blocks of the subsequent type     MPI_Datatype types[2];//number of the types used in the mpi struct     MPI_Aint     displs[2];//record of the displacement from the beginning of a particular type block     MPI_Datatype B_Tree_contour;// name of the mpi structure object
     // initialize types and displs with addresses of items     MPI_Address( &contour[0].front, &displs[0] );     MPI_Address( &contour[0].back, &displs[1] );
     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_INT;

    for (int i = 1; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 2, blockcounts, displs, types, &B_Tree_contour );    //use the structure in mpi    MPI_Type_commit( &B_Tree_contour );
    // send the mpi structure    MPI_Send(&contour, modules_N, B_Tree_contour, proc, tag, MPI_COMM_WORLD);

    return 1;}int B_Tree::receivecontour(int proc, int tag) {

     int blockcounts[2] = {1,1};//count of the blocks of the subsequent type     MPI_Datatype types[2];//number of the types used in the mpi struct     MPI_Aint     displs[2];//record of the displacement from the beginning of a particular type block     MPI_Datatype B_Tree_contour;// name of the mpi structure object            MPI_Status status;     // initialize types and displs with addresses of items     MPI_Address( &contour[0].front, &displs[0] );     MPI_Address( &contour[0].back, &displs[1] );
     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_INT;

    for (int i = 1; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 2, blockcounts, displs, types, &B_Tree_contour );    //use the structure in mpi    MPI_Type_commit( &B_Tree_contour );
    // send the mpi structure    MPI_Recv(&contour, modules_N, B_Tree_contour, proc, tag, MPI_COMM_WORLD, &status);
    return 1;}/*struct Node{  int id,parent,left,right; int rotate,flip;  int isleaf(){ return (left==NIL && right==NIL); }};*/
// A function for defining a structure for MPI to distribute the node/state object through out the processesint B_Tree::sendNode(int proc, int tag) {

     int blockcounts[6] = {1,1,1,1,1,1};//count of the blocks of the subsequent type     MPI_Datatype types[6];//number of the types used in the mpi struct     MPI_Aint     displs[6];//record of the displacement from the beginning of a particular type block     MPI_Datatype B_Tree_node;// name of the mpi structure object
     // initialize types and displs with addresses of items     MPI_Address( &nodes[0].id, &displs[0] );     MPI_Address( &nodes[0].parent, &displs[1] );     MPI_Address( &nodes[0].left, &displs[2] );     MPI_Address( &nodes[0].right, &displs[3] );     MPI_Address( &nodes[0].rotate, &displs[4] );     MPI_Address( &nodes[0].flip, &displs[5] );     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_INT;     types[2] = MPI_INT;       types[3] = MPI_INT;     types[4] = MPI_INT ;     types[5] = MPI_INT ;
    for (int i = 5; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 6, blockcounts, displs, types, &B_Tree_node );    //use the structure in mpi    MPI_Type_commit( &B_Tree_node );
    // send the mpi structure    MPI_Send(&nodes[0],modules_N, B_Tree_node, proc, tag, MPI_COMM_WORLD);

    return 1;}
// A function for defining a structure for MPI to collect the node/state object through out the processesint B_Tree::receiveNode(int proc, int tag) {
    int blockcounts[6] = {1,1,1,1,1,1};//count of the blocks of the subsequent type     MPI_Datatype types[6];//number of the types used in the mpi struct     MPI_Aint     displs[6];//record of the displacement from the beginning of a particular type block     MPI_Datatype B_Tree_node;// name of the mpi structure object          MPI_Status status;     // initialize types and displs with addresses of items     MPI_Address( &nodes[0].id, &displs[0] );     MPI_Address( &nodes[0].parent, &displs[1] );     MPI_Address( &nodes[0].left, &displs[2] );       MPI_Address( &nodes[0].right, &displs[3] );     MPI_Address( &nodes[0].rotate, &displs[4] );     MPI_Address( &nodes[0].flip, &displs[5] );     //consecutive types in mpi     types[0] = MPI_INT;     types[1] = MPI_INT;     types[2] = MPI_INT;       types[3] = MPI_INT;     types[4] = MPI_INT;     types[5] = MPI_INT;
    for (int i = 5; i >= 0; i --)  //substracting the base address from the subsequent displacements            displs [i] -= displs [0];     //MPI_Type_struct( no, blockcounts, displs, types,mpi_structure);    MPI_Type_struct( 6, blockcounts, displs, types, &B_Tree_node );    //use the structure in mpi    MPI_Type_commit( &B_Tree_node );
    // recieve the mpi structure
       MPI_Recv(&nodes[0],modules_N, B_Tree_node, proc, tag, MPI_COMM_WORLD, &status);
    return 1;}
//--------------------------btree.cpp-------------------------------------//// Project: B*-trees floorplanning// Advisor: Yao-Wen Chang  <ywchang at cis.nctu.edu.tw>// Authors: Jer-Ming Hsu   <barz at cis.nctu.edu.tw>// 	    Hsun-Cheng Lee <gis88526 at cis.nctu.edu.tw>// Sponsor: Arcadia Inc.// Date:    7/19/2000 ~
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------float rotate_rate = 0.3;float swap_rate = 0.5;
//---------------------------------------------------------------------------//   Initialization//---------------------------------------------------------------------------
void B_Tree::clear(){  // initial contour value  contour_root = NIL;  FPlan::clear();}
void B_Tree::init(){
  // initialize contour structure  contour.resize(modules_N);      // initialize b*tree by complete binary tree  nodes.resize(modules_N);  nodes_root=0;  for(int i=0; i < modules_N; i++){    nodes[i].id = i;    nodes[i].parent = (i+1)/2-1;    nodes[i].left   = (2*i+1 < modules_N ? 2*i+1 : NIL);    nodes[i].right  = (2*i+2 < modules_N ? 2*i+2 : NIL);  }  nodes[0].parent = NIL;  best_sol.clear();  last_sol.clear();  clear();  normalize_cost(10);} 
//---------------------------------------------------------------------------//   Testing, Debuging tools//---------------------------------------------------------------------------
bool B_Tree::legal(){  int num=0;  return legal_tree(NIL,nodes_root,num);}
bool B_Tree::legal_tree(int p,int n,int &num){  num++;  if(nodes[n].parent!=p) return false;  if(nodes[n].left != NIL)    if(legal_tree(n,nodes[n].left,num) != true) return false;
  if(nodes[n].right != NIL)    if(legal_tree(n,nodes[n].right,num) != true) return false;
  if(p==NIL) // root    return (num==modules_N);  return true;}
void B_Tree::testing(){  int p,n;  Solution E;
  do{    n = rand()%modules_N;    p = rand()%modules_N;
    while(n==nodes_root)		// n is not root      n = rand()%modules_N;
    while(n==p||nodes[n].parent==p||nodes[p].parent==n)	// n != p & n.parent != p      p = rand()%modules_N;       Node &node = nodes[n];    Node &parent = nodes[p];    get_solution(E);    swap_node(parent,node);  }while(legal());
  cout << "p=" << p << ", n=" << n << endl;  recover(E);  show_tree();  cout << "\n  p=" << p << ", n=" << n << endl;  swap_node(nodes[p],nodes[n]);  show_tree();}
void B_Tree::show_tree(){  cout << "root: " << nodes_root << endl;  for(int i=0; i < modules_N; i++){    cout << nodes[i].id << ": ";    cout << nodes[i].left << " ";    cout << nodes[i].parent << " ";    cout << nodes[i].right << endl;  }}
//---------------------------------------------------------------------------//   Placement modules//---------------------------------------------------------------------------
void B_Tree::packing(){  stack<int> S;
  clear();  int p = nodes_root;
  place_module(p,NIL);  Node &n = nodes[p];  if(n.right != NIL)      S.push(n.right);  if(n.left  != NIL)      S.push(n.left);
  // inorder traverse  while(!S.empty()){    p = S.top();    S.pop();    Node &n = nodes[p];
    assert(n.parent != NIL);    bool is_left = (nodes[n.parent].left == n.id);    place_module(p,n.parent,is_left);
    if(n.right != NIL)      S.push(n.right);    if(n.left  != NIL)      S.push(n.left);  }
  // compute Width, Height  double max_x=-1,max_y=-1;  for(int p= contour_root; p != NIL; p=contour[p].front){    max_x = max(max_x,double(modules_info[p].rx));      max_y = max(max_y,double(modules_info[p].ry));  }
  Width  = max_x;  Height = max_y;  Area   = Height*Width;
  FPlan::packing(); 	// for wirelength  }
// is_left: default is trueint B_Tree::place_module(int mod,int abut,bool is_left){ //this routine can be parallelized   B_Tree obj;  obj.init();  if(Size>1){ if(rank==0){         	for(int i=0; i<modules_N; i++)    	{                obj.nodes[i].id=nodes[i].id;      obj.nodes[i].parent=nodes[i].parent;      obj.nodes[i].left=nodes[i].left;      obj.nodes[i].right=nodes[i].right;      obj.nodes[i].flip=nodes[i].flip;
    		 obj.contour[i].front=contour[i].front;          obj.contour[i].back=contour[i].back;          	obj.modules[i].id=modules[i].id;         obj.modules[i].name[20]=modules[i].name[20];         obj.modules[i].width=modules[i].width;         obj.modules[i].height=modules[i].height;         obj.modules[i].x=modules[i].x;         obj.modules[i].y=modules[i].y;         obj.modules[i].area=modules[i].area;         obj.modules[i].pins=modules[i].pins;          obj.modules[i].type=modules[i].type;     		obj.modules_info[i].rotate=modules_info[i].rotate;         obj.modules_info[i].flip=modules_info[i].flip;         obj.modules_info[i].x=modules_info[i].x;         obj.modules_info[i].y=modules_info[i].y;        obj. modules_info[i].rx=modules_info[i].rx;         obj.modules_info[i].ry=modules_info[i].ry;          obj.contour_root=contour_root;           obj.nodes_root=nodes_root;         }  	for(int i=1; i<Size; i++)    	{
             obj.sendNode(i,0);            obj.sendcontour(i, 20);            obj.sendModule_Info(i, 30);           obj.sendModule(i, 40);    	}

    for(int i=1; i<Size; i++)    	{


    	obj.receiveNode(i, 0);    obj.receivecontour(i, 20);  	  obj.receiveModule_Info(i, 30);  	 	obj.receiveModule(i,40);
           for(int j=((i-1)*(modules_N/Size));j<((i)*(modules_N/Size));j++)    			{

              B_Tree(obj,j);
       		}       }       return 0;}if(rank!=0){         obj.receiveNode(0, 0);		 	obj.receivecontour(0, 20);    		obj.receiveModule_Info(0, 30);        obj.receiveModule(0,40);

  		 /*   Modules modules;           //dynamic array which store modules   		 Module  root_module;       //for storing root node   		 Modules_Info modules_info; */   	 	for(int i=((rank-1)*(modules_N/Size));i<((rank)*(modules_N/Size));i++)   		 {
          B_Tree(obj,i);   		 }
}  Module_Info &mod_mf = modules_info[mod];  mod_mf.rotate       = nodes[mod].rotate;  mod_mf.flip         = nodes[mod].flip;
  int w =  modules[mod].width;  int h =  modules[mod].height;  if(nodes[mod].rotate)    swap(w,h);
  if(abut==NIL){	// root node    contour_root = mod;    contour[mod].back = NIL;    contour[mod].front = NIL;    mod_mf.x  = mod_mf.y = 0;    mod_mf.rx = w, mod_mf.ry = h;    return 0;  }
  int p;   // trace contour from p
  if(is_left){	// left    int abut_width = (nodes[abut].rotate ? modules[abut].height :                                           modules[abut].width);    mod_mf.x  = modules_info[abut].x + abut_width;    mod_mf.rx = mod_mf.x + w;    p = contour[abut].front;
    contour[abut].front = mod;    contour[mod].back = abut;
    if(p==NIL){  // no obstacle in X axis      mod_mf.y = 0;      mod_mf.ry = h;      contour[mod].front = NIL;      return 0;    }  }else{	// upper    mod_mf.x = modules_info[abut].x;    mod_mf.rx = mod_mf.x + w;    p = abut;
    int n=contour[abut].back;
    if(n==NIL)    { // i.e, mod_mf.x==0      contour_root = mod;      contour[mod].back = NIL;    }    else{      contour[n].front = mod;      contour[mod].back = n;        }  }
  int min_y = INT_MIN;  int bx,by;  assert(p!=NIL);
  for(; p!=NIL ; p=contour[p].front)  {    bx = modules_info[p].rx;    by = modules_info[p].ry;    min_y = max(min_y, by);
    if(bx >= mod_mf.rx){ 	// update contour      mod_mf.y = min_y;      mod_mf.ry = mod_mf.y + h;      if(bx > mod_mf.rx){        contour[mod].front = p;        contour[p].back = mod;      }else{ 			// bx==mod_mf.rx        int n= contour[p].front;        contour[mod].front = n;        if(n!=NIL)          contour[n].back = mod;      }      break;    }  }
  if(p==NIL){    mod_mf.y  = (min_y==INT_MIN? 0 : min_y);    mod_mf.ry = mod_mf.y + h;    contour[mod].front = NIL;  }//////////////////////////////////////////////////////////////////////////////// 		 		for(int i=((rank-1)*(modules_N/Size));i<((rank)*(modules_N/Size));i++)    			{		obj.nodes[i].id=nodes[i].id;      obj.nodes[i].parent=nodes[i].parent;      obj.nodes[i].left=nodes[i].left;      obj.nodes[i].right=nodes[i].right;      obj.nodes[i].flip=nodes[i].flip;
    		 obj.contour[i].front=contour[i].front;          obj.contour[i].back=contour[i].back;
          	obj.modules[i].id=modules[i].id;         obj.modules[i].name[20]=modules[i].name[20];         obj.modules[i].width=modules[i].width;         obj.modules[i].height=modules[i].height;         obj.modules[i].x=modules[i].x;         obj.modules[i].y=modules[i].y;         obj.modules[i].area=modules[i].area;         obj.modules[i].pins=modules[i].pins;          obj.modules[i].type=modules[i].type;     		obj.modules_info[i].rotate=modules_info[i].rotate;         obj.modules_info[i].flip=modules_info[i].flip;         obj.modules_info[i].x=modules_info[i].x;         obj.modules_info[i].y=modules_info[i].y;        obj. modules_info[i].rx=modules_info[i].rx;         obj.modules_info[i].ry=modules_info[i].ry;            obj.contour_root=contour_root;           obj.nodes_root=nodes_root;              }////////////////////////////////////////////////////////////////////////////////

   	 obj.sendNode(0, 0);         obj.sendcontour(0, 20);         obj.sendModule_Info(0, 30);         obj.sendModule(0, 40);          return 0; } else {  Module_Info &mod_mf = modules_info[mod];  mod_mf.rotate       = nodes[mod].rotate;  mod_mf.flip         = nodes[mod].flip;
  int w =  modules[mod].width;  int h =  modules[mod].height;  if(nodes[mod].rotate)    swap(w,h);
  if(abut==NIL){	// root node    contour_root = mod;    contour[mod].back = NIL;    contour[mod].front = NIL;    mod_mf.x  = mod_mf.y = 0;    mod_mf.rx = w, mod_mf.ry = h;    return 0;  }
  int p;   // trace contour from p
  if(is_left){	// left    int abut_width = (nodes[abut].rotate ? modules[abut].height :                                           modules[abut].width);    mod_mf.x  = modules_info[abut].x + abut_width;    mod_mf.rx = mod_mf.x + w;    p = contour[abut].front;
    contour[abut].front = mod;    contour[mod].back = abut;
    if(p==NIL){  // no obstacle in X axis      mod_mf.y = 0;      mod_mf.ry = h;      contour[mod].front = NIL;      return 0;    }  }else{	// upper    mod_mf.x = modules_info[abut].x;    mod_mf.rx = mod_mf.x + w;    p = abut;         int n=contour[abut].back;
    if(n==NIL){ // i.e, mod_mf.x==0      contour_root = mod;      contour[mod].back = NIL;    }    else{      contour[n].front = mod;      contour[mod].back = n;    }  }    int min_y = INT_MIN;  int bx,by;  assert(p!=NIL);      for(; p!=NIL ; p=contour[p].front)  {    bx = modules_info[p].rx;    by = modules_info[p].ry;    min_y = max(min_y, by);          if(bx >= mod_mf.rx){ 	// update contour      mod_mf.y = min_y;      mod_mf.ry = mod_mf.y + h;      if(bx > mod_mf.rx){        contour[mod].front = p;        contour[p].back = mod;      }else{ 			// bx==mod_mf.rx        int n= contour[p].front;        contour[mod].front = n;        if(n!=NIL)          contour[n].back = mod;      }      break;         }  }
  if(p==NIL){    mod_mf.y  = (min_y==INT_MIN? 0 : min_y);    mod_mf.ry = mod_mf.y + h;    contour[mod].front = NIL;  }   return 0;  }}
//---------------------------------------------------------------------------//   Manipulate B*Tree auxilary procedure//---------------------------------------------------------------------------
void B_Tree::wire_nodes(int parent,int child,DIR edge){  assert(parent!=NIL);  (edge==LEFT? nodes[parent].left: nodes[parent].right) = child;  if(child!=NIL) nodes[child].parent = nodes[parent].id;}
int B_Tree::child(int node,DIR d){  assert(node!=NIL);  return (d==LEFT? nodes[node].left:nodes[node].right);  }

//---------------------------------------------------------------------------//   Simulated Annealing Temporal Solution//---------------------------------------------------------------------------
void B_Tree::get_solution(Solution &sol){  sol.nodes_root = nodes_root;  sol.nodes = nodes;  sol.cost = getCost();}
void B_Tree::keep_sol(){  get_solution(last_sol);}
void B_Tree::keep_best(){  get_solution(best_sol);}
void B_Tree::recover(){  recover(last_sol);  // recover_partial();}
void B_Tree::recover_best(){  recover(best_sol);}
void B_Tree::recover(Solution &sol){  nodes_root = sol.nodes_root;  nodes = sol.nodes;}
void B_Tree::recover_partial(){  if(changed_root != NIL)    nodes_root = changed_root;    for(int i=0; i < changed_nodes.size(); i++){    Node &n = changed_nodes[i];    nodes[n.id] = n;  }}
void B_Tree::add_changed_nodes(int n){  if(n==NIL) return;
  for(int i=0; i < changed_nodes.size(); i++)    if(changed_nodes[i].id == n)	return;  changed_nodes.push_back(nodes[n]);}
//---------------------------------------------------------------------------//   Simulated Annealing Permutation Operations//---------------------------------------------------------------------------
void B_Tree::perturb(){  int p,n;  n = rand()%modules_N;
//  changed_nodes.clear();//  changed_root = NIL;

  if(rotate_rate > rand_01()){//    changed_nodes.push_back(nodes[n]);    nodes[n].rotate = !nodes[n].rotate;    if(rand_bool()) nodes[n].flip = !nodes[n].flip;  }  else{ 	
    if(swap_rate >rand_01()){      do{        p = rand()%modules_N;      }while(n==p||nodes[n].parent==p||nodes[p].parent==n);
//      changed_nodes.push_back(nodes[p]);//      changed_nodes.push_back(nodes[n]);
      swap_node(nodes[p],nodes[n]);
    }else{      do{        p = rand()%modules_N;      }while(n==p);
//      changed_nodes.push_back(nodes[p]);//      changed_nodes.push_back(nodes[n]);
      delete_node(nodes[n]);      insert_node(nodes[p],nodes[n]);    }  }}
void B_Tree::swap_node(Node &n1, Node &n2){
  if(n1.left!=NIL){      //add_changed_nodes(n1.left);    nodes[n1.left].parent  = n2.id;  }  if(n1.right!=NIL){    //add_changed_nodes(n1.right);    nodes[n1.right].parent = n2.id;    }  if(n2.left!=NIL){    //add_changed_nodes(n2.left);    nodes[n2.left].parent  = n1.id;  }  if(n2.right!=NIL){    //add_changed_nodes(n2.right);    nodes[n2.right].parent = n1.id;    }
  if(n1.parent != NIL){    //add_changed_nodes(n1.parent);    if(nodes[n1.parent].left==n1.id)       nodes[n1.parent].left  = n2.id;    else       nodes[n1.parent].right = n2.id;   }else{    changed_root = n1.id;    nodes_root = n2.id;  }
  if(n2.parent != NIL){    //add_changed_nodes(n2.parent);    if(nodes[n2.parent].left==n2.id)       nodes[n2.parent].left  = n1.id;    else       nodes[n2.parent].right = n1.id;   }else{//    changed_root = n2.id;    nodes_root = n1.id;  }
  swap(n1.left,n2.left);  swap(n1.right,n2.right);  swap(n1.parent,n2.parent);}
void B_Tree::insert_node(Node &parent, Node &node){  node.parent = parent.id;  bool edge = rand_bool();
  if(edge){    //add_changed_nodes(parent.left);    node.left  = parent.left;    node.right = NIL;    if(parent.left!=NIL)      nodes[parent.left].parent = node.id;
    parent.left = node.id;
  }else{    //add_changed_nodes(parent.right);    node.left  = NIL;    node.right = parent.right;    if(parent.right!=NIL)      nodes[parent.right].parent = node.id;        parent.right = node.id;  }}
void B_Tree::delete_node(Node &node){  int child    = NIL;	// pull which child  int subchild = NIL;   // child's subtree  int subparent= NIL; 
  if(!node.isleaf()){    bool left= rand_bool();			// choose a child to pull up    if(node.left ==NIL) left=false;    if(node.right==NIL) left=true;
    //add_changed_nodes(node.left);    //add_changed_nodes(node.right);
    if(left){      child = node.left;			// child will never be NIL      if(node.right!=NIL){        subchild  = nodes[child].right;        subparent = node.right;        nodes[node.right].parent = child;         nodes[child].right = node.right;	// abut with node's another child      }    }    else{      child = node.right;      if(node.left!=NIL){        subchild  = nodes[child].left;        subparent = node.left;	nodes[node.left].parent = child;        nodes[child].left = node.left;      }    }    //add_changed_nodes(subchild);    nodes[child].parent = node.parent;  }
  if(node.parent == NIL){			// root//    changed_root = nodes_root;    nodes_root = child;  }else{					// let parent connect to child    //add_changed_nodes(node.parent);    if(node.id == nodes[node.parent].left)      nodes[node.parent].left  = child;    else      nodes[node.parent].right = child;  }
  // place subtree  if(subchild != NIL){    Node &sc = nodes[subchild];    assert(subparent != NIL);
    while(1){      Node &p = nodes[subparent];
      if(p.left==NIL || p.right==NIL){        //add_changed_nodes(p.id);
	sc.parent = p.id;        if(p.left==NIL) p.left = sc.id;        else p.right = sc.id;        break;      }else{	subparent = (rand_bool() ? p.left : p.right);      }    }  }}

bool B_Tree::delete_node2(Node &node,DIR pull){  DIR npull = !pull;   int p = node.parent;  int n= node.id;  int c= child(n,pull);  int cn=child(n,npull);
  assert(n!= nodes_root); // not root;
  DIR p2c = (nodes[p].left==n ? LEFT:RIGHT);
  if(c==NIL){    wire_nodes(p,cn,p2c);    return (cn!=NIL);   // folding  }else{    wire_nodes(p,c,p2c);  }
  while(c!=NIL){    int k=child(c,npull);    wire_nodes(c,cn ,npull);    cn= k;    n= c;    c= child(c,pull);  }
  if(cn != NIL){    wire_nodes(n,cn,pull);    return true;  }else     return false;}
/*   Insert node into parent's left or right subtree according by "edge".   Push node into parent's subtree in  "push" direction.
   if "fold" is true, then fold the leaf.   (for the boundary condition of "delete" operation)
   delete <==> insert are permutating operations that can be recoved.*/
void B_Tree::insert_node2(Node &parent,Node &node,                        DIR edge,DIR push,bool fold){  DIR npush = !push;  int p= parent.id;  int n= node.id;  int c= child(p,edge);
  wire_nodes(p,n,edge);  wire_nodes(n,c,push);      while(c!=NIL){    wire_nodes(n,child(c,npush) ,npush);    n= c;    c= child(c,push);  }  wire_nodes(n,NIL,npush);
  if(fold){    wire_nodes(nodes[n].parent,NIL,push);    wire_nodes(nodes[n].parent,n,npush);   }}
int main(int argc,char **argv){char processor_name[ MPI_MAX_PROCESSOR_NAME ];           int namelen;    MPI::Init(argc, argv);    int rank = MPI::COMM_WORLD.Get_rank();    int size = MPI::COMM_WORLD.Get_size();     MPI_Get_processor_name( processor_name, &namelen );   char filename[80],outfile[80]="";   int times=400, local=7;   float init_temp=0.9, term_temp=0.1;   float alpha=1;

   if(argc<=1){     printf("Usage: btree <filename> [times=%d] [hill_climb_stage=%d]\n",           times, local);     printf("        [avg_ratio=%.1f] [cost_ratio=%f]\n",avg_ratio,alpha);     printf("        [lamda=%.2f] [term-temp=%.2f]\n",lamda,term_temp);     printf("        [output]\n");     return 0;   }else{     int argi=1;     if(argi < argc) strcpy(filename, argv[argi++]);     if(argi < argc) times=atoi(argv[argi++]);     if(argi < argc) local=atoi(argv[argi++]);     if(argi < argc) avg_ratio=atof(argv[argi++]);     if(argi < argc) alpha=atof(argv[argi++]);     if(argi < argc) lamda=atof(argv[argi++]);     if(argi < argc) term_temp=atof(argv[argi++]);     if(argi < argc) strcpy(outfile, argv[argi++]);   }
   try{     double time = seconds();     B_Tree fp(alpha);     fp.read(filename);     //fp.show_modules();     fp.init();     double last_time =  SA_Floorplan(fp, times, local, term_temp);     //Random_Floorplan(fp,times);     fp.list_information();
     { // log performance and quality       if(strlen(outfile)==0)         strcpy(outfile,strcat(filename,".res"));
       last_time = last_time - time;       printf("CPU time       = %.2f\n",seconds()-time);       printf("Last CPU time  = %.2f\n",last_time);       FILE *fs= fopen(outfile,"a+");       
       fprintf(fs,"CPU= %.2f, Cost= %.6f, Area= %.0f, Wire= %.0f, Dead=%.4f ",               last_time, float(fp.getCost()),  float(fp.getArea()),                float(fp.getWireLength()), float(fp.getDeadSpace()));       fprintf(fs," :%d %d %.0f \n", times, local, avg_ratio);       fclose(fs);     }
   }catch(...){}          MPI::Finalize();   return 1;} 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mcs.anl.gov/pipermail/mpich-discuss/attachments/20110806/08b52327/attachment-0001.htm>


More information about the mpich-discuss mailing list