void Candidate_Evaluator_Threaded<RETURNTYPE,DIMTYPE,SUBSET,CRITERION,max_threads>::evaluator_thread(unsigned int tidx) { assert(tidx>=0 && tidx<max_threads); ThreadLocal &tl=tlocal[tidx]; assert(tl.crit); DIMTYPE idx; while(get_candidate(idx)) { CandidateResult &cr=cres[idx]; if(!tl.crit->evaluate(cr.result,cr.sub)) throw fst_error("Candidate_Evaluator_Threaded::crit->evaluate(cr.result,cr.sub) criterion evaluation failure."); } }
void benchmark() { char * input; md5_state test_target; int i = 0; int ret = FALSE; char bytes_begin = 'A'; char bytes_end = 'G'; int bytes_base = bytes_end - bytes_begin; input = (char*) calloc(11, sizeof(char)); get_candidate(bytes_begin, bytes_base, 500, input); printf("Benchmarking with password: %s\n", input); test_target = md5(input); printf("Looking for %.08x %.08x %.08x %.08x\n", test_target.a, test_target.b, test_target.c, test_target.d); ret = naive_search(bytes_begin, bytes_end, test_target.a, test_target.b, test_target.c, test_target.d, 9); printf("%d\n", ret); ret = cache_attack(bytes_begin, bytes_end, test_target.a, test_target.b, test_target.c, test_target.d, 9); printf("%d\n", ret); ret = mitm_attack(bytes_begin, bytes_end, test_target.a, test_target.b, test_target.c, test_target.d, 9); printf("%d\n", ret); }
int extended_compute_move( int side_to_move, int book_only, int book, int mid, int exact, int wld ) { int i, j; int index; int changed; int this_move; int disc_diff, corrected_diff; int best_move, temp_move; int best_score; int best_pv_depth; int stored_echo; int shallow_eval; int empties; int current_mid, current_exact, current_wld; int first_iteration; int unsearched; int unsearched_count; int unsearched_move[61]; int best_pv[60]; unsigned int transform1[60], transform2[60]; CandidateMove book_move; EvaluatedMove temp; EvaluationType book_eval_info; EvalResult res; /* Disable all time control mechanisms and randomization */ toggle_abort_check( FALSE ); toggle_midgame_abort_check( FALSE ); toggle_perturbation_usage( FALSE ); start_move( 0, 0, disc_count( BLACKSQ ) + disc_count( WHITESQ ) ); clear_ponder_times(); determine_hash_values( side_to_move, board ); empties = 60 - disks_played; best_move = 0; game_evaluated_count = 0; reset_counter( &nodes ); generate_all( side_to_move ); if ( book_only || book ) { /* Evaluations for database moves */ int flags = 0; if ( empties <= exact ) flags = FULL_SOLVED; else if ( empties <= wld ) flags = WLD_SOLVED; fill_move_alternatives( side_to_move, flags ); game_evaluated_count = get_candidate_count(); for ( i = 0; i < game_evaluated_count; i++ ) { int child_flags; book_move = get_candidate( i ); evaluated_list[i].side_to_move = side_to_move; evaluated_list[i].move = book_move.move; evaluated_list[i].pv_depth = 1; evaluated_list[i].pv[0] = book_move.move; evaluated_list[i].eval = create_eval_info( UNDEFINED_EVAL, UNSOLVED_POSITION, book_move.score, 0.0, 0, TRUE ); child_flags = book_move.flags & book_move.parent_flags; if ( child_flags & (FULL_SOLVED | WLD_SOLVED) ) { if ( child_flags & FULL_SOLVED ) evaluated_list[i].eval.type = EXACT_EVAL; else evaluated_list[i].eval.type = WLD_EVAL; if ( book_move.score > 0 ) { evaluated_list[i].eval.res = WON_POSITION; /* Normalize the scores so that e.g. 33-31 becomes +256 */ evaluated_list[i].eval.score -= CONFIRMED_WIN; evaluated_list[i].eval.score *= 128; } else if ( book_move.score == 0 ) evaluated_list[i].eval.res = DRAWN_POSITION; else { /* score < 0 */ evaluated_list[i].eval.res = LOST_POSITION; /* Normalize the scores so that e.g. 30-34 becomes -512 */ evaluated_list[i].eval.score += CONFIRMED_WIN; evaluated_list[i].eval.score *= 128; } } else evaluated_list[i].eval.type = MIDGAME_EVAL; } } if ( book_only ) { /* Only book moves are to be considered */ if ( game_evaluated_count > 0 ) { best_move = get_book_move( side_to_move, FALSE, &book_eval_info ); set_current_eval( book_eval_info ); } else { pv_depth[0] = 0; best_move = PASS; book_eval_info = create_eval_info( UNDEFINED_EVAL, UNSOLVED_POSITION, 0, 0.0, 0, FALSE ); set_current_eval( book_eval_info ); } } else { /* Make searches for moves not in the database */ int shallow_depth; int empties = 60 - disks_played; book = FALSE; best_score = -INFINITE_EVAL; if ( game_evaluated_count > 0 ) { /* Book PV available */ best_score = evaluated_list[0].eval.score; best_move = evaluated_list[0].move; } negate_current_eval( TRUE ); /* Store the available moves, clear their evaluations and sort them on shallow evaluation. */ if ( empties < 12 ) shallow_depth = 1; else { int max_depth = MAX( mid, MAX( exact, wld ) ); if ( max_depth >= 16 ) shallow_depth = 6; else shallow_depth = 4; } unsearched_count = 0; for ( i = 0; i < move_count[disks_played]; i++ ) { this_move = move_list[disks_played][i]; unsearched = TRUE; for ( j = 0; j < game_evaluated_count; j++ ) if ( evaluated_list[j].move == this_move ) unsearched = FALSE; if ( !unsearched ) continue; unsearched_move[unsearched_count] = this_move; unsearched_count++; (void) make_move( side_to_move, this_move, TRUE ); if ( shallow_depth == 1 ) /* Compute move doesn't allow depth 0 */ shallow_eval = -static_evaluation( OPP( side_to_move ) ); else { EvaluationType shallow_info; (void) compute_move( OPP( side_to_move ), FALSE, 0, 0, FALSE, book, shallow_depth - 1, 0, 0, TRUE, &shallow_info ); if ( shallow_info.type == PASS_EVAL ) { /* Don't allow pass */ (void) compute_move( side_to_move, FALSE, 0, 0, FALSE, book, shallow_depth - 1, 0, 0, TRUE, &shallow_info ); if ( shallow_info.type == PASS_EVAL ) { /* Game over */ disc_diff = disc_count( side_to_move ) - disc_count( OPP( side_to_move ) ); if ( disc_diff > 0 ) corrected_diff = 64 - 2 * disc_count( OPP( side_to_move) ); else if ( disc_diff == 0 ) corrected_diff = 0; else corrected_diff = 2 * disc_count( side_to_move ) - 64; shallow_eval = 128 * corrected_diff; } else shallow_eval = shallow_info.score; } else /* Sign-correct the score produced */ shallow_eval = -shallow_info.score; } unmake_move( side_to_move, this_move ); evals[disks_played][this_move] = shallow_eval; } do { changed = FALSE; for ( i = 0; i < unsearched_count - 1; i++ ) if ( evals[disks_played][unsearched_move[i]] < evals[disks_played][unsearched_move[i + 1]] ) { temp_move = unsearched_move[i]; unsearched_move[i] = unsearched_move[i + 1]; unsearched_move[i + 1] = temp_move; changed = TRUE; } } while ( changed ); /* Initialize the entire list as being empty */ for ( i = 0, index = game_evaluated_count; i < unsearched_count; i++, index++ ) { evaluated_list[index].side_to_move = side_to_move; evaluated_list[index].move = unsearched_move[i]; evaluated_list[index].eval = create_eval_info( UNDEFINED_EVAL, UNSOLVED_POSITION, 0, 0.0, 0, FALSE ); evaluated_list[index].pv_depth = 1; evaluated_list[index].pv[0] = unsearched_move[i]; if ( empties > MAX( wld, exact ) ) { transform1[i] = abs( my_random() ); transform2[i] = abs( my_random() ); } else { transform1[i] = 0; transform2[i] = 0; } } stored_echo = echo; echo = FALSE; best_pv_depth = 0; if ( mid == 1 ) { /* compute_move won't be called */ pv_depth[0] = 0; piece_count[BLACKSQ][disks_played] = disc_count( BLACKSQ ); piece_count[WHITESQ][disks_played] = disc_count( WHITESQ ); } /* Perform iterative deepening if the search depth is large enough */ #define ID_STEP 2 if ( exact > empties ) exact = empties; if ( (exact < 12) || (empties > exact) ) current_exact = exact; else current_exact = (8 + (exact % 2)) - ID_STEP; if ( wld > empties ) wld = empties; if ( (wld < 14) || (empties > wld) ) current_wld = wld; else current_wld = (10 + (wld % 2)) - ID_STEP; if ( ((empties == exact) || (empties == wld)) && (empties > 16) && (mid < empties - 12) ) mid = empties - 12; if ( mid < 10 ) current_mid = mid; else current_mid = (6 + (mid % 2)) - ID_STEP; first_iteration = TRUE; do { if ( current_mid < mid ) { current_mid += ID_STEP; /* Avoid performing deep midgame searches if the endgame is reached anyway. */ if ( (empties <= wld) && (current_mid + 7 >= empties) ) { current_wld = wld; current_mid = mid; } if ( (empties <= exact) && (current_mid + 7 >= empties) ) { current_exact = exact; current_mid = mid; } } else if ( current_wld < wld ) current_wld = wld; else current_exact = exact; for ( i = 0; (i < unsearched_count) && !force_return; i++ ) { EvaluationType this_eval; this_move = unsearched_move[i]; /* Locate the current move in the list. This has to be done because the moves might have been reordered during the iterative deepening. */ index = 0; while ( evaluated_list[index].move != this_move ) index++; /* To avoid strange effects when browsing back and forth through a game during the midgame, rehash the hash transformation masks for each move unless the endgame is reached */ set_hash_transformation( transform1[i], transform2[i] ); /* Determine the score for the ith move */ prefix_move = this_move; (void) make_move( side_to_move, this_move, TRUE ); if ( current_mid == 1 ) { /* compute_move doesn't like 0-ply searches */ shallow_eval = static_evaluation( OPP( side_to_move ) ); this_eval = create_eval_info( MIDGAME_EVAL, UNSOLVED_POSITION, shallow_eval, 0.0, 0, FALSE ); } else (void) compute_move( OPP( side_to_move ), FALSE, 0, 0, FALSE, book, current_mid - 1, current_exact - 1, current_wld - 1, TRUE, &this_eval ); if ( force_return ) { /* Clear eval and exit search immediately */ this_eval = create_eval_info( UNDEFINED_EVAL, UNSOLVED_POSITION, 0, 0.0, 0, FALSE ); unmake_move( side_to_move, this_move ); break; } if ( this_eval.type == PASS_EVAL ) { /* Don't allow pass */ if ( current_mid == 1 ) { /* compute_move doesn't like 0-ply searches */ shallow_eval = static_evaluation( side_to_move ); this_eval = create_eval_info( MIDGAME_EVAL, UNSOLVED_POSITION, shallow_eval, 0.0, 0, FALSE ); } else (void) compute_move( side_to_move, FALSE, 0, 0, FALSE, book, current_mid - 1, current_exact - 1, current_wld - 1, TRUE, &this_eval ); if ( this_eval.type == PASS_EVAL ) { /* Game over */ disc_diff = disc_count( side_to_move ) - disc_count( OPP( side_to_move ) ); if ( disc_diff > 0 ) { corrected_diff = 64 - 2 * disc_count( OPP( side_to_move) ); res = WON_POSITION; } else if ( disc_diff == 0 ) { corrected_diff = 0; res = DRAWN_POSITION; } else { corrected_diff = 2 * disc_count( side_to_move ) - 64; res = LOST_POSITION; } this_eval = create_eval_info( EXACT_EVAL, res, 128 * corrected_diff, 0.0, 60 - disks_played, FALSE ); } } else { /* Sign-correct the score produced */ this_eval.score = -this_eval.score; if ( this_eval.res == WON_POSITION ) this_eval.res = LOST_POSITION; else if ( this_eval.res == LOST_POSITION ) this_eval.res = WON_POSITION; } if ( force_return ) break; else evaluated_list[index].eval = this_eval; /* Store the PV corresponding to the move */ evaluated_list[index].pv_depth = pv_depth[0] + 1; evaluated_list[index].pv[0] = this_move; for ( j = 0; j < pv_depth[0]; j++ ) evaluated_list[index].pv[j + 1] = pv[0][j]; /* Store the PV corresponding to the best move */ if ( evaluated_list[index].eval.score > best_score ) { best_score = evaluated_list[index].eval.score; best_move = this_move; best_pv_depth = pv_depth[0]; for ( j = 0; j < best_pv_depth; j++ ) best_pv[j] = pv[0][j]; } unmake_move( side_to_move, this_move ); /* Sort the moves evaluated */ if ( first_iteration ) game_evaluated_count++; if ( !force_return ) do { changed = FALSE; for ( j = 0; j < game_evaluated_count - 1; j++ ) if ( compare_eval( evaluated_list[j].eval, evaluated_list[j + 1].eval ) < 0 ) { changed = TRUE; temp = evaluated_list[j]; evaluated_list[j] = evaluated_list[j + 1]; evaluated_list[j + 1] = temp; } } while ( changed ); display_status(stdout, FALSE); } first_iteration = FALSE; /* Reorder the moves after each iteration. Each move is moved to the front of the list, starting with the bad moves and ending with the best move. This ensures that unsearched_move will be sorted w.r.t. the order in evaluated_list. */ for ( i = game_evaluated_count - 1; i >= 0; i-- ) { int this_move = evaluated_list[i].move; j = 0; while ( (j != unsearched_count) && (unsearched_move[j] != this_move) ) j++; if ( j == unsearched_count ) /* Must be book move, skip */ continue; /* Move the move to the front of the list. */ while ( j >= 1 ) { unsearched_move[j] = unsearched_move[j - 1]; j--; } unsearched_move[0] = this_move; } } while ( !force_return && ((current_mid != mid) || (current_exact != exact) || (current_wld != wld)) ); echo = stored_echo; game_evaluated_count = move_count[disks_played]; /* Make sure that the PV and the score correspond to the best move */ pv_depth[0] = best_pv_depth + 1; pv[0][0] = best_move; for ( i = 0; i < best_pv_depth; i++ ) pv[0][i + 1] = best_pv[i]; negate_current_eval( FALSE ); if ( move_count[disks_played] > 0 ) set_current_eval( evaluated_list[0].eval ); } /* Reset the hash transformation masks prior to leaving */ set_hash_transformation( 0, 0 ); /* Don't forget to enable the time control mechanisms when leaving */ toggle_abort_check( TRUE ); toggle_midgame_abort_check( TRUE ); toggle_perturbation_usage( TRUE ); max_depth_reached++; prefix_move = 0; return best_move; }
const derivation_type* lazy_kth_best(int v, size_type k) { //std::cerr << "lazy-kth-best: node: " << v << " kbest: " << k << std::endl; state_type & state = get_candidate(v); derivation_heap_type& cand = state.cand; derivation_list_type& D = state.D; yield_set_type yields; while (D.size() <= k) { // lazy-next for the last of the derivation, D if (! D.empty()) lazy_next(*D.back(), state); // We will add an item from cand into D. bool incremented = false; while (! cand.empty()) { const derivation_type* derivation = cand.top(); cand.pop(); // perform traversal here... yields.clear(); for (size_t i = 0; i != derivation->edge->tails.size(); ++ i) { const derivation_type* antecedent = lazy_kth_best(derivation->edge->tails[i], derivation->j[i]); if (! antecedent) throw std::runtime_error("no antecedent???"); yields.push_back(&(antecedent->yield)); } traversal(*(derivation->edge), const_cast<yield_type&>(derivation->yield), yield_iterator(yields.begin()), yield_iterator(yields.end())); // perform filtering here...! // if we have duplicates of "yield", do not insert into D if (! filter(graph.nodes[v], derivation->yield)) { D.push_back(derivation); // increment the edge count... ++ counts[derivation->edge->id]; // update the score in the heap which shares the same current derivation... bool updated = false; typename derivation_heap_type::iterator citer_end = cand.end(); for (typename derivation_heap_type::iterator citer = cand.begin(); citer != citer_end; ++ citer) if ((*citer)->edge->id == derivation->edge->id) { const_cast<weight_type&>((*citer)->score) *= cicada::semiring::traits<weight_type>::exp(- diversity); updated = true; } if (updated) cand.make_heap(); incremented = true; break; } // lazy-next for this derivation, otherwise, we may have computed wrong k-best... lazy_next(*derivation, state); } // if D was not incremented, no new item was found! if (! incremented) break; } return (k < D.size() ? D[k] : 0); }