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); } }
void distribute_cells ( int myid, int np, int nspt, int dim, int *nbpaths ) { int nbcell,*cell,nbsols,i,j,k,left[np],L,R,*m,sn,mysolnum; int count,labSize,cnt,dest; MPI_Status status; MPI_Comm com = MPI_COMM_WORLD; int length[nspt],*labels ; int fail,A[2],n; double normal[dim],sol[2*(dim-1)+5],*c; lisStack *s; int *a,*b; n=dim-1;A[0]=n; if(myid == 0) { fail=celcon_number_of_cells(&nbcell); /* get the number of cells */ cell=(int*)calloc(nbcell,sizeof(int)); for(i=0; i<nbcell; i++) fail = celcon_mixed_volume(i+1,&cell[i]); nbsols=0; for(i=0; i<nbcell; i++) nbsols=nbsols+cell[i]; if(v>0) printf("The number cells are %d\n",nbcell); if(v>0) print_cell(nbcell,cell); if(v>0) printf("The total solutions are %d\n",nbsols); } MPI_Bcast(&nbsols,1,MPI_INT,0,com); if(myid == 0) { if(v>0) printf("\n"); left[0] = 0; for(i=1; i<np; i++) if(i <= (nbsols%(np-1))) left[i] = nbsols/(np-1)+1; else left[i] = nbsols/(np-1); if(v>0) printf("left:"); if(v>0) Print_Integer_Array(np,left); } MPI_Scatter(left,1,MPI_INT,&mysolnum,1,MPI_INT,0,com); if(myid == 0) { fail = celcon_number_of_points_in_cell(1,nspt,length); labSize=0; for(i=0; i<nspt; i++) labSize = labSize+length[i]; labSize = 1+nspt+labSize; } MPI_Bcast(&labSize,1,MPI_INT,0,MPI_COMM_WORLD); labels = (int*)calloc(labSize,sizeof(int)); m=(int*)calloc(3,sizeof(int)); if(myid==0) { L=1; R=np-1; for(i=0; i<nbcell; i++) { m[0] = i+1; m[2] = labSize; celcon_retrieve_mixed_cell(dim,nspt,i+1,labels,normal); sn=1; while(cell[i]!=0) { if(cell[i]>=left[L]) { m[1] = left[L]; m[2] = sn; MPI_Send(&m[1],2,MPI_INT,L,SEND_CELL,com); /* if(v>0) printf("%2d paths from cell %d is sending to node %d\n", m[1],m[0],L); */ MPI_Send(labels,labSize,MPI_INT,L,SEND_SUPP,com); MPI_Send(normal,dim,MPI_DOUBLE,L,SEND_NORMAL,com) ; cell[i] = cell[i]-left[L]; sn = sn+left[L]; L++; } else if(cell[i]>=left[R]) { m[1] = left[R]; m[2] = sn; MPI_Send(&m[1],2,MPI_INT,R,SEND_CELL,com); /* if(v>0) printf("%2d paths from cell %d is sending to node %d\n", m[1],m[0],R); */ MPI_Send(labels,labSize,MPI_INT,R,SEND_SUPP,com); MPI_Send(normal,dim,MPI_DOUBLE,R,SEND_NORMAL,com) ; cell[i] = cell[i]-left[R]; sn = sn+left[R]; R--; } else { m[1] = cell[i]; m[2] = sn; MPI_Send(&m[1],2,MPI_INT,R,SEND_CELL,com); /* if(v>0) printf("%2d paths from cell %d is sending to node %d\n", m[1],m[0],R); */ MPI_Send(labels,labSize,MPI_INT,R,SEND_SUPP,com); MPI_Send(normal,dim,MPI_DOUBLE,R,SEND_NORMAL,com); left[R]=left[R]-cell[i]; sn = sn+cell[i]; cell[i]=0; } } } if(v>0) printf("****************************************************\n"); printf("writing random coefficient system and its solutions to file\n"); fail = celcon_write_random_coefficient_system(); fail = solcon_write_solution_dimensions_to_defined_output_file(nbsols,n); cnt = 0; for(k=1; k<=nbsols; k++) { MPI_Recv(&A[1],1,MPI_INT,MPI_ANY_SOURCE,SEND_MUL, MPI_COMM_WORLD,&status); MPI_Recv(sol,2*n+5,MPI_DOUBLE,MPI_ANY_SOURCE,SEND_SOL, MPI_COMM_WORLD,&status); fail = solcon_write_next_solution_to_defined_output_file (&cnt,n,A[1],sol); } *nbpaths = nbsols; } /* myid=0 finish */ else { *nbpaths = mysolnum; if(v>0) printf("Node %d has %d paths\n",myid,mysolnum); s=(lisStack*)calloc(1,sizeof(lisStack)); ls_init(s); count = 0; sn = 0; while(count < mysolnum) { MPI_Recv(&m[1],2,MPI_INT,0,SEND_CELL,com,&status); sn++; m[0] = sn; ls_push(s,m); count = count+m[1]; /* if(v>0) printf("Node %d is receving %2d paths from cell %d\n", myid,m[1],m[0]); */ MPI_Recv(labels,labSize,MPI_INT,0,SEND_SUPP,com,&status) ; MPI_Recv(normal,dim,MPI_DOUBLE,0,SEND_NORMAL,com,&status) ; fail = celcon_append_mixed_cell(dim,nspt,labSize,labels,normal); } fail = celcon_create_polyhedral_homotopy(); for(i=1; i<=sn; i++) { m = ls_cur(s); fail = celcon_solve_start_system(m[0],&R); if(fail == 1) { printf("Solving start system failed.\n"); printf("Node %d skips cell %d with volume %d...\n",myid,m[0],R); } else { /* printf("found %d start solutions from cell %d\n",R,m[0]); */ fail=celcon_mixed_volume(m[0],&L); /* if(R==L) printf("#start solutions equals mixed volume %d, OK\n",L); else printf("#start solutions not equals mixed volume %d!!!, \n",L); */ for(j=m[2]; j<m[1]+m[2]; j++) { fail = celcon_track_solution_path(m[0],j,0); fail = solcon_clear_solutions(); fail = celcon_copy_target_solution_to_container(m[0],j-m[2]+1); fail = solcon_retrieve_solution(n,1,&A[1],sol); MPI_Send(&A[1],1,MPI_INT,0,SEND_MUL,MPI_COMM_WORLD); MPI_Send(sol,2*n+5,MPI_DOUBLE,0,SEND_SOL,MPI_COMM_WORLD); } } ls_pop(s); } } /* end else */ /* MPI_Barrier(com); */ if(myid == 0) free(cell); else free(s); free(labels); free(m); }