← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
ckernel_strict.c File Reference
#include "ckernel_engine.h"
#include "ck_threadpool.h"
#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

Go to the source code of this file.

Macros

#define CK_ADD_PAIR(pid, cid)
 

Typedefs

typedef size_t(* ck_strict_mtmd_clip_embd_nbytes_by_img_fn) (void *, int, int)
 
typedef int(* ck_strict_mtmd_clip_encode_float_image_fn) (void *, int, float *, int, int, float *)
 
typedef void(* ck_strict_mtmd_clip_free_fn) (void *)
 
typedef void *(* ck_strict_mtmd_clip_init_fn) (const char *, int, int, int, int, int)
 

Functions

int ck_get_num_threads (void)
 
int ck_get_physical_cores (void)
 
ck_threadpool_t * ck_get_threadpool (void)
 
static int ck_parse_env_int (const char *name)
 
void ck_set_num_threads (int num_threads)
 
void ck_set_strict_parity (int enabled)
 
const float * ck_strict_consume_next_gemm_a (size_t elems)
 
int ck_strict_mtmd_clip_encode_planar_f32 (const float *planar, int channels, int height, int width, float *out, size_t out_elems)
 
int ck_strict_parity_enabled (void)
 
void ck_strict_store_next_gemm_a (const float *data, size_t elems)
 
void ck_threadpool_init (void)
 
void ck_threadpool_shutdown (void)
 

Variables

static float * ck_strict_next_gemm_a = NULL
 
static size_t ck_strict_next_gemm_a_cap = 0
 
static size_t ck_strict_next_gemm_a_size = 0
 
static int ck_strict_next_gemm_a_valid = 0
 
static int ck_strict_parity = 0
 
static int g_num_threads = 0
 
static int g_threads_initialized = 0
 

Macro Definition Documentation

◆ CK_ADD_PAIR

#define CK_ADD_PAIR (   pid,
  cid 
)
Value:
do { \
if ((pid) >= 0 && (cid) >= 0) { \
int exists = 0; \
for (int ii = 0; ii < seen_count; ++ii) { \
if (seen[ii].physical_id == (pid) && \
seen[ii].core_id == (cid)) { \
exists = 1; \
break; \
} \
} \
if (!exists && seen_count < seen_cap) { \
seen[seen_count].physical_id = (pid); \
seen[seen_count].core_id = (cid); \
++seen_count; \
} \
} \
} while (0)

Typedef Documentation

◆ ck_strict_mtmd_clip_embd_nbytes_by_img_fn

typedef size_t(* ck_strict_mtmd_clip_embd_nbytes_by_img_fn) (void *, int, int)

Definition at line 81 of file ckernel_strict.c.

◆ ck_strict_mtmd_clip_encode_float_image_fn

typedef int(* ck_strict_mtmd_clip_encode_float_image_fn) (void *, int, float *, int, int, float *)

Definition at line 82 of file ckernel_strict.c.

◆ ck_strict_mtmd_clip_free_fn

typedef void(* ck_strict_mtmd_clip_free_fn) (void *)

Definition at line 80 of file ckernel_strict.c.

◆ ck_strict_mtmd_clip_init_fn

typedef void *(* ck_strict_mtmd_clip_init_fn) (const char *, int, int, int, int, int)

Definition at line 79 of file ckernel_strict.c.

Function Documentation

◆ ck_get_num_threads()

int ck_get_num_threads ( void  )

Definition at line 310 of file ckernel_strict.c.

311{
312 // Auto-initialize if not set
314 ck_set_num_threads(0); // Auto-detect
315 }
316 return g_num_threads;
317}
void ck_set_num_threads(int num_threads)
static int g_num_threads
static int g_threads_initialized

References ck_set_num_threads(), g_num_threads, and g_threads_initialized.

Referenced by attention_forward_decode_head_major_gqa_flash_f16cache_contract(), gemm_blocked_serial(), and global_pool_init().

