Skip to content

Commit c4452ed

Browse files
max-krasnyanskyfmz
authored andcommitted
threadpool: add support for ggml_threadpool_params_default/init
Also removes the need for explicit mask_specified param. all-zero cpumask means use default (usually inherited) cpu affinity mask.
1 parent 4a4d715 commit c4452ed

File tree

4 files changed

+41
-43
lines changed

4 files changed

+41
-43
lines changed

common/common.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,7 @@ void postprocess_cpu_params(cpu_params& cpuparams, const cpu_params* role_model)
295295
}
296296
}
297297

298-
if (n_set == 0) {
299-
// You hit the jackpot!
300-
memset(&cpuparams.cpumask[0], 1, GGML_MAX_N_THREADS);
301-
n_set = GGML_MAX_N_THREADS;
302-
}
303-
304-
if (n_set < cpuparams.n_threads) {
298+
if (n_set && n_set < cpuparams.n_threads) {
305299
// Not enough set bits, may experience performance issues.
306300
fprintf(stderr, "warn: Not enough set bits in CPU mask (%d) to satisfy requested thread count: %d\n", n_set, cpuparams.n_threads);
307301
}
@@ -2606,16 +2600,15 @@ struct llama_context_params llama_context_params_from_gpt_params(const gpt_param
26062600
struct ggml_threadpool_params ggml_threadpool_params_from_cpu_params(const cpu_params & params) {
26072601
struct ggml_threadpool_params tpp;
26082602

2609-
tpp.mask_specified = params.mask_valid;
2603+
ggml_threadpool_params_init(&tpp, params.n_threads); // setup the defaults
2604+
26102605
if (params.mask_valid) {
26112606
std::memcpy(&tpp.cpumask, &params.cpumask, GGML_MAX_N_THREADS);
26122607
}
26132608

2614-
tpp.n_threads = params.n_threads;
26152609
tpp.prio = params.priority;
26162610
tpp.poll = params.poll;
26172611
tpp.strict_cpu = params.strict_cpu;
2618-
tpp.paused = false;
26192612

26202613
return tpp;
26212614
}

examples/llama-bench/llama-bench.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1462,14 +1462,13 @@ int main(int argc, char ** argv) {
14621462

14631463
llama_kv_cache_clear(ctx);
14641464

1465-
struct ggml_threadpool_params tpp;
1466-
tpp.n_threads = t.n_threads;
1467-
tpp.mask_specified = params.cpuparams.mask_valid;
1465+
struct ggml_threadpool_params tpp = ggml_threadpool_params_default(t.n_threads);
14681466
tpp.strict_cpu = params.cpuparams.strict_cpu;
14691467
tpp.prio = params.cpuparams.priority;
14701468
tpp.poll = params.cpuparams.poll;
1471-
1472-
std::memcpy(&tpp.cpumask[0], &params.cpuparams.cpumask[0], GGML_MAX_N_THREADS);
1469+
if (params.cpuparams.mask_valid) {
1470+
std::memcpy(&tpp.cpumask[0], &params.cpuparams.cpumask[0], GGML_MAX_N_THREADS);
1471+
}
14731472

14741473
struct ggml_compute_threadpool* threadpool = ggml_create_threadpool(&tpp);
14751474
if (!threadpool) {

ggml/include/ggml.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -626,9 +626,10 @@ extern "C" {
626626
// If it returns true, the computation is aborted
627627
typedef bool (*ggml_abort_callback)(void * data);
628628

629+
// Threadpool params
630+
// Use ggml_threadpool_params_default() or ggml_threadpool_params_init() to populate the defaults
629631
struct ggml_threadpool_params {
630-
bool cpumask[GGML_MAX_N_THREADS]; // mask of cpu cores
631-
bool mask_specified; // mask is non-empty
632+
bool cpumask[GGML_MAX_N_THREADS]; // mask of cpu cores (all-zeros means use default affinity settings)
632633
int n_threads; // number of threads
633634
int32_t prio; // thread priority
634635
uint32_t poll; // polling level (0 - no polling, 100 - aggressive polling)
@@ -2025,6 +2026,8 @@ extern "C" {
20252026
GGML_API size_t ggml_graph_overhead(void);
20262027
GGML_API size_t ggml_graph_overhead_custom(size_t size, bool grads);
20272028

2029+
GGML_API struct ggml_threadpool_params ggml_threadpool_params_default(int n_threads);
2030+
GGML_API void ggml_threadpool_params_init(struct ggml_threadpool_params *p, int n_threads);
20282031
GGML_API bool ggml_threadpool_params_match (const struct ggml_threadpool_params *p0, const struct ggml_threadpool_params *p1);
20292032
GGML_API struct ggml_compute_threadpool* ggml_create_threadpool (struct ggml_threadpool_params * params);
20302033
GGML_API void ggml_release_threadpool (struct ggml_compute_threadpool * threadpool);

ggml/src/ggml.c

Lines changed: 29 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1987,7 +1987,6 @@ struct ggml_compute_state {
19871987
#ifndef GGML_USE_OPENMP
19881988
ggml_thread_t thrd;
19891989
bool cpumask[GGML_MAX_N_THREADS];
1990-
bool mask_specified;
19911990
int last_graph;
19921991
bool pending;
19931992
#endif
@@ -18828,11 +18827,14 @@ static bool ggml_thread_apply_thread_priority(int32_t prio) {
1882818827

1882918828
#endif
1883018829

18831-
static void ggml_thread_cpumask_next(const bool * global_mask, bool * local_mask, bool strict, int32_t* iter) {
18832-
if (!global_mask) {
18833-
memset(local_mask, 1, GGML_MAX_N_THREADS);
18834-
return;
18830+
static bool ggml_thread_cpumask_is_valid(const bool * mask) {
18831+
for (int i = 0; i < GGML_MAX_N_THREADS; i++) {
18832+
if (mask[i]) { return true; }
1883518833
}
18834+
return false;
18835+
}
18836+
18837+
static void ggml_thread_cpumask_next(const bool * global_mask, bool * local_mask, bool strict, int32_t* iter) {
1883618838
if (!strict) {
1883718839
memcpy(local_mask, global_mask, GGML_MAX_N_THREADS);
1883818840
return;
@@ -19189,8 +19191,10 @@ static thread_ret_t ggml_graph_compute_secondary_thread(void* data) {
1918919191
struct ggml_compute_threadpool * threadpool = state->threadpool;
1919019192

1919119193
ggml_thread_apply_thread_priority(threadpool->prio);
19192-
if (state->mask_specified)
19194+
19195+
if (ggml_thread_cpumask_is_valid(state->cpumask)) {
1919319196
ggml_thread_apply_affinity(state->cpumask);
19197+
}
1919419198

1919519199
while (true) {
1919619200
// Check if we need to sleep
@@ -19249,17 +19253,27 @@ static void ggml_graph_compute_kickoff(struct ggml_compute_threadpool * threadpo
1924919253

1925019254
#endif // GGML_USE_OPENMP
1925119255

19256+
void ggml_threadpool_params_init(struct ggml_threadpool_params * p, int n_threads) {
19257+
p->n_threads = n_threads;
19258+
p->prio = 0; // default priority (usually means normal or inherited)
19259+
p->poll = 50; // hybrid-polling enabled
19260+
p->strict_cpu = false; // no strict placement (all threads share same cpumask)
19261+
p->paused = false; // threads are ready to go
19262+
memset(p->cpumask, 0, GGML_MAX_N_THREADS); // all-zero means use the default affinity (usually inherited)
19263+
}
19264+
19265+
struct ggml_threadpool_params ggml_threadpool_params_default(int n_threads) {
19266+
struct ggml_threadpool_params p;
19267+
ggml_threadpool_params_init(&p, n_threads);
19268+
return p;
19269+
}
19270+
1925219271
bool ggml_threadpool_params_match(const struct ggml_threadpool_params * p0, const struct ggml_threadpool_params * p1) {
1925319272
if (p0->n_threads != p1->n_threads ) return false;
1925419273
if (p0->prio != p1->prio ) return false;
1925519274
if (p0->poll != p1->poll ) return false;
1925619275
if (p0->strict_cpu != p1->strict_cpu ) return false;
19257-
if (p0->mask_specified != p1->mask_specified) return false;
19258-
if (p0->mask_specified) {
19259-
return memcmp(p0->cpumask, p1->cpumask, GGML_MAX_N_THREADS) == 0;
19260-
}
19261-
19262-
return true;
19276+
return memcmp(p0->cpumask, p1->cpumask, GGML_MAX_N_THREADS) == 0;
1926319277
}
1926419278

1926519279
static struct ggml_compute_threadpool * ggml_create_threadpool_impl(
@@ -19312,16 +19326,13 @@ static struct ggml_compute_threadpool * ggml_create_threadpool_impl(
1931219326
for (int j = 0; j < tpp->n_threads; j++) {
1931319327
workers[j] = (struct ggml_compute_state) {
1931419328
.thrd = 0,
19315-
.mask_specified = tpp->mask_specified,
1931619329
.threadpool = threadpool,
1931719330
.ith = j,
1931819331
.last_graph = 0,
1931919332
.pending = false
1932019333
};
1932119334

19322-
if (tpp->mask_specified) {
19323-
ggml_thread_cpumask_next(tpp->cpumask, workers[j].cpumask, tpp->strict_cpu, &cpumask_iter);
19324-
}
19335+
ggml_thread_cpumask_next(tpp->cpumask, workers[j].cpumask, tpp->strict_cpu, &cpumask_iter);
1932519336

1932619337
// Spin threads for all secondary workers
1932719338
if (j > 0) {
@@ -19357,15 +19368,7 @@ enum ggml_status ggml_graph_compute(struct ggml_cgraph * cgraph, struct ggml_cpl
1935719368
GGML_PRINT_DEBUG("Threadpool is not specified. Will create a disposable threadpool : n_threads %d\n", n_threads);
1935819369
disposable_threadpool = true;
1935919370

19360-
struct ggml_threadpool_params ttp = {
19361-
.mask_specified = false,
19362-
.n_threads = n_threads,
19363-
.prio = 0,
19364-
.poll = 1,
19365-
.strict_cpu = false,
19366-
.paused = false
19367-
};
19368-
19371+
struct ggml_threadpool_params ttp = ggml_threadpool_params_default(n_threads);
1936919372
threadpool = ggml_create_threadpool_impl(&ttp, cgraph, cplan);
1937019373
} else {
1937119374
// Reset some of the parameters that need resetting
@@ -19407,7 +19410,7 @@ enum ggml_status ggml_graph_compute(struct ggml_cgraph * cgraph, struct ggml_cpl
1940719410
}
1940819411
#else
1940919412
// Update main thread affinity to match the current threadpool
19410-
if (threadpool->workers[0].mask_specified) {
19413+
if (!ggml_thread_cpumask_is_valid(threadpool->workers[0].cpumask)) {
1941119414
ggml_thread_apply_affinity(threadpool->workers[0].cpumask);
1941219415
}
1941319416

0 commit comments

Comments
 (0)