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 | /* |