◆ ck_get_physical_cores()

int ck_get_physical_cores ( void  )

Definition at line 170 of file ckernel_strict.c.

171{
172 int physical_cores = 0;
173 int logical_cores = (int)sysconf(_SC_NPROCESSORS_ONLN);
174 if (logical_cores <= 0) {
175 logical_cores = 1;
176 }
177
178 int cpu_cores_hint = 0;
179 int siblings_hint = 0;
180
181 // Read from /proc/cpuinfo (Linux) and count unique (physical id, core id) pairs.
182 FILE *f = fopen("/proc/cpuinfo", "r");
183 if (f) {
184 char line[256];
185 int physical_id = -1;
186 int core_id = -1;
187
188 struct {
189 int physical_id;
190 int core_id;
191 } seen[8192];
192 int seen_count = 0;
193
194 const int seen_cap = (int)(sizeof(seen) / sizeof(seen[0]));
195
196 // Helper: add (pid,cid) to set if not present.
197 #define CK_ADD_PAIR(pid, cid) \
198 do { \
199 if ((pid) >= 0 && (cid) >= 0) { \
200 int exists = 0; \
201 for (int ii = 0; ii < seen_count; ++ii) { \
202 if (seen[ii].physical_id == (pid) && \
203 seen[ii].core_id == (cid)) { \
204 exists = 1; \
205 break; \
206 } \
207 } \
208 if (!exists && seen_count < seen_cap) { \
209 seen[seen_count].physical_id = (pid); \
210 seen[seen_count].core_id = (cid); \
211 ++seen_count; \
212 } \
213 } \
214 } while (0)
215
216 while (fgets(line, sizeof(line), f)) {
217 int val;
218
219 // Blank line separates processor blocks.
220 if (line[0] == '\n' || line[0] == '\0') {
221 CK_ADD_PAIR(physical_id, core_id);
222 physical_id = -1;
223 core_id = -1;
224 continue;
225 }
226
227 if (sscanf(line, "physical id : %d", &val) == 1) {
228 physical_id = val;
229 continue;
230 }
231 if (sscanf(line, "core id : %d", &val) == 1) {
232 core_id = val;
233 continue;
234 }
235 if (sscanf(line, "cpu cores : %d", &val) == 1) {
236 if (val > cpu_cores_hint) cpu_cores_hint = val;
237 continue;
238 }
239 if (sscanf(line, "siblings : %d", &val) == 1) {
240 if (val > siblings_hint) siblings_hint = val;
241 continue;
242 }
243 }
244 fclose(f);
245
246 // Handle file without trailing blank line.
247 CK_ADD_PAIR(physical_id, core_id);
248
249 #undef CK_ADD_PAIR
250
251 physical_cores = seen_count;
252 }
253
254 // Fallback: infer threads-per-core from siblings/cpu cores when pair data
255 // is missing (common in containers/VMs).
256 if (physical_cores <= 1 && logical_cores > 1) {
257 int threads_per_core = 0;
258 if (siblings_hint > 0 && cpu_cores_hint > 0 && siblings_hint >= cpu_cores_hint) {
259 threads_per_core = siblings_hint / cpu_cores_hint;
260 }
261 if (threads_per_core > 1) {
262 int inferred_physical = logical_cores / threads_per_core;
263 if (inferred_physical > 1) {
264 return inferred_physical;
265 }
266 }
267 if (cpu_cores_hint > 1 && cpu_cores_hint <= logical_cores) {
268 return cpu_cores_hint;
269 }
270 return logical_cores;
271 }
272
273 if (physical_cores > 1) {
274 return physical_cores;
275 }
276
277 return logical_cores;
278}
#define CK_ADD_PAIR(pid, cid)

References CK_ADD_PAIR.

Referenced by ck_set_num_threads(), ck_threadpool_create_capacity(), and global_pool_init().

◆ ck_get_threadpool()

