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);
   }
}
Exemple #2
0
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);
   } 
}