=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.42 retrieving revision 1.43 diff -u -p -r1.42 -r1.43 --- OpenXM_contrib2/asir2000/engine/nd.c 2003/08/21 08:20:06 1.42 +++ OpenXM_contrib2/asir2000/engine/nd.c 2003/08/22 07:12:49 1.43 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.41 2003/08/21 07:39:25 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.42 2003/08/21 08:20:06 noro Exp $ */ #include "ca.h" #include "inline.h" @@ -79,12 +79,19 @@ typedef struct oEPOS { int s; /* shift */ } *EPOS; +typedef struct oBlockMask { + int n; + struct order_pair *order_pair; + unsigned int **mask; +} *BlockMask; + int (*nd_compare_function)(unsigned int *a1,unsigned int *a2); static double nd_scale=2; static unsigned int **nd_bound; static struct order_spec *nd_ord; static EPOS nd_epos; +static BlockMask nd_blockmask; static int nd_nvar; static int nd_isrlex; static int nd_epw,nd_bpe,nd_wpd,nd_exporigin; @@ -127,8 +134,16 @@ extern int Top,Reverse,dp_nelim; /* macros for term comparison */ #define TD_DL_COMPARE(d1,d2)\ (TD(d1)>TD(d2)?1:(TD(d1)0?TD_DL_COMPARE(d1,d2)\ + :(nd_dcomp==0?ndl_lex_compare(d1,d2)\ + :(nd_blockmask?ndl_block_compare(d1,d2)\ + :(*nd_compare_function)(d1,d2)))) +#else +#define DL_COMPARE(d1,d2)\ +(nd_dcomp>0?TD_DL_COMPARE(d1,d2):(*nd_compare_function)(d1,d2)) +#endif /* allocators */ #define NEWRHist(r) \ @@ -202,10 +217,12 @@ NODE nd_gb_trace(int m); /* ndl functions */ int ndl_weight(unsigned int *d); +int ndl_weight_mask(unsigned int *d,int i); void ndl_dehomogenize(unsigned int *p); -void ndl_reconstruct(int obpe,unsigned int *d,unsigned int *r); +void ndl_reconstruct(int obpe,EPOS oepos,unsigned int *d,unsigned int *r); INLINE int ndl_reducible(unsigned int *d1,unsigned int *d2); INLINE int ndl_lex_compare(unsigned int *d1,unsigned int *d2); +INLINE int ndl_block_compare(unsigned int *d1,unsigned int *d2); INLINE int ndl_equal(unsigned int *d1,unsigned int *d2); INLINE void ndl_copy(unsigned int *d1,unsigned int *d2); INLINE void ndl_add(unsigned int *d1,unsigned int *d2,unsigned int *d); @@ -234,7 +251,6 @@ void nd_free_private_storage(); void _NM_alloc(); void _ND_alloc(); void nd_free(ND p); -void nd_realloc(ND p,int obpe); void nd_free_redlist(); /* printing */ @@ -250,6 +266,7 @@ ND_pairs nd_reconstruct(int mod,int trace,ND_pairs ndp void nd_reconstruct_direct(int mod,NDV *ps,int len); void nd_setup(int mod,int trace,NODE f); void nd_setup_parameters(); +BlockMask nd_create_blockmask(struct order_spec *ord); /* ND functions */ int nd_check_candidate(NODE input,NODE cand); @@ -268,7 +285,7 @@ INLINE int nd_length(ND p); /* NDV functions */ void ndv_mul_c(int mod,NDV p,int mul); void ndv_mul_c_q(NDV p,Q mul); -void ndv_realloc(NDV p,int obpe,int oadv); +void ndv_realloc(NDV p,int obpe,int oadv,EPOS oepos); ND ndv_mul_nm(int mod,NDV p,NM m0); void ndv_dehomogenize(NDV p); void ndv_removecont(int mod,NDV p); @@ -405,6 +422,8 @@ INLINE int ndl_reducible(unsigned int *d1,unsigned int } } +/* XXX : block order not supported */ + void ndl_dehomogenize(unsigned int *d) { unsigned int mask; @@ -435,7 +454,7 @@ void ndl_dehomogenize(unsigned int *d) void ndl_lcm(unsigned int *d1,unsigned *d2,unsigned int *d) { unsigned int t1,t2,u,u1,u2; - int i,j; + int i,j,l; switch ( nd_bpe ) { case 4: @@ -498,6 +517,11 @@ void ndl_lcm(unsigned int *d1,unsigned *d2,unsigned in break; } TD(d) = ndl_weight(d); + if ( nd_blockmask ) { + l = nd_blockmask->n; + for ( j = 0; j < l; j++ ) + d[j+1] = ndl_weight_mask(d,j); + } } int ndl_weight(unsigned int *d) @@ -513,8 +537,23 @@ int ndl_weight(unsigned int *d) return t; } -INLINE int ndl_lex_compare(unsigned int *d1,unsigned int *d2) +int ndl_weight_mask(unsigned int *d,int index) { + unsigned int t,u; + unsigned int *mask; + int i,j; + + mask = nd_blockmask->mask[index]; + for ( t = 0, i = nd_exporigin; i < nd_wpd; i++ ) { + u = d[i]&mask[i]; + for ( j = 0; j < nd_epw; j++, u>>=nd_bpe ) + t += (u&nd_mask0); + } + return t; +} + +int ndl_lex_compare(unsigned int *d1,unsigned int *d2) +{ int i; d1 += nd_exporigin; @@ -527,6 +566,33 @@ INLINE int ndl_lex_compare(unsigned int *d1,unsigned i return 0; } +int ndl_block_compare(unsigned int *d1,unsigned int *d2) +{ + int i,l,j,ord_o,ord_l; + struct order_pair *op; + unsigned int t1,t2; + unsigned int *mask; + + l = nd_blockmask->n; + op = nd_blockmask->order_pair; + for ( j = 0; j < l; j++ ) { + mask = nd_blockmask->mask[j]; + ord_o = op[j].order; + if ( ord_o < 2 ) + if ( d1[j+1] > d2[j+1] ) return 1; + else if ( d1[j+1] < d2[j+1] ) return -1; + for ( i = nd_exporigin; i < nd_wpd; i++ ) { + t1 = d1[i]&mask[i]; + t2 = d2[i]&mask[i]; + if ( t1 > t2 ) + return !ord_o ? -1 : 1; + else if ( t1 < t2 ) + return !ord_o ? 1 : -1; + } + } + return 0; +} + INLINE int ndl_equal(unsigned int *d1,unsigned int *d2) { int i; @@ -562,6 +628,7 @@ INLINE void ndl_add(unsigned int *d1,unsigned int *d2, { int i; +#if 1 switch ( nd_wpd ) { case 2: TD(d) = TD(d1)+TD(d2); @@ -573,18 +640,19 @@ INLINE void ndl_add(unsigned int *d1,unsigned int *d2, d[2] = d1[2]+d2[2]; break; default: - for ( i = 0; i < nd_wpd; i++ ) - d[i] = d1[i]+d2[i]; + for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i]; break; } +#else + for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]+d2[i]; +#endif } INLINE void ndl_sub(unsigned int *d1,unsigned int *d2,unsigned int *d) { int i; - for ( i = 0; i < nd_wpd; i++ ) - d[i] = d1[i]-d2[i]; + for ( i = 0; i < nd_wpd; i++ ) d[i] = d1[i]-d2[i]; } int ndl_disjoint(unsigned int *d1,unsigned int *d2) @@ -2075,32 +2143,69 @@ void nd_gr_trace(LIST f,LIST v,int m,int homo,struct o void dltondl(int n,DL dl,unsigned int *r) { unsigned int *d; - int i; + int i,j,l,s,ord_l,ord_o; + struct order_pair *op; d = dl->d; for ( i = 0; i < nd_wpd; i++ ) r[i] = 0; - if ( nd_isrlex ) - for ( i = 0; i < n; i++ ) PUT_EXP(r,n-1-i,d[i]); - else - for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]); - TD(r) = ndl_weight(r); + if ( nd_blockmask ) { + l = nd_blockmask->n; + op = nd_blockmask->order_pair; + for ( j = 0, s = 0; j < l; j++ ) { + ord_o = op[j].order; + ord_l = op[j].length; + if ( !ord_o ) + for ( i = 0; i < ord_l; i++ ) + PUT_EXP(r,s+ord_l-i-1,d[s+i]); + else + for ( i = 0; i < ord_l; i++ ) + PUT_EXP(r,s+i,d[s+i]); + s += ord_l; + } + TD(r) = ndl_weight(r); + for ( j = 0; j < l; j++ ) + r[j+1] = ndl_weight_mask(r,j); + } else { + if ( nd_isrlex ) + for ( i = 0; i < n; i++ ) PUT_EXP(r,n-1-i,d[i]); + else + for ( i = 0; i < n; i++ ) PUT_EXP(r,i,d[i]); + TD(r) = ndl_weight(r); + } } DL ndltodl(int n,unsigned int *ndl) { DL dl; int *d; - int i; + int i,j,l,s,ord_l,ord_o; + struct order_pair *op; NEWDL(dl,n); dl->td = TD(ndl); d = dl->d; - if ( nd_isrlex ) - for ( i = 0; i < n; i++ ) - d[i] = GET_EXP(ndl,n-1-i); - else - for ( i = 0; i < n; i++ ) - d[i] = GET_EXP(ndl,i); + if ( nd_blockmask ) { + l = nd_blockmask->n; + op = nd_blockmask->order_pair; + for ( j = 0, s = 0; j < l; j++ ) { + ord_o = op[j].order; + ord_l = op[j].length; + if ( !ord_o ) + for ( i = 0; i < ord_l; i++ ) + d[s+i] = GET_EXP(ndl,s+ord_l-i-1); + else + for ( i = 0; i < ord_l; i++ ) + d[s+i] = GET_EXP(ndl,s+i); + s += ord_l; + } + } else { + if ( nd_isrlex ) + for ( i = 0; i < n; i++ ) + d[i] = GET_EXP(ndl,n-1-i); + else + for ( i = 0; i < n; i++ ) + d[i] = GET_EXP(ndl,i); + } return dl; } @@ -2153,14 +2258,30 @@ DP ndtodp(int mod,ND p) void ndl_print(unsigned int *dl) { int n; - int i; + int i,j,l,ord_o,ord_l,s,s0; + struct order_pair *op; n = nd_nvar; printf("<<"); - if ( nd_isrlex ) - for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,n-1-i)); - else - for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i)); + if ( nd_blockmask ) { + l = nd_blockmask->n; + op = nd_blockmask->order_pair; + for ( j = 0, s = s0 = 0; j < l; j++ ) { + ord_o = op[j].order; + ord_l = op[j].length; + if ( !ord_o ) + for ( i = 0, s0 += ord_l; i < ord_l; i++, s++ ) + printf(s==n-1?"%d":"%d,",GET_EXP(dl,s0-i-1)); + else + for ( i = 0; i < ord_l; i++, s++ ) + printf(s==n-1?"%d":"%d,",GET_EXP(dl,s)); + } + } else { + if ( nd_isrlex ) + for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,n-1-i)); + else + for ( i = 0; i < n; i++ ) printf(i==n-1?"%d":"%d,",GET_EXP(dl,i)); + } printf(">>"); } @@ -2437,23 +2558,30 @@ unsigned int *nd_compute_bound(ND p) } void nd_setup_parameters() { - int i; + int i,n,elen; nd_epw = (sizeof(unsigned int)*8)/nd_bpe; - nd_wpd = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0); + elen = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0); + switch ( nd_ord->id ) { case 0: nd_exporigin = 1; break; case 1: /* block order */ - nd_exporigin = nd_ord->ord.block.length; + /* d[0]:weight d[1]:w0,...,d[nd_exporigin-1]:w(n-1) */ + nd_exporigin = nd_ord->ord.block.length+1; break; case 2: error("nd_setup_parameters : matrix order is not supported yet."); break; } - nd_wpd += nd_exporigin; + nd_wpd = nd_exporigin+elen; + nd_epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS)); + for ( i = 0; i < nd_nvar; i++ ) { + nd_epos[i].i = nd_exporigin + i/nd_epw; + nd_epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe; + } if ( nd_bpe < 32 ) { nd_mask0 = (1<= 0; i-- ) ndv_realloc(nd_ps[i],obpe,oadv); + for ( i = nd_psn-1; i >= 0; i-- ) ndv_realloc(nd_ps[i],obpe,oadv,oepos); if ( !mod || trace ) - for ( i = nd_psn-1; i >= 0; i-- ) ndv_realloc(nd_psq[i],obpe,oadv); + for ( i = nd_psn-1; i >= 0; i-- ) ndv_realloc(nd_psq[i],obpe,oadv,oepos); s0 = 0; for ( t = d; t; t = NEXT(t) ) { NEXTND_pairs(s0,s); s->i1 = t->i1; s->i2 = t->i2; SG(s) = SG(t); - ndl_reconstruct(obpe,LCM(t),LCM(s)); + ndl_reconstruct(obpe,oepos,LCM(t),LCM(s)); } old_red = (RHist *)ALLOCA(REDTAB_LEN*sizeof(RHist)); @@ -2521,7 +2646,7 @@ ND_pairs nd_reconstruct(int mod,int trace,ND_pairs d) NEWRHist(mr); mr->index = r->index; SG(mr) = SG(r); - ndl_reconstruct(obpe,DL(r),DL(mr)); + ndl_reconstruct(obpe,oepos,DL(r),DL(mr)); h = ndl_hash_value(DL(mr)); NEXT(mr) = nd_red[h]; nd_red[h] = mr; @@ -2530,7 +2655,7 @@ ND_pairs nd_reconstruct(int mod,int trace,ND_pairs d) old_red = 0; for ( i = 0; i < nd_psn; i++ ) { NEWRHist(r); SG(r) = SG(nd_psh[i]); - ndl_reconstruct(obpe,DL(nd_psh[i]),DL(r)); + ndl_reconstruct(obpe,oepos,DL(nd_psh[i]),DL(r)); nd_psh[i] = r; } if ( s0 ) NEXT(s) = 0; @@ -2548,9 +2673,11 @@ void nd_reconstruct_direct(int mod,NDV *ps,int len) RHist r; RHist *old_red; ND_pairs s0,s,t,prev_ndp_free_list; + EPOS oepos; obpe = nd_bpe; oadv = nmv_adv; + oepos = nd_epos; if ( obpe < 4 ) nd_bpe = 4; else if ( obpe < 6 ) nd_bpe = 6; else if ( obpe < 8 ) nd_bpe = 8; @@ -2562,7 +2689,7 @@ void nd_reconstruct_direct(int mod,NDV *ps,int len) prev_nm_free_list = _nm_free_list; prev_ndp_free_list = _ndp_free_list; _nm_free_list = 0; _ndp_free_list = 0; - for ( i = len-1; i >= 0; i-- ) ndv_realloc(ps[i],obpe,oadv); + for ( i = len-1; i >= 0; i-- ) ndv_realloc(ps[i],obpe,oadv,oepos); old_red = (RHist *)ALLOCA(REDTAB_LEN*sizeof(RHist)); for ( i = 0; i < REDTAB_LEN; i++ ) { old_red[i] = nd_red[i]; @@ -2573,7 +2700,7 @@ void nd_reconstruct_direct(int mod,NDV *ps,int len) NEWRHist(mr); mr->index = r->index; SG(mr) = SG(r); - ndl_reconstruct(obpe,DL(r),DL(mr)); + ndl_reconstruct(obpe,oepos,DL(r),DL(mr)); h = ndl_hash_value(DL(mr)); NEXT(mr) = nd_red[h]; nd_red[h] = mr; @@ -2585,43 +2712,49 @@ void nd_reconstruct_direct(int mod,NDV *ps,int len) GC_gcollect(); } -void ndl_reconstruct(int obpe,unsigned int *d,unsigned int *r) +void ndl_reconstruct(int obpe,EPOS oepos,unsigned int *d,unsigned int *r) { - int n,i,ei,oepw,cepw,cbpe; + int n,i,ei,oepw,omask0,j,s,ord_l,ord_o,l; + struct order_pair *op; +#define GET_EXP_OLD(d,a) (((d)[oepos[a].i]>>oepos[a].s)&omask0) +#define PUT_EXP_OLD(r,a,e) ((r)[oepos[a].i] |= ((e)<>((oepw-((n-1-i)%oepw)-1)*obpe)) - &((1<n; + op = nd_blockmask->order_pair; + for ( i = 1; i < nd_exporigin; i++ ) + r[i] = d[i]; + for ( j = 0, s = 0; j < l; j++ ) { + ord_o = op[j].order; + ord_l = op[j].length; + if ( !ord_o ) + for ( i = 0; i < ord_l; i++ ) { + ei = GET_EXP_OLD(d,s+ord_l-i-1); + PUT_EXP(r,s+ord_l-i-1,ei); + } + else + for ( i = 0; i < ord_l; i++ ) { + ei = GET_EXP_OLD(d,s+i); + PUT_EXP(r,s+i,ei); + } + s += ord_l; } - else - for ( i = 0; i < n; i++ ) { - ei = (d[i/oepw+nd_exporigin]>>((oepw-(i%oepw)-1)*obpe)) - &((1<id ) - error("nd_gr : unsupported order"); - nd_dcomp = 0; - switch ( ord->ord.simple ) { + switch ( ord->id ) { case 0: - nd_dcomp = 1; - nd_isrlex = 1; + switch ( ord->ord.simple ) { + case 0: + nd_dcomp = 1; + nd_isrlex = 1; + break; + case 1: + nd_dcomp = 1; + nd_isrlex = 0; + break; + case 2: + nd_dcomp = 0; + nd_isrlex = 0; + break; + default: + error("nd_gr : unsupported order"); + } break; case 1: - nd_dcomp = 1; + /* XXX */ + nd_dcomp = -1; nd_isrlex = 0; + nd_compare_function = ndl_block_compare; break; - case 9: - /* td1->td->rlex */ - nd_dcomp = -dp_nelim; - nd_isrlex = 1; + case 2: + error("nd_init_ord : matrix order is not supported yet."); break; - default: - error("nd_gr : unsupported order"); } nd_ord = ord; } +BlockMask nd_create_blockmask(struct order_spec *ord) +{ + int n,i,j,s,l; + unsigned int *t; + BlockMask bm; + + if ( !ord->id ) + return 0; + n = ord->ord.block.length; + bm = (BlockMask)MALLOC(sizeof(struct oBlockMask)); + bm->n = n; + bm->order_pair = ord->ord.block.order_pair; + bm->mask = (unsigned int **)MALLOC(n*sizeof(unsigned int *)); + for ( i = 0, s = 0; i < n; i++ ) { + bm->mask[i] = t + = (unsigned int *)MALLOC_ATOMIC(nd_wpd*sizeof(unsigned int)); + for ( j = 0; j < nd_wpd; j++ ) t[j] = 0; + l = bm->order_pair[i].length; + for ( j = 0; j < l; j++, s++ ) PUT_EXP(t,s,nd_mask0); + } + return bm; +}