ck_threadpool_t * ck_get_threadpool ( void  )

Get the global thread pool handle for dispatch. Convenience wrapper — initializes on first call.

Definition at line 350 of file ckernel_strict.c.

351{
352 return ck_threadpool_global();
353}
ck_threadpool_t * ck_threadpool_global(void)

References ck_threadpool_global().

◆ ck_parse_env_int()

static int ck_parse_env_int ( const char *  name)
static

Definition at line 153 of file ckernel_strict.c.

154{
155 const char *val = getenv(name);
156 if (!val || !val[0]) {
157 return 0;
158 }
159
160 errno = 0;
161 char *end = NULL;
162 long n = strtol(val, &end, 10);
163 if (errno != 0 || end == val || n <= 0 || n > (1L << 20)) {
164 return 0;
165 }
166 return (int)n;
167}
uint32_t end
Definition utf8.c:215

References end.

Referenced by ck_set_num_threads().

◆ ck_set_num_threads()

void ck_set_num_threads ( int  num_threads)

Definition at line 280 of file ckernel_strict.c.

281{
282 // 0 = auto-detect
283 if (num_threads <= 0) {
284 // Prefer explicit env controls when present:
285 // - CK_NUM_THREADS: engine-level override
286 // - OMP_NUM_THREADS: standard OpenMP control (set by `ck run --threads`)
287 int env_threads = ck_parse_env_int("CK_NUM_THREADS");
288 if (env_threads <= 0) {
289 env_threads = ck_parse_env_int("OMP_NUM_THREADS");
290 }
291 num_threads = env_threads > 0 ? env_threads : ck_get_physical_cores();
292 }
293
294 g_num_threads = num_threads;
296
297#ifdef _OPENMP
298 omp_set_dynamic(0); // Disable dynamic adjustment
299 omp_set_num_threads(num_threads);
300#endif
301
302#if defined(USE_MKL)
303 mkl_set_num_threads(num_threads);
304#endif
305
306 fprintf(stderr, "[CK] Set %d threads (auto=%d)\n",
307 num_threads, ck_get_physical_cores());
308}
static int ck_parse_env_int(const char *name)
int ck_get_physical_cores(void)

References ck_get_physical_cores(), ck_parse_env_int(), g_num_threads, and g_threads_initialized.

Referenced by ck_get_num_threads().

◆ ck_set_strict_parity()

void ck_set_strict_parity ( int  enabled)

Definition at line 28 of file ckernel_strict.c.

29{
30 ck_strict_parity = enabled ? 1 : 0;
31 if (!ck_strict_parity) {
34 }
35#ifdef _OPENMP
36 if (ck_strict_parity) {
37 omp_set_dynamic(0);
38 omp_set_num_threads(1);
39 }
40#endif
41}
static size_t ck_strict_next_gemm_a_size
static int ck_strict_parity
static int ck_strict_next_gemm_a_valid

References ck_strict_next_gemm_a_size, ck_strict_next_gemm_a_valid, and ck_strict_parity.

◆ ck_strict_consume_next_gemm_a()

const float * ck_strict_consume_next_gemm_a ( size_t  elems)

Definition at line 70 of file ckernel_strict.c.

71{
73 return NULL;
74 }
77}
static float * ck_strict_next_gemm_a

References ck_strict_next_gemm_a, ck_strict_next_gemm_a_size, ck_strict_next_gemm_a_valid, and ck_strict_parity.

Referenced by gemm_nt_q8_0_q8_0_contract().

◆ ck_strict_mtmd_clip_encode_planar_f32()

int ck_strict_mtmd_clip_encode_planar_f32 ( const float *  planar,
int  channels,
int  height,
int  width,
float *  out,
size_t  out_elems 
)

Definition at line 84 of file ckernel_strict.c.

