ABC: A System for Sequential Synthesis and Verification
 
Loading...
Searching...
No Matches
place_qpsolver.c File Reference
#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "place_qpsolver.h"
Include dependency graph for place_qpsolver.c:

Go to the source code of this file.

Macros

#define QPS_TOL   1.0e-3
 
#define QPS_EPS   (QPS_TOL * QPS_TOL)
 
#define QPS_MAX_TOL   0.1
 
#define QPS_LOOP_TOL   1.0e-3
 
#define QPS_RELAX_ITER   180
 
#define QPS_MAX_ITER   200
 
#define QPS_STEPSIZE_RETRIES   2
 
#define QPS_MINSTEP   1.0e-6
 
#define QPS_DEC_CHANGE   0.01
 
#define QPS_PRECON
 
#define QPS_PRECON_EPS   1.0e-9
 

Functions

void qps_init (qps_problem_t *p)
 
void qps_solve (qps_problem_t *p)
 
void qps_clean (qps_problem_t *p)
 

Macro Definition Documentation

◆ QPS_DEC_CHANGE

#define QPS_DEC_CHANGE   0.01

Definition at line 32 of file place_qpsolver.c.

◆ QPS_EPS

#define QPS_EPS   (QPS_TOL * QPS_TOL)

Definition at line 23 of file place_qpsolver.c.

◆ QPS_LOOP_TOL

#define QPS_LOOP_TOL   1.0e-3

Definition at line 26 of file place_qpsolver.c.

◆ QPS_MAX_ITER

#define QPS_MAX_ITER   200

Definition at line 29 of file place_qpsolver.c.

◆ QPS_MAX_TOL

#define QPS_MAX_TOL   0.1

Definition at line 25 of file place_qpsolver.c.

◆ QPS_MINSTEP

#define QPS_MINSTEP   1.0e-6

Definition at line 31 of file place_qpsolver.c.

◆ QPS_PRECON

#define QPS_PRECON

Definition at line 34 of file place_qpsolver.c.

◆ QPS_PRECON_EPS

#define QPS_PRECON_EPS   1.0e-9

Definition at line 35 of file place_qpsolver.c.

◆ QPS_RELAX_ITER

#define QPS_RELAX_ITER   180

Definition at line 28 of file place_qpsolver.c.

◆ QPS_STEPSIZE_RETRIES

#define QPS_STEPSIZE_RETRIES   2

Definition at line 30 of file place_qpsolver.c.

◆ QPS_TOL

#define QPS_TOL   1.0e-3

Definition at line 22 of file place_qpsolver.c.

Function Documentation

◆ qps_clean()

void qps_clean ( qps_problem_t * p)

Definition at line 1259 of file place_qpsolver.c.

1260{
1261 free(p->priv_tp);
1262 free(p->priv_ii);
1263 free(p->priv_cc);
1264 free(p->priv_cr);
1265 free(p->priv_cw);
1266 free(p->priv_ct);
1267
1268#if defined(QPS_DEBUG)
1269 fclose(p->priv_fp);
1270#endif /* QPS_DEBUG */
1271}
Cube * p
Definition exorList.c:222
VOID_HACK free()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ qps_init()

void qps_init ( qps_problem_t * p)

Definition at line 542 of file place_qpsolver.c.

