#include "espresso.h"
Go to the source code of this file.
Defines | |
#define | POW2(x) (1 << (x)) |
Functions | |
static void | minimize () |
void | phase_assignment (pPLA PLA, int opo_strategy) |
void | repeated_phase_assignment (pPLA PLA) |
pcube | find_phase (pPLA PLA, int first_output, pcube phase1) |
pcover | opo (pcube phase, pcover T, pcover D, pcover R, int first_output) |
pset_family | opo_recur (pcover T, pcover D, pcube select, int offset, int first, int last) |
pset_family | opo_leaf (pcover T, pset select, int out1, int out2) |
output_phase_setup (INOUT pPLA PLA, int first_output) | |
pPLA | set_phase (INOUT pPLA PLA) |
void | opoall (pPLA PLA, int first_output, int last_output, int opo_strategy) |
static void | minimize (pPLA PLA) |
Variables | |
static int | opo_no_make_sparse |
static int | opo_repeated |
static int | opo_exact |
pcube find_phase | ( | pPLA | PLA, | |
int | first_output, | |||
pcube | phase1 | |||
) |
Definition at line 126 of file opo.c.
00130 { 00131 pcube phase; 00132 pPLA PLA1; 00133 00134 phase = set_save(cube.fullset); 00135 00136 /* setup the double-phase characteristic function, resize the cube */ 00137 PLA1 = new_PLA(); 00138 PLA1->F = sf_save(PLA->F); 00139 PLA1->R = sf_save(PLA->R); 00140 PLA1->D = sf_save(PLA->D); 00141 if (phase1 != NULL) { 00142 PLA1->phase = set_save(phase1); 00143 (void) set_phase(PLA1); 00144 } 00145 EXEC_S(output_phase_setup(PLA1, first_output), "OPO-SETUP ", PLA1->F); 00146 00147 /* minimize the double-phase function */ 00148 minimize(PLA1); 00149 00150 /* set the proper phases according to what gives a minimum solution */ 00151 EXEC_S(PLA1->F = opo(phase, PLA1->F, PLA1->D, PLA1->R, first_output), 00152 "OPO ", PLA1->F); 00153 free_PLA(PLA1); 00154 00155 /* set the cube structure to reflect the old size */ 00156 setdown_cube(); 00157 cube.part_size[cube.output] -= 00158 (cube.part_size[cube.output] - first_output) / 2; 00159 cube_setup(); 00160 00161 return phase; 00162 }
static void minimize | ( | pPLA | PLA | ) | [static] |
static void minimize | ( | ) | [static] |
pcover opo | ( | pcube | phase, | |
pcover | T, | |||
pcover | D, | |||
pcover | R, | |||
int | first_output | |||
) |
Definition at line 170 of file opo.c.
00174 { 00175 int offset, output, i, last_output, ind; 00176 pset pdest, select, p, p1, last, last1, not_covered, tmp; 00177 pset_family temp, T1, T2; 00178 00179 /* must select all primes for outputs [0 .. first_output-1] */ 00180 select = set_full(T->count); 00181 for(output = 0; output < first_output; output++) { 00182 ind = cube.first_part[cube.output] + output; 00183 foreachi_set(T, i, p) { 00184 if (is_in_set(p, ind)) { 00185 set_remove(select, i); 00186 } 00187 } 00188 } 00189 00190 /* Recursively perform the intersections */ 00191 offset = (cube.part_size[cube.output] - first_output) / 2; 00192 last_output = first_output + offset - 1; 00193 temp = opo_recur(T, D, select, offset, first_output, last_output); 00194 00195 /* largest set is on top -- select primes which are inferred from it */ 00196 pdest = temp->data; 00197 T1 = new_cover(T->count); 00198 foreachi_set(T, i, p) { 00199 if (! is_in_set(pdest, i)) { 00200 T1 = sf_addset(T1, p); 00201 } 00202 } 00203 00204 set_free(select); 00205 sf_free(temp); 00206 00207 /* finding phases is difficult -- see which functions are not covered */ 00208 T2 = complement(cube1list(T1)); 00209 not_covered = new_cube(); 00210 tmp = new_cube(); 00211 foreach_set(T, last, p) { 00212 foreach_set(T2, last1, p1) { 00213 if (cdist0(p, p1)) { 00214 (void) set_or(not_covered, not_covered, set_and(tmp, p, p1)); 00215 } 00216 } 00217 } 00218 free_cover(T); 00219 free_cover(T2); 00220 set_free(tmp); 00221 00222 /* Now reflect the phase choice in a single cube */ 00223 for(output = first_output; output <= last_output; output++) { 00224 ind = cube.first_part[cube.output] + output; 00225 if (is_in_set(not_covered, ind)) { 00226 if (is_in_set(not_covered, ind + offset)) { 00227 fatal("error in output phase assignment"); 00228 } else { 00229 set_remove(phase, ind); 00230 } 00231 } 00232 } 00233 set_free(not_covered); 00234 return T1; 00235 }
pset_family opo_leaf | ( | pcover | T, | |
pset | select, | |||
int | out1, | |||
int | out2 | |||
) |
Definition at line 275 of file opo.c.
00279 { 00280 register pset_family temp; 00281 register pset p, pdest; 00282 register int i; 00283 00284 out1 += cube.first_part[cube.output]; 00285 out2 += cube.first_part[cube.output]; 00286 00287 /* Allocate space for the result */ 00288 temp = sf_new(2, T->count); 00289 00290 /* Find which primes are needed for the ON-set of this fct */ 00291 pdest = GETSET(temp, temp->count++); 00292 (void) set_copy(pdest, select); 00293 foreachi_set(T, i, p) { 00294 if (is_in_set(p, out1)) { 00295 set_remove(pdest, i); 00296 } 00297 } 00298 00299 /* Find which primes are needed for the OFF-set of this fct */ 00300 pdest = GETSET(temp, temp->count++); 00301 (void) set_copy(pdest, select); 00302 foreachi_set(T, i, p) { 00303 if (is_in_set(p, out2)) { 00304 set_remove(pdest, i); 00305 } 00306 } 00307 00308 return temp; 00309 }
pset_family opo_recur | ( | pcover | T, | |
pcover | D, | |||
pcube | select, | |||
int | offset, | |||
int | first, | |||
int | last | |||
) |
Definition at line 237 of file opo.c.
00241 { 00242 static int level = 0; 00243 int middle; 00244 pset_family sl, sr, temp; 00245 00246 level++; 00247 if (first == last) { 00248 #if 0 00249 if (opo_no_make_sparse) { 00250 temp = form_cover_table(T, D, select, first, first + offset); 00251 } else { 00252 temp = opo_leaf(T, select, first, first + offset); 00253 } 00254 #else 00255 temp = opo_leaf(T, select, first, first + offset); 00256 #endif 00257 } else { 00258 middle = (first + last) / 2; 00259 sl = opo_recur(T, D, select, offset, first, middle); 00260 sr = opo_recur(T, D, select, offset, middle+1, last); 00261 temp = unate_intersect(sl, sr, level == 1); 00262 if (trace) { 00263 printf("# OPO[%d]: %4d = %4d x %4d, time = %s\n", level - 1, 00264 temp->count, sl->count, sr->count, print_time(ptime())); 00265 (void) fflush(stdout); 00266 } 00267 free_cover(sl); 00268 free_cover(sr); 00269 } 00270 level--; 00271 return temp; 00272 }
void opoall | ( | pPLA | PLA, | |
int | first_output, | |||
int | last_output, | |||
int | opo_strategy | |||
) |
Definition at line 538 of file opo.c.
00542 { 00543 pcover F, D, R, best_F, best_D, best_R; 00544 int i, j, ind, num; 00545 pcube bestphase; 00546 00547 opo_exact = opo_strategy; 00548 00549 if (PLA->phase != NULL) { 00550 set_free(PLA->phase); 00551 } 00552 00553 bestphase = set_save(cube.fullset); 00554 best_F = sf_save(PLA->F); 00555 best_D = sf_save(PLA->D); 00556 best_R = sf_save(PLA->R); 00557 00558 for(i = 0; i < POW2(last_output - first_output + 1); i++) { 00559 00560 /* save the initial PLA covers */ 00561 F = sf_save(PLA->F); 00562 D = sf_save(PLA->D); 00563 R = sf_save(PLA->R); 00564 00565 /* compute the phase cube for this iteration */ 00566 PLA->phase = set_save(cube.fullset); 00567 num = i; 00568 for(j = last_output; j >= first_output; j--) { 00569 if (num % 2 == 0) { 00570 ind = cube.first_part[cube.output] + j; 00571 set_remove(PLA->phase, ind); 00572 } 00573 num /= 2; 00574 } 00575 00576 /* set the phase and minimize */ 00577 (void) set_phase(PLA); 00578 printf("# phase is %s\n", pc1(PLA->phase)); 00579 summary = TRUE; 00580 minimize(PLA); 00581 00582 /* see if this is the best so far */ 00583 if (PLA->F->count < best_F->count) { 00584 /* save new best solution */ 00585 set_copy(bestphase, PLA->phase); 00586 sf_free(best_F); 00587 sf_free(best_D); 00588 sf_free(best_R); 00589 best_F = PLA->F; 00590 best_D = PLA->D; 00591 best_R = PLA->R; 00592 } else { 00593 /* throw away the solution */ 00594 free_cover(PLA->F); 00595 free_cover(PLA->D); 00596 free_cover(PLA->R); 00597 } 00598 set_free(PLA->phase); 00599 00600 /* restore the initial PLA covers */ 00601 PLA->F = F; 00602 PLA->D = D; 00603 PLA->R = R; 00604 } 00605 00606 /* one more minimization to restore the best answer */ 00607 PLA->phase = bestphase; 00608 sf_free(PLA->F); 00609 sf_free(PLA->D); 00610 sf_free(PLA->R); 00611 PLA->F = best_F; 00612 PLA->D = best_D; 00613 PLA->R = best_R; 00614 }
output_phase_setup | ( | INOUT pPLA | PLA, | |
int | first_output | |||
) |
Definition at line 414 of file opo.c.
00417 { 00418 pcover F, R, D; 00419 pcube mask, mask1, last; 00420 int first_part, offset; 00421 bool save; 00422 register pcube p, pr, pf; 00423 register int i, last_part; 00424 00425 if (cube.output == -1) 00426 fatal("output_phase_setup: must have an output"); 00427 00428 F = PLA->F; 00429 D = PLA->D; 00430 R = PLA->R; 00431 first_part = cube.first_part[cube.output] + first_output; 00432 last_part = cube.last_part[cube.output]; 00433 offset = cube.part_size[cube.output] - first_output; 00434 00435 /* Change the output size, setup the cube structure */ 00436 setdown_cube(); 00437 cube.part_size[cube.output] += offset; 00438 cube_setup(); 00439 00440 /* Create a mask to select that part of the cube which isn't changing */ 00441 mask = set_save(cube.fullset); 00442 for(i = first_part; i < cube.size; i++) 00443 set_remove(mask, i); 00444 mask1 = set_save(mask); 00445 for(i = cube.first_part[cube.output]; i < first_part; i++) { 00446 set_remove(mask1, i); 00447 } 00448 00449 PLA->F = new_cover(F->count + R->count); 00450 PLA->R = new_cover(F->count + R->count); 00451 PLA->D = new_cover(D->count); 00452 00453 foreach_set(F, last, p) { 00454 pf = GETSET(PLA->F, (PLA->F)->count++); 00455 pr = GETSET(PLA->R, (PLA->R)->count++); 00456 INLINEset_and(pf, mask, p); 00457 INLINEset_and(pr, mask1, p); 00458 for(i = first_part; i <= last_part; i++) 00459 if (is_in_set(p, i)) 00460 set_insert(pf, i); 00461 save = FALSE; 00462 for(i = first_part; i <= last_part; i++) 00463 if (is_in_set(p, i)) 00464 save = TRUE, set_insert(pr, i+offset); 00465 if (! save) PLA->R->count--; 00466 } 00467 00468 foreach_set(R, last, p) { 00469 pf = GETSET(PLA->F, (PLA->F)->count++); 00470 pr = GETSET(PLA->R, (PLA->R)->count++); 00471 INLINEset_and(pf, mask1, p); 00472 INLINEset_and(pr, mask, p); 00473 save = FALSE; 00474 for(i = first_part; i <= last_part; i++) 00475 if (is_in_set(p, i)) 00476 save = TRUE, set_insert(pf, i+offset); 00477 if (! save) PLA->F->count--; 00478 for(i = first_part; i <= last_part; i++) 00479 if (is_in_set(p, i)) 00480 set_insert(pr, i); 00481 } 00482 00483 foreach_set(D, last, p) { 00484 pf = GETSET(PLA->D, (PLA->D)->count++); 00485 INLINEset_and(pf, mask, p); 00486 for(i = first_part; i <= last_part; i++) 00487 if (is_in_set(p, i)) { 00488 set_insert(pf, i); 00489 set_insert(pf, i+offset); 00490 } 00491 } 00492 00493 free_cover(F); 00494 free_cover(D); 00495 free_cover(R); 00496 set_free(mask); 00497 set_free(mask1); 00498 }
void phase_assignment | ( | pPLA | PLA, | |
int | opo_strategy | |||
) |
Definition at line 64 of file opo.c.
00067 { 00068 opo_no_make_sparse = opo_strategy % 2; 00069 skip_make_sparse = opo_no_make_sparse; 00070 opo_repeated = (opo_strategy / 2) % 2; 00071 opo_exact = (opo_strategy / 4) % 2; 00072 00073 /* Determine a phase assignment */ 00074 if (PLA->phase != NULL) { 00075 FREE(PLA->phase); 00076 } 00077 00078 if (opo_repeated) { 00079 PLA->phase = set_save(cube.fullset); 00080 repeated_phase_assignment(PLA); 00081 } else { 00082 PLA->phase = find_phase(PLA, 0, (pcube) NULL); 00083 } 00084 00085 /* Now minimize with this assignment */ 00086 skip_make_sparse = FALSE; 00087 (void) set_phase(PLA); 00088 minimize(PLA); 00089 }
void repeated_phase_assignment | ( | pPLA | PLA | ) |
Definition at line 96 of file opo.c.
00098 { 00099 int i; 00100 pcube phase; 00101 00102 for(i = 0; i < cube.part_size[cube.output]; i++) { 00103 00104 /* Find best assignment for all undecided outputs */ 00105 phase = find_phase(PLA, i, PLA->phase); 00106 00107 /* Commit for only a single output ... */ 00108 if (! is_in_set(phase, cube.first_part[cube.output] + i)) { 00109 set_remove(PLA->phase, cube.first_part[cube.output] + i); 00110 } 00111 00112 if (trace || summary) { 00113 printf("\nOPO loop for output #%d\n", i); 00114 printf("PLA->phase is %s\n", pc1(PLA->phase)); 00115 printf("phase is %s\n", pc1(phase)); 00116 } 00117 set_free(phase); 00118 } 00119 }
Definition at line 504 of file opo.c.
00506 { 00507 pcover F1, R1; 00508 register pcube last, p, outmask; 00509 register pcube temp=cube.temp[0], phase=PLA->phase, phase1=cube.temp[1]; 00510 00511 outmask = cube.var_mask[cube.num_vars - 1]; 00512 set_diff(phase1, outmask, phase); 00513 set_or(phase1, set_diff(temp, cube.fullset, outmask), phase1); 00514 F1 = new_cover((PLA->F)->count + (PLA->R)->count); 00515 R1 = new_cover((PLA->F)->count + (PLA->R)->count); 00516 00517 foreach_set(PLA->F, last, p) { 00518 if (! setp_disjoint(set_and(temp, p, phase), outmask)) 00519 set_copy(GETSET(F1, F1->count++), temp); 00520 if (! setp_disjoint(set_and(temp, p, phase1), outmask)) 00521 set_copy(GETSET(R1, R1->count++), temp); 00522 } 00523 foreach_set(PLA->R, last, p) { 00524 if (! setp_disjoint(set_and(temp, p, phase), outmask)) 00525 set_copy(GETSET(R1, R1->count++), temp); 00526 if (! setp_disjoint(set_and(temp, p, phase1), outmask)) 00527 set_copy(GETSET(F1, F1->count++), temp); 00528 } 00529 free_cover(PLA->F); 00530 free_cover(PLA->R); 00531 PLA->F = F1; 00532 PLA->R = R1; 00533 return PLA; 00534 }
int opo_no_make_sparse [static] |
int opo_repeated [static] |