90{
91 const char *gguf_path = getenv("CK_STRICT_GGUF_PATH");
92 const char *shim_path = getenv("CK_STRICT_MTMD_SHIM_SO");
93 if (!gguf_path || !gguf_path[0] || !shim_path || !shim_path[0]) {
94 return 0;
95 }
96 if (!planar || !out || channels != 3 || height <= 0 || width <= 0) {
97 return 0;
98 }
99
100 void *shim = dlopen(shim_path, RTLD_LAZY | RTLD_LOCAL);
101 if (!shim) {
102 return 0;
103 }
104
106 (ck_strict_mtmd_clip_init_fn) dlsym(shim, "ck_mtmd_clip_init");
108 (ck_strict_mtmd_clip_free_fn) dlsym(shim, "ck_mtmd_clip_free");
110 (ck_strict_mtmd_clip_embd_nbytes_by_img_fn) dlsym(shim, "ck_mtmd_clip_embd_nbytes_by_img");
112 (ck_strict_mtmd_clip_encode_float_image_fn) dlsym(shim, "ck_mtmd_clip_encode_float_image");
113
114 if (!init_fn || !free_fn || !embd_nbytes_fn || !encode_fn) {
115 dlclose(shim);
116 return 0;
117 }
118
119 const size_t pixel_count = (size_t) height * (size_t) width;
120 float *interleaved = (float *) malloc(pixel_count * (size_t) channels * sizeof(float));
121 if (!interleaved) {
122 dlclose(shim);
123 return 0;
124 }
125 for (size_t idx = 0; idx < pixel_count; ++idx) {
126 interleaved[idx * 3 + 0] = planar[idx];
127 interleaved[idx * 3 + 1] = planar[pixel_count + idx];
128 interleaved[idx * 3 + 2] = planar[2 * pixel_count + idx];
129 }
130
131 int ok = 0;
132 void *handle = init_fn(gguf_path, 0, 0, 0, 0, 0);
133 if (handle) {
134 const size_t needed_bytes = embd_nbytes_fn(handle, width, height);
135 if (needed_bytes > 0 && needed_bytes <= out_elems * sizeof(float)) {
136 ok = encode_fn(handle, 1, interleaved, height, width, out) ? 1 : 0;
137 }
138 free_fn(handle);
139 }
140
141 free(interleaved);
142 dlclose(shim);
143 return ok;
144}
void(* ck_strict_mtmd_clip_free_fn)(void *)
void *(* ck_strict_mtmd_clip_init_fn)(const char *, int, int, int, int, int)
size_t(* ck_strict_mtmd_clip_embd_nbytes_by_img_fn)(void *, int, int)
int(* ck_strict_mtmd_clip_encode_float_image_fn)(void *, int, float *, int, int, float *)

◆ ck_strict_parity_enabled()

int ck_strict_parity_enabled ( void  )

Definition at line 43 of file ckernel_strict.c.

44{
45 return ck_strict_parity;
46}

References ck_strict_parity.

Referenced by adamw_update_f32_impl(), attention_forward_decode_head_major_gqa_regular(), attention_forward_full_head_major_gqa_exact_strided(), attention_forward_full_head_major_gqa_ggml_strided_workspace(), attention_forward_head_major_gqa_flash_impl(), attention_forward_mixed_visual_chunk_head_major_gqa_flash_strided_gemma4_impl(), ck_dot_q6_k_q8_k_fast_or_ref(), ck_layer_forward_rmsnorm_swiglu(), ck_layer_forward_rmsnorm_swiglu_ref(), ck_mlp_swiglu_forward(), ck_mlp_swiglu_forward_ref(), ck_q6_k_q8_k_provider_name(), ck_q8k_activations_enabled(), gated_deltanet_autoregressive_forward(), gated_deltanet_impl_name(), geglu_forward_fp32(), gemm_avx512_parallel(), gemm_blocked_serial(), gemm_fine_grained_parallel(), gemm_naive_parallel(), gemm_nn_avx512(), gemm_nn_avx512_probe(), gemm_nn_blocked(), gemm_nn_parallel(), gemm_nt_f16(), gemm_nt_fp32_exact_parallel_dispatch(), gemm_nt_q6_k_q8_k_m4_tile(), gemm_nt_q8_0_q8_0_contract(), gemm_tn_avx512(), gemm_tn_blocked(), gemm_tn_parallel(), gemv_q4_k_q8_k_vnni(), gemv_q6_k_q8_k(), gemv_q6_k_q8_k_parallel_simd(), gemv_q8_0_q8_0_contract(), layernorm_forward_rolled_slice(), layernorm_forward_unrolled_slice(), mrope_qk_imrope_positions(), mrope_qk_vision(), rmsnorm_backward(), rmsnorm_forward_strided_f32(), softmax_cross_entropy_loss_index_mean_impl(), softmax_cross_entropy_loss_legacy_mean_impl(), swiglu_backward(), swiglu_forward(), and swiglu_forward_q8_k().

