OverviewFilesCommitsIssuesDocsReleasesPeers

opencog-CompactHash commits / e27f79b

Adding openmp functionality
e27f79becde8c3c8964bdcff57ecda34ddc7ab28
by brobey <brobey@lanl.gov> · 2015-10-21T22:00:10.000Z

Changed files (1) +195 -43

simplehash/simplehash.c +195 -43
……@@ -105,6 +105,50 @@ int *compact_hash_init(int ncells, uint isize, uint jsize, uint report_level){
105105 for (uint ii = 0; ii<2*hashtablesize; ii+=2){
106106 hash[ii] = -1;
107107 }
108
109 if (hash_method == LINEAR){
110 if (hash_report_level == 0){
111 read_hash = read_hash_linear;
112 write_hash = write_hash_linear;
113 } else if (hash_report_level == 1){
114 read_hash = read_hash_linear_report_level_1;
115 write_hash = write_hash_linear_report_level_1;
116 } else if (hash_report_level == 2){
117 read_hash = read_hash_linear_report_level_2;
118 write_hash = write_hash_linear_report_level_2;
119 } else if (hash_report_level == 3){
120 read_hash = read_hash_linear_report_level_3;
121 write_hash = write_hash_linear_report_level_3;
122 }
123 } else if (hash_method == QUADRATIC) {
124 if (hash_report_level == 0){
125 read_hash = read_hash_quadratic;
126 write_hash = write_hash_quadratic;
127 } else if (hash_report_level == 1){
128 read_hash = read_hash_quadratic_report_level_1;
129 write_hash = write_hash_quadratic_report_level_1;
130 } else if (hash_report_level == 2){
131 read_hash = read_hash_quadratic_report_level_2;
132 write_hash = write_hash_quadratic_report_level_2;
133 } else if (hash_report_level == 3){
134 read_hash = read_hash_quadratic_report_level_3;
135 write_hash = write_hash_quadratic_report_level_3;
136 }
137 } else if (hash_method == PRIME_JUMP) {
138 if (hash_report_level == 0){
139 read_hash = read_hash_primejump;
140 write_hash = write_hash_primejump;
141 } else if (hash_report_level == 1){
142 read_hash = read_hash_primejump_report_level_1;
143 write_hash = write_hash_primejump_report_level_1;
144 } else if (hash_report_level == 2){
145 read_hash = read_hash_primejump_report_level_2;
146 write_hash = write_hash_primejump_report_level_2;
147 } else if (hash_report_level == 3){
148 read_hash = read_hash_primejump_report_level_3;
149 write_hash = write_hash_primejump_report_level_3;
150 }
151 }
108152 } else {
109153 hashtablesize = perfect_hash_size;
110154
……@@ -112,6 +156,9 @@ int *compact_hash_init(int ncells, uint isize, uint jsize, uint report_level){
112156 for (uint ii = 0; ii<hashtablesize; ii++){
113157 hash[ii] = -1;
114158 }
159
160 read_hash = read_hash_perfect;
161 write_hash = write_hash_perfect;
115162 }
116163
117164 if (hash_report_level >= 2) {
……@@ -120,55 +167,137 @@ int *compact_hash_init(int ncells, uint isize, uint jsize, uint report_level){
120167 (double)hashtablesize/(double)(isize*jsize));
121168 }
122169
123 if (! do_compact_hash) {
124 read_hash = read_hash_perfect;
125 write_hash = write_hash_perfect;
126 } else if (hash_method == LINEAR){
127 if (hash_report_level == 0){
128 read_hash = read_hash_linear;
129 write_hash = write_hash_linear;
130 } else if (hash_report_level == 1){
131 read_hash = read_hash_linear_report_level_1;
132 write_hash = write_hash_linear_report_level_1;
133 } else if (hash_report_level == 2){
134 read_hash = read_hash_linear_report_level_2;
135 write_hash = write_hash_linear_report_level_2;
136 } else if (hash_report_level == 3){
137 read_hash = read_hash_linear_report_level_3;
138 write_hash = write_hash_linear_report_level_3;
170 return(hash);
171}
172
173#ifdef _OPENMP
174
175#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
176int *compact_hash_init_openmp(int ncells, uint isize, uint jsize, uint report_level){
177#else
178int *compact_hash_init_openmp(int ncells, uint isize, uint jsize, uint report_level, omp_lock_t **lock){
179#endif
180
181 hash_ncells = 0;
182 write_hash_collisions = 0;
183 read_hash_collisions = 0;
184 hash_queries = 0;
185 hash_report_level = report_level;
186 hash_stride = isize;
187 int *hash = NULL;
188
189 if (choose_hash_method != METHOD_UNSET) hash_method = choose_hash_method;
190
191 uint compact_hash_size = (uint)((double)ncells*hash_mult);
192 uint perfect_hash_size = (uint)(isize*jsize);
193
194 if (hash_method == METHOD_UNSET){
195 float hash_mem_factor = 20.0;
196 float hash_mem_ratio = (double)perfect_hash_size/(double)compact_hash_size;
197 if (mem_opt_factor != 1.0) hash_mem_factor /= (mem_opt_factor*0.2);
198 hash_method = (hash_mem_ratio < hash_mem_factor) ? PERFECT_HASH : QUADRATIC;
199 //hash_method = QUADRATIC;
200
201 if (hash_report_level >= 2) printf("DEBUG hash_method %d hash_mem_ratio %f hash_mem_factor %f mem_opt_factor %f perfect_hash_size %u compact_hash_size %u\n",
202 hash_method,hash_mem_ratio,hash_mem_factor,mem_opt_factor,perfect_hash_size,compact_hash_size);
203 }
204
205 int do_compact_hash = (hash_method == PERFECT_HASH) ? 0 : 1;
206
207 if (hash_report_level >= 2) printf("DEBUG do_compact_hash %d hash_method %d perfect_hash_size %u compact_hash_size %u\n",
208 do_compact_hash,hash_method,perfect_hash_size,compact_hash_size);
209
210 if (do_compact_hash) {
211 hashtablesize = compact_hash_size;
212 //srand48(0);
213 AA = (ulong)(1.0+(double)(prime-1)*drand48());
214 BB = (ulong)(0.0+(double)(prime-1)*drand48());
215 if (AA > prime-1 || BB > prime-1) exit(0);
216 if (hash_report_level > 1) printf("Factors AA %lu BB %lu\n",AA,BB);
217
218 hash = (int *)genvector(2*hashtablesize,sizeof(int));
219
220#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
221 (*lock) = (omp_lock_t *)malloc(hashtablesize*sizeof(omp_lock_t));
222#endif
223
224#ifdef _OPENMP
225#pragma omp parallel for
226#endif
227 for (uint ii = 0; ii<hashtablesize; ii++){
228 hash[2*ii] = -1;
229#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
230 omp_init_lock(&((*lock)[ii]));
231#endif
139232 }
140 } else if (hash_method == QUADRATIC){
141 if (hash_report_level == 0){
142 read_hash = read_hash_quadratic;
143 write_hash = write_hash_quadratic;
144 } else if (hash_report_level == 1){
145 read_hash = read_hash_quadratic_report_level_1;
146 write_hash = write_hash_quadratic_report_level_1;
147 } else if (hash_report_level == 2){
148 read_hash = read_hash_quadratic_report_level_2;
149 write_hash = write_hash_quadratic_report_level_2;
150 } else if (hash_report_level == 3){
151 read_hash = read_hash_quadratic_report_level_3;
152 write_hash = write_hash_quadratic_report_level_3;
233
234 if (hash_method == LINEAR){
235 if (hash_report_level == 0){
236 read_hash = read_hash_linear;
237 write_hash_openmp = write_hash_linear_openmp;
238 } else if (hash_report_level == 1){
239 read_hash = read_hash_linear_report_level_1;
240 write_hash_openmp = write_hash_linear_openmp_report_level_1;
241 } else if (hash_report_level == 2){
242 read_hash = read_hash_linear_report_level_2;
243 write_hash_openmp = write_hash_linear_openmp_report_level_2;
244 } else if (hash_report_level == 3){
245 read_hash = read_hash_linear_report_level_3;
246 write_hash_openmp = write_hash_linear_openmp_report_level_3;
247 }
248 } else if (hash_method == QUADRATIC) {
249 if (hash_report_level == 0){
250 read_hash = read_hash_quadratic;
251 write_hash_openmp = write_hash_quadratic_openmp;
252 } else if (hash_report_level == 1){
253 read_hash = read_hash_quadratic_report_level_1;
254 write_hash_openmp = write_hash_quadratic_openmp_report_level_1;
255 } else if (hash_report_level == 2){
256 read_hash = read_hash_quadratic_report_level_2;
257 write_hash_openmp = write_hash_quadratic_openmp_report_level_2;
258 } else if (hash_report_level == 3){
259 read_hash = read_hash_quadratic_report_level_3;
260 write_hash_openmp = write_hash_quadratic_openmp_report_level_3;
261 }
262 } else if (hash_method == PRIME_JUMP) {
263 if (hash_report_level == 0){
264 read_hash = read_hash_primejump;
265 write_hash_openmp = write_hash_primejump_openmp;
266 } else if (hash_report_level == 1){
267 read_hash = read_hash_primejump_report_level_1;
268 write_hash_openmp = write_hash_primejump_openmp_report_level_1;
269 } else if (hash_report_level == 2){
270 read_hash = read_hash_primejump_report_level_2;
271 write_hash_openmp = write_hash_primejump_openmp_report_level_2;
272 } else if (hash_report_level == 3){
273 read_hash = read_hash_primejump_report_level_3;
274 write_hash_openmp = write_hash_primejump_openmp_report_level_3;
275 }
153276 }
154 } else if (hash_method == PRIME_JUMP){
155 if (hash_report_level == 0){
156 read_hash = read_hash_primejump;
157 write_hash = write_hash_primejump;
158 } else if (hash_report_level == 1){
159 read_hash = read_hash_primejump_report_level_1;
160 write_hash = write_hash_primejump_report_level_1;
161 } else if (hash_report_level == 2){
162 read_hash = read_hash_primejump_report_level_2;
163 write_hash = write_hash_primejump_report_level_2;
164 } else if (hash_report_level == 3){
165 read_hash = read_hash_primejump_report_level_3;
166 write_hash = write_hash_primejump_report_level_3;
277 } else {
278 hashtablesize = perfect_hash_size;
279
280 hash = (int *)genvector(hashtablesize,sizeof(int));
281#ifdef _OPENMP
282#pragma omp parallel for
283#endif
284 for (uint ii = 0; ii<hashtablesize; ii++){
285 hash[ii] = -1;
167286 }
287
288 read_hash = read_hash_perfect;
289 write_hash_openmp = write_hash_perfect_openmp;
290 }
291
292 if (hash_report_level >= 2) {
293 printf("Hash table size %u perfect hash table size %u memory savings %d by percentage %lf\n",
294 hashtablesize,isize*jsize,(int)isize*(int)jsize-(int)hashtablesize,
295 (double)hashtablesize/(double)(isize*jsize) * 100.0);
168296 }
169297
170298 return(hash);
171299}
300#endif
172301
173302void write_hash_perfect(uint ic, ulong hashkey, int *hash){
174303 hash[hashkey] = ic;
……@@ -1105,9 +1234,31 @@ int read_hash_primejump_report_level_3(ulong hashkey, int *hash){
11051234}
11061235
11071236void compact_hash_delete(int *hash){
1108 free(hash);
1237 read_hash = NULL;
1238 free(hash);
11091239}
11101240
1241#ifdef _OPENMP
1242 #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
1243 void compact_hash_delete_openmp(int *hash){
1244 #else
1245 void compact_hash_delete_openmp(int *hash, omp_lock_t *lock){
1246 #endif
1247
1248 read_hash = NULL;
1249 genvectorfree((void *)hash);
1250#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
1251 if (hash_method != PERFECT_HASH){
1252 for (uint i = 0; i<hashtablesize; i++){
1253 omp_destroy_lock(&(lock[i]));
1254 }
1255 free(lock);
1256 }
1257#endif
1258 hash_method = METHOD_UNSET;
1259}
1260#endif
1261
11111262void write_hash_collision_report(void){
11121263 if (hash_method == PERFECT_HASH) return;
11131264 if (hash_report_level == 1) {
……@@ -1131,6 +1282,7 @@ void read_hash_collision_report(void){
11311282}
11321283
11331284void final_hash_collision_report(void){
1285
11341286 if (hash_report_level >= 1 && read_hash_collisions_count > 0) {
11351287 printf("Final hash collision report -- write/read collisions per cell %lf/%lf\n",write_hash_collisions_runsum/(double)write_hash_collisions_count,read_hash_collisions_runsum/(double)read_hash_collisions_count);
11361288 }