src/misc/espresso/opo.c File Reference

#include "espresso.h"
Include dependency graph for opo.c:

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

Define Documentation

#define POW2 (  )     (1 << (x))

Definition at line 536 of file opo.c.


Function Documentation

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]

Definition at line 616 of file opo.c.

00618 {
00619     if (opo_exact) {
00620         EXEC_S(PLA->F = minimize_exact(PLA->F,PLA->D,PLA->R,1), "EXACT", PLA->F);
00621     } else {
00622         EXEC_S(PLA->F = espresso(PLA->F, PLA->D, PLA->R), "ESPRESSO  ",PLA->F);
00623     }
00624 }

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 }

pPLA set_phase ( INOUT pPLA  PLA  ) 

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 }


Variable Documentation

int opo_exact [static]

Definition at line 61 of file opo.c.

int opo_no_make_sparse [static]

Definition at line 59 of file opo.c.

int opo_repeated [static]

Definition at line 60 of file opo.c.


Generated on Tue Jan 5 12:19:12 2010 for abc70930 by  doxygen 1.6.1