◆ ck_strict_store_next_gemm_a()

void ck_strict_store_next_gemm_a ( const float *  data,
size_t  elems 
)

Definition at line 48 of file ckernel_strict.c.

49{
50 if (!ck_strict_parity || !data || elems == 0) {
53 return;
54 }
55 if (elems > ck_strict_next_gemm_a_cap) {
56 float *next = (float *) realloc(ck_strict_next_gemm_a, elems * sizeof(float));
57 if (!next) {
60 return;
61 }
64 }
65 memcpy(ck_strict_next_gemm_a, data, elems * sizeof(float));
68}
static size_t ck_strict_next_gemm_a_cap

References ck_strict_next_gemm_a, ck_strict_next_gemm_a_cap, ck_strict_next_gemm_a_size, ck_strict_next_gemm_a_valid, and ck_strict_parity.

Referenced by ck_attention_full_ggml_graph_oracle_multihead().

◆ ck_threadpool_init()

void ck_threadpool_init ( void  )

Initialize the global thread pool. Called once during engine startup (e.g., from ck_model_init). Uses ck_get_num_threads() for thread count (respects CK_NUM_THREADS env).

Safe to call multiple times — subsequent calls are no-ops.

Definition at line 330 of file ckernel_strict.c.

331{
332 /* ck_threadpool_global() uses pthread_once internally */
333 ck_threadpool_t *pool = ck_threadpool_global();
334 (void)pool;
335}

References ck_threadpool_global().

◆ ck_threadpool_shutdown()

void ck_threadpool_shutdown ( void  )

Shut down the global thread pool. Called during engine teardown. Workers are joined and freed.

Definition at line 341 of file ckernel_strict.c.

342{
344}
void ck_threadpool_global_destroy(void)

References ck_threadpool_global_destroy().

Variable Documentation

◆ ck_strict_next_gemm_a

float* ck_strict_next_gemm_a = NULL
static

Definition at line 23 of file ckernel_strict.c.

Referenced by ck_strict_consume_next_gemm_a(), and ck_strict_store_next_gemm_a().

◆ ck_strict_next_gemm_a_cap

size_t ck_strict_next_gemm_a_cap = 0
static

Definition at line 25 of file ckernel_strict.c.

Referenced by ck_strict_store_next_gemm_a().

◆ ck_strict_next_gemm_a_size

size_t ck_strict_next_gemm_a_size = 0
static

◆ ck_strict_next_gemm_a_valid

int ck_strict_next_gemm_a_valid = 0
static

◆ ck_strict_parity

int ck_strict_parity = 0
static

◆ g_num_threads

int g_num_threads = 0
static

Definition at line 150 of file ckernel_strict.c.

Referenced by ck_get_num_threads(), and ck_set_num_threads().

◆ g_threads_initialized

int g_threads_initialized = 0
static

Definition at line 151 of file ckernel_strict.c.

Referenced by ck_get_num_threads(), and ck_set_num_threads().