AMF-Placer  2.0
An Open-Source Timing-driven Analytical Mixed-size FPGA Placer
SAPlacer.cc
Go to the documentation of this file.
1 
25 #include "SAPlacer.h"
26 #include <algorithm>
27 #include <cmath>
28 #include <cstdlib>
29 #include <ctime>
30 #include <iostream>
31 
32 double SAPlacer::evaluateClusterPlacement(const std::vector<std::vector<std::vector<int>>> &grid2clusters,
33  const std::vector<std::pair<int, int>> &cluster2XY)
34 {
35 
36  float regionW = deviceW / gridW;
37  float regionH = deviceH / gridH;
38 
39  double resWL = 0;
40 
41  for (unsigned int clusterA = 1; clusterA < clusterAdjMat.size(); clusterA++)
42  for (unsigned int clusterB = 0; clusterB < clusterA; clusterB++)
43  {
44  if (clusterAdjMat[clusterA][clusterB] > 0.00001)
45  {
46  resWL += clusterAdjMat[clusterA][clusterB] *
47  (fabs(cluster2XY[clusterA].first - cluster2XY[clusterB].first) * regionW +
48  y2xRatio * fabs(cluster2XY[clusterA].second - cluster2XY[clusterB].second) * regionH);
49  if (cluster2XY[clusterA].first == 2 || cluster2XY[clusterB].first == 2)
50  resWL += fabs(cluster2XY[clusterA].first - cluster2XY[clusterB].first) * regionW * 0.5;
51  }
52  }
53  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
54  {
55  for (unsigned int fixedUnitId = 0; fixedUnitId < cluster2FixedUnitMat[clusterA].size(); fixedUnitId++)
56  {
57  if (cluster2FixedUnitMat[clusterA][fixedUnitId] > 0.00001)
58  {
59  resWL += connectionToFixedFactor * cluster2FixedUnitMat[clusterA][fixedUnitId] *
60  (fabs((cluster2XY[clusterA].first * regionW + regionW / 2) - fixedX[fixedUnitId]) +
61  y2xRatio * fabs((cluster2XY[clusterA].second * regionH + regionH / 2) - fixedY[fixedUnitId]));
62  }
63  }
64  }
65 
66  for (int gridY = 0; gridY < gridH; gridY++)
67  for (int gridX = 0; gridX < gridW; gridX++)
68  {
69  if (grid2clusters[gridY][gridX].size() > 1)
70  {
71  // resWL *= 10;
72  for (unsigned int clusterAId = 1; clusterAId < grid2clusters[gridY][gridX].size(); clusterAId++)
73  for (unsigned int clusterBId = 0; clusterBId < clusterAId; clusterBId++)
74  {
75  int clusterA = grid2clusters[gridY][gridX][clusterAId];
76  int clusterB = grid2clusters[gridY][gridX][clusterBId];
77  resWL +=
78  5000 *
79  std::pow(std::min(1.1, (clusterWeights[clusterA] + clusterWeights[clusterB]) / 20000.0),
80  2) *
81  (regionW + y2xRatio * regionH);
82  }
83  }
84  }
85 
86  return resWL;
87 }
88 
89 double SAPlacer::incrementalEvaluateClusterPlacement(const std::vector<std::vector<std::vector<int>>> &grid2clusters,
90  const std::vector<std::pair<int, int>> &cluster2XY)
91 {
92  std::vector<bool> placed;
93  placed.clear();
94  float regionW = deviceW / gridW;
95  float regionH = deviceH / gridH;
96 
97  double resWL = 0;
98 
99  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
100  {
101  placed.push_back(cluster2XY[clusterA].first >= 0 && cluster2XY[clusterA].second >= 0);
102  }
103 
104  for (unsigned int clusterA = 1; clusterA < clusterAdjMat.size(); clusterA++)
105  for (unsigned int clusterB = 0; clusterB < clusterA; clusterB++)
106  {
107  if (placed[clusterA] && placed[clusterB])
108  {
109  if (clusterAdjMat[clusterA][clusterB] > 0.00001)
110  {
111  resWL += clusterAdjMat[clusterA][clusterB] *
112  (fabs(cluster2XY[clusterA].first - cluster2XY[clusterB].first) * regionW +
113  y2xRatio * fabs(cluster2XY[clusterA].second - cluster2XY[clusterB].second) * regionH);
114  }
115  }
116  }
117  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
118  {
119  for (unsigned int fixedUnitId = 0; fixedUnitId < cluster2FixedUnitMat[clusterA].size(); fixedUnitId++)
120  {
121  if (placed[clusterA])
122  {
123  if (cluster2FixedUnitMat[clusterA][fixedUnitId] > 0.00001)
124  {
125  resWL +=
126  connectionToFixedFactor * cluster2FixedUnitMat[clusterA][fixedUnitId] *
127  (fabs((cluster2XY[clusterA].first * regionW + regionW / 2) - fixedX[fixedUnitId]) +
128  y2xRatio * fabs((cluster2XY[clusterA].second * regionH + regionH / 2) - fixedY[fixedUnitId]));
129  }
130  }
131  }
132  }
133 
134  for (int gridY = 0; gridY < gridH; gridY++)
135  for (int gridX = 0; gridX < gridW; gridX++)
136  {
137  if (grid2clusters[gridY][gridX].size() > 1)
138  {
139  // resWL *= 10;
140  for (unsigned int clusterAId = 1; clusterAId < grid2clusters[gridY][gridX].size(); clusterAId++)
141  for (unsigned int clusterBId = 0; clusterBId < clusterAId; clusterBId++)
142  {
143  int clusterA = grid2clusters[gridY][gridX][clusterAId];
144  int clusterB = grid2clusters[gridY][gridX][clusterBId];
145  assert(placed[clusterA] && placed[clusterB]);
146  resWL +=
147  5000 *
148  std::pow(std::min(1.1, (clusterWeights[clusterA] + clusterWeights[clusterB]) / 20000.0),
149  2) *
150  (regionW + y2xRatio * regionH);
151  }
152  }
153  }
154 
155  return resWL;
156 }
157 
158 void swapVectors(std::vector<int> &a, std::vector<int> &b)
159 {
160  std::vector<int> c = a;
161  a = b;
162  b = c;
163 }
164 
165 void shuffleVectors(std::vector<std::vector<int>> &a, boost::mt19937 &rng)
166 {
167  int N = a.size();
168  for (int i = N - 1; i > 0; --i)
169  { // gist, note, i>0 not i>=0
170  int r = rng() % (i + 1); // gist, note, i+1 not i. "rng() % (i+1)" means
171  // generate rand numbers from 0 to i
172  swapVectors(a[i], a[r]);
173  }
174 }
175 
176 void SAPlacer::randomSwapInWideRange(const std::vector<std::vector<std::vector<int>>> &grid2clusters,
177  std::vector<std::vector<std::vector<int>>> &new_grid2clusters,
178  const std::vector<std::pair<int, int>> &cluster2XY,
179  std::vector<std::pair<int, int>> &new_cluster2XY, float temperature,
180  boost::mt19937 &rng)
181 {
182  int gridY0 = rng() % (gridH * gridW) / gridW;
183  int gridX0 = rng() % (gridH * gridW) % gridW;
184 
185  int gridY1 = rng() % (gridH * gridW) / gridW;
186  int gridX1 = rng() % (gridH * gridW) % gridW;
187 
188  while ((gridX1 == gridX0 && gridY1 == gridY0) ||
189  (grid2clusters[gridY1][gridX1].size() + grid2clusters[gridY0][gridX0].size()) == 0)
190  {
191  gridY0 = rng() % (gridH * gridW) / gridW;
192  gridX0 = rng() % (gridH * gridW) % gridW;
193 
194  gridY1 = rng() % (gridH * gridW) / gridW;
195  gridX1 = rng() % (gridH * gridW) % gridW;
196  }
197 
198  new_grid2clusters = grid2clusters;
199  new_cluster2XY = cluster2XY;
200 
201  std::vector<int> clustersMixed;
202  clustersMixed.clear();
203  for (auto id : grid2clusters[gridY0][gridX0])
204  clustersMixed.push_back(id);
205  for (auto id : grid2clusters[gridY1][gridX1])
206  clustersMixed.push_back(id);
207 
208  // std::random_shuffle(clustersMixed.begin(), clustersMixed.end(), myrandom);
209  for (unsigned int i = 0; i < clustersMixed.size(); i++)
210  {
211  for (unsigned int j = i + 1; j < clustersMixed.size(); j++)
212  {
213  if (rng() % 2)
214  {
215  int tmp = clustersMixed[i];
216  clustersMixed[i] = clustersMixed[j];
217  clustersMixed[j] = tmp;
218  }
219  }
220  }
221 
222  while (true)
223  {
224  new_grid2clusters[gridY0][gridX0].clear();
225  new_grid2clusters[gridY1][gridX1].clear();
226  for (auto id : clustersMixed)
227  {
228  if (rng() % 2)
229  {
230  new_grid2clusters[gridY1][gridX1].push_back(id);
231  new_cluster2XY[id] = std::pair<int, int>(gridX1, gridY1);
232  }
233  else
234  {
235  new_grid2clusters[gridY0][gridX0].push_back(id);
236  new_cluster2XY[id] = std::pair<int, int>(gridX0, gridY0);
237  }
238  }
239  std::sort(new_grid2clusters[gridY0][gridX0].begin(), new_grid2clusters[gridY0][gridX0].end());
240  std::sort(new_grid2clusters[gridY1][gridX1].begin(), new_grid2clusters[gridY1][gridX1].end());
241  if (new_grid2clusters[gridY0][gridX0].size() != grid2clusters[gridY0][gridX0].size())
242  {
243  break;
244  }
245  else
246  {
247  bool changed = false;
248  for (unsigned int i = 0; i < grid2clusters[gridY0][gridX0].size(); i++)
249  {
250  if (grid2clusters[gridY0][gridX0][i] != new_grid2clusters[gridY0][gridX0][i])
251  {
252  changed = true;
253  break;
254  }
255  }
256  if (changed)
257  break;
258  }
259  }
260 
261  // if (randGen() % 5 == 0) // shuffle multiple cluster?
262  // {
263  // if (randGen() % 2) // shuffle row
264  // {
265  // int rowId = randGen() % gridH;
266  // int colA = randGen() % gridW;
267  // int colB = randGen() % gridW;
268  // swapVectors(new_grid2clusters[rowId][colA], new_grid2clusters[rowId][colB]);
269  // }
270  // else
271  // {
272  // int columnId = randGen() % gridW;
273  // int rowA = randGen() % gridH;
274  // int rowB = randGen() % gridH;
275  // swapVectors(new_grid2clusters[rowA][columnId], new_grid2clusters[rowB][columnId]);
276  // }
277  // for (int gridY = 0; gridY < gridH; gridY++)
278  // for (int gridX = 0; gridX < gridW; gridX++)
279  // for (auto clusterId : new_grid2clusters[gridY][gridX])
280  // {
281  // new_cluster2XY[clusterId] = std::pair<int, int>(gridX, gridY);
282  // }
283  // }
284  // else
285  if (rng() % 20 == 0 && temperature > 0.5) // shuffle multiple cluster?
286  {
287  if (rng() % 2) // shuffle row
288  {
289  int rowId = rng() % gridH;
290  shuffleVectors(new_grid2clusters[rowId], rng);
291  }
292  else
293  {
294  int columnId = rng() % gridW;
295  std::vector<std::vector<int>> tmpVec(gridH);
296  for (int tmpI = 0; tmpI < gridH; tmpI++)
297  tmpVec[tmpI] = new_grid2clusters[tmpI][columnId];
298  shuffleVectors(tmpVec, rng);
299  for (int tmpI = 0; tmpI < gridH; tmpI++)
300  new_grid2clusters[tmpI][columnId] = tmpVec[tmpI];
301  }
302  for (int gridY = 0; gridY < gridH; gridY++)
303  for (int gridX = 0; gridX < gridW; gridX++)
304  for (auto clusterId : new_grid2clusters[gridY][gridX])
305  {
306  new_cluster2XY[clusterId] = std::pair<int, int>(gridX, gridY);
307  }
308  }
309 
310  return;
311 }
312 
313 void SAPlacer::randomSwapInWideRangeWithNeighbors(const std::vector<std::vector<std::vector<int>>> &grid2clusters,
314  std::vector<std::vector<std::vector<int>>> &new_grid2clusters,
315  const std::vector<std::pair<int, int>> &cluster2XY,
316  std::vector<std::pair<int, int>> &new_cluster2XY, float temperature,
317  boost::mt19937 &rng)
318 {
319  int gridY0 = rng() % (gridH * gridW) / gridW;
320  int gridX0 = rng() % (gridH * gridW) % gridW;
321 
322  int gridY1 = -1;
323  int gridX1 = -1;
324 
325  while (grid2clusters[gridY0][gridX0].size() == 0)
326  {
327  gridY0 = rng() % (gridH * gridW) / gridW;
328  gridX0 = rng() % (gridH * gridW) % gridW;
329  }
330 
331  while ((gridX1 == gridX0 && gridY1 == gridY0) || gridY1 < 0 || gridY1 >= gridH || gridX1 < 0 || gridX1 >= gridW)
332  {
333  gridY1 = (1 - (rng() % 3)) + gridY0;
334  gridX1 = (1 - (rng() % 3)) + gridX0;
335  }
336 
337  new_grid2clusters = grid2clusters;
338  new_cluster2XY = cluster2XY;
339 
340  std::vector<int> clustersMixed;
341  clustersMixed.clear();
342  for (auto id : grid2clusters[gridY0][gridX0])
343  clustersMixed.push_back(id);
344  for (auto id : grid2clusters[gridY1][gridX1])
345  clustersMixed.push_back(id);
346 
347  // std::random_shuffle(clustersMixed.begin(), clustersMixed.end(), myrandom);
348  for (unsigned int i = 0; i < clustersMixed.size(); i++)
349  {
350  for (unsigned int j = i + 1; j < clustersMixed.size(); j++)
351  {
352  if (rng() % 2)
353  {
354  int tmp = clustersMixed[i];
355  clustersMixed[i] = clustersMixed[j];
356  clustersMixed[j] = tmp;
357  }
358  }
359  }
360 
361  while (true)
362  {
363  new_grid2clusters[gridY0][gridX0].clear();
364  new_grid2clusters[gridY1][gridX1].clear();
365  for (auto id : clustersMixed)
366  {
367  if (rng() % 2)
368  {
369  new_grid2clusters[gridY1][gridX1].push_back(id);
370  new_cluster2XY[id] = std::pair<int, int>(gridX1, gridY1);
371  }
372  else
373  {
374  new_grid2clusters[gridY0][gridX0].push_back(id);
375  new_cluster2XY[id] = std::pair<int, int>(gridX0, gridY0);
376  }
377  }
378  std::sort(new_grid2clusters[gridY0][gridX0].begin(), new_grid2clusters[gridY0][gridX0].end());
379  std::sort(new_grid2clusters[gridY1][gridX1].begin(), new_grid2clusters[gridY1][gridX1].end());
380  if (new_grid2clusters[gridY0][gridX0].size() != grid2clusters[gridY0][gridX0].size())
381  {
382  break;
383  }
384  else
385  {
386  bool changed = false;
387  for (unsigned int i = 0; i < grid2clusters[gridY0][gridX0].size(); i++)
388  {
389  if (grid2clusters[gridY0][gridX0][i] != new_grid2clusters[gridY0][gridX0][i])
390  {
391  changed = true;
392  break;
393  }
394  }
395  if (changed)
396  break;
397  }
398  }
399  return;
400 }
401 
402 void SAPlacer::randomShuffleRowColumn(const std::vector<std::vector<std::vector<int>>> &grid2clusters,
403  std::vector<std::vector<std::vector<int>>> &new_grid2clusters,
404  const std::vector<std::pair<int, int>> &cluster2XY,
405  std::vector<std::pair<int, int>> &new_cluster2XY, boost::mt19937 &rng)
406 {
407  new_grid2clusters = grid2clusters;
408  new_cluster2XY = cluster2XY;
409 
410  if (rng() % 2) // shuffle row
411  {
412  int rowId = rng() % gridH;
413  shuffleVectors(new_grid2clusters[rowId], rng);
414  }
415  else
416  {
417  int columnId = rng() % gridW;
418  std::vector<std::vector<int>> tmpVec(gridH);
419  for (int tmpI = 0; tmpI < gridH; tmpI++)
420  tmpVec[tmpI] = new_grid2clusters[tmpI][columnId];
421  shuffleVectors(tmpVec, rng);
422  for (int tmpI = 0; tmpI < gridH; tmpI++)
423  new_grid2clusters[tmpI][columnId] = tmpVec[tmpI];
424  }
425  for (int gridY = 0; gridY < gridH; gridY++)
426  for (int gridX = 0; gridX < gridW; gridX++)
427  for (auto clusterId : new_grid2clusters[gridY][gridX])
428  {
429  new_cluster2XY[clusterId] = std::pair<int, int>(gridX, gridY);
430  }
431 
432  return;
433 }
434 
435 float SAPlacer::probabilituFunc(double oriE, double newE, float T)
436 {
437  if (newE < oriE)
438  return 1.0;
439  return exp(-10 * (newE / SACalibrationOffset - oriE / SACalibrationOffset) / T);
440 }
441 
442 void SAPlacer::worker(SAPlacer *saPlacer, std::vector<std::vector<std::vector<int>>> &init_grid2clusters,
443  std::vector<std::pair<int, int>> &init_cluster2XY,
444  std::vector<std::vector<std::vector<int>>> &opt_grid2clusters,
445  std::vector<std::pair<int, int>> &opt_cluster2XY, int &totalIterNum, int &workers_randomSeed,
446  double &resE)
447 {
448  std::vector<std::pair<int, int>> cur_cluster2XY = init_cluster2XY;
449  std::vector<std::vector<std::vector<int>>> cur_grid2clusters = init_grid2clusters;
450  std::vector<std::pair<int, int>> new_cluster2XY;
451  std::vector<std::vector<std::vector<int>>> new_grid2clusters;
452 
453  boost::mt19937 rng(workers_randomSeed);
454 
455  double oriE = saPlacer->evaluateClusterPlacement(init_grid2clusters, init_cluster2XY);
456  resE = oriE;
457  // double inputE = oriE;
458 
459  int SAIterNum = (totalIterNum - 1);
460  for (int k = SAIterNum; k >= 0; k--)
461  {
462 
463  float temperature = (float)(k + 1) / SAIterNum;
464  new_cluster2XY.clear();
465  new_grid2clusters.clear();
466 
467  if (k > SAIterNum)
468  saPlacer->randomShuffleRowColumn(cur_grid2clusters, new_grid2clusters, cur_cluster2XY, new_cluster2XY, rng);
469  else
470  saPlacer->randomSwapInWideRange(cur_grid2clusters, new_grid2clusters, cur_cluster2XY, new_cluster2XY,
471  temperature, rng);
472  double newE = saPlacer->evaluateClusterPlacement(new_grid2clusters, new_cluster2XY);
473 
474  float thr = (float)rng() / (float)rng.max();
475  float P = saPlacer->probabilituFunc(oriE, newE, temperature);
476  if (P >= thr || k > SAIterNum)
477  {
478  oriE = newE;
479  cur_grid2clusters = new_grid2clusters;
480  cur_cluster2XY = new_cluster2XY;
481  }
482 
483  if (resE > newE)
484  {
485  resE = newE;
486  opt_grid2clusters = new_grid2clusters;
487  opt_cluster2XY = new_cluster2XY;
488  }
489  }
490 
491  // assert(inputE > resE);
492 }
493 
494 void SAPlacer::greedyPlaceACluster(const std::vector<std::pair<int, int>> &init_cluster2XY,
495  const std::vector<std::vector<std::vector<int>>> &init_grid2clusters,
496  std::vector<std::pair<int, int>> &res_cluster2XY,
497  std::vector<std::vector<std::vector<int>>> &res_grid2clusters, int clusterIdToPlace)
498 {
499  std::vector<bool> placed;
500  placed.clear();
501 
502  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
503  {
504  placed.push_back(init_cluster2XY[clusterA].first >= 0 && init_cluster2XY[clusterA].second >= 0);
505  }
506 
507  int highConnectCluster = -1;
508  float connectRatio = 0;
509 
510  for (unsigned int clusterB = 0; clusterB < clusterAdjMat.size(); clusterB++)
511  {
512  if (!placed[clusterB])
513  {
514  if (clusterAdjMat[clusterIdToPlace][clusterB] > 0.00001)
515  {
516  if (clusterAdjMat[clusterIdToPlace][clusterB] > connectRatio)
517  {
518  connectRatio = clusterAdjMat[clusterIdToPlace][clusterB];
519  highConnectCluster = clusterB;
520  }
521  }
522  }
523  }
524 
525  if (highConnectCluster < 0)
526  {
527  int gridY0 = random() % (gridH * gridW) / gridW;
528  int gridX0 = random() % (gridH * gridW) % gridW;
529  res_cluster2XY[clusterIdToPlace].first = gridX0;
530  res_cluster2XY[clusterIdToPlace].second = gridY0;
531  res_grid2clusters[gridY0][gridX0].push_back(clusterIdToPlace);
532  }
533  else
534  {
535 
536  double res = 10e+10;
537  for (int gridY = 0; gridY < gridH; gridY++)
538  for (int gridX = 0; gridX < gridW; gridX++)
539  {
540  std::vector<std::pair<int, int>> new_cluster2XY;
541  std::vector<std::vector<std::vector<int>>> new_grid2clusters;
542  new_cluster2XY = init_cluster2XY;
543  new_grid2clusters = init_grid2clusters;
544  new_cluster2XY[clusterIdToPlace].first = gridX;
545  new_cluster2XY[clusterIdToPlace].second = gridY;
546  new_grid2clusters[gridY][gridX].push_back(clusterIdToPlace);
547  double tmpRes = incrementalEvaluateClusterPlacement(new_grid2clusters, new_cluster2XY);
548  if (tmpRes < res)
549  {
550  res = tmpRes;
551  res_cluster2XY = new_cluster2XY;
552  res_grid2clusters = new_grid2clusters;
553  }
554  }
555  }
556 }
557 
558 int SAPlacer::greedyFindNextClusterToPlace(std::vector<std::pair<int, int>> &tmp_cluster2XY,
559  std::vector<std::vector<std::vector<int>>> &tmp_grid2clusters)
560 {
561  std::vector<bool> placed;
562  std::vector<int> unplacedClusterIds;
563  unplacedClusterIds.clear();
564  placed.clear();
565 
566  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
567  {
568  placed.push_back(tmp_cluster2XY[clusterA].first >= 0 && tmp_cluster2XY[clusterA].second >= 0);
569  if (!(tmp_cluster2XY[clusterA].first >= 0 && tmp_cluster2XY[clusterA].second >= 0))
570  {
571  unplacedClusterIds.push_back(clusterA);
572  }
573  }
574 
575  int highConnectCluster = -1;
576  float connectRatio = 0;
577  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
578  {
579  if (placed[clusterA])
580  {
581  for (unsigned int clusterB = 0; clusterB < clusterAdjMat.size(); clusterB++)
582  {
583  if (!placed[clusterB])
584  {
585  if (clusterAdjMat[clusterA][clusterB] > 0.00001)
586  {
587  if (clusterAdjMat[clusterA][clusterB] > connectRatio)
588  {
589  connectRatio = clusterAdjMat[clusterA][clusterB];
590  highConnectCluster = clusterB;
591  }
592  }
593  }
594  }
595  }
596  }
597 
598  if (highConnectCluster < 0)
599  {
600  assert(unplacedClusterIds.size());
601  return unplacedClusterIds[random() % unplacedClusterIds.size()];
602  }
603  else
604  {
605  return highConnectCluster;
606  }
607 }
608 
609 void SAPlacer::greedyInitialize(std::vector<std::pair<int, int>> &init_cluster2XY,
610  std::vector<std::vector<std::vector<int>>> &init_grid2clusters, int initOffset)
611 {
612  for (unsigned int clusterId = 0; clusterId < clusterAdjMat.size(); clusterId++)
613  {
614  init_cluster2XY.push_back(std::pair<int, int>(-1, -1));
615  }
616 
617  int iterNum = clusterAdjMat.size();
618 
619  while (iterNum == clusterAdjMat.size())
620  {
621  for (int i = 0; i < clusterAdjMat.size(); i++)
622  {
623  bool placed = false;
624  for (unsigned int fixedUnitId = 0; fixedUnitId < cluster2FixedUnitMat[i].size(); fixedUnitId++)
625  {
626  if (cluster2FixedUnitMat[i][fixedUnitId])
627  {
628  if (random() % 2 == 0)
629  {
630  std::vector<std::pair<int, int>> new_cluster2XY;
631  std::vector<std::vector<std::vector<int>>> new_grid2clusters;
632  new_cluster2XY = init_cluster2XY;
633  new_grid2clusters = init_grid2clusters;
634 
635  greedyPlaceACluster(init_cluster2XY, init_grid2clusters, new_cluster2XY, new_grid2clusters, i);
636  iterNum--;
637  init_cluster2XY = new_cluster2XY;
638  init_grid2clusters = new_grid2clusters;
639  placed = true;
640  }
641  break;
642  }
643  }
644  // if (!placed)
645  // {
646  // if (random() % 10 == 0)
647  // {
648  // std::vector<std::pair<int, int>> new_cluster2XY;
649  // std::vector<std::vector<std::vector<int>>> new_grid2clusters;
650  // new_cluster2XY = init_cluster2XY;
651  // new_grid2clusters = init_grid2clusters;
652 
653  // greedyPlaceACluster(init_cluster2XY, init_grid2clusters, new_cluster2XY, new_grid2clusters, i);
654  // iterNum--;
655  // init_cluster2XY = new_cluster2XY;
656  // init_grid2clusters = new_grid2clusters;
657  // placed = true;
658  // }
659  // }
660  }
661  }
662 
663  while (iterNum--)
664  {
665  int nextClusterId = greedyFindNextClusterToPlace(init_cluster2XY, init_grid2clusters);
666  std::vector<std::pair<int, int>> new_cluster2XY;
667  std::vector<std::vector<std::vector<int>>> new_grid2clusters;
668  new_cluster2XY = init_cluster2XY;
669  new_grid2clusters = init_grid2clusters;
670 
671  greedyPlaceACluster(init_cluster2XY, init_grid2clusters, new_cluster2XY, new_grid2clusters, nextClusterId);
672 
673  init_cluster2XY = new_cluster2XY;
674  init_grid2clusters = new_grid2clusters;
675  }
676 }
677 
679 {
680  resE = 1e13;
681  std::string dumpSAFile = "";
682  if (verbose)
683  dumpSAFile = placerName + "DumpFile";
684 
685  std::ofstream outfile0;
686  // bool dump = false;
687  // if (dumpSAFile != "")
688  // {
689  // dump = true;
690  // outfile0 = std::ofstream(dumpSAFile.c_str());
691  // }
692 
693  std::vector<std::pair<int, int>> init_cluster2XY;
694  std::vector<std::vector<std::vector<int>>> init_grid2clusters;
695 
696  std::vector<std::thread> threads;
697  std::vector<std::vector<std::pair<int, int>>> workers_cluster2XY;
698  std::vector<std::vector<std::vector<std::vector<int>>>> workers_grid2clusters;
699  std::vector<double> works_E;
700  std::vector<int> workers_randomSeed;
701 
702  // assign each restarted task to a thread
703  int workerIterNum = Kmax / restartNum;
704  std::vector<std::pair<int, double>> seedAndE;
705  seedAndE.clear();
706 
707  int initOffset = 0;
708  for (int restartI = restartNum; restartI > 0; restartI -= nJobs)
709  {
710 
711  printProgress(1 - ((double)restartI / restartNum));
712 
713  threads.clear();
714  workers_cluster2XY.clear();
715  workers_grid2clusters.clear();
716  works_E.clear();
717  workers_randomSeed.clear();
718 
719  for (int threadId = restartI; threadId >= 0 && threadId > restartI - nJobs; threadId--)
720  {
721 
722  // generate initial cluster placement
723  init_cluster2XY.clear();
724  init_grid2clusters = std::vector<std::vector<std::vector<int>>>(
725  gridH, std::vector<std::vector<int>>(gridW, std::vector<int>()));
726 
727  initOffset++;
728  greedyInitialize(init_cluster2XY, init_grid2clusters, initOffset / 8);
729 
730  for (unsigned int clusterA = 0; clusterA < clusterAdjMat.size(); clusterA++)
731  {
732  assert(init_cluster2XY[clusterA].first >= 0 && init_cluster2XY[clusterA].second >= 0);
733  }
734  for (int gridY = 0; gridY < gridH; gridY++)
735  {
736  for (int gridX = 0; gridX < gridW; gridX++)
737  {
738  std::sort(init_grid2clusters[gridY][gridX].begin(), init_grid2clusters[gridY][gridX].end());
739  }
740  }
741  SACalibrationOffset = evaluateClusterPlacement(init_grid2clusters, init_cluster2XY);
742 
743  workers_cluster2XY.push_back(init_cluster2XY);
744  workers_grid2clusters.push_back(init_grid2clusters);
745  works_E.push_back(0);
746  workers_randomSeed.push_back(threadId);
747  }
748  for (unsigned int threadId = 0; threadId < workers_cluster2XY.size(); threadId++)
749  {
750  threads.push_back(std::thread(worker, this, std::ref(init_grid2clusters), std::ref(init_cluster2XY),
751  std::ref(workers_grid2clusters[threadId]),
752  std::ref(workers_cluster2XY[threadId]), std::ref(workerIterNum),
753  std::ref(workers_randomSeed[threadId]), std::ref(works_E[threadId])));
754  }
755  for (unsigned int threadId = 0; threadId < threads.size(); threadId++)
756  {
757  threads[threadId].join();
758  seedAndE.emplace_back(workers_randomSeed[threadId], works_E[threadId]);
759  }
760 
761  if (works_E[0] < resE)
762  {
763  resE = works_E[0];
764  res_grid2clusters = workers_grid2clusters[0];
765  res_cluster2XY = workers_cluster2XY[0];
766  }
767 
768  for (unsigned int threadId = 1; threadId < threads.size(); threadId++)
769  {
770  if (works_E[threadId] < resE)
771  {
772  resE = works_E[threadId];
773  res_grid2clusters = workers_grid2clusters[threadId];
774  res_cluster2XY = workers_cluster2XY[threadId];
775  }
776  }
777  }
778  printf("\n");
779  print_info("SA optimization ratio (finalE/initE) = " + std::to_string(resE / SACalibrationOffset));
780  print_info("SA optimization initE = " + std::to_string(SACalibrationOffset));
781  for (int restartI = restartNum - 1; restartI >= 0; restartI--)
782  {
783  std::cout << " " << seedAndE[restartI].first << "(" << seedAndE[restartI].second << ")";
784  if (restartI % 10 == 0)
785  std::cout << "\n";
786  }
787  std::cout << "\n";
788  int occupiedRegionNum = 0;
789  for (int gridY = 0; gridY < gridH; gridY++)
790  for (int gridX = 0; gridX < gridW; gridX++)
791  {
792  if (res_grid2clusters[gridY][gridX].size() > 0)
793  {
794  occupiedRegionNum++;
795  }
796  }
797  print_info("SA final occupied region num = " + std::to_string(occupiedRegionNum));
798 
799  if (dumpSAFile != "")
800  outfile0.close();
801  print_info("SAPlace handle " + std::to_string(init_cluster2XY.size()) +
802  " cluster(s) and the final placement cost is " + std::to_string(resE));
803 }
SAPlacer::placerName
std::string placerName
Definition: SAPlacer.h:76
SAPlacer::randomSwapInWideRangeWithNeighbors
void randomSwapInWideRangeWithNeighbors(const std::vector< std::vector< std::vector< int >>> &grid2clusters, std::vector< std::vector< std::vector< int >>> &new_Grid2clusters, const std::vector< std::pair< int, int >> &cluster2XY, std::vector< std::pair< int, int >> &new_cluster2XY, float temperature, boost::mt19937 &rng)
Definition: SAPlacer.cc:313
SAPlacer::deviceH
float deviceH
Definition: SAPlacer.h:87
SAPlacer::gridH
int gridH
Definition: SAPlacer.h:85
SAPlacer::clusterWeights
std::vector< float > & clusterWeights
Definition: SAPlacer.h:79
SAPlacer::deviceW
float deviceW
Definition: SAPlacer.h:88
SAPlacer::res_grid2clusters
std::vector< std::vector< std::vector< int > > > res_grid2clusters
Definition: SAPlacer.h:98
SAPlacer::clusterAdjMat
std::vector< std::vector< float > > & clusterAdjMat
Definition: SAPlacer.h:78
swapVectors
void swapVectors(std::vector< int > &a, std::vector< int > &b)
Definition: SAPlacer.cc:158
shuffleVectors
void shuffleVectors(std::vector< std::vector< int >> &a, boost::mt19937 &rng)
Definition: SAPlacer.cc:165
SAPlacer.h
SAPlacer::gridW
int gridW
Definition: SAPlacer.h:86
SAPlacer::randomSwapInWideRange
void randomSwapInWideRange(const std::vector< std::vector< std::vector< int >>> &grid2clusters, std::vector< std::vector< std::vector< int >>> &new_Grid2clusters, const std::vector< std::pair< int, int >> &cluster2XY, std::vector< std::pair< int, int >> &new_cluster2XY, float temperature, boost::mt19937 &rng)
Definition: SAPlacer.cc:176
SAPlacer::SACalibrationOffset
double SACalibrationOffset
Definition: SAPlacer.h:101
SAPlacer::connectionToFixedFactor
float connectionToFixedFactor
Definition: SAPlacer.h:90
DSE.end
end
Definition: DSE.py:18
SAPlacer::randomShuffleRowColumn
void randomShuffleRowColumn(const std::vector< std::vector< std::vector< int >>> &grid2clusters, std::vector< std::vector< std::vector< int >>> &new_grid2clusters, const std::vector< std::pair< int, int >> &cluster2XY, std::vector< std::pair< int, int >> &new_cluster2XY, boost::mt19937 &rng)
Definition: SAPlacer.cc:402
delayVisualization.c
c
Definition: delayVisualization.py:99
SAPlacer::evaluateClusterPlacement
double evaluateClusterPlacement(const std::vector< std::vector< std::vector< int >>> &grid2clusters, const std::vector< std::pair< int, int >> &cluster2XY)
Definition: SAPlacer.cc:32
SAPlacer::worker
static void worker(SAPlacer *saPlacer, std::vector< std::vector< std::vector< int >>> &init_grid2clusters, std::vector< std::pair< int, int >> &init_cluster2XY, std::vector< std::vector< std::vector< int >>> &opt_grid2clusters, std::vector< std::pair< int, int >> &opt_cluster2XY, int &totalIterNum, int &workers_randomSeed, double &resE)
Definition: SAPlacer.cc:442
SAPlacer::incrementalEvaluateClusterPlacement
double incrementalEvaluateClusterPlacement(const std::vector< std::vector< std::vector< int >>> &grid2clusters, const std::vector< std::pair< int, int >> &cluster2XY)
Definition: SAPlacer.cc:89
SAPlacer::cluster2FixedUnitMat
std::vector< std::vector< float > > & cluster2FixedUnitMat
Definition: SAPlacer.h:81
SAPlacer::solve
void solve()
Definition: SAPlacer.cc:678
SAPlacer
Definition: SAPlacer.h:41
printProgress
void printProgress(double percentage)
Definition: strPrint.cc:70
SAPlacer::probabilituFunc
float probabilituFunc(double oriE, double newE, float T)
Definition: SAPlacer.cc:435
SAPlacer::restartNum
int restartNum
Definition: SAPlacer.h:94
SAPlacer::nJobs
int nJobs
Definition: SAPlacer.h:93
SAPlacer::res_cluster2XY
std::vector< std::pair< int, int > > res_cluster2XY
Definition: SAPlacer.h:97
SAPlacer::fixedY
std::vector< float > & fixedY
Definition: SAPlacer.h:83
SAPlacer::fixedX
std::vector< float > & fixedX
Definition: SAPlacer.h:82
SAPlacer::greedyFindNextClusterToPlace
int greedyFindNextClusterToPlace(std::vector< std::pair< int, int >> &tmp_cluster2XY, std::vector< std::vector< std::vector< int >>> &tmp_grid2clusters)
Definition: SAPlacer.cc:558
SAPlacer::resE
double resE
Definition: SAPlacer.h:99
SAPlacer::y2xRatio
float y2xRatio
Definition: SAPlacer.h:91
print_info
void print_info(std::string tmp_string)
Definition: strPrint.cc:39
SAPlacer::greedyInitialize
void greedyInitialize(std::vector< std::pair< int, int >> &init_cluster2XY, std::vector< std::vector< std::vector< int >>> &init_grid2clusters, int initOffset)
Definition: SAPlacer.cc:609
checkHalfColumn.i
int i
Definition: checkHalfColumn.py:5
SAPlacer::verbose
bool verbose
Definition: SAPlacer.h:95
SAPlacer::Kmax
int Kmax
Definition: SAPlacer.h:92
SAPlacer::greedyPlaceACluster
void greedyPlaceACluster(const std::vector< std::pair< int, int >> &init_cluster2XY, const std::vector< std::vector< std::vector< int >>> &init_grid2clusters, std::vector< std::pair< int, int >> &new_cluster2XY, std::vector< std::vector< std::vector< int >>> &new_grid2clusters, int clusterIdToPlace)
Definition: SAPlacer.cc:494