543{
544 int i, j;
545 int pr, pw;
546
547#if defined(QPS_DEBUG)
548 p->priv_fp = fopen(QPS_DEBUG_FILE, "a");
549 assert(p->priv_fp);
550#endif
551
552#if (QPS_DEBUG > 5)
553 fprintf(p->priv_fp, "### n=%d gn=%d ln=%d\n", p->num_cells, p->cog_num,
554 p->loop_num);
555 pr = 0;
556 fprintf(p->priv_fp, "### (c w) values\n");
557 for (i = 0; i < p->num_cells; i++) {
558 fprintf(p->priv_fp, "net %d: ", i);
559 while (p->connect[pr] >= 0) {
560 fprintf(p->priv_fp, "(%d %f) ", p->connect[pr], p->edge_weight[pr]);
561 pr++;
562 }
563 fprintf(p->priv_fp, "(-1 -1.0)\n");
564 pr++;
565 }
566 fprintf(p->priv_fp, "### (x y f) values\n");
567 for (i = 0; i < p->num_cells; i++) {
568 fprintf(p->priv_fp, "cell %d: (%f %f %d)\n", i, p->x[i], p->y[i],
569 p->fixed[i]);
570 }
571#if 0
572 if (p->cog_num) {
573 fprintf(p->priv_fp, "### ga values\n");
574 for (i = 0; i < p->num_cells; i++) {
575 fprintf(p->priv_fp, "cell %d: (%f)\n", i, p->area[i]);
576 }
577 }
578 pr = 0;
579 fprintf(p->priv_fp, "### gl values\n");
580 for (i = 0; i < p->cog_num; i++) {
581 fprintf(p->priv_fp, "cog %d: ", i);
582 while (p->cog_list[pr] >= 0) {
583 fprintf(p->priv_fp, "%d ", p->cog_list[pr]);
584 pr++;
585 }
586 fprintf(p->priv_fp, "-1\n");
587 pr++;
588 }
589 fprintf(p->priv_fp, "### (gx gy) values\n");
590 for (i = 0; i < p->cog_num; i++) {
591 fprintf(p->priv_fp, "cog %d: (%f %f)\n", i, p->cog_x[i], p->cog_y[i]);
592 }
593#endif
594#endif /* QPS_DEBUG */
595
596 p->priv_ii = (int *)malloc(p->num_cells * sizeof(int));
597 assert(p->priv_ii);
598
599 p->max_enable = 0;
600
601 p->priv_fopt = 0.0;
602
603 /* canonify c and w */
604 pr = pw = 0;
605 for (i = 0; i < p->num_cells; i++) {
606 while ((j = p->connect[pr]) >= 0) {
607 if (j > i) {
608 pw++;
609 }
610 pr++;
611 }
612 pw++;
613 pr++;
614 }
615 p->priv_cc = (int *)malloc(pw * sizeof(int));
616 assert(p->priv_cc);
617 p->priv_cr = (int *)malloc(p->num_cells * sizeof(int));
618 assert(p->priv_cr);
619 p->priv_cw = (qps_float_t*)malloc(pw * sizeof(qps_float_t));
620 assert(p->priv_cw);
621 p->priv_ct = (qps_float_t*)malloc(pw * sizeof(qps_float_t));
622 assert(p->priv_ct);
623 p->priv_cm = pw;
624 pr = pw = 0;
625 for (i = 0; i < p->num_cells; i++) {
626 p->priv_cr[i] = pw;
627 while ((j = p->connect[pr]) >= 0) {
628 if (j > i) {
629 p->priv_cc[pw] = p->connect[pr];
630 p->priv_ct[pw] = p->edge_weight[pr];
631 pw++;
632 }
633 pr++;
634 }
635 p->priv_cc[pw] = -1;
636 p->priv_ct[pw] = -1.0;
637 pw++;
638 pr++;
639 }
640 assert(pw == p->priv_cm);
641
642 /* temp arrays for function eval */
643 p->priv_tp = (qps_float_t *) malloc(4 * p->num_cells * sizeof(qps_float_t));
644 assert(p->priv_tp);
645 p->priv_tp2 = p->priv_tp + 2 * p->num_cells;
646}
ABC_NAMESPACE_HEADER_START typedef float qps_float_t
#define assert(ex)
Definition util_old.h:213
char * malloc()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ qps_solve()

void qps_solve ( qps_problem_t * p)

Definition at line 981 of file place_qpsolver.c.

