aboutsummaryrefslogtreecommitdiff
path: root/src/solvers
diff options
context:
space:
mode:
authorSebastiano Tronto <sebastiano@tronto.net>2024-09-17 21:53:36 +0200
committerSebastiano Tronto <sebastiano@tronto.net>2024-09-17 21:53:36 +0200
commit10e3c671ac33983b815e90e641633409280f045e (patch)
tree17bae570c8d30906d28671f4e9a7af22c4e52085 /src/solvers
parentca68b59475f6b1773fa62e6dbc4b68349602b441 (diff)
downloadnissy-core-10e3c671ac33983b815e90e641633409280f045e.tar.gz
nissy-core-10e3c671ac33983b815e90e641633409280f045e.zip
Parallelized h48k2 gendata
Diffstat (limited to 'src/solvers')
-rw-r--r--src/solvers/h48/gendata_h48.h92
-rw-r--r--src/solvers/h48/map.h4
2 files changed, 68 insertions, 28 deletions
diff --git a/src/solvers/h48/gendata_h48.h b/src/solvers/h48/gendata_h48.h
index 135d9d2..480e4f9 100644
--- a/src/solvers/h48/gendata_h48.h
+++ b/src/solvers/h48/gendata_h48.h
@@ -9,6 +9,7 @@
9#define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k)) 9#define H48_MASK(i, k) ((UINT8_BIT(k) - UINT8_C(1)) << H48_SHIFT(i, k))
10 10
11#define MAXLEN 20 11#define MAXLEN 20
12#define CHUNKS COCSEP_CLASSES /* Must be a divisor of H48_COORDMAX_NOEO */
12 13
13/* 14/*
14TODO: This loop over similar h48 coordinates can be improved by only 15TODO: This loop over similar h48 coordinates can be improved by only
@@ -69,6 +70,10 @@ typedef struct {
69 uint64_t *selfsim; 70 uint64_t *selfsim;
70 cube_t *crep; 71 cube_t *crep;
71 h48map_t *shortcubes; 72 h48map_t *shortcubes;
73 pthread_mutex_t *shortcubes_mutex;
74 pthread_mutex_t *table_mutex[CHUNKS];
75 uint64_t *next;
76 uint64_t *count;
72} h48k2_dfs_arg_t; 77} h48k2_dfs_arg_t;
73 78
74STATIC uint64_t gen_h48short(gendata_h48short_arg_t *); 79STATIC uint64_t gen_h48short(gendata_h48short_arg_t *);
@@ -78,6 +83,7 @@ STATIC int64_t gendata_h48h0k4_bfs(h48h0k4_bfs_arg_t *);
78STATIC int64_t gendata_h48h0k4_bfs_fromdone(h48h0k4_bfs_arg_t *); 83STATIC int64_t gendata_h48h0k4_bfs_fromdone(h48h0k4_bfs_arg_t *);
79STATIC int64_t gendata_h48h0k4_bfs_fromnew(h48h0k4_bfs_arg_t *); 84STATIC int64_t gendata_h48h0k4_bfs_fromnew(h48h0k4_bfs_arg_t *);
80STATIC size_t gendata_h48k2(gendata_h48_arg_t *); 85STATIC size_t gendata_h48k2(gendata_h48_arg_t *);
86STATIC void * gendata_h48k2_runthread(void *);
81STATIC_INLINE void gendata_h48k2_mark(cube_t, int8_t, h48k2_dfs_arg_t *); 87STATIC_INLINE void gendata_h48k2_mark(cube_t, int8_t, h48k2_dfs_arg_t *);
82STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, uint8_t, h48k2_dfs_arg_t *); 88STATIC_INLINE bool gendata_h48k2_dfs_stop(cube_t, uint8_t, h48k2_dfs_arg_t *);
83STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg); 89STATIC void gendata_h48k2_dfs(h48k2_dfs_arg_t *arg);
@@ -339,11 +345,12 @@ gendata_h48k2(gendata_h48_arg_t *arg)
339 345
340 uint8_t t, selectedbase, *table; 346 uint8_t t, selectedbase, *table;
341 int64_t j; 347 int64_t j;
342 uint64_t nshort, i, ii; 348 uint64_t nshort, i, ii, inext, count;
343 h48map_t shortcubes; 349 h48map_t shortcubes;
344 kvpair_t kv;
345 gendata_h48short_arg_t shortarg; 350 gendata_h48short_arg_t shortarg;
346 h48k2_dfs_arg_t dfsarg; 351 h48k2_dfs_arg_t dfsarg[THREADS];
352 pthread_t thread[THREADS];
353 pthread_mutex_t shortcubes_mutex, table_mutex[CHUNKS];
347 354
348 if (arg->buf == NULL) 355 if (arg->buf == NULL)
349 goto gendata_h48k2_return_size; 356 goto gendata_h48k2_return_size;
@@ -383,32 +390,37 @@ gendata_h48k2(gendata_h48_arg_t *arg)
383 if (arg->h >= 10) 390 if (arg->h >= 10)
384 arg->info.solver[14] = (arg->h / 10) + '0'; 391 arg->info.solver[14] = (arg->h / 10) + '0';
385 392
386 dfsarg = (h48k2_dfs_arg_t){ 393 inext = count = 0;
387 .h = arg->h, 394 pthread_mutex_init(&shortcubes_mutex, NULL);
388 .k = arg->k, 395 for (i = 0; i < CHUNKS; i++)
389 .base = selectedbase, 396 pthread_mutex_init(&table_mutex[i], NULL);
390 .shortdepth = shortdepth, 397 for (i = 0; i < THREADS; i++) {
391 .cocsepdata = arg->cocsepdata, 398 dfsarg[i] = (h48k2_dfs_arg_t){
392 .table = table, 399 .h = arg->h,
393 .selfsim = arg->selfsim, 400 .k = arg->k,
394 .crep = arg->crep, 401 .base = selectedbase,
395 .shortcubes = &shortcubes 402 .shortdepth = shortdepth,
396 }; 403 .cocsepdata = arg->cocsepdata,
404 .table = table,
405 .selfsim = arg->selfsim,
406 .crep = arg->crep,
407 .shortcubes = &shortcubes,
408 .shortcubes_mutex = &shortcubes_mutex,
409 .next = &inext,
410 .count = &count,
411 };
412 for (ii = 0; ii < CHUNKS; ii++)
413 dfsarg[i].table_mutex[ii] = &table_mutex[ii];
397 414
398 i = ii = 0; 415 pthread_create(
399 for (kv = h48map_nextkvpair(&shortcubes, &i); 416 &thread[i], NULL, gendata_h48k2_runthread, &dfsarg[i]);
400 i != shortcubes.capacity;
401 kv = h48map_nextkvpair(&shortcubes, &i)
402 ) {
403 dfsarg.cube = invcoord_h48(kv.key, arg->crep, 11);
404 gendata_h48k2_dfs(&dfsarg);
405 if (++ii % UINT64_C(1000000) == 0)
406 LOG("Processed %" PRIu64 " short cubes\n", ii);
407 } 417 }
408 418
419 for (i = 0; i < THREADS; i++)
420 pthread_join(thread[i], NULL);
421
409 h48map_destroy(&shortcubes); 422 h48map_destroy(&shortcubes);
410 423
411 arg->info.base = selectedbase;
412 for (j = 0; j < H48_COORDMAX(arg->h); j++) { 424 for (j = 0; j < H48_COORDMAX(arg->h); j++) {
413 t = get_h48_pval(table, j, 2); 425 t = get_h48_pval(table, j, 2);
414 arg->info.distribution[t]++; 426 arg->info.distribution[t]++;
@@ -420,6 +432,36 @@ gendata_h48k2_return_size:
420 return H48_TABLESIZE(arg->h, 2) + INFOSIZE; 432 return H48_TABLESIZE(arg->h, 2) + INFOSIZE;
421} 433}
422 434
435STATIC void *
436gendata_h48k2_runthread(void *arg)
437{
438 kvpair_t kv;
439 h48k2_dfs_arg_t *dfsarg;
440
441 dfsarg = (h48k2_dfs_arg_t *)arg;
442
443 while (true) {
444 pthread_mutex_lock(dfsarg->shortcubes_mutex);
445
446 kv = h48map_nextkvpair(dfsarg->shortcubes, dfsarg->next);
447 if (*dfsarg->next == dfsarg->shortcubes->capacity) {
448 pthread_mutex_unlock(dfsarg->shortcubes_mutex);
449 break;
450 }
451 dfsarg->cube = invcoord_h48(kv.key, dfsarg->crep, 11);
452 (*dfsarg->count)++;
453 if (*dfsarg->count % UINT64_C(1000000) == 0)
454 LOG("Processing %" PRIu64 "th short cube\n",
455 *dfsarg->count);
456
457 pthread_mutex_unlock(dfsarg->shortcubes_mutex);
458
459 gendata_h48k2_dfs(dfsarg);
460 }
461
462 return NULL;
463}
464
423STATIC void 465STATIC void
424gendata_h48k2_dfs(h48k2_dfs_arg_t *arg) 466gendata_h48k2_dfs(h48k2_dfs_arg_t *arg)
425{ 467{
@@ -488,9 +530,11 @@ gendata_h48k2_mark(cube_t cube, int8_t depth, h48k2_dfs_arg_t *arg)
488 FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim, 530 FOREACH_H48SIM(cube, arg->cocsepdata, arg->selfsim,
489 fullcoord = coord_h48(cube, arg->cocsepdata, 11); 531 fullcoord = coord_h48(cube, arg->cocsepdata, 11);
490 coord = fullcoord >> (int64_t)(11 - arg->h); 532 coord = fullcoord >> (int64_t)(11 - arg->h);
533 pthread_mutex_lock(arg->table_mutex[coord % CHUNKS]);
491 oldval = get_h48_pval(arg->table, coord, arg->k); 534 oldval = get_h48_pval(arg->table, coord, arg->k);
492 newval = (uint8_t)MAX(depth, 0); 535 newval = (uint8_t)MAX(depth, 0);
493 set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval)); 536 set_h48_pval(arg->table, coord, arg->k, MIN(oldval, newval));
537 pthread_mutex_unlock(arg->table_mutex[coord % CHUNKS]);
494 ) 538 )
495} 539}
496 540
diff --git a/src/solvers/h48/map.h b/src/solvers/h48/map.h
index baffe39..e74a5dd 100644
--- a/src/solvers/h48/map.h
+++ b/src/solvers/h48/map.h
@@ -88,10 +88,6 @@ h48map_nextkvpair(h48map_t *map, uint64_t *p)
88 kv.key = MAP_KEYMASK; 88 kv.key = MAP_KEYMASK;
89 kv.val = MAP_UNSET_VAL; 89 kv.val = MAP_UNSET_VAL;
90 90
91 DBG_ASSERT(*p < map->capacity, kv,
92 "Error looping over map: given index %" PRIu64 " is out of "
93 "range [0,%" PRIu64 "]", *p, map->capacity);
94
95 for ( ; *p < map->capacity; (*p)++) { 91 for ( ; *p < map->capacity; (*p)++) {
96 if (map->table[*p] != MAP_UNSET) { 92 if (map->table[*p] != MAP_UNSET) {
97 pair = map->table[(*p)++]; 93 pair = map->table[(*p)++];

Generated with cgit - Back to sebastiano.tronto.net