From 4a88a686d5e08404080ed6954b70c0db252aa220 Mon Sep 17 00:00:00 2001 From: Sebastiano Tronto Date: Sat, 14 Dec 2024 11:59:22 +0100 Subject: Allow choosing number of threads when calling solve() --- src/nissy.c | 16 +++++++++++++++- src/nissy.h | 4 ++++ src/solvers/h48/solve.h | 17 ++++++++++------- 3 files changed, 29 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/nissy.c b/src/nissy.c index f933cab..5d009ba 100644 --- a/src/nissy.c +++ b/src/nissy.c @@ -489,6 +489,7 @@ nissy_solve( unsigned maxmoves, unsigned maxsols, int optimal, + int threads, unsigned long long data_size, const char data[data_size], unsigned sols_size, @@ -499,6 +500,7 @@ nissy_solve( cube_t c; long long parse_ret; uint8_t h, k; + int t; if (solver == NULL) { LOG("Error: 'solver' argument is NULL\n"); @@ -522,10 +524,22 @@ nissy_solve( return 0; } + t = threads == 0 ? THREADS : threads; + if (t < 0) { + LOG("solve: 'threads' is negative. Please provide a " + "number of threads between 1 and %d\n", THREADS); + return NISSY_ERROR_OPTIONS; + } + if (t > THREADS) { + LOG("solve: 'threads' is above the maximum value of %d\n", + THREADS); + return NISSY_ERROR_OPTIONS; + } + if (!strncmp(solver, "h48", 3)) { parse_ret = parse_h48_solver(solver, &h, &k); if (parse_ret == NISSY_OK) - return solve_h48(c, minmoves, maxmoves, maxsols, + return solve_h48(c, minmoves, maxmoves, maxsols, t, data_size, data, sols_size, sols, stats); else return parse_ret; diff --git a/src/nissy.h b/src/nissy.h index 8394fad..94c604c 100644 --- a/src/nissy.h +++ b/src/nissy.h @@ -259,6 +259,9 @@ Parameters: maxsols - The maximum number of solutions. optimal - If set to a non-negative value, the maximum number of moves above the optimal solution length. + threads - The number of threads to use. Must be less than or equalt to + the value of the compile-time constant THREADS. If set to 0, + the default value THREADS will be used. data_size - The size of the data buffer. data - The data for the solver. Can be computed with gendata. sols_size - The size of the solutions buffer. @@ -286,6 +289,7 @@ nissy_solve( unsigned maxmoves, unsigned maxsolutions, int optimal, + int threads, unsigned long long data_size, const char data[data_size], unsigned sols_size, diff --git a/src/solvers/h48/solve.h b/src/solvers/h48/solve.h index 8666007..0969c45 100644 --- a/src/solvers/h48/solve.h +++ b/src/solvers/h48/solve.h @@ -38,6 +38,7 @@ typedef struct { int64_t nodes_visited; int64_t table_fallbacks; int64_t table_lookups; + int threads; int ntasks; solve_h48_task_t *tasks; int thread_id; @@ -62,7 +63,7 @@ STATIC int64_t solve_h48_maketasks( solve_h48_task_t [static STARTING_CUBES], int *); STATIC void *solve_h48_runthread(void *); STATIC int64_t solve_h48_dfs(dfsarg_solve_h48_t *); -STATIC int64_t solve_h48(cube_t, int8_t, int8_t, uint64_t, uint64_t, +STATIC int64_t solve_h48(cube_t, int8_t, int8_t, uint64_t, int, uint64_t, const void *, uint64_t, char *, long long [static NISSY_SIZE_SOLVE_STATS]); STATIC int64_t @@ -316,7 +317,7 @@ solve_h48_runthread(void *arg) dfsarg = (dfsarg_solve_h48_t *)arg; cube = dfsarg->start_cube; - for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += THREADS) { + for (i = dfsarg->thread_id; i < dfsarg->ntasks; i += dfsarg->threads) { task = dfsarg->tasks[i]; memcpy(dfsarg->moves, task.moves, STARTING_MOVES); dfsarg->cube = cube; @@ -407,6 +408,7 @@ solve_h48( int8_t minmoves, int8_t maxmoves, uint64_t maxsolutions, + int threads, uint64_t data_size, const void *data, uint64_t solutions_size, @@ -461,7 +463,7 @@ solve_h48( fallback2 = h48data + offset; symmask = symmetry_mask(cube); - for (i = 0; i < THREADS; i++) { + for (i = 0; i < threads; i++) { arg[i] = (dfsarg_solve_h48_t) { .start_cube = cube, .cube = cube, @@ -481,6 +483,7 @@ solve_h48( .nodes_visited = 0, .table_fallbacks = 0, .table_lookups = 0, + .threads = threads, .thread_id = i, .solutions_mutex = &solutions_mutex, }; @@ -505,7 +508,7 @@ solve_h48( if (*arg[0].nsols >= (int64_t)maxsolutions) goto solve_h48_done; - for (i = 0; i < THREADS; i++) { + for (i = 0; i < threads; i++) { arg[i].ntasks = ntasks; arg[i].tasks = tasks; } @@ -520,12 +523,12 @@ solve_h48( if (d >= 10) LOG("Found %" PRId64 " solutions, searching at depth %" PRId8 "\n", nsols, d); - for (i = 0; i < THREADS; i++) { + for (i = 0; i < threads; i++) { arg[i].depth = d; pthread_create( &thread[i], NULL, solve_h48_runthread, &arg[i]); } - for (i = 0; i < THREADS; i++) + for (i = 0; i < threads; i++) pthread_join(thread[i], NULL); } @@ -534,7 +537,7 @@ solve_h48_done: goto solve_h48_error_solutions_buffer; nodes_visited = table_lookups = table_fallbacks = 0; - for (i = 0; i < THREADS; i++) { + for (i = 0; i < threads; i++) { nodes_visited += arg[i].nodes_visited; table_fallbacks += arg[i].table_fallbacks; table_lookups += arg[i].table_lookups; -- cgit v1.3