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; }
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); }
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; }
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 ); } } }
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); } }