Exemplo n.º 1
0
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);
   } 
}
Exemplo n.º 2
0
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);
}