Rev 108 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 108 | Rev 154 | ||
---|---|---|---|
Line 2... | Line 2... | ||
2 | #include "data.h" |
2 | #include "data.h" |
3 | #include "epdglue.h" |
3 | #include "epdglue.h" |
- | 4 | #include "tbprobe.h" |
|
4 | /* last modified |
5 | /* last modified 08/03/16 */ |
5 | /* |
6 | /* |
6 | ******************************************************************************* |
7 | ******************************************************************************* |
7 | * * |
8 | * * |
8 | * Iterate() is the routine used to drive the iterated search. It * |
9 | * Iterate() is the routine used to drive the iterated search. It * |
9 | * repeatedly calls search, incrementing the search depth after each call, * |
10 | * repeatedly calls search, incrementing the search depth after each call, * |
Line 45... | Line 46... | ||
45 | ROOT_MOVE temp_rm; |
46 | ROOT_MOVE temp_rm; |
46 | int i, alpha, beta, current_rm = 0, force_print = 0; |
47 | int i, alpha, beta, current_rm = 0, force_print = 0; |
47 | int value = 0, twtm, correct, correct_count, npc, cpl, max; |
48 | int value = 0, twtm, correct, correct_count, npc, cpl, max; |
48 | unsigned int idle_time; |
49 | unsigned int idle_time; |
49 | char buff[32]; |
50 | char buff[32]; |
50 | #if (CPUS > 1) |
51 | #if (CPUS > 1) && defined(UNIX) |
51 | # if defined(UNIX) // Pierre-Marie Baty -- missing conditional macro |
- | |
52 | pthread_t pt; |
52 | pthread_t pt; |
53 | # endif |
- | |
54 | #endif |
53 | #endif |
55 | 54 | ||
56 | /* |
55 | /* |
57 | ************************************************************ |
56 | ************************************************************ |
58 | * * |
57 | * * |
Line 85... | Line 84... | ||
85 | tree->fail_high_first_move = 0; |
84 | tree->fail_high_first_move = 0; |
86 | parallel_splits = 0; |
85 | parallel_splits = 0; |
87 | parallel_splits_wasted = 0; |
86 | parallel_splits_wasted = 0; |
88 | parallel_aborts = 0; |
87 | parallel_aborts = 0; |
89 | parallel_joins = 0; |
88 | parallel_joins = 0; |
90 | for (i = 0; i < |
89 | for (i = 0; i < smp_max_threads; i++) { |
91 | thread[i].max_blocks = 0; |
90 | thread[i].max_blocks = 0; |
92 | thread[i].tree = 0; |
91 | thread[i].tree = 0; |
93 | thread[i].idle = 0; |
92 | thread[i].idle = 0; |
94 | thread[i].terminate = 0; |
93 | thread[i].terminate = 0; |
95 | } |
94 | } |
Line 128... | Line 127... | ||
128 | * * |
127 | * * |
129 | ************************************************************ |
128 | ************************************************************ |
130 | */ |
129 | */ |
131 | if (!root_list_done) |
130 | if (!root_list_done) |
132 | RootMoveList(wtm); |
131 | RootMoveList(wtm); |
133 | if (booking || !Book(tree, wtm)) |
132 | if (booking || (!Book(tree, wtm) && !RootMoveEGTB(wtm))) |
134 | do { |
133 | do { |
135 | if (abort_search) |
134 | if (abort_search) |
136 | break; |
135 | break; |
137 | #if !defined(NOEGTB) |
- | |
138 | if (EGTB_draw && !puzzling && swindle_mode) |
- | |
139 | EGTB_use = 0; |
- | |
140 | else |
- | |
141 | EGTB_use = EGTBlimit; |
- | |
142 | if (EGTBlimit && !EGTB_use) |
- | |
143 | Print(32, "Drawn at root, trying for swindle.\n"); |
- | |
144 | #endif |
- | |
145 | /* |
136 | /* |
146 | ************************************************************ |
137 | ************************************************************ |
147 | * * |
138 | * * |
148 | * The first action for a real search is to generate the * |
139 | * The first action for a real search is to generate the * |
149 | * root move list if it has not already been done. For * |
140 | * root move list if it has not already been done. For * |
Line 168... | Line 159... | ||
168 | if (Check(wtm)) |
159 | if (Check(wtm)) |
169 | value = -(MATE - 1); |
160 | value = -(MATE - 1); |
170 | else |
161 | else |
171 | value = DrawScore(wtm); |
162 | value = DrawScore(wtm); |
172 | Print(2, " depth time score variation\n"); |
163 | Print(2, " depth time score variation\n"); |
173 | Print(2, " |
164 | Print(2, " Mated (no moves)\n"); |
174 | tree->nodes_searched = 1; |
165 | tree->nodes_searched = 1; |
175 | if (!puzzling) |
166 | if (!puzzling) |
176 | last_root_value = value; |
167 | last_root_value = value; |
177 | return value; |
168 | return value; |
178 | } |
169 | } |
Line 231... | Line 222... | ||
231 | * initialized everything. * |
222 | * initialized everything. * |
232 | * * |
223 | * * |
233 | ************************************************************ |
224 | ************************************************************ |
234 | */ |
225 | */ |
235 | #if (CPUS > 1) |
226 | #if (CPUS > 1) |
236 | if ( |
227 | if (smp_max_threads > smp_threads + 1) { |
237 | long proc; |
228 | long proc; |
238 | 229 | ||
239 | initialized_threads = 1; |
230 | initialized_threads = 1; |
240 | Print(32, "starting thread"); |
231 | Print(32, "starting thread"); |
241 | for (proc = smp_threads + 1; proc < |
232 | for (proc = smp_threads + 1; proc < smp_max_threads; proc++) { |
242 | Print(32, " %d", proc); |
233 | Print(32, " %d", proc); |
243 | # if defined(UNIX) |
234 | # if defined(UNIX) |
244 | pthread_create(&pt, &attributes, ThreadInit, (void *) proc); |
235 | pthread_create(&pt, &attributes, ThreadInit, (void *) proc); |
245 | # else |
236 | # else |
246 | NumaStartThread(ThreadInit, (void *) proc); |
237 | NumaStartThread(ThreadInit, (void *) proc); |
Line 248... | Line 239... | ||
248 | smp_threads++; |
239 | smp_threads++; |
249 | } |
240 | } |
250 | Print(32, " <done>\n"); |
241 | Print(32, " <done>\n"); |
251 | } |
242 | } |
252 | WaitForAllThreadsInitialized(); |
243 | WaitForAllThreadsInitialized(); |
253 | ThreadAffinity( |
244 | ThreadAffinity(0); |
254 | #endif |
245 | #endif |
255 | if (search_nodes) |
246 | if (search_nodes) |
256 | nodes_between_time_checks = |
247 | nodes_between_time_checks = search_nodes; |
257 | /* |
248 | /* |
258 | ************************************************************ |
249 | ************************************************************ |
259 | * * |
250 | * * |
260 | * Main iterative-deepening loop starts here. We either * |
251 | * Main iterative-deepening loop starts here. We either * |
261 | * start at depth = 1, or if we are pondering and have a * |
252 | * start at depth = 1, or if we are pondering and have a * |
Line 321... | Line 312... | ||
321 | nodes_between_time_checks /= 10; |
312 | nodes_between_time_checks /= 10; |
322 | } else |
313 | } else |
323 | nodes_between_time_checks = Min(nodes_per_second, 1000000); |
314 | nodes_between_time_checks = Min(nodes_per_second, 1000000); |
324 | } |
315 | } |
325 | if (search_nodes) |
316 | if (search_nodes) |
326 | nodes_between_time_checks = |
317 | nodes_between_time_checks = search_nodes - tree->nodes_searched; |
327 | nodes_between_time_checks = |
318 | nodes_between_time_checks = |
328 | Min(nodes_between_time_checks, MAX_TC_NODES); |
319 | Min(nodes_between_time_checks, MAX_TC_NODES); |
329 | next_time_check = nodes_between_time_checks; |
320 | next_time_check = nodes_between_time_checks; |
330 | /* |
321 | /* |
331 | ************************************************************ |
322 | ************************************************************ |
Line 341... | Line 332... | ||
341 | */ |
332 | */ |
342 | failhi_delta = 16; |
333 | failhi_delta = 16; |
343 | faillo_delta = 16; |
334 | faillo_delta = 16; |
344 | for (i = 0; i < n_root_moves; i++) { |
335 | for (i = 0; i < n_root_moves; i++) { |
345 | if (i || iteration == 1) |
336 | if (i || iteration == 1) |
346 | root_moves[i].path.pathv = - |
337 | root_moves[i].path.pathv = -MATE; |
347 | root_moves[i].status &= 4; |
338 | root_moves[i].status &= 4; |
348 | } |
339 | } |
349 | while (1) { |
340 | while (1) { |
350 | if (smp_max_threads > 1) |
341 | if (smp_max_threads > 1) |
351 | smp_split = 1; |
342 | smp_split = 1; |
Line 443... | Line 434... | ||
443 | DisplayFail(tree, 2, 5, wtm, end_time - start_time, |
434 | DisplayFail(tree, 2, 5, wtm, end_time - start_time, |
444 | root_moves[current_rm].move, value, force_print); |
435 | root_moves[current_rm].move, value, force_print); |
445 | } else |
436 | } else |
446 | break; |
437 | break; |
447 | } |
438 | } |
448 | if (value > alpha && value < beta) |
- | |
449 | last_root_value = value; |
- | |
450 | /* |
439 | /* |
451 | ************************************************************ |
440 | ************************************************************ |
452 | * * |
441 | * * |
453 | * If we are running a test suite, check to see if we can * |
442 | * If we are running a test suite, check to see if we can * |
454 | * exit the search. This happens when N successive * |
443 | * exit the search. This happens when N successive * |
455 | * iterations produce the correct solution. N is set by * |
444 | * iterations produce the correct solution. N is set by * |
456 | * the test command in Option(). * |
445 | * the test command in Option(). * |
457 | * * |
446 | * * |
458 | ************************************************************ |
447 | ************************************************************ |
459 | */ |
448 | */ |
- | 449 | if (value > alpha && value < beta) |
|
- | 450 | last_root_value = value; |
|
460 | correct = solution_type; |
451 | correct = solution_type; |
461 | for (i = 0; i < number_of_solutions; i++) { |
452 | for (i = 0; i < number_of_solutions; i++) { |
462 | if (!solution_type) { |
453 | if (!solution_type) { |
463 | if (solutions[i] == tree->pv[0].path[1]) |
454 | if (solutions[i] == tree->pv[0].path[1]) |
464 | correct = 1; |
455 | correct = 1; |
Line 483... | Line 474... | ||
483 | if (root_moves[i].bm_age) |
474 | if (root_moves[i].bm_age) |
484 | root_moves[i].bm_age--; |
475 | root_moves[i].bm_age--; |
485 | if (root_moves[i].bm_age) |
476 | if (root_moves[i].bm_age) |
486 | root_moves[i].status |= 4; |
477 | root_moves[i].status |= 4; |
487 | } |
478 | } |
488 | SortRootMoves(); |
- | |
489 | difficulty = ComputeDifficulty(difficulty, 0); |
479 | difficulty = ComputeDifficulty(difficulty, 0); |
490 | /* |
480 | /* |
491 | ************************************************************ |
481 | ************************************************************ |
492 | * * |
482 | * * |
493 | * If requested, print the ply=1 move list along with the * |
483 | * If requested, print the ply=1 move list along with the * |
Line 502... | Line 492... | ||
502 | */ |
492 | */ |
503 | if (display_options & 64) { |
493 | if (display_options & 64) { |
504 | Print(64, " rmove score age S ! ?\n"); |
494 | Print(64, " rmove score age S ! ?\n"); |
505 | for (i = 0; i < n_root_moves; i++) { |
495 | for (i = 0; i < n_root_moves; i++) { |
506 | Print(64, " %10s ", OutputMove(tree, 1, wtm, root_moves[i].move)); |
496 | Print(64, " %10s ", OutputMove(tree, 1, wtm, root_moves[i].move)); |
507 | if (root_moves[i].path.pathv > -MATE |
497 | if (root_moves[i].path.pathv > -MATE && |
- | 498 | root_moves[i].path.pathv <= MATE) |
|
508 | Print(64, "%s", DisplayEvaluation(root_moves[i].path.pathv, |
499 | Print(64, "%s", DisplayEvaluation(root_moves[i].path.pathv, |
509 | wtm)); |
500 | wtm)); |
510 | else |
501 | else |
511 | Print(64, " -----"); |
502 | Print(64, " -----"); |
512 | Print(64, " %d %d %d %d\n", root_moves[i].bm_age, |
503 | Print(64, " %d %d %d %d\n", root_moves[i].bm_age, |
Line 523... | Line 514... | ||
523 | * iteration to the current score +/- 16. * |
514 | * iteration to the current score +/- 16. * |
524 | * * |
515 | * * |
525 | ************************************************************ |
516 | ************************************************************ |
526 | */ |
517 | */ |
527 | if (end_time - start_time > 10) |
518 | if (end_time - start_time > 10) |
528 | nodes_per_second = |
519 | nodes_per_second = |
529 |
|
520 | tree->nodes_searched * 100 / (uint64_t) (end_time - start_time); |
530 | else |
521 | else |
531 | nodes_per_second = 1000000; |
522 | nodes_per_second = 1000000; |
532 | tree->pv[0] = root_moves[0].path; |
523 | tree->pv[0] = root_moves[0].path; |
533 | if (!abort_search && value != -(MATE - 1)) { |
524 | if (!abort_search && value != -(MATE - 1)) { |
534 | if (end_time - start_time >= noise_level) { |
525 | if (end_time - start_time >= noise_level) { |
Line 566... | Line 557... | ||
566 | if (abort_search) |
557 | if (abort_search) |
567 | break; |
558 | break; |
568 | end_time = ReadClock() - start_time; |
559 | end_time = ReadClock() - start_time; |
569 | if (correct_count >= early_exit) |
560 | if (correct_count >= early_exit) |
570 | break; |
561 | break; |
571 | #if !defined(NOEGTB) |
- | |
572 | if (iteration > EGTB_depth + 10 && TotalAllPieces <= EGTBlimit && |
- | |
573 | EGTB_use && EGTBProbe(tree, 1, wtm, &i)) |
- | |
574 | break; |
- | |
575 | #endif |
- | |
576 | if (search_nodes && tree->nodes_searched >= search_nodes) |
562 | if (search_nodes && tree->nodes_searched >= search_nodes) |
577 | break; |
563 | break; |
578 | } |
564 | } |
579 | /* |
565 | /* |
580 | ************************************************************ |
566 | ************************************************************ |
Line 598... | Line 584... | ||
598 | * * |
584 | * * |
599 | ************************************************************ |
585 | ************************************************************ |
600 | */ |
586 | */ |
601 | end_time = ReadClock(); |
587 | end_time = ReadClock(); |
602 | if (end_time > 10) |
588 | if (end_time > 10) |
603 | nodes_per_second = |
589 | nodes_per_second = |
604 |
|
590 | (uint64_t) tree->nodes_searched * 100 / Max((uint64_t) end_time - |
605 | start_time, 1 |
591 | start_time, 1); |
606 | if (abort_search != 2 && !puzzling) { |
592 | if (abort_search != 2 && !puzzling) { |
607 | if (noise_block) |
593 | if (noise_block) |
608 | DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0], 1); |
594 | DisplayPV(tree, 5, wtm, end_time - start_time, &tree->pv[0], 1); |
609 | tree->evaluations = (tree->evaluations) ? tree->evaluations : 1; |
595 | tree->evaluations = (tree->evaluations) ? tree->evaluations : 1; |
610 | tree->fail_highs++; |
596 | tree->fail_highs++; |
611 | tree->fail_high_first_move++; |
597 | tree->fail_high_first_move++; |
612 | idle_time = 0; |
598 | idle_time = 0; |
613 | for (i = 0; i < |
599 | for (i = 0; i < smp_max_threads; i++) |
614 | idle_time += thread[i].idle; |
600 | idle_time += thread[i].idle; |
615 | busy_percent = |
601 | busy_percent = |
616 | 100 - Min(100, |
602 | 100 - Min(100, |
617 | 100 * idle_time / (smp_max_threads * (end_time - start_time) + |
603 | 100 * idle_time / (smp_max_threads * (end_time - start_time) + |
618 | 1)); |
604 | 1)); |
Line 626... | Line 612... | ||
626 | Print(8, " nps=%s\n", DisplayKMB(nodes_per_second, 0)); |
612 | Print(8, " nps=%s\n", DisplayKMB(nodes_per_second, 0)); |
627 | Print(8, " chk=%s", DisplayKMB(tree->extensions_done, 0)); |
613 | Print(8, " chk=%s", DisplayKMB(tree->extensions_done, 0)); |
628 | Print(8, " qchk=%s", DisplayKMB(tree->qchecks_done, 0)); |
614 | Print(8, " qchk=%s", DisplayKMB(tree->qchecks_done, 0)); |
629 | Print(8, " fp=%s", DisplayKMB(tree->moves_fpruned, 0)); |
615 | Print(8, " fp=%s", DisplayKMB(tree->moves_fpruned, 0)); |
630 | Print(8, " mcp=%s", DisplayKMB(tree->moves_mpruned, 0)); |
616 | Print(8, " mcp=%s", DisplayKMB(tree->moves_mpruned, 0)); |
631 | Print(8, " 50move=%d", |
617 | Print(8, " 50move=%d", |
- | 618 | (ReversibleMove(last_pv.path[1]) ? Reversible(0) + 1 : 0)); |
|
632 | if (tree->egtb_hits) |
619 | if (tree->egtb_hits) |
633 | Print(8, " egtb=%s", DisplayKMB(tree->egtb_hits, 0)); |
620 | Print(8, " egtb=%s", DisplayKMB(tree->egtb_hits, 0)); |
634 | Print(8, "\n"); |
621 | Print(8, "\n"); |
635 | Print(8, " LMReductions:"); |
622 | Print(8, " LMReductions:"); |
636 | npc = 21; |
623 | npc = 21; |
637 | cpl = 75; |
624 | cpl = 75; |
638 | for (i = 1; i < 16; i++) |
625 | for (i = 1; i < 16; i++) |
639 | if (tree->LMR_done[i]) { |
626 | if (tree->LMR_done[i]) { |
640 | sprintf(buff, "%d/%s", i, DisplayKMB(tree->LMR_done[i], 0)); |
627 | sprintf(buff, "%d/%s", i, DisplayKMB(tree->LMR_done[i], 0)); |
641 | if (npc + |
628 | if (npc + strlen(buff) > cpl) { |
642 | Print(8, "\n "); |
629 | Print(8, "\n "); |
643 | npc = 12; |
630 | npc = 12; |
644 | } |
631 | } |
645 | Print(8, " %s", buff); |
632 | Print(8, " %s", buff); |
646 | npc += strlen(buff) + 2; |
633 | npc += strlen(buff) + 2; |
Line 652... | Line 639... | ||
652 | if (tree->null_done[null_depth]) |
639 | if (tree->null_done[null_depth]) |
653 | Print(8, " null-move (R):"); |
640 | Print(8, " null-move (R):"); |
654 | for (i = null_depth; i < 16; i++) |
641 | for (i = null_depth; i < 16; i++) |
655 | if (tree->null_done[i]) { |
642 | if (tree->null_done[i]) { |
656 | sprintf(buff, "%d/%s", i, DisplayKMB(tree->null_done[i], 0)); |
643 | sprintf(buff, "%d/%s", i, DisplayKMB(tree->null_done[i], 0)); |
657 | if (npc + |
644 | if (npc + strlen(buff) > cpl) { |
658 | Print(8, "\n "); |
645 | Print(8, "\n "); |
659 | npc = 12; |
646 | npc = 12; |
660 | } |
647 | } |
661 | Print(8, " %s", buff); |
648 | Print(8, " %s", buff); |
662 | npc += strlen(buff) + 2; |
649 | npc += strlen(buff) + 2; |
663 | } |
650 | } |
664 | if (npc) |
651 | if (npc) |
665 | Print(8, "\n"); |
652 | Print(8, "\n"); |
666 | if (parallel_splits) { |
653 | if (parallel_splits) { |
667 | max = 0; |
654 | max = 0; |
668 | for (i = 0; i < |
655 | for (i = 0; i < smp_max_threads; i++) { |
669 | max = Max(max, PopCnt(thread[i].max_blocks)); |
656 | max = Max(max, PopCnt(thread[i].max_blocks)); |
670 | game_max_blocks |= thread[i].max_blocks; |
657 | game_max_blocks |= thread[i].max_blocks; |
671 | } |
658 | } |
672 | Print(8, " splits=%s", DisplayKMB(parallel_splits, 0)); |
659 | Print(8, " splits=%s", DisplayKMB(parallel_splits, 0)); |
673 | Print(8, "(%s)", DisplayKMB(parallel_splits_wasted, 0)); |
660 | Print(8, "(%s)", DisplayKMB(parallel_splits_wasted, 0)); |
Line 686... | Line 673... | ||
686 | * iterated search at all. * |
673 | * iterated search at all. * |
687 | * * |
674 | * * |
688 | ************************************************************ |
675 | ************************************************************ |
689 | */ |
676 | */ |
690 | else { |
677 | else { |
691 | last_root_value = 0; |
678 | last_root_value = tree->pv[0].pathv; |
692 | value = 0; |
679 | value = tree->pv[0].pathv; |
693 | book_move = 1; |
680 | book_move = 1; |
694 | if (analyze_mode) |
681 | if (analyze_mode) |
695 | Kibitz(4, wtm, 0, 0, 0, 0, 0, 0, kibitz_text); |
682 | Kibitz(4, wtm, 0, 0, 0, 0, 0, 0, kibitz_text); |
696 | } |
683 | } |
697 | /* |
684 | /* |