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 17... | Line 17... | ||
17 | * * |
17 | * * |
18 | ******************************************************************************* |
18 | ******************************************************************************* |
19 | */ |
19 | */ |
20 | void Initialize() { |
20 | void Initialize() { |
21 | TREE *tree; |
21 | TREE *tree; |
22 | int |
22 | int j, v, major, id; |
- | 23 | #if defined(UNIX) |
|
- | 24 | int i, node; |
|
- | 25 | #endif |
|
23 | 26 | ||
24 | tree = block[0]; |
27 | tree = block[0]; |
25 | for (j = 1; j <= MAX_BLOCKS; j++) |
28 | for (j = 1; j <= MAX_BLOCKS; j++) |
26 | block[j] = NULL; |
29 | block[j] = NULL; |
27 | InitializeMasks(); |
30 | InitializeMasks(); |
Line 62... | Line 65... | ||
62 | if (computer_bs_file) |
65 | if (computer_bs_file) |
63 | Print(32, "found computer opening book file [%s/bookc.bin].\n", |
66 | Print(32, "found computer opening book file [%s/bookc.bin].\n", |
64 | book_path); |
67 | book_path); |
65 | if (book_file) { |
68 | if (book_file) { |
66 | int maj_min; |
69 | int maj_min; |
67 | fseek(book_file, |
70 | fseek(book_file, - (long) sizeof(int), SEEK_END); |
68 | v = fread(&maj_min, 4, 1, book_file); |
71 | v = fread(&maj_min, 4, 1, book_file); |
69 | if (v <= 0) |
72 | if (v <= 0) |
70 | perror("Initialize() fread error: "); |
73 | perror("Initialize() fread error: "); |
71 | major = BookIn32((unsigned char *) &maj_min); |
74 | major = BookIn32((unsigned char *) &maj_min); |
72 | major = major >> 16; |
75 | major = major >> 16; |
Line 85... | Line 88... | ||
85 | history_file = fopen(history_filename, "w+"); |
88 | history_file = fopen(history_filename, "w+"); |
86 | if (!history_file) { |
89 | if (!history_file) { |
87 | printf("ERROR, unable to open game history file, exiting\n"); |
90 | printf("ERROR, unable to open game history file, exiting\n"); |
88 | CraftyExit(1); |
91 | CraftyExit(1); |
89 | } |
92 | } |
90 | AlignedMalloc |
93 | AlignedMalloc((void *) &hash_table, 64, |
91 | sizeof(HASH_ENTRY) * hash_table_size); |
94 | sizeof(HASH_ENTRY) * hash_table_size); |
92 | AlignedMalloc |
95 | AlignedMalloc((void *) &hash_path, 64, |
93 | sizeof(HPATH_ENTRY) * hash_path_size); |
96 | sizeof(HPATH_ENTRY) * hash_path_size); |
94 | AlignedMalloc |
97 | AlignedMalloc((void *) &pawn_hash_table, 64, |
95 | sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size); |
98 | sizeof(PAWN_HASH_ENTRY) * pawn_hash_table_size); |
96 | AlignedMalloc((void *) ((void *) &eval_hash_table), 64, |
- | |
97 | sizeof(uint64_t) * eval_hash_table_size); |
- | |
98 | if (!hash_table) { |
99 | if (!hash_table) { |
99 | Print(2048, |
100 | Print(2048, |
100 | "AlignedMalloc() failed, not enough memory (primary trans/ref table).\n"); |
101 | "AlignedMalloc() failed, not enough memory (primary trans/ref table).\n"); |
101 | hash_table_size = 0; |
102 | hash_table_size = 0; |
102 | hash_table = 0; |
103 | hash_table = 0; |
Line 136... | Line 137... | ||
136 | AlignedMalloc((void **) &block[i * 64 + j + 1], 2048, |
137 | AlignedMalloc((void **) &block[i * 64 + j + 1], 2048, |
137 | (size_t) sizeof(TREE)); |
138 | (size_t) sizeof(TREE)); |
138 | } |
139 | } |
139 | } |
140 | } |
140 | for (i = 1; i < 64; i++) { |
141 | for (i = 1; i < 64; i++) { |
141 | memset(( |
142 | memset((char *) block[i], 0, sizeof(TREE)); |
142 | LockInit(block[i]->lock); |
143 | LockInit(block[i]->lock); |
143 | } |
144 | } |
144 | for (node = 1; node < CPUS; node++) { |
145 | for (node = 1; node < CPUS; node++) { |
145 | ThreadAffinity(node); |
146 | ThreadAffinity(node); |
146 | for (i = 0; i < 64; i++) { |
147 | for (i = 0; i < 64; i++) { |
147 | memset(( |
148 | memset((char *) block[node * 64 + i], 0, sizeof(TREE)); |
148 | LockInit(block[node * 64 + i]->lock); |
149 | LockInit(block[node * 64 + i]->lock); |
149 | } |
150 | } |
150 | } |
151 | } |
151 | ThreadAffinity( |
152 | ThreadAffinity(0); |
152 | # endif |
153 | # endif |
153 | #endif |
154 | #endif |
154 | thread[0].blocks = 0xffffffffffffffffull; |
155 | thread[0].blocks = 0xffffffffffffffffull; |
155 | initialized_threads++; |
156 | initialized_threads++; |
156 | InitializeHashTables(1); |
157 | InitializeHashTables(1); |
157 | InitializeKingSafety(); |
158 | InitializeKingSafety(); |
- | 159 | InitializeLMP(); |
|
158 |
|
160 | InitializeLMR(); |
159 | } |
161 | } |
160 | 162 | ||
161 | /* |
163 | /* |
162 | ******************************************************************************* |
164 | ******************************************************************************* |
163 | * * |
165 | * * |
Line 410... | Line 412... | ||
410 | int squares[64]; |
412 | int squares[64]; |
411 | int numsquares = 0; |
413 | int numsquares = 0; |
412 | uint64_t temp = magic_bishop_mask[i]; |
414 | uint64_t temp = magic_bishop_mask[i]; |
413 | 415 | ||
414 | while (temp) { |
416 | while (temp) { |
415 | uint64_t abit = temp & |
417 | uint64_t abit = temp & -temp; |
416 | 418 | ||
417 | squares[numsquares++] = |
419 | squares[numsquares++] = |
418 | initmagicmoves_bitpos64_database[(abit * |
420 | initmagicmoves_bitpos64_database[(abit * |
419 | 0x07EDD5E59A4E28C2ull) >> 58]; |
421 | 0x07EDD5E59A4E28C2ull) >> 58]; |
420 | temp ^= abit; |
422 | temp ^= abit; |
Line 443... | Line 445... | ||
443 | int squares[64]; |
445 | int squares[64]; |
444 | int numsquares = 0; |
446 | int numsquares = 0; |
445 | uint64_t temp = magic_rook_mask[i]; |
447 | uint64_t temp = magic_rook_mask[i]; |
446 | 448 | ||
447 | while (temp) { |
449 | while (temp) { |
448 | uint64_t abit = temp & |
450 | uint64_t abit = temp & -temp; |
449 | 451 | ||
450 | squares[numsquares++] = |
452 | squares[numsquares++] = |
451 | initmagicmoves_bitpos64_database[(abit * |
453 | initmagicmoves_bitpos64_database[(abit * |
452 | 0x07EDD5E59A4E28C2ull) >> 58]; |
454 | 0x07EDD5E59A4E28C2ull) >> 58]; |
453 | temp ^= abit; |
455 | temp ^= abit; |
Line 738... | Line 740... | ||
738 | * in sequence. * |
740 | * in sequence. * |
739 | * * |
741 | * * |
740 | ******************************************************************************* |
742 | ******************************************************************************* |
741 | */ |
743 | */ |
742 | int InitializeGetLogID(void) { |
744 | int InitializeGetLogID(void) { |
743 | int t; |
745 | int t, total_files = 0; |
744 | #if defined(UNIX) |
746 | #if defined(UNIX) |
745 | struct stat *fileinfo = malloc(sizeof(struct stat)); |
747 | struct stat *fileinfo = malloc(sizeof(struct stat)); |
746 | #endif |
748 | #endif |
747 | 749 | ||
748 | if (!log_id) { |
- | |
749 |
|
750 | for (; total_files < 300; log_id++) { |
750 |
|
751 | sprintf(log_filename, "%s/log.%03d", log_path, log_id); |
751 |
|
752 | sprintf(history_filename, "%s/game.%03d", log_path, log_id); |
752 |
|
753 | log_file = fopen(log_filename, "r"); |
753 |
|
754 | if (!log_file) |
754 |
|
755 | break; |
755 |
|
756 | fclose(log_file); |
756 |
|
757 | total_files++; |
757 | } |
758 | } |
758 | #if defined(UNIX) |
759 | #if defined(UNIX) |
759 | /* a kludge to work around an xboard 4.2.3 problem. It sends two "quit" |
760 | /* a kludge to work around an xboard 4.2.3 problem. It sends two "quit" |
760 | commands, which causes every other log.nnn file to be empty. this code |
761 | commands, which causes every other log.nnn file to be empty. this code |
761 | looks for a very small log.nnn file as the last one, and if it is small, |
762 | looks for a very small log.nnn file as the last one, and if it is small, |
Line 799... | Line 800... | ||
799 | * Note that if no size has changed, (fault_in = 0) then we skip the NUMA * |
800 | * Note that if no size has changed, (fault_in = 0) then we skip the NUMA * |
800 | * stuff and just clear the tables, period. * |
801 | * stuff and just clear the tables, period. * |
801 | * * |
802 | * * |
802 | ******************************************************************************* |
803 | ******************************************************************************* |
803 | */ |
804 | */ |
804 | void InitializeHashTables(fault_in) { |
805 | void InitializeHashTables(int fault_in) { |
805 | uint64_t mem_per_node; |
806 | uint64_t mem_per_node; |
806 | int node; |
807 | int node; |
807 | 808 | ||
808 | transposition_age = 0; |
809 | transposition_age = 0; |
809 | if (fault_in && smp_numa) { |
810 | if (fault_in && smp_numa) { |
Line 816... | Line 817... | ||
816 | * * |
817 | * * |
817 | ************************************************************ |
818 | ************************************************************ |
818 | */ |
819 | */ |
819 | mem_per_node = |
820 | mem_per_node = |
820 | hash_table_size * sizeof(HASH_ENTRY) / Max(smp_max_threads, 1); |
821 | hash_table_size * sizeof(HASH_ENTRY) / Max(smp_max_threads, 1); |
821 | for (node = 0; node < |
822 | for (node = 0; node < smp_max_threads; node++) { |
822 | ThreadAffinity(node); |
823 | ThreadAffinity(node); |
823 | memset(( |
824 | memset((char *) hash_table + node * mem_per_node, 0, mem_per_node); |
824 | } |
825 | } |
825 | ThreadAffinity(0); |
826 | ThreadAffinity(0); |
826 | if (mem_per_node * Max(smp_max_threads, |
827 | if (mem_per_node * Max(smp_max_threads, |
827 | 1) < hash_table_size * sizeof(HASH_ENTRY)) |
828 | 1) < hash_table_size * sizeof(HASH_ENTRY)) |
828 | memset(( |
829 | memset((char *) hash_table + smp_max_threads * mem_per_node, 0, |
829 | hash_table_size * sizeof(HASH_ENTRY) - |
830 | hash_table_size * sizeof(HASH_ENTRY) - |
830 |
|
831 | mem_per_node * smp_max_threads); |
831 | /* |
832 | /* |
832 | ************************************************************ |
833 | ************************************************************ |
833 | * * |
834 | * * |
834 | * Second, initialize the primary hash path table, using * |
835 | * Second, initialize the primary hash path table, using * |
835 | * the NUMA trick to place part of the hash path table on * |
836 | * the NUMA trick to place part of the hash path table on * |
Line 837... | Line 838... | ||
837 | * * |
838 | * * |
838 | ************************************************************ |
839 | ************************************************************ |
839 | */ |
840 | */ |
840 | mem_per_node = |
841 | mem_per_node = |
841 | hash_path_size * sizeof(HPATH_ENTRY) / Max(smp_max_threads, 1); |
842 | hash_path_size * sizeof(HPATH_ENTRY) / Max(smp_max_threads, 1); |
842 | for (node = 0; node < |
843 | for (node = 0; node < smp_max_threads; node++) { |
843 | ThreadAffinity(node); |
844 | ThreadAffinity(node); |
844 | memset(( |
845 | memset((char *) hash_path + node * mem_per_node, 0, mem_per_node); |
845 | } |
846 | } |
846 | ThreadAffinity( |
847 | ThreadAffinity(0); |
847 | if (mem_per_node * Max(smp_max_threads, |
848 | if (mem_per_node * Max(smp_max_threads, |
848 | 1) < hash_path_size * sizeof(HPATH_ENTRY)) |
849 | 1) < hash_path_size * sizeof(HPATH_ENTRY)) |
849 | memset(( |
850 | memset((char *) hash_path + smp_max_threads * mem_per_node, 0, |
850 | hash_path_size * sizeof(HPATH_ENTRY) - |
851 | hash_path_size * sizeof(HPATH_ENTRY) - |
851 |
|
852 | mem_per_node * smp_max_threads); |
852 | /* |
853 | /* |
853 | ************************************************************ |
854 | ************************************************************ |
854 | * * |
855 | * * |
855 | * |
856 | * Finally, initialize the primary pawn hash table, using * |
856 | * the NUMA trick to place part of the pawn hash table on * |
857 | * the NUMA trick to place part of the pawn hash table on * |
857 | * each node of the NUMA system. * |
858 | * each node of the NUMA system. * |
858 | * * |
859 | * * |
859 | ************************************************************ |
860 | ************************************************************ |
860 | */ |
861 | */ |
861 | mem_per_node = |
862 | mem_per_node = |
862 | pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) / Max(smp_max_threads, |
863 | pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) / Max(smp_max_threads, |
863 | 1); |
864 | 1); |
864 | for (node = 0; node < |
865 | for (node = 0; node < smp_max_threads; node++) { |
865 | ThreadAffinity(node); |
866 | ThreadAffinity(node); |
866 | memset(( |
867 | memset((char *) pawn_hash_table + node * mem_per_node, 0, mem_per_node); |
867 | } |
868 | } |
868 | ThreadAffinity( |
869 | ThreadAffinity(0); |
869 | if (mem_per_node * Max(smp_max_threads, |
870 | if (mem_per_node * Max(smp_max_threads, |
870 | 1) < pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY)) |
871 | 1) < pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY)) |
871 | memset(( |
872 | memset((char *) pawn_hash_table + smp_max_threads * mem_per_node, 0, |
872 | pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) - |
873 | pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY) - |
873 | (size_t) mem_per_node * smp_max_threads); // Pierre-Marie Baty -- added type cast |
- | |
874 | /* |
- | |
875 | ************************************************************ |
- | |
876 | * * |
- | |
877 | * Finally, initialize the eval hash table, using the NUMA * |
- | |
878 | * trick to place part of the eval hash table on each node * |
- | |
879 | * of the NUMA system. * |
- | |
880 | * * |
- | |
881 | ************************************************************ |
- | |
882 | */ |
- | |
883 | mem_per_node = |
- | |
884 | eval_hash_table_size * sizeof(uint64_t) / Max(smp_max_threads, 1); |
- | |
885 | for (node = 0; node < (int) smp_max_threads; node++) { // Pierre-Marie Baty -- added type cast |
- | |
886 | ThreadAffinity(node); |
- | |
887 | memset((void *) ((size_t) eval_hash_table + node * mem_per_node), 0, (size_t) mem_per_node); // Pierre-Marie Baty -- added type casts + missing critical parentheses! |
- | |
888 | } |
- | |
889 | ThreadAffinity(4 % Min(4, smp_max_threads)); |
- | |
890 |
|
874 | mem_per_node * smp_max_threads); |
891 | 1) < eval_hash_table_size * sizeof(uint64_t)) |
- | |
892 | memset((void *) ((size_t) eval_hash_table + smp_max_threads * mem_per_node), 0, // Pierre-Marie Baty -- added type cast + missing critical parentheses! |
- | |
893 | eval_hash_table_size * sizeof(uint64_t) - |
- | |
894 | (size_t) mem_per_node * smp_max_threads); // Pierre-Marie Baty -- added type cast |
- | |
895 | /* |
875 | /* |
896 | ************************************************************ |
876 | ************************************************************ |
897 | * * |
877 | * * |
898 | * Before we return, we need to re-pin this thread to the * |
878 | * Before we return, we need to re-pin this thread to the * |
899 | * correct processor. * |
879 | * correct processor. * |
Line 909... | Line 889... | ||
909 | * tables since they have already been faulted in to the * |
889 | * tables since they have already been faulted in to the * |
910 | * correct NUMA node. * |
890 | * correct NUMA node. * |
911 | * * |
891 | * * |
912 | ************************************************************ |
892 | ************************************************************ |
913 | */ |
893 | */ |
914 | memset(( |
894 | memset((char *) hash_table, 0, hash_table_size * sizeof(HASH_ENTRY)); |
915 | memset(( |
895 | memset((char *) hash_path, 0, hash_path_size * sizeof(HPATH_ENTRY)); |
916 | memset(( |
896 | memset((char *) pawn_hash_table, 0, |
917 | pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY)); |
897 | pawn_hash_table_size * sizeof(PAWN_HASH_ENTRY)); |
918 | memset((void *) eval_hash_table, 0, |
- | |
919 | eval_hash_table_size * sizeof(uint64_t)); |
- | |
920 | } |
898 | } |
921 | } |
899 | } |
922 | 900 | ||
923 | /* |
901 | /* |
924 | ******************************************************************************* |
902 | ******************************************************************************* |
Line 1147... | Line 1125... | ||
1147 | } |
1125 | } |
1148 | 1126 | ||
1149 | /* |
1127 | /* |
1150 | ******************************************************************************* |
1128 | ******************************************************************************* |
1151 | * * |
1129 | * * |
- | 1130 | * InitializeLMP() is used to initialize the LMP thresholds used to decide * |
|
- | 1131 | * when to stop searching additional branches near the tips of the tree. * |
|
- | 1132 | * * |
|
- | 1133 | ******************************************************************************* |
|
- | 1134 | */ |
|
- | 1135 | void InitializeLMP() { |
|
- | 1136 | int i; |
|
- | 1137 | ||
- | 1138 | for (i = 0; i < LMP_depth; i++) |
|
- | 1139 | LMP[i] = LMP_base + pow(i + .5, LMP_scale); |
|
- | 1140 | } |
|
- | 1141 | ||
- | 1142 | /* |
|
- | 1143 | ******************************************************************************* |
|
- | 1144 | * * |
|
1152 | * |
1145 | * InitializeLMR() is used to initialize the reduction matrix used to set * |
1153 | * |
1146 | * the reduction value for LMR for each move searched. It is indexed by * |
1154 | * depth remaining and # moves searched. * |
1147 | * depth remaining and # moves searched. * |
1155 | * * |
1148 | * * |
1156 | ******************************************************************************* |
1149 | ******************************************************************************* |
1157 | */ |
1150 | */ |
1158 | void |
1151 | void InitializeLMR() { |
1159 | int d, m; |
1152 | int d, m; |
1160 | 1153 | ||
1161 | for (d = 0; d < 32; d++) |
1154 | for (d = 0; d < 32; d++) |
1162 | for (m = 0; m < 64; m++) |
1155 | for (m = 0; m < 64; m++) |
1163 | LMR[d][m] = 0; |
1156 | LMR[d][m] = 0; |
1164 | for (d = 3; d < 32; d++) |
1157 | for (d = 3; d < 32; d++) |
1165 | for (m = 1; m < 64; m++) { |
1158 | for (m = 1; m < 64; m++) { |
1166 | LMR[d][m] = |
1159 | LMR[d][m] = |
1167 | Max(Min(log(d * LMR_db) * log(m * LMR_mb) / LMR_s, LMR_max), |
1160 | Max(Min(log(d * LMR_db) * log(m * LMR_mb) / LMR_s, LMR_max), |
1168 | LMR_min); |
1161 | LMR_min); |
1169 | LMR[d][m] = Min(LMR[d][m], Max(d - 1 - LMR_rdepth, 0)); |
1162 | LMR[d][m] = Min(LMR[d][m], Max(d - 1 - LMR_rdepth, 0)); |
1170 | } |
1163 | } |
1171 | } |
1164 | } |