BCP_process.cpp
Go to the documentation of this file.
1 // (C) 2007 Copyright International Business Machines Corporation
2 // All Rights Reserved.
3 // This code is published under the Common Public License.
4 //
5 // Authors :
6 // Pierre Bonami, International Business Machines Corporation
7 // Andreas Waechter, International Business Machines Corporation
8 // Laszlo Ladanyi, International Business Machines Corporation
9 //
10 // Date : 10/03/2007
11 
12 #include "CoinTime.hpp"
13 #include "BCP_process.hpp"
14 
15 #ifndef BCP_DEBUG_PRINT
16 #define BCP_DEBUG_PRINT 0
17 #endif
18 
20  totalNumberIds_(0),
21  freeIds_(),
22  numNodeIds_(0),
23  maxNodeIds_(1),
24  maxNodeIdRatio_(1.0),
25  maxNodeIdNum_(1)
26 {}
27 
28 void
29 BCP_scheduler::setParams(double OverEstimationStatic,
30  double SwitchToRateThreshold,
31  double TimeRootNodeSolve,
32  double FactorTimeHorizon,
33  double OverEstimationRate,
34  double MaxNodeIdRatio,
35  int MaxNodeIdNum,
36  int MaxSbIds,
37  int MinSbIds)
38 {
39  rho_static_ = OverEstimationStatic;
40  switch_thresh_ = SwitchToRateThreshold;
41  numSecRateInterval_ = (int)ceil(TimeRootNodeSolve*FactorTimeHorizon);
48  counts_ptr_ = 0;
50  static_ = true;
51  have_rates_ = false;
52  rho_rate_ = OverEstimationRate;
53  maxNodeIdRatio_ = MaxNodeIdRatio;
54  maxNodeIdNum_ = MaxNodeIdNum;
55  maxNodeIds_ = CoinMin((int)floor(maxNodeIdRatio_ * totalNumberIds_),
57  if (maxNodeIds_ == 0) {
58  maxNodeIds_ = 1;
59  }
60  maxSbIds_ = MaxSbIds;
61  // printf("Setting max SbIds to %i\n",maxSbIds_);
62  minSbIds_ = MinSbIds;
63 }
64 
65 //------------------------------------------------------------------------------
66 void
67 BCP_scheduler::add_free_ids(int numIds, const int* ids)
68 {
69  freeIds_.insert(freeIds_.end(), ids, ids+numIds);
70  totalNumberIds_ += numIds;
71  maxNodeIds_ = CoinMin((int)floor(maxNodeIdRatio_ * totalNumberIds_),
73  const double t = CoinWallclockTime();
74  for (int i = 0; i < numIds; ++i) {
75  sb_idle_time_[ids[i]] = 0.0;
76  node_idle_time_[ids[i]] = 0.0;
77  last_release_time_[ids[i]] = t;
78  last_release_type_[ids[i]] = 0;
79  }
80 }
81 
82 //------------------------------------------------------------------------------
83 
84 int
85 BCP_scheduler::request_sb_ids(int reqNumIds, int* ids)
86 {
87  // increase the count for requests by one
88  update_rates(1, 0);
89 
90  int numIds = CoinMin(reqNumIds, max_id_allocation(reqNumIds));
91 #if (BCP_DEBUG_PRINT != 0)
92  if (static_) {
93  printf("SC static: req: %i given: %i total: %i node(max): %i(%i) free: %i minSb: %i maxSb: %i rho: %lf\n",
94  reqNumIds, numIds, totalNumberIds_, numNodeIds_, maxNodeIds_,
95  (int)freeIds_.size(), minSbIds_, maxSbIds_, rho_static_);
96  } else {
97  printf("SC rate: req: %i given: %i total: %i node(max): %i(%i) free: %i minSb: %i maxSb: %i rho: %lf rel_cnt: %i req_cnt: %i\n",
98  reqNumIds, numIds, totalNumberIds_, numNodeIds_, maxNodeIds_,
99  (int)freeIds_.size(), minSbIds_, maxSbIds_, rho_rate_,
101  }
102 #endif
103  if (numIds==0) return 0;
104 
105  const int newsize = freeIds_.size() - numIds;
106  CoinDisjointCopyN(&freeIds_[newsize], numIds, ids);
107  freeIds_.erase(freeIds_.begin()+newsize, freeIds_.end());
108  const double t = CoinWallclockTime();
109  for (int i = 0; i < numIds; ++i) {
110  const int id = ids[i];
111  if (last_release_type_[id] != 2) {
112  sb_idle_time_[id] += t - last_release_time_[id];
113  } else {
114  node_idle_time_[id] += t - last_release_time_[id];
115  }
116  }
117  return numIds;
118 }
119 
120 void
122 {
123  // increase the count for releases by one
124  update_rates(0, 1);
125  freeIds_.push_back(id);
126  last_release_time_[id] = CoinWallclockTime();
127  last_release_type_[id] = 1;
128 }
129 
130 //------------------------------------------------------------------------------
131 
134 int
136 {
137  if (freeIds_.empty() || numNodeIds_ == maxNodeIds_) return -1;
138  numNodeIds_ ++;
139  int id = freeIds_.back();
140  freeIds_.pop_back();
141  return id;
142 }
143 
144 void
146 {
147  // increase the count for releases by one
148  update_rates(0, 1);
149  freeIds_.push_back(id);
150  last_release_time_[id] = CoinWallclockTime();
151  last_release_type_[id] = 2;
152  numNodeIds_--;
153 }
154 
155 //------------------------------------------------------------------------------
156 
157 void
159 {
160  const double t = CoinWallclockTime();
161  for (int i = freeIds_.size()-1; i >= 0; --i) {
162  const int id = freeIds_[i];
163  if (last_release_type_[id] != 2) {
164  sb_idle_time_[id] += t - last_release_time_[id];
165  } else {
166  node_idle_time_[id] += t - last_release_time_[id];
167  }
168  }
169 }
170 
171 
172 //------------------------------------------------------------------------------
173 
174 void
175 BCP_scheduler::update_rates(int add_req, int add_rel)
176 {
177  // Update the counts for the requests
178  time_t time_now = time(NULL);
179  if (time_now == time_last_action_) {
180  request_counts_[counts_ptr_] += add_req;;
181  release_counts_[counts_ptr_] += add_rel;;
182  }
183  else if (time_last_action_ == 0) {
184  counts_ptr_ = 0;
185  request_counts_[counts_ptr_] = add_req;
186  release_counts_[counts_ptr_] = add_rel;
187  time_last_action_ = time_now;
188  }
189  else {
190  while (time_last_action_ < time_now) {
193  counts_ptr_++;
195  counts_ptr_ = 0;
196  have_rates_ = true;
197  }
198  if (have_rates_) {
201  }
204 
206  }
207  request_counts_[counts_ptr_] = add_req;
208  release_counts_[counts_ptr_] = add_rel;
209 
211  }
212 }
213 
214 //------------------------------------------------------------------------------
215 
216 int
218 {
219  double dretval;
220  int retval;
221 
222  /* FIXME: this might be incorrect if in request_node_ids() more than 1 id is
223  requested. If only LPs processes are used then it's correct. */
224 
225  const int numFree = freeIds_.size();
226 
227  double expRate =
228  (double)CoinMin(2*numNodeIds_,maxNodeIds_) / (double)numNodeIds_;
229 
230  if (static_) {
231  dretval = (rho_static_ * (double)(totalNumberIds_-numNodeIds_*expRate) /
232  (double)(numNodeIds_*expRate) );
233  }
234  else {
235  if (request_counts_tot_ == 0) {
236  dretval = numFree;
237  }
238  else {
239  dretval = (rho_rate_ * (double)(release_counts_tot_) /
240  (double)(request_counts_tot_));
241  }
242  }
243  retval = CoinMin(numFree, (int)floor(dretval));
244 
245  if (numIds >= minSbIds_ && retval < minSbIds_) {
246  retval = 0;
247  }
248  if (retval > maxSbIds_) {
249  retval = maxSbIds_;
250  }
251 
252  // At this point, we only want to send an odd number of processors
253  if (retval && (retval & 1) == 0) {
254  --retval;
255  }
256 
257  return retval;
258 }
bool static_
flag indicating whether we are in the static or the rate-based phase
int maxSbIds_
Upper threshold for IDs returned at a request.
void setParams(double OverEstimationStatic, double SwitchToRateThreshold, double TimeRootNodeSolve, double FactorTimeHorizon, double OverEstimationRate, double MaxNodeIdRatio, int MaxNodeIdNum, int MaxSbIdNum, int MinSbIdNum)
Method for setting scheduler parameters.
Definition: BCP_process.cpp:29
int maxNodeIdNum_
At most this many ids can be used as a nodeid.
int numNodeIds_
number of lp ids served.
std::map< int, double > sb_idle_time_
the SB idle time for each process
std::map< int, double > node_idle_time_
the node idle time for each process
void update_idle_times()
Update idle times with the last idle time.
double maxNodeIdRatio_
At most this fraction of the total number of ids can be used as a nodeid.
int request_counts_tot_
total number of requests in considered time interval
int numSecRateInterval_
Number of seconds in time horizon for rate computation.
std::map< int, double > last_release_time_
when was the process release last time
void add_free_ids(int numIds, const int *ids)
Pass in a list of freeIds_ to add.
Definition: BCP_process.cpp:67
int minSbIds_
Lower threshold for IDs returned at a request.
int request_sb_ids(int numIds, int *ids)
Request for a number of id&#39;s to do some strong branching.
Definition: BCP_process.cpp:85
time_t time_last_action_
Time stamp of last request or release.
double rho_static_
overestimation factor for static strategy
int counts_ptr_
Array counter.
int request_node_id()
Request an id for processing nodes.
BCP_scheduler()
Default constructor.
Definition: BCP_process.cpp:19
int max_id_allocation(int numIds)
Compute max allowed allocation of CPUs.
void release_sb_id(int id)
Gives back to scheduler an id used for strong branching.
static int
Definition: OSdtoa.cpp:2173
std::vector< int > freeIds_
List of free CPUs ids.
std::map< int, double > last_release_type_
the type of the last release (0: algo start, 1: from SB, 2: from node
double switch_thresh_
percentage threshold to swtich to rate-based strategy
int release_counts_tot_
total number of releases in considered time interval
int totalNumberIds_
Store the total number of CPUs.
double rho_rate_
overestimation factor for rate-based strategy
int maxNodeIds_
The maximum number of lp ids that can be served.
bool have_rates_
flag indicating whether we have rate information (i.e., the time horizon has passed at least once) ...
void update_rates(int add_req, int add_rel)
Update the counts and the static_ flag.
std::vector< int > release_counts_
vector for counting released sb id requests per time unit
void release_node_id(int id)
Give back an id to scheduler used for processing a node.
static char * t
Definition: OSdtoa.cpp:3645
std::vector< int > request_counts_
vector for counting id requests per time unit