=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.239 retrieving revision 1.244 diff -u -p -r1.239 -r1.244 --- OpenXM_contrib2/asir2000/engine/nd.c 2017/09/14 01:34:53 1.239 +++ OpenXM_contrib2/asir2000/engine/nd.c 2018/03/05 06:43:09 1.244 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.238 2017/08/31 02:36:21 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.243 2018/03/05 01:56:17 noro Exp $ */ #include "nd.h" @@ -65,7 +65,7 @@ static int *nd_gbblock; static NODE nd_nzlist,nd_check_splist; static int nd_splist; static int *nd_sugarweight; -static int nd_f4red,nd_rank0; +static int nd_f4red,nd_rank0,nd_last_nonzero; NumberField get_numberfield(); UINT *nd_det_compute_bound(NDV **dm,int n,int j); @@ -100,7 +100,7 @@ void nd_mul_c_lf(ND p,GZ mul); void ndv_mul_c_lf(NDV p,GZ mul); NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col, NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz); -NODE nd_f4_red_mod128_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col, +NODE nd_f4_red_mod64_main(int m,ND_pairs sp0,int nsp,UINT *s0vect,int col, NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred,ND_pairs *nz); NODE nd_f4_red_lf_main(int m,ND_pairs sp0,int nsp,int trace,UINT *s0vect,int col, NM_ind_pair *rvect,int *rhead,IndArray *imat,int nred); @@ -3228,7 +3228,7 @@ void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int NODE tr,tl1,tl2,tl3,tl4,nzlist; LIST l1,l2,l3,l4,l5; int j; - Q jq,bpe; + Q jq,bpe,last_nonzero; int *perm; EPOS oepos; int obpe,oadv,ompos,cbpe; @@ -3315,7 +3315,7 @@ void nd_gr(LIST f,LIST v,int m,int homo,int retdp,int } homogenize_order(ord,nvar,&ord1); nd_init_ord(ord1); - nd_setup_parameters(nvar+1,wmax); + nd_setup_parameters(nvar+1,nd_nzlist?0:wmax); for ( t = fd0; t; t = NEXT(t) ) ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos); } @@ -3387,7 +3387,9 @@ FINAL: if ( nd_gentrace ) { if ( f4 ) { STOQ(16,bpe); - tr = mknode(4,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe); MKLIST(*rp,tr); + STOQ(nd_last_nonzero,last_nonzero); + tr = mknode(5,*rp,(!ishomo&&homo)?ONE:0,BDY(nzlist),bpe,last_nonzero); MKLIST(*rp,tr); + } else { tl1 = reverse_node(tl1); tl2 = reverse_node(tl2); tl3 = reverse_node(tl3); @@ -3840,7 +3842,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int } get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1); if ( DP_Print ) - fprintf(asir_out,"check=%fsec\n",eg_check.exectime+eg_check.gctime); + fprintf(asir_out,"check=%.3fsec,",eg_check.exectime+eg_check.gctime); /* dp->p */ nd_bpe = cbpe; nd_setup_parameters(nd_nvar,0); @@ -5822,8 +5824,11 @@ int nd_to_vect(int mod,UINT *s0,int n,ND d,UINT *r) return i; } -#if defined(__GNUC__) -int nd_to_vect128(int mod,UINT *s0,int n,ND d,U128 *r) +#if defined(__GNUC__) && SIZEOF_LONG==8 + +#define MOD128(a,c,m) ((a)=(((c)!=0||((a)>=(m)))?(((((U128)(c))<<64)+(a))%(m)):(a))) + +int nd_to_vect64(int mod,UINT *s0,int n,ND d,U64 *r) { NM m; UINT *t,*s; @@ -5833,7 +5838,7 @@ int nd_to_vect128(int mod,UINT *s0,int n,ND d,U128 *r) for ( i = 0, s = s0, m = BDY(d); m; m = NEXT(m) ) { t = DL(m); for ( ; !ndl_equal(t,s); s += nd_wpd, i++ ); - r[i] = (U128)CM(m); + r[i] = (U64)CM(m); } for ( i = 0; !r[i]; i++ ); return i; @@ -6234,12 +6239,12 @@ int ndv_reduce_vect(int m,UINT *svect,int col,IndArray return maxrs; } -#if defined(__GNUC__) -int ndv_reduce_vect128(int m,U128 *svect,int col,IndArray *imat,NM_ind_pair *rp0,int nred) +#if defined(__GNUC__) && SIZEOF_LONG==8 + +int ndv_reduce_vect64(int m,U64 *svect,U64 *cvect,int col,IndArray *imat,NM_ind_pair *rp0,int nred) { int i,j,k,len,pos,prev; - U64 c,c1; - U128 a; + U64 a,c,c1,c2; IndArray ivect; unsigned char *ivc; unsigned short *ivs; @@ -6249,10 +6254,14 @@ int ndv_reduce_vect128(int m,U128 *svect,int col,IndAr NODE rp; int maxrs; + for ( i = 0; i < col; i++ ) cvect[i] = 0; maxrs = 0; for ( i = 0; i < nred; i++ ) { ivect = imat[i]; - k = ivect->head; svect[k] %= m; + k = ivect->head; + a = svect[k]; c = cvect[k]; + MOD128(a,c,m); + svect[k] = a; cvect[k] = 0; if ( c = svect[k] ) { maxrs = MAX(maxrs,rp0[i]->sugar); c = m-c; redv = nd_ps[rp0[i]->index]; @@ -6263,27 +6272,41 @@ int ndv_reduce_vect128(int m,U128 *svect,int col,IndAr ivc = ivect->index.c; for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { pos = prev+ivc[j]; c1 = CM(mr); prev = pos; - if ( c1 ) svect[pos] += c1*c; + if ( c1 ) { + c2 = svect[pos]+c1*c; + if ( c2 < svect[pos] ) cvect[pos]++; + svect[pos] = c2; + } } break; case 2: ivs = ivect->index.s; for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { pos = prev+ivs[j]; c1 = CM(mr); prev = pos; - if ( c1 ) svect[pos] += c1*c; + if ( c1 ) { + c2 = svect[pos]+c1*c; + if ( c2 < svect[pos] ) cvect[pos]++; + svect[pos] = c2; + } } break; case 4: ivi = ivect->index.i; for ( j = 1, NMV_ADV(mr); j < len; j++, NMV_ADV(mr) ) { pos = prev+ivi[j]; c1 = CM(mr); prev = pos; - if ( c1 ) svect[pos] += c1*c; + if ( c1 ) { + c2 = svect[pos]+c1*c; + if ( c2 < svect[pos] ) cvect[pos]++; + svect[pos] = c2; + } } break; } } } - for ( i = 0; i < col; i++ ) svect[i] %= m; + for ( i = 0; i < col; i++ ) { + a = svect[i]; c = cvect[i]; MOD128(a,c,m); svect[i] = a; + } return maxrs; } #endif @@ -6545,8 +6568,8 @@ NDV vect_to_ndv(UINT *vect,int spcol,int col,int *rhea } } -#if defined(__GNUC__) -NDV vect128o_ndv(U128 *vect,int spcol,int col,int *rhead,UINT *s0vect) +#if defined(__GNUC__) && SIZEOF_LONG==8 +NDV vect64_to_ndv(U64 *vect,int spcol,int col,int *rhead,UINT *s0vect) { int j,k,len; UINT *p; @@ -6781,11 +6804,20 @@ int nd_symbolic_preproc(PGeoBucket bucket,int trace,UI return col; } +void print_ndp(ND_pairs l) +{ + ND_pairs t; + + for ( t = l; t; t = NEXT(t) ) + printf("[%d,%d] ",t->i1,t->i2); + printf("\n"); +} + NODE nd_f4(int m,int checkonly,int **indp) { int i,nh,stat,index,f4red; NODE r,g,tn0,tn,node; - ND_pairs d,l,t,ll0,ll; + ND_pairs d,l,t,ll0,ll,lh; LIST l0,l1; ND spol,red; NDV nf,redv; @@ -6799,7 +6831,7 @@ NODE nd_f4(int m,int checkonly,int **indp) IndArray *imat; int *rhead; int spcol,sprow; - int sugar; + int sugar,sugarh; PGeoBucket bucket; struct oEGT eg0,eg1,eg_f4; Q i1,i2,sugarq; @@ -6808,37 +6840,35 @@ NODE nd_f4(int m,int checkonly,int **indp) #endif g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - if ( !nd_nzlist ) d = update_pairs(d,g,i,0); + d = update_pairs(d,g,i,0); g = update_base(g,i); } nzlist = 0; nzlist_t = nd_nzlist; - f4red = 0; - while ( d || nzlist_t ) { + f4red = 1; + nd_last_nonzero = 0; + while ( d ) { get_eg(&eg0); - if ( nd_nzlist ) { + l = nd_minsugarp(d,&d); + sugar = nd_sugarweight?l->sugar2:SG(l); + if ( MaxDeg > 0 && sugar > MaxDeg ) break; + if ( nzlist_t ) { node = BDY((LIST)BDY(nzlist_t)); - sugar = (int)ARG0(node); + sugarh = QTOS((Q)ARG0(node)); tn = BDY((LIST)ARG1(node)); if ( !tn ) { nzlist_t = NEXT(nzlist_t); continue; } /* tn = [[i1,i2],...] */ - l = nd_ipairtospair(tn); - } else { - l = nd_minsugarp(d,&d); - sugar = nd_sugarweight?l->sugar2:SG(l); - if ( MaxDeg > 0 && sugar > MaxDeg ) break; + lh = nd_ipairtospair(tn); } bucket = create_pbucket(); stat = nd_sp_f4(m,0,l,bucket); if ( !stat ) { - if ( !nd_nzlist ) { - for ( t = l; NEXT(t); t = NEXT(t) ); - NEXT(t) = d; d = l; - d = nd_reconstruct(0,d); - } + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(0,d); continue; } if ( bucket->m < 0 ) continue; @@ -6851,11 +6881,12 @@ NODE nd_f4(int m,int checkonly,int **indp) } get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); if ( DP_Print ) - fprintf(asir_out,"sugar=%d,symb=%fsec,", + fprintf(asir_out,"sugar=%d,symb=%.3fsec,", sugar,eg_f4.exectime+eg_f4.gctime); - nflist = nd_f4_red(m,l,0,s0vect,col,rp0,nd_gentrace?&ll:0); + nflist = nd_f4_red(m,nd_nzlist?lh:l,0,s0vect,col,rp0,nd_gentrace?&ll:0); if ( checkonly && nflist ) return 0; /* adding new bases */ + if ( nflist ) nd_last_nonzero = f4red; for ( r = nflist; r; r = NEXT(r) ) { nf = (NDV)BDY(r); ndv_removecont(m,nf); @@ -6868,11 +6899,11 @@ NODE nd_f4(int m,int checkonly,int **indp) nf = ndtondv(m,nf1); } nh = ndv_newps(m,nf,0,1); - if ( !nd_nzlist ) d = update_pairs(d,g,nh,0); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } if ( DP_Print ) { - fprintf(asir_out,"f4red=%d,gblen=%d,",f4red,length(g)); fflush(asir_out); + fprintf(asir_out,"f4red=%d,gblen=%d\n",f4red,length(g)); fflush(asir_out); } if ( nd_gentrace ) { for ( t = ll, tn0 = 0; t; t = NEXT(t) ) { @@ -6887,7 +6918,7 @@ NODE nd_f4(int m,int checkonly,int **indp) } if ( nd_nzlist ) nzlist_t = NEXT(nzlist_t); f4red++; - if ( nd_f4red && f4red >= nd_f4red ) break; + if ( nd_f4red && f4red > nd_f4red ) break; if ( nd_rank0 && !nflist ) break; } if ( nd_gentrace ) { @@ -6950,7 +6981,7 @@ NODE nd_f4_trace(int m,int **indp) } get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); if ( DP_Print ) - fprintf(asir_out,"sugar=%d,symb=%fsec,", + fprintf(asir_out,"sugar=%d,symb=%.3fsec,", sugar,eg_f4.exectime+eg_f4.gctime); nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0); if ( !l0 ) continue; @@ -7164,7 +7195,7 @@ init_eg(&eg_search); get_eg(&eg2); init_eg(&eg_elim2); add_eg(&eg_elim2,&eg1,&eg2); if ( DP_Print ) { - fprintf(asir_out,"elim1=%fsec,elim2=%fsec\n", + fprintf(asir_out,"elim1=%.3fsec,elim2=%.3fsec,", eg_elim1.exectime+eg_elim1.gctime,eg_elim2.exectime+eg_elim2.gctime); fflush(asir_out); } @@ -7195,7 +7226,7 @@ init_eg(&eg_search); /* construction of index arrays */ if ( DP_Print ) { - fprintf(stderr,"%dx%d,",nsp+nred,col); + fprintf(asir_out,"%dx%d,",nsp+nred,col); } rvect = (NM_ind_pair *)MALLOC(nred*sizeof(NM_ind_pair)); s0hash = (int *)MALLOC(col*sizeof(int)); @@ -7206,13 +7237,12 @@ init_eg(&eg_search); imat[i] = nm_ind_pair_to_vect_compress(trace,s0vect,col,s0hash,rvect[i]); rhead[imat[i]->head] = 1; } -#if defined(__GNUC__) - if ( m >= (1<<15) ) - r0 = nd_f4_red_mod128_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz); - else -#endif if ( m > 0 ) +#if defined(__GNUC__) && SIZEOF_LONG==8 + r0 = nd_f4_red_mod64_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz); +#else r0 = nd_f4_red_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz); +#endif else if ( m == -1 ) r0 = nd_f4_red_sf_main(m,sp0,nsp,s0vect,col,rvect,rhead,imat,nred,nz); else if ( m == -2 ) @@ -7223,7 +7253,9 @@ init_eg(&eg_search); #else r0 = nd_f4_red_gz_main(sp0,nsp,trace,s0vect,col,rvect,rhead,imat,nred); #endif +#if 0 if ( DP_Print ) print_eg("search",&eg_search); +#endif return r0; } @@ -7274,7 +7306,7 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s } get_eg(&eg1); init_eg(&eg_f4_1); add_eg(&eg_f4_1,&eg0,&eg1); if ( DP_Print ) { - fprintf(asir_out,"elim1=%fsec,",eg_f4_1.exectime+eg_f4_1.gctime); + fprintf(asir_out,"elim1=%.3fsec,",eg_f4_1.exectime+eg_f4_1.gctime); fflush(asir_out); } /* free index arrays */ @@ -7299,10 +7331,10 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s get_eg(&eg2); init_eg(&eg_f4_2); add_eg(&eg_f4_2,&eg1,&eg2); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg2); if ( DP_Print ) { - fprintf(asir_out,"elim2=%fsec\n",eg_f4_2.exectime+eg_f4_2.gctime); - fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ", + fprintf(asir_out,"elim2=%.3fsec,",eg_f4_2.exectime+eg_f4_2.gctime); + fprintf(asir_out,"nsp=%d,nred=%d,spmat=(%d,%d),rank=%d ", nsp,nred,sprow,spcol,rank); - fprintf(asir_out,"%fsec\n",eg_f4.exectime+eg_f4.gctime); + fprintf(asir_out,"%.3fsec,",eg_f4.exectime+eg_f4.gctime); } if ( nz ) { for ( i = 0; i < rank-1; i++ ) NEXT(spactive[i]) = spactive[i+1]; @@ -7315,10 +7347,10 @@ NODE nd_f4_red_main(int m,ND_pairs sp0,int nsp,UINT *s return r0; } -#if defined(__GNUC__) +#if defined(__GNUC__) && SIZEOF_LONG==8 /* for Fp, 2^15== md ) a %= md; - *pk = ((U64)a*inv)%md; - } - for ( i = rank+1; i < row; i++ ) { - t = mat[i]; - if ( a = (t[j]%md) ) { - sugar[i] = MAX(sugar[i],s); - red_by_vect128(md,t+j,pivot+j,(int)(md-a),col-j); - } - } - rank++; + cmat = (UINT **)MALLOC(row*sizeof(UINT *)); + for ( i = 0; i < row; i++ ) { + cmat[i] = MALLOC_ATOMIC(col*sizeof(UINT)); + bzero(cmat[i],col*sizeof(UINT)); + } + + for ( rank = 0, j = 0; j < col; j++ ) { + for ( i = rank; i < row; i++ ) { + a = mat[i][j]; c = cmat[i][j]; + MOD128(a,c,md); + mat[i][j] = a; cmat[i][j] = 0; } - for ( j = col-1, l = rank-1; j >= 0; j-- ) - if ( colstat[j] ) { - pivot = mat[l]; - for ( k = j; k < col; k++ ) - if ( pivot[k] >= md ) pivot[k] %= md; - s = sugar[l]; - for ( i = 0; i < l; i++ ) { - t = mat[i]; - t[j] %= md; - if ( a = (t[j]%md) ) { - sugar[i] = MAX(sugar[i],s); - red_by_vect128(md,t+j,pivot+j,(int)(md-a),col-j); - } - } - l--; + for ( i = rank; i < row; i++ ) + if ( mat[i][j] ) + break; + if ( i == row ) { + colstat[j] = 0; + continue; + } else + colstat[j] = 1; + if ( i != rank ) { + t = mat[i]; mat[i] = mat[rank]; mat[rank] = t; + ct = cmat[i]; cmat[i] = cmat[rank]; cmat[rank] = ct; + s = sugar[i]; sugar[i] = sugar[rank]; sugar[rank] = s; + if ( spactive ) { + pair = spactive[i]; spactive[i] = spactive[rank]; + spactive[rank] = pair; + } + } + /* column j is normalized */ + s = sugar[rank]; + inv = invm((UINT)mat[rank][j],md); + /* normalize pivot row */ + for ( k = j, pk = mat[rank]+j, ck = cmat[rank]+j; k < col; k++, pk++, ck++ ) { + a = *pk; c = *ck; MOD128(a,c,md); *pk = (a*inv)%md; *ck = 0; + } + for ( i = rank+1; i < row; i++ ) { + if ( a = mat[i][j] ) { + sugar[i] = MAX(sugar[i],s); + red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[rank]+j,(int)(md-a),col-j); + } + } + rank++; + } + for ( j = col-1, l = rank-1; j >= 0; j-- ) + if ( colstat[j] ) { + for ( k = j, pk = mat[l]+j, ck = cmat[l]+j; k < col; k++, pk++, ck++ ) { + a = *pk; c = *ck; MOD128(a,c,md); *pk = a; *ck = 0; + } + s = sugar[l]; + for ( i = 0; i < l; i++ ) { + a = mat[i][j]; c = cmat[i][j]; MOD128(a,c,md); mat[i][j] = a; cmat[i][j] = 0; + if ( a ) { + sugar[i] = MAX(sugar[i],s); + red_by_vect64(md,mat[i]+j,cmat[i]+j,mat[l]+j,(int)(md-a),col-j); } - return rank; + } + l--; + } + for ( i = 0; i < row; i++ ) GCFREE(cmat[i]); + GCFREE(cmat); + return rank; } #endif @@ -8330,7 +8377,7 @@ void nd_det(int mod,MAT f,P *rp) chsgnq(ONE,&mone); for ( j = 0, sgn = 1; j < n; j++ ) { if ( DP_Print ) { - fprintf(stderr,".",j); + fprintf(asir_out,".",j); } for ( i = j; i < n && !dm[i][j]; i++ ); if ( i == n ) { @@ -8360,14 +8407,14 @@ void nd_det(int mod,MAT f,P *rp) nd_det_reconstruct(dm,n,j,d); for ( i = j+1, mj = dm[j], mjj = mj[j]; i < n; i++ ) { -/* if ( DP_Print ) fprintf(stderr," i=%d\n ",i); */ +/* if ( DP_Print ) fprintf(asir_out," i=%d\n ",i); */ mi = dm[i]; mij = mi[j]; if ( mod ) ndv_mul_c(mod,mij,mod-1); else ndv_mul_c_q(mij,mone); for ( k = j+1; k < n; k++ ) { -/* if ( DP_Print ) fprintf(stderr,"k=%d ",k); */ +/* if ( DP_Print ) fprintf(asir_out,"k=%d ",k); */ bucket = create_pbucket(); if ( mi[k] ) { nmv = BDY(mjj); len = LEN(mjj); @@ -8386,12 +8433,12 @@ void nd_det(int mod,MAT f,P *rp) u = nd_quo(mod,bucket,d); mi[k] = ndtondv(mod,u); } -/* if ( DP_Print ) fprintf(stderr,"\n",k); */ +/* if ( DP_Print ) fprintf(asir_out,"\n",k); */ } d = mjj; } if ( DP_Print ) { - fprintf(stderr,"\n",k); + fprintf(asir_out,"\n",k); } if ( sgn < 0 ) if ( mod ) @@ -8753,9 +8800,11 @@ void parse_nd_option(NODE opt) else if ( !strcmp(key,"lf") ) nd_lf = value?1:0; else if ( !strcmp(key,"trace") ) { - u = BDY((LIST)value); - nd_nzlist = BDY((LIST)ARG2(u)); - nd_bpe = QTOS((Q)ARG3(u)); + if ( value ) { + u = BDY((LIST)value); + nd_nzlist = BDY((LIST)ARG2(u)); + nd_bpe = QTOS((Q)ARG3(u)); + } } else if ( !strcmp(key,"f4red") ) { nd_f4red = QTOS((Q)value); } else if ( !strcmp(key,"rank0") ) { @@ -9190,7 +9239,7 @@ void nd_f4_lf_trace(LIST f,LIST v,int trace,int homo,s } get_eg(&eg1); init_eg(&eg_check); add_eg(&eg_check,&eg0,&eg1); if ( DP_Print ) - fprintf(asir_out,"check=%fsec\n",eg_check.exectime+eg_check.gctime); + fprintf(asir_out,"check=%.3fsec\n",eg_check.exectime+eg_check.gctime); /* dp->p */ nd_bpe = cbpe; nd_setup_parameters(nd_nvar,0); @@ -9250,7 +9299,7 @@ NODE nd_f4_lf_trace_main(int m,int **indp) } get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); if ( DP_Print ) - fprintf(asir_out,"sugar=%d,symb=%fsec,", + fprintf(asir_out,"sugar=%d,symb=%.3fsec,", sugar,eg_f4.exectime+eg_f4.gctime); nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0); if ( !l0 ) continue;