void compute_witness_sets(int myid, int stages, int cnt_stage, int numbprocs, int NUM_GROUP, int NUM_VARS, int num_group, WSET *ws, int *TaskCount, int *cnt_index, char filename[50], int *remainder_pos, int remainder[2][2]) { int cnt_step, expected=0, dim=0, cnt_dim=0, update_flag=0, fail, cnt_numgroup, slv, i, remainderjob=0, quit=1, record_flag=0, dimension; WSET *wspointer_1, *wspointer_2; LISTELEMENT *lp=NULL; IDLE_ELEMENT *ie=NULL; char *name_1, *name_2, *namebase, *infile, *outfile; JOB *temp_j; MPI_Status status; double groupwtime; if(myid == 0) { for(slv=1;slv<=numbprocs-1;slv++) ie = addslv(ie, slv); if((int)fmod(num_group,2)==0 && *remainder_pos==1) record_flag=1; } while(quit) { for(cnt_numgroup=1;cnt_numgroup<=num_group;cnt_numgroup++) { /* 3 steps: starting of a diagonal homotopy; cascading; collapse; */ for(cnt_step=1;cnt_step<=3;cnt_step++) { if(myid == 0) {groupwtime=MPI_Wtime(); printf("\n -------- cnt_step=%d --------------\n", cnt_step); } else if(v>3) printf("node %d is ready! \n", myid); /* for starting a diagonal homotopy */ if(cnt_step==1) { if(myid==0) { if(remainderjob!=1) { printf("start the JOBs for GROUP %d\n", cnt_numgroup); printf("ws[%d][%d]:\n", cnt_numgroup*2-2, cnt_stage-1); print_ws(ws+(cnt_numgroup*2-2)*(stages+1)+(cnt_stage-1)); printf("ws[%d][%d]:\n", cnt_numgroup*2-1, cnt_stage-1); print_ws(ws+(cnt_numgroup*2-1)*(stages+1)+(cnt_stage-1)); wspointer_1 = ws+(cnt_numgroup*2-2)*(stages+1)+(cnt_stage-1); wspointer_2 = ws+(cnt_numgroup*2-1)*(stages+1)+(cnt_stage-1); } if(remainderjob==1 || (cnt_stage==stages && *remainder_pos==1)) { printf("start the JOBs for remainders:\n"); printf("ws[%d][%d]:\n", remainder[0][0], remainder[0][1]); print_ws(ws+remainder[0][0]*(stages+1)+remainder[0][1]); printf("ws[%d][%d]:\n", remainder[1][0], remainder[1][1]); print_ws(ws+remainder[1][0]*(stages+1)+remainder[1][1]); wspointer_1 = ws+remainder[0][0]*(stages+1)+remainder[0][1]; wspointer_2 = ws+remainder[1][0]*(stages+1)+remainder[1][1]; *remainder_pos = -1; remainderjob = 1; } lp = add_jobs(wspointer_1, wspointer_2, lp); temp_j = (JOB *) (lp->dataitem); namebase = (char *) calloc(100+temp_j->num_eqns_1+temp_j->num_eqns_2,sizeof(char)); name_1 = (char *) calloc(100+temp_j->num_eqns_1+temp_j->num_eqns_2, sizeof(char)); name_2 = (char *) calloc(100+temp_j->num_eqns_1+temp_j->num_eqns_2, sizeof(char)); infile = (char *) calloc(100+temp_j->num_eqns_1+temp_j->num_eqns_2, sizeof(char)); outfile = (char *) calloc(100+temp_j->num_eqns_1+temp_j->num_eqns_2, sizeof(char)); obtain_namebase(filename, temp_j, namebase, name_1, name_2); sprintf(outfile, "%s_%d", namebase, cnt_step); if(cnt_stage!=1 && remainderjob!=1) { name_1 = strcat(name_1, "_3"); name_2 = strcat(name_2, "_3");} else { if(remainderjob==1) { if(remainder[0][1]!=0) /* 1st remainder is not from ws[x][0] */ name_1 = strcat(name_1, "_3"); /* 2nd remainder is not from ws[xx][0] */ name_2 = strcat(name_2, "_3"); printf("change remainderjob=0\n"); remainderjob=0; } } printf("name_1=%s\n", name_1); printf("name_2=%s\n", name_2); printf("outfile=%s\n", outfile); } MPI_Barrier(MPI_COMM_WORLD); start_a_diagonal_homotopy(myid, numbprocs, name_1, name_2, outfile, ws, num_group, stages, cnt_stage, cnt_step, &ie, &lp, TaskCount, NUM_GROUP, NUM_VARS, cnt_index, &expected, &dim, update_flag); MPI_Barrier(MPI_COMM_WORLD); /*stack overflow, erroneous access error! WHY????? /*MPI_Bcast(&dim,sizeof(int),MPI_INT,0,MPI_COMM_WORLD); */ if(myid==0) { for(slv=1;slv<=numbprocs-1;slv++) MPI_Send(&dim,sizeof(int),MPI_INT,slv,DIM_TAG,MPI_COMM_WORLD); } else MPI_Recv(&dim,sizeof(int),MPI_INT,0,DIM_TAG,MPI_COMM_WORLD,&status); MPI_Barrier(MPI_COMM_WORLD); if(v>3) printf("node %d knows dim=%d\n", myid, dim); if(myid==0) { printf("dim=%d\n", dim); if(v>1) { printf("outside of start_a_diagonal_homotopy\n"); printf("expected dimension=%d\n", expected); printf("dim=%d\n", dim); printf("%d JOBs in lp\n", length(lp)); printf("%d idles\n", num_idle(ie)); printf("indexing........ with cnt_index=%d\n", *cnt_index); } } else if(v>1) {printf("node %d finishes step 1 \n", myid); fflush;} } /* cnt_step==1 */ MPI_Barrier(MPI_COMM_WORLD); /* for one-level-down cascade homotopy */ if(cnt_step==2) { if(myid==0) { /* the state table is updated only at cnt_step==2 */ if(dim==1) update_flag=1; lp = add_jobs(wspointer_1, wspointer_2, lp); printf("namebase=%s\n", namebase); sprintf(infile, "%s_%d", namebase, cnt_step-1); sprintf(outfile, "%s_%d", namebase, cnt_step); printf("infile=%s\n", infile); printf("outfile=%s\n", outfile); } MPI_Barrier(MPI_COMM_WORLD); cascade_one_level_down(myid, numbprocs, infile, outfile, ws, num_group, stages, cnt_stage, cnt_step, &ie, &lp, TaskCount, NUM_GROUP, &dimension, cnt_index, update_flag); /* dim => (dim-1) times of {remove last slack variable and cascade} */ if(dim>1) { for(cnt_dim=1;cnt_dim<=dim-1;cnt_dim++) { if(myid==0) { /*the state table need to be updated when the last cascade is done. */ if(cnt_dim==dim-1) update_flag=1; printf("removing last slack variable \n"); sprintf(infile, "%s", outfile); sprintf(outfile, "%s%s", outfile, "r"); printf("infile=%s\n", infile); printf("outfile=%s\n", outfile); remove_last_slack_variable(infile, outfile); printf("dimension=%d\n", dimension); fail = syscon_remove_symbol_from_table(dimension); sprintf(infile, "%s", outfile); sprintf(outfile, "%s%d", outfile, cnt_step); printf("%d times cascade_one_level_down\n", cnt_dim+1); printf("infile=%s\n", infile); printf("outfile=%s\n", outfile); lp = add_jobs(wspointer_1, wspointer_2, lp); } MPI_Barrier(MPI_COMM_WORLD); cascade_one_level_down(myid, numbprocs, infile, outfile, ws, num_group, stages, cnt_stage, cnt_step, &ie, &lp, TaskCount, NUM_GROUP, &dimension, cnt_index, update_flag); } } /* dim>1 */ } /* cnt_step==2 */ MPI_Barrier(MPI_COMM_WORLD); /* for collapsing the extrinsic diagonal */ if(cnt_step==3) { /* only manager does collapsing */ if(myid==0) { sprintf(infile, "%s", outfile); sprintf(outfile, "%s_%d", namebase, cnt_step); printf("infile=%s\n", infile); printf("outfile=%s\n", outfile); collapse(cnt_stage, stages, infile, outfile, ws, cnt_index, &expected); if(v>1) { printf("outside of collapse\n"); printf("%d idles\n", num_idle(ie)); printf("indexing........ with cnt_index=%d\n", *cnt_index); } } /* myid==0 */ } /* cnt_step==3 */ MPI_Barrier(MPI_COMM_WORLD); if(myid==0) update_flag=0; } /* for cnt_step */ if(myid == 0) { free(namebase); free(name_1); free(name_2); free(infile); free(outfile); printf("group %d: %lf seconds ", cnt_numgroup, MPI_Wtime()-groupwtime); } }/* for cnt_numgroup */ if(myid == 0) { if(*remainder_pos==1) { num_group=1; remainderjob=1; } else { quit=0; if(record_flag) { printf("in compute_witness_sets\n"); printf("*remainder_pos=%d\n", *remainder_pos); (*remainder_pos)++; remainder[*remainder_pos][0] = *cnt_index-1; remainder[*remainder_pos][1] = cnt_stage; printf("record remainder: ws[%d][%d]\n", remainder[*remainder_pos][0], remainder[*remainder_pos][1]); printf("*remainder_pos=%d\n", *remainder_pos); } } } MPI_Bcast(&num_group,sizeof(int),MPI_INT,0,MPI_COMM_WORLD); MPI_Bcast(&quit,sizeof(int),MPI_INT,0,MPI_COMM_WORLD); MPI_Barrier(MPI_COMM_WORLD); } }
void print_separator (void) { putchar ('@'); print_ws (53); puts ("@@"); }
void send_collect(WSET *ws, int num_group, int stages, int cnt_stage, int numbprocs, int cnt_step, IDLE_ELEMENT **ie, LISTELEMENT **listpointer, int *TaskCount, int NUM_GROUP, int *cnt_index, int update_flag, int n1, int n2, int cd) { int slv,flght,flag,*buffer,*package,count,cnt_count, idle_procs[numbprocs],idle_pos,cnt_idle, r,c,s_max,s_min, deg,n=cd,m[2],send[3],label_sol,fail,i=0,j=0; double sol1[2*n1+5], sol2[2*n2+5], ps[2*cd+5]; WSET *ws_p; JOB *temp_j; MPI_Status status; if(v>3) printf("inside of send_collect\n"); fflush; temp_j = (JOB *)((*listpointer)->dataitem); count = temp_j->num_eqns_1 + temp_j->num_eqns_2 + 8; if(cnt_step==2 && update_flag) { package = (int*) malloc(count*sizeof(int)); pack(count, temp_j, package); } cnt_idle = num_idle(*ie); /* Initial JOB distribution */ while(*ie != NULL) /* there are idle processors */ { if(*listpointer!=NULL) /* JOB queue is not empty */ { /* pop one JOB from the queue */ *listpointer = removeitem (*listpointer); slv = (*ie)->data; *ie = removeslv(*ie); /* obtain start solution & send */ if(v>3) printf("sent a job & path to node %d.\n",slv); if(cnt_step==1) { if(v>3) fail = get_next_start_product (&i,&j,1,temp_j->num_vars_1,temp_j->num_vars_2, temp_j->dim_1,temp_j->dim_2, temp_j->deg_1,temp_j->deg_2,cd,sol1,sol2,ps); else fail = get_next_start_product (&i,&j,0,temp_j->num_vars_1,temp_j->num_vars_2, temp_j->dim_1,temp_j->dim_2, temp_j->deg_1,temp_j->deg_2,cd,sol1,sol2,ps); m[0] = n; m[1] = 1; send[0] = slv; send[1] = m[1]; send[2] = m[0]; MPI_Send(send,3,MPI_INT,slv,SEND_SMUL,MPI_COMM_WORLD); MPI_Send(ps,2*n+5,MPI_DOUBLE,slv,SEND_SSOL,MPI_COMM_WORLD); } if(cnt_step==2) { fail = solcon_read_next_solution(n,&m[1],ps); if(fail>0) printf("solcon_read_next_solution fail!\n"); m[0] = n; send[0] = slv; send[1] = m[1]; send[2] = m[0]; MPI_Send(send,3,MPI_INT,slv,SEND_SMUL,MPI_COMM_WORLD); MPI_Send(ps,2*n+5,MPI_DOUBLE,slv,SEND_SSOL,MPI_COMM_WORLD); } /* end of obtaining start solution & sending */ *(TaskCount+slv-1)=*(TaskCount+slv-1)+1; } else break; } flght = cnt_idle - num_idle(*ie); flag = 0; while(flght>0 || *listpointer!=NULL) /* JOB queue loop */ { if(flght>0) { MPI_Iprobe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&flag,&status); while(flag) /* while flag -- pending recv */ { if(v>3) printf("manager starting recv... \n"); slv = status.MPI_SOURCE; /* which slave sent this JOB back */ /* recv end solution */ MPI_Recv(ps,2*n+7,MPI_DOUBLE,MPI_ANY_SOURCE,SEND_TSOL, MPI_COMM_WORLD,&status); m[1] = (int) ps[2*n+5]; label_sol = (int) ps[2*n+6] - 1; fail = solcon_write_next_solution_to_defined_output_file (&label_sol,n,m[1],ps); /* end of recv. end solution */ /* update idle processor list */ *ie = addslv(*ie, slv); /* update corresponding cell when cnt_step==2 && update_flag is TRUE */ if(cnt_step==2 && update_flag) { c = cnt_stage; r = *cnt_index; ws_p = ws+r*(stages+1)+c; if(ws_p->count==0) /* first returned JOB for current witness set */ { printf("update num_eqns, source, dim, deg\n"); ws_p->num_eqns = package[0]; ws_p->source = (int*) malloc(package[0]*sizeof(int)); deg = 1; for(cnt_count=0;cnt_count<package[0];cnt_count++) { ws_p->source[cnt_count] = package[cnt_count+1]; printf("ws[%d][%d].source[%d]=%d\n",r,c,cnt_count,ws_p->source[cnt_count]); deg = (ws+(package[cnt_count+1]-1)*(stages+1))->deg*deg; } ws_p->dim = package[package[0]+1]; /*ws_p->sols = (int*) malloc(deg*sizeof(int));*/ ws_p->deg = deg; } /*ws_p->sols[ws_p->count]=ws_p->count+1; */ ws_p->count++; if(ws_p->count==ws_p->deg) /* this witness set is complete */ { if(ws_p->num_eqns==NUM_GROUP) { printf("\nrecord [%d][%d]\n", r,c); printf("ALL DONE! aha........\n"); print_ws(ws_p); } } /* if: count==deg */ } /* cnt_step == 2 && update_flag */ if(*listpointer!=NULL) /* JOB queue is not empty */ { /* pop one JOB from the queue */ *listpointer = removeitem (*listpointer); slv = (*ie)->data; *ie = removeslv(*ie); if(v>3) printf("sending a job & path to node %d.\n",slv); /* obtain start solution & send */ if(cnt_step==1) { if(v>3) fail = get_next_start_product (&i,&j,1,temp_j->num_vars_1,temp_j->num_vars_2, temp_j->dim_1,temp_j->dim_2, temp_j->deg_1,temp_j->deg_2,cd,sol1,sol2,ps); else fail = get_next_start_product (&i,&j,0,temp_j->num_vars_1,temp_j->num_vars_2, temp_j->dim_1,temp_j->dim_2, temp_j->deg_1,temp_j->deg_2,cd,sol1,sol2,ps); m[0] = n; m[1] = 1; send[0] = slv; send[1] = m[1]; send[2] = m[0]; MPI_Send(send,3,MPI_INT,slv,SEND_SMUL,MPI_COMM_WORLD); MPI_Send(ps,2*n+5,MPI_DOUBLE,slv,SEND_SSOL,MPI_COMM_WORLD); } if(cnt_step==2) { fail = solcon_read_next_solution(n,&m[1],ps); m[0] = n; send[0] = slv; send[1] = m[1]; send[2] = m[0]; MPI_Send(send,3,MPI_INT,slv,SEND_SMUL,MPI_COMM_WORLD); MPI_Send(ps,2*n+5,MPI_DOUBLE,slv,SEND_SSOL,MPI_COMM_WORLD); } /* end of obtaining start solution & sending */ *(TaskCount+slv-1)=*(TaskCount+slv-1)+1; } else /* JOB queue is empty */ { flght=flght-1; /* one in-flight task less */ if(v>3) {printf ("Job queue empty!\n"); printf("flght=%d\n",flght); } } MPI_Iprobe(MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&flag,&status); } /* while flag */ } /* if flght */ } /* while flght listpointer */ /* send termination to all workers */ if(v>3) printf("\nmanager sent termination\n"); for(slv=1;slv<=numbprocs-1;slv++) { count = -1; MPI_Send(&count,1,MPI_INT,slv,COUNT_TAG,MPI_COMM_WORLD); } }