982{
983 int i, j;
984 int pr, pw;
985 qps_float_t bk;
986 int tk;
987
988#if defined(QPS_PRECON)
989 int c;
990 qps_float_t t;
991#endif
992
993#if defined(QPS_HOIST)
994 int k;
995 int st;
996 int m1, m2;
997#endif
998
999 if (p->max_enable) {
1000 p->priv_mxl = (qps_float_t *)
1001 malloc(4 * p->num_cells * sizeof(qps_float_t));
1002 assert(p->priv_mxl);
1003 p->priv_mxh = p->priv_mxl + p->num_cells;
1004 p->priv_myl = p->priv_mxl + 2 * p->num_cells;
1005 p->priv_myh = p->priv_mxl + 3 * p->num_cells;
1006 for (i = 4 * p->num_cells; i--;) {
1007 p->priv_mxl[i] = 0.0;
1008 }
1009 }
1010
1011 /* flag fixed cells with -1 */
1012 for (i = p->num_cells; i--;) {
1013 p->priv_ii[i] = (p->fixed[i]) ? (-1) : (0);
1014 }
1015
1016 /* read gl and set up dependent variables */
1017 if (p->cog_num) {
1018 p->priv_gt = (int *)malloc(p->cog_num * sizeof(int));
1019 assert(p->priv_gt);
1020 p->priv_gm = (qps_float_t*)malloc(p->cog_num * sizeof(qps_float_t));
1021 assert(p->priv_gm);
1022 pr = 0;
1023 for (i = 0; i < p->cog_num; i++) {
1024 tk = -1;
1025 bk = -1.0;
1026 pw = pr;
1027 while ((j = p->cog_list[pr++]) >= 0) {
1028 if (!p->fixed[j]) {
1029 /* use largest entry for numerical stability; see Gordian paper */
1030 if (p->area[j] > bk) {
1031 tk = j;
1032 bk = p->area[j];
1033 }
1034 }
1035 }
1036 assert(bk > 0.0);
1037 /* dependent variables have index=(-2-COG_constraint) */
1038 p->priv_ii[tk] = -2 - i;
1039 p->priv_gt[i] = pw;
1040 p->priv_gm[i] = bk;
1041 }
1042 p->priv_gw = (qps_float_t*)malloc(pr * sizeof(qps_float_t));
1043 assert(p->priv_gw);
1044 pr = 0;
1045 for (i = 0; i < p->cog_num; i++) {
1046 while ((j = p->cog_list[pr]) >= 0) {
1047 p->priv_gw[pr] = p->area[j] / p->priv_gm[i];
1048 pr++;
1049 }
1050 p->priv_gw[pr] = -1.0;
1051 pr++;
1052 }
1053 }
1054
1055 /* set up indexes from independent floating cells to variables */
1056 p->priv_n = 0;
1057 for (i = p->num_cells; i--;) {
1058 if (!p->priv_ii[i]) {
1059 p->priv_ii[i] = 2 * (p->priv_n++);
1060 }
1061 }
1062 p->priv_n *= 2;
1063
1064#if (QPS_DEBUG > 5)
1065 for (i = 0; i < p->num_cells; i++) {
1066 fprintf(p->priv_fp, "### ii %d %d\n", i, p->priv_ii[i]);
1067 }
1068#endif
1069
1070#if defined(QPS_PRECON)
1071 p->priv_pcg = (qps_float_t *) malloc(p->num_cells * sizeof(qps_float_t));
1072 assert(p->priv_pcg);
1073 p->priv_pcgt = (qps_float_t *) malloc(p->priv_n * sizeof(qps_float_t));
1074 assert(p->priv_pcgt);
1075 for (i = p->num_cells; i--;) {
1076 p->priv_pcg[i] = 0.0;
1077 }
1078 pr = 0;
1079 for (i = 0; i < p->num_cells; i++) {
1080 while ((c = p->priv_cc[pr]) >= 0) {
1081 t = p->priv_ct[pr];
1082 p->priv_pcg[i] += t;
1083 p->priv_pcg[c] += t;
1084 pr++;
1085 }
1086 pr++;
1087 }
1088 pr = 0;
1089 for (i = 0; i < p->loop_num; i++) {
1090 t = 2.0 * p->loop_penalty[i];
1091 while ((c = p->loop_list[pr++]) >= 0) {
1092 p->priv_pcg[c] += t;
1093 }
1094 pr++;
1095 }
1096#if (QPS_DEBUG > 6)
1097 for (i = p->num_cells; i--;) {
1098 fprintf(p->priv_fp, "### precon %d %.2e\n", i, p->priv_pcg[i]);
1099 }
1100#endif
1101 for (i = p->priv_n; i--;) {
1102 p->priv_pcgt[i] = 0.0;
1103 }
1104 for (i = 0; i < p->num_cells; i++) {
1105 c = p->priv_ii[i];
1106 if (c >= 0) {
1107 t = p->priv_pcg[i];
1108 p->priv_pcgt[c] += t;
1109 p->priv_pcgt[c + 1] += t;
1110 }
1111#if 0
1112 else if (c < -1) {
1113 pr = p->priv_gt[-(c+2)];
1114 while ((j = p->cog_list[pr++]) >= 0) {
1115 ji = p->priv_ii[j];
1116 if (ji >= 0) {
1117 w = p->area[j] / p->area[i];
1118 t = w * w * p->priv_pcg[i];
1119 p->priv_pcgt[ji] += t;
1120 p->priv_pcgt[ji + 1] += t;
1121 }
1122 }
1123 }
1124#endif
1125 }
1126 for (i = 0; i < p->priv_n; i++) {
1127 t = p->priv_pcgt[i];
1128 if (fabs(t) < QPS_PRECON_EPS || fabs(t) > 1.0/QPS_PRECON_EPS) {
1129 p->priv_pcgt[i] = 1.0;
1130 }
1131 else {
1132 p->priv_pcgt[i] = 1.0 / p->priv_pcgt[i];
1133 }
1134 }
1135#endif
1136
1137 /* allocate variable storage */
1138 p->priv_cp = (qps_float_t *) malloc(4 * p->priv_n * sizeof(qps_float_t));
1139 assert(p->priv_cp);
1140
1141 /* temp arrays for cg */
1142 p->priv_g = p->priv_cp + p->priv_n;
1143 p->priv_h = p->priv_cp + 2 * p->priv_n;
1144 p->priv_xi = p->priv_cp + 3 * p->priv_n;
1145
1146 /* set values */
1147 for (i = p->num_cells; i--;) {
1148 if (p->priv_ii[i] >= 0) {
1149 p->priv_cp[p->priv_ii[i]] = p->x[i];
1150 p->priv_cp[p->priv_ii[i] + 1] = p->y[i];
1151 }
1152 }
1153
1154 if (p->loop_num) {
1155 p->priv_lt = (qps_float_t *) malloc(p->loop_num * sizeof(qps_float_t));
1156 assert(p->priv_lt);
1157#if defined(QPS_HOIST)
1158 pr = 0;
1159 for (i=p->loop_num; i--;) {
1160 while (p->loop_list[pr++] >= 0) {
1161 }
1162 pr++;
1163 }
1164 p->priv_lm = pr;
1165 p->priv_la = (int *) malloc(pr * sizeof(int));
1166 assert(p->priv_la);
1167 pr = 0;
1168 for (i = 0; i < p->loop_num; i++) {
1169 j = st = p->loop_list[pr++];
1170 while ((k = p->loop_list[pr]) >= 0) {
1171 if (j > k) {
1172 m1 = k;
1173 m2 = j;
1174 }
1175 else {
1176 assert(k > j);
1177 m1 = j;
1178 m2 = k;
1179 }
1180 pw = p->priv_cr[m1];
1181 while (p->priv_cc[pw] != m2) {
1182/* assert(p->priv_cc[pw] >= 0); */
1183 if (p->priv_cc[pw] < 0) {
1184 pw = -2;
1185 break;
1186 }
1187 pw++;
1188 }
1189 p->priv_la[pr-1] = pw;
1190 j = k;
1191 pr++;
1192 }
1193 if (j > st) {
1194 m1 = st;
1195 m2 = j;
1196 }
1197 else {
1198 assert(st > j);
1199 m1 = j;
1200 m2 = st;
1201 }
1202 pw = p->priv_cr[m1];
1203 while (p->priv_cc[pw] != m2) {
1204/* assert(p->priv_cc[pw] >= 0); */
1205 if (p->priv_cc[pw] < 0) {
1206 pw = -2;
1207 break;
1208 }
1209 pw++;
1210 }
1211 p->priv_la[pr-1] = pw;
1212 p->priv_la[pr] = -1;
1213 pr++;
1214 }
1215#endif /* QPS_HOIST */
1216 }
1217
1218 do {
1219 qps_solve_inner(p);
1220 } while (!p->loop_done || !p->max_done);
1221
1222 /* retrieve values */
1223 /* qps_settp() should have already been called at this point */
1224 for (i = p->num_cells; i--;) {
1225 p->x[i] = p->priv_tp[i * 2];
1226 p->y[i] = p->priv_tp[i * 2 + 1];
1227 }
1228#if (QPS_DEBUG > 5)
1229 for (i = p->num_cells; i--;) {
1230 fprintf(p->priv_fp, "### cloc %d %f %f\n", i, p->x[i], p->y[i]);
1231 }
1232#endif
1233
1234 free(p->priv_cp);
1235 if (p->max_enable) {
1236 free(p->priv_mxl);
1237 }
1238 if (p->cog_num) {
1239 free(p->priv_gt);
1240 free(p->priv_gm);
1241 free(p->priv_gw);
1242 }
1243 if(p->loop_num) {
1244 free(p->priv_lt);
1245#if defined(QPS_HOIST)
1246 free(p->priv_la);
1247#endif
1248 }
1249
1250#if defined(QPS_PRECON)
1251 free(p->priv_pcg);
1252 free(p->priv_pcgt);
1253#endif
1254}
#define QPS_PRECON_EPS
Here is the call graph for this function:
Here is the caller graph for this function: