Esempio n. 1
0
int merge_check(Puzzle *puz, Solution *sol)
{
    MergeElem *m;
    //dir_t z;
    int found= 0;
    
    for (m= merge_list; m != NULL; m= m->next)
    {
        if (m->maxc == merge_no && m->cell != NULL)
        {
            if (VM)
            {
                printf("M: FOUND MERGED CONSEQUENCE ON CELL (%d,%d) BITS ",
                       m->cell->line[0], m->cell->line[1]);
                dump_bits(stdout, puz, m->bit);
                printf("\n");
            }
            
            /* Add to history as a necessary consequence */
            add_hist(puz, m->cell, 0);
            
            /* Set the new value in the cell */
#ifdef LIMITCOLORS
            oldval[0]= m->cell->bit[0];
            m->cell->bit[0]&= ~m->bit[0];
#else
            for (z= 0; z < fbit_size; z++)
            {
                oldval[z]= m->cell->bit[z];
                m->cell->bit[z]&= ~m->bit[z];
            }
#endif
            if (puz->ncolor <= 2)
                m->cell->n= 1;
            else
                count_cell(puz,m->cell);
            
            if (m->cell->n == 1) solved_a_cell(puz, m->cell,1);
            
            /* Add rows/columns containing this cell to the job list */
            add_jobs(puz, sol, -1, m->cell, 0, oldval);
            
            found= 1;
        }
        /* Reset to unused state */
        m->cell= NULL;
    }
    if (VM && !found) printf("M: NO MERGE CONSEQUENCES\n");
    
    merge_list= NULL;
    merge_no= -1;
    merging= 0;
    
    return found;
}
Esempio n. 2
0
void guess_cell(Puzzle *puz, Solution *sol, Cell *cell, color_t c)
{
    dir_t k;
    Hist *h;

    /* Save old cell in backtrack history */
    h= add_hist(puz, cell, 1);

    /* Set just that one color */
    cell->n= 1;
    fbit_setonly(cell->bit,c);
    solved_a_cell(puz,cell, 1);

    /* Put all crossing lines onto the job list */
    add_jobs(puz, sol, -1, cell, 0, h->bit);
}
Esempio n. 3
0
int backtrack(Puzzle *puz, Solution *sol)
{
    Hist *h;
    //color_t z, oldn, newn;
    //dir_t k;

    if (VB) printf("B: BACKTRACKING TO LAST GUESS\n");

    /* Undo up to, but not including, the most recent branch point */
    if (undo(puz,sol, 1))
    {
        if (VB) printf("B: CANNOT BACKTRACK\n");
        return 1;
    }

    if (VB) print_solution(stdout,puz,sol);

    /* This will be the branch point since undo() backed us up to it */
    h= HIST(puz, puz->nhist-1);

    if (VB || WC(h->cell))
    {
        printf("B: LAST GUESS WAS ");
        print_coord(stdout,puz,h->cell);
        printf(" |");
        dump_bits(stdout,puz,h->bit);
        printf("| -> |");
        dump_bits(stdout,puz,h->cell->bit);
        printf("|\n");
    }

    /* If undoing a solved cell, uncount it */
    if (h->cell->n == 1) solved_a_cell(puz, h->cell, -1);

    /* Reset any bits previously set */
#ifdef LIMITCOLORS
    h->cell->bit[0]= ((~h->cell->bit[0]) & h->bit[0]);
#else
    for (z= 0; z < fbit_size; z++)
        h->cell->bit[z]= ((~h->cell->bit[z]) & h->bit[z]);
#endif
    h->cell->n= h->n - h->cell->n;  /* Since the bits set in h are always
				       a superset of those in h->cell,
				       this should always work */

    /* If inverted cell is solved, count it */
    if (h->cell->n == 1) solved_a_cell(puz, h->cell, 1);

    if (VB || WC(h->cell))
    {
        printf("B: INVERTING GUESS TO |");
        dump_bits(stdout,puz,h->cell->bit);
        printf("| (%d)\n",h->cell->n);
    }

    /* Now that we've backtracked to it and inverted it, it is no
     * longer a branch point.  If there is no previous history, delete
     * this node.  Otherwise, convert it into a non-branch point.
     * Next time we backtrack we will just delete it.
     */
    if (puz->nhist == 1)
        puz->nhist= 0;
    else
        h->branch= 0;

    /* Remove everything from the job list except the lines containing
     * the inverted cell.
     */
    if (maylinesolve)
    {
        flush_jobs(puz);
        add_jobs(puz, sol, -1, h->cell, 0, h->bit);
    }

    backtracks++;

    return 0;
}
Esempio n. 4
0
int main( int argc, char ** argv) {
  if (argc == 1)
    util_exit("block_node  node1  node2  node3:2  \n");
  
  /* Initialize lsf environment */
  util_setenv( "LSF_BINDIR"    , "/prog/LSF/9.1/linux2.6-glibc2.3-x86_64/bin" );
  util_setenv( "LSF_LINDIR"    , "/prog/LSF/9.1/linux2.6-glibc2.3-x86_64/lib" );
  util_setenv( "XLSF_UIDDIR"   , "/prog/LSF/9.1/linux2.6-glibc2.3-x86_64/lib/uid" );
  util_setenv( "LSF_SERVERDIR" , "/prog/LSF/9.1/linux2.6-glibc2.3-x86_64/etc");
  util_setenv( "LSF_ENVDIR"    , "/prog/LSF/conf");
  
  util_update_path_var( "PATH"               , "/prog/LSF/9.1/linux2.6-glibc2.3-x86_64/bin" , false);
  util_update_path_var( "LD_LIBRARY_PATH"    , "/prog/LSF/9.1/linux2.6-glibc2.3-x86_64/lib" , false);

  
  lsf_driver = lsf_driver_alloc();
  if (lsf_driver_get_submit_method( lsf_driver ) != LSF_SUBMIT_INTERNAL)
    util_exit("Sorry - the block_node program must be invoked on a proper LSF node \n");

  {
    
    int iarg;
    int total_blocked_target = 0;
    nodes       = hash_alloc();
    for (iarg = 1; iarg < argc; iarg++) {
      char   *node_name;
      int    num_slots;
      
      {
        char * num_slots_string;
        util_binary_split_string( argv[iarg] , ":" , true , &node_name , &num_slots_string);
        if (num_slots_string)
          util_sscanf_int( num_slots_string , &num_slots);
        else
          num_slots = 1;
      }
      
      if (!hash_has_key( nodes , node_name))
        hash_insert_hash_owned_ref( nodes , node_name , count_pair_alloc() , free);

      {
        count_pair_type * pair = hash_get( nodes , node_name);
        pair->target += num_slots;
      }
      total_blocked_target += num_slots;
    }

    signal(SIGINT , block_node_exit );
    {
      const int sleep_time    = 5;
      const int chunk_size    = 10;    /* We submit this many at a time. */
      const int max_pool_size = 1000;  /* The absolute total maximum of jobs we will submit. */  

      bool           cont        = true;
      int            pending     = 0;   
      bool           all_blocked;
      job_pool                   = vector_alloc_new();

      while (cont) {
        printf("[Ctrl-C to give up] "); fflush( stdout );
        if (cont) sleep( sleep_time );
        if (pending == 0) {
          if (vector_get_size( job_pool ) < max_pool_size)
            add_jobs( chunk_size );
        }
        
        update_pool_status( &all_blocked , &pending);
        print_status();

        if (all_blocked)
          cont = false;
      }
      if (!all_blocked)
        printf("Sorry - failed to block all the nodes \n");
      
      block_node_exit( 0 );
      hash_free( nodes );
    }
  }
}
Esempio n. 5
0
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);
   }
}