259#if defined(NO_HMETIS)
260 printf(
"QPAR_02 : \t\tERROR: hMetis not available. Ignoring.\n");
265 int *edgeConnections = NULL;
269 int numConnections = 0;
281 printf(
"QPAR-02 : \t\trepartitioning with hMetis\n");
288 edgeDegree[++numEdges] = numConnections;
291 if (parent->m_vertical) {
293 initial_cut = parent->m_sub2->m_bounds.x;
298 partitionAssignment[c] = 0;
300 partitionAssignment[c] = 1;
304 for(t=0; t<parent->m_sub1->m_numMembers; t++)
if (parent->m_sub1->m_members[t]) {
305 cell = parent->m_sub1->m_members[t];
310 partitionAssignment[
cell->
m_id] = -1;
315 for(t=0; t<parent->m_sub2->m_numMembers; t++)
if (parent->m_sub2->m_members[t]) {
316 cell = parent->m_sub2->m_members[t];
321 partitionAssignment[
cell->
m_id] = -1;
327 initial_cut = parent->m_sub2->m_bounds.y;
332 partitionAssignment[c] = 0;
334 partitionAssignment[c] = 1;
338 for(t=0; t<parent->m_sub1->m_numMembers; t++)
if (parent->m_sub1->m_members[t]) {
339 cell = parent->m_sub1->m_members[t];
344 partitionAssignment[
cell->
m_id] = -1;
349 for(t=0; t<parent->m_sub2->m_numMembers; t++)
if (parent->m_sub2->m_members[t]) {
350 cell = parent->m_sub2->m_members[t];
355 partitionAssignment[
cell->
m_id] = -1;
367 options[7] = 12261980;
370 edgeConnections = (
int *)
malloc(
sizeof(
int)*numConnections);
380 edgeDegree, edgeConnections, NULL,
382 options, partitionAssignment, &afterCuts);
390 parent->m_sub1->m_numMembers = 0;
391 parent->m_sub1->m_area = 0;
392 parent->m_sub2->m_numMembers = 0;
393 parent->m_sub2->m_area = 0;
399 for(t=0; t<parent->m_numMembers; t++)
if (parent->m_members[t]) {
400 cell = parent->m_members[t];
402 if (partitionAssignment[
cell->
m_id] == 0) {
403 parent->m_sub1->m_members[parent->m_sub1->m_numMembers++] =
cell;
404 parent->m_sub1->m_area += area;
407 parent->m_sub2->m_members[parent->m_sub2->m_numMembers++] =
cell;
408 parent->m_sub2->m_area += area;
419 free(edgeConnections);
422 free(partitionAssignment);
437 assert(!parent->leaf && parent->m_sub1->leaf && parent->m_sub2->leaf);
440 int count_1[m_design->nets.length()];
441 memset(count_1, 0,
sizeof(
int)*m_design->nets.length());
442 int count_2[m_design->nets.length()];
443 memset(count_2, 0,
sizeof(
int)*m_design->nets.length());
445 FM_cell target[m_design->cells.length()];
452 int before_cuts = 0, current_cuts = 0;
456 double halfArea = parent->m_area / 2.0;
463 if (parent->vertical) {
466 initial_cut = parent->m_sub2->m_bounds.x;
469 for(h::list<ConcreteCell *>::iterator it = rootPartition->m_members.begin(); !it; it++) {
470 cell_id = (*it)->getID();
471 if ((*it)->temp_x < initial_cut)
472 target[cell_id].
loc = -1;
474 target[cell_id].
loc = -2;
475 target[cell_id].
cell = *it;
476 target[cell_id].
gain = 0;
480 for(h::list<ConcreteCell *>::iterator it = parent->m_sub1->m_members.begin(); !it; it++) {
481 cell_id = (*it)->getID();
485 target[cell_id].
loc = 1;
490 for(h::list<ConcreteCell *>::iterator it = parent->m_sub2->m_members.begin(); !it; it++) {
491 cell_id = (*it)->getID();
495 target[cell_id].
loc = 2;
500 for(h::hash_map<ConcreteNet *>::iterator n_it = m_design->nets.begin(); !n_it; n_it++) {
501 for(ConcretePinList::iterator p_it = (net = *n_it)->getPins().begin(); !p_it; p_it++)
502 if (abs(target[(*p_it)->getCell()->getID()].
loc) == 1)
503 count_1[net->getID()]++;
504 else if (abs(target[(*p_it)->getCell()->getID()].
loc) == 2)
505 count_2[net->getID()]++;
506 else if ((*p_it)->getCell()->temp_x < initial_cut)
507 count_1[net->getID()]++;
509 count_2[net->getID()]++;
510 if (count_1[net->getID()] > 0 && count_2[net->getID()] > 0) before_cuts++;
516 initial_cut = parent->m_sub2->m_bounds.y;
519 for(h::list<ConcreteCell *>::iterator it = rootPartition->m_members.begin(); !it; it++) {
520 cell_id = (*it)->getID();
521 if ((*it)->temp_y < initial_cut)
522 target[cell_id].
loc = -1;
524 target[cell_id].
loc = -2;
525 target[cell_id].
cell = *it;
526 target[cell_id].
gain = 0;
530 for(h::list<ConcreteCell *>::iterator it = parent->m_sub1->m_members.begin(); !it; it++) {
531 cell_id = (*it)->getID();
535 target[cell_id].
loc = 1;
540 for(h::list<ConcreteCell *>::iterator it = parent->m_sub2->m_members.begin(); !it; it++) {
541 cell_id = (*it)->getID();
545 target[cell_id].
loc = 2;
550 for(h::hash_map<ConcreteNet *>::iterator n_it = m_design->nets.begin(); !n_it; n_it++) {
551 for(ConcretePinList::iterator p_it = (net = *n_it)->getPins().begin(); !p_it; p_it++)
552 if (abs(target[(*p_it)->getCell()->getID()].
loc) == 1)
553 count_1[net->getID()]++;
554 else if (abs(target[(*p_it)->getCell()->getID()].
loc) == 2)
555 count_2[net->getID()]++;
556 else if ((*p_it)->getCell()->temp_y < initial_cut)
557 count_1[net->getID()]++;
559 count_2[net->getID()]++;
560 if (count_1[net->getID()] > 0 && count_2[net->getID()] > 0) before_cuts++;
565 for(
long id=0;
id < m_design->cells.length();
id++)
566 if (target[
id].
loc > 0) {
571 for(ConcretePinMap::iterator p_it = target[
id].
cell->getPins().begin(); !p_it; p_it++)
572 if ((*p_it)->isAttached()) {
573 int n_id = (*p_it)->getNet()->getID();
574 if (target[
id].
loc == 1 && count_1[n_id] == 1) target[id].
gain++;
575 if (target[
id].
loc == 1 && count_2[n_id] == 0) target[id].
gain--;
576 if (target[
id].
loc == 2 && count_1[n_id] == 0) target[id].
gain--;
577 if (target[
id].
loc == 2 && count_2[n_id] == 1) target[id].
gain++;
580 assert(target[
id].
cell->getPins().length() >= abs(target[
id].
gain));
584 max_gain = max(max_gain, bin_num);
587 target[id].
next = bin[bin_num];
589 if (bin[bin_num] != 0)
590 bin[bin_num]->
prev = &target[id];
591 bin[bin_num] = &target[id];
595 current_cuts = before_cuts;
611 max_gain = max(max_gain, bin_num);
617 if (bin[bin_num] != 0)
618 bin[bin_num]->
prev = current;
619 current->
next = bin[bin_num];
620 bin[bin_num] = current;
628 while(bin[max_gain] == 0 && max_gain > 0) max_gain--;
634 FM_cell *current = bin[bin_num];
637 while (bin_num > 0 && (current == 0 ||
638 (current->
loc==1 && current->
cell->getArea()+parent->m_sub2->m_area > halfArea+areaFlexibility) ||
639 (current->
loc==2 && current->
cell->getArea()+parent->m_sub1->m_area > halfArea+areaFlexibility))) {
641 if (current == 0) current = bin[--bin_num];
else current = current->
next;
651 if (current->
loc == 1) {
653 parent->m_sub1->m_area -= current->
cell->getArea();
654 parent->m_sub2->m_area += current->
cell->getArea();
657 for(ConcretePinMap::iterator p_it = current->
cell->getPins().begin();
660 if (!(*p_it)->isAttached())
662 net = (*p_it)->getNet();
664 count_1[net->getID()]--;
665 count_2[net->getID()]++;
670 if (count_1[net->getID()] == 0) { current_cuts--;
FM_updateGains(net, 2, -1, target, bin, count_1, count_2); }
671 if (count_2[net->getID()] == 1) { current_cuts++;
FM_updateGains(net, 1, -1, target, bin, count_1, count_2); }
678 parent->m_sub2->m_area -= current->
cell->getArea();
679 parent->m_sub1->m_area += current->
cell->getArea();
682 for(ConcretePinMap::iterator p_it = current->
cell->getPins().begin();
685 if (!(*p_it)->isAttached())
687 net = (*p_it)->getNet();
688 count_2[net->getID()]--;
689 count_1[net->getID()]++;
693 if (count_2[net->getID()] == 0) { current_cuts--;
FM_updateGains(net, 2, -1, target, bin, count_1, count_2); }
694 if (count_1[net->getID()] == 1) { current_cuts++;
FM_updateGains(net, 1, -1, target, bin, count_1, count_2); }
718 if (bin[bin_num] == current)
719 bin[bin_num] = current->
next;
720 if (current->
prev != 0)
722 if (current->
next != 0)
749 while(bin[max_gain] == 0 && max_gain > 0) max_gain--;
756 cout <<
"FIDM-20 : \tbalance before " << parent->m_sub1->m_members.length() <<
"/"
757 << parent->m_sub2->m_members.length() <<
" ";
758 parent->m_sub1->m_members.clear();
759 parent->m_sub1->m_area = 0;
760 parent->m_sub2->m_members.clear();
761 parent->m_sub2->m_area = 0;
762 for(h::list<ConcreteCell *>::iterator it = parent->m_members.begin(); !it; it++) {
763 if (target[(*it)->getID()].
loc == 1 || target[(*it)->getID()].
loc == -1) {
764 parent->m_sub1->m_members.push_back(*it);
765 parent->m_sub1->m_area += (*it)->getArea();
768 parent->m_sub2->m_members.push_back(*it);
769 parent->m_sub2->m_area += (*it)->getArea();
772 cout <<
" after " << parent->m_sub1->m_members.length() <<
"/"
773 << parent->m_sub2->m_members.length() << endl;
776 cout <<
"FIDM-21 : \tloc: " << initial_cut <<
" targetting: " << targets*100/parent->m_members.length() <<
"%" << endl;
777 cout <<
"FIDM-22 : \tstarting cuts= " << before_cuts <<
" final cuts= " << current_cuts << endl;
835 float halfArea, area;
839 if (parent->m_vertical)
847 halfArea = parent->m_area*0.5;
848 parent->m_sub1->m_area = 0.0;
849 parent->m_sub1->m_numMembers = 0;
852 parent->m_sub2->m_area = 0.0;
853 parent->m_sub2->m_numMembers = 0;
857 for(; parent->m_sub1->m_area < halfArea; i++)
858 if (parent->m_members[i]) {
860 parent->m_sub1->m_members[parent->m_sub1->m_numMembers++] = parent->m_members[i];
861 parent->m_sub1->m_area += area;
863 for(; i<parent->m_numMembers; i++)
864 if (parent->m_members[i]) {
866 parent->m_sub2->m_members[parent->m_sub2->m_numMembers++] = parent->m_members[i];
867 parent->m_sub2->m_area += area;
881 int current_cuts = 0;
882 int minimum_cuts = INT_MAX;
884 double currentArea = 0, halfArea = parent->m_area * 0.5;
886 double newLine, oldLine = -DBL_MAX;
888 for(ConcreteNetList::iterator n_it = m_design->nets.begin(); !n_it; n_it++)
890 for(h::list<ConcreteCell *>::iterator i = parent->m_members.begin();
893 for(ConcretePinMap::iterator j = (*i)->getPins().begin();
896 if((*j)->isAttached()) {
897 (*j)->getNet()->m_mark = 1;
902 if (parent->vertical) {
903 parent->m_members.sort(sortByX);
904 int all1 = 0, all2 = 0;
905 h::list<ConcreteCell *>::iterator
local = parent->m_members.begin();
907 currentArea += (*local)->getArea();
908 if (currentArea < halfArea-areaFlexibility)
910 if (currentArea > halfArea+areaFlexibility)
912 newLine = (*local)->temp_x;
925 if (current_cuts < minimum_cuts) {
926 minimum_cuts = current_cuts;
927 minimum_location = *
local;
933 parent->m_members.sort(sortByY);
934 int all1 = 0, all2 = 0;
935 h::list<ConcreteCell *>::iterator
local = parent->m_members.begin();
937 currentArea += (*local)->getArea();
938 if (currentArea < halfArea-areaFlexibility)
940 if (currentArea > halfArea+areaFlexibility)
942 newLine = (*local)->temp_y;
955 if (current_cuts < minimum_cuts) {
956 minimum_cuts = current_cuts;
957 minimum_location = *
local;
962 if (minimum_location == NULL) {
965 h::list<ConcreteCell *>::iterator it = parent->m_members.begin();
966 parent->m_sub1->m_members.clear();
967 parent->m_sub1->m_area = 0;
968 for(; *it != minimum_location; it++) {
969 parent->m_sub1->m_members.push_front(*it);
970 parent->m_sub1->m_area += (*it)->getArea();
972 parent->m_sub2->m_members.clear();
973 parent->m_sub2->m_area = 0;
975 parent->m_sub2->m_members.push_front(*it);
976 parent->m_sub2->m_area += (*it)->getArea();