Optimizer kernels for training (AdamW, SGD) More...
#include <math.h>#include <stddef.h>#include <stdint.h>#include <string.h>#include "ck_threadpool.h"#include "ckernel_engine.h"Go to the source code of this file.
Macros | |
| #define | CK_OPT_PAR_MAX_THREADS 256 |
| #define | CK_OPT_PAR_MIN_NUMEL ((size_t)262144) |
Functions | |
| void | adamw_clip_update_multi_f32 (float *const *grads, float *const *weights, float *const *m_states, float *const *v_states, const size_t *numels, int tensor_count, float lr, float beta1, float beta2, float eps, float weight_decay, float max_grad_norm, int step) |
| void | adamw_update_f32 (const float *grad, float *weight, float *m, float *v, size_t numel, float lr, float beta1, float beta2, float eps, float weight_decay, int step) |
| static void | adamw_update_f32_impl (const float *grad, float *weight, float *m, float *v, size_t numel, float lr, float beta1, float beta2, float eps, float weight_decay, int step) |
| AdamW optimizer update (fp32 version) | |
| static void | ck_accum_multi_parallel_work (int ith, int nth, void *argp) |
| static void | ck_accum_parallel_work (int ith, int nth, void *argp) |
| static void | ck_adamw_multi_parallel_work (int ith, int nth, void *argp) |
| static void | ck_adamw_parallel_work (int ith, int nth, void *argp) |
| static int | ck_opt_pick_active_threads (int nth, size_t work_items, size_t min_chunk) |
| static void | ck_scale_parallel_work (int ith, int nth, void *argp) |
| static void | ck_sum_sq_multi_parallel_work (int ith, int nth, void *argp) |
| static void | ck_sum_sq_parallel_work (int ith, int nth, void *argp) |
| void | gradient_accumulate_f32 (float *dst, const float *src, size_t numel) |
| static void | gradient_accumulate_f32_impl (float *dst, const float *src, size_t numel) |
| Accumulate gradients: dst += src (fp32) | |
| void | gradient_accumulate_multi_f32 (float *const *dsts, const float *const *srcs, const size_t *numels, int tensor_count) |
| float | gradient_clip_norm_f32 (float *grad, size_t numel, float max_norm) |
| Clip gradient norm (fp32) | |
| float | gradient_global_norm_multi_f32 (const float *const *grads, const size_t *numels, int tensor_count) |
| void | gradient_scale_f32 (float *grad, size_t numel, float scale) |
| static void | gradient_scale_f32_impl (float *grad, size_t numel, float scale) |
| Scale gradients by a constant: grad *= scale (fp32) | |
| static double | gradient_sum_sq_f32_impl (const float *grad, size_t numel) |
| void | sgd_momentum_update_f32 (const float *grad, float *weight, float *velocity, size_t numel, float lr, float momentum, float weight_decay) |
| SGD with momentum optimizer update (fp32 version) | |
| void | zero_gradients_f32 (float *grad, size_t numel) |
| Zero out gradient buffer (fp32) | |
Optimizer kernels for training (AdamW, SGD)
After changes: make test && make llamacpp-parity-full
AdamW Algorithm: m_t = beta1 * m_{t-1} + (1 - beta1) * g_t v_t = beta2 * v_{t-1} + (1 - beta2) * g_t^2 m_hat = m_t / (1 - beta1^t) v_hat = v_t / (1 - beta2^t) w_t = w_{t-1} - lr * (m_hat / (sqrt(v_hat) + eps) + weight_decay * w_{t-1})
Note: AdamW applies weight decay directly to weights, not to gradients. This is different from L2 regularization (Adam with L2 adds decay to gradient).
Epsilon amplification at early steps: at step 1 with bc2=0.001, elements where vā0 (sparse/near-zero gradients) produce sqrt(v_hat)+eps ā eps=1e-8, amplifying any fp32 rounding in the accumulated gradient by up to lr/eps = 1e6. This is expected AdamW behavior, not a bug. In parity tests, gate on mean_param_diff (not max_param_diff) for grad_accum > 1 to avoid false alarms from these outliers.
Long-horizon fp32 risk: at lr=1e-3 with all-fp32 SIMD paths, known drift begins around step ~800 due to accumulated rounding. Use ck_strict_parity_enabled() (fp64 path) for parity validation; for production training keep lr < 1e-3 or monitor.
Definition in file optimizer_kernels.c.
| #define CK_OPT_PAR_MAX_THREADS 256 |
Definition at line 48 of file optimizer_kernels.c.
| #define CK_OPT_PAR_MIN_NUMEL ((size_t)262144) |
Definition at line 47 of file optimizer_kernels.c.
| void adamw_clip_update_multi_f32 | ( | float *const * | grads, |
| float *const * | weights, | ||
| float *const * | m_states, | ||
| float *const * | v_states, | ||
| const size_t * | numels, | ||
| int | tensor_count, | ||
| float | lr, | ||
| float | beta1, | ||
| float | beta2, | ||
| float | eps, | ||
| float | weight_decay, | ||
| float | max_grad_norm, | ||
| int | step | ||
| ) |
Definition at line 638 of file optimizer_kernels.c.
References adamw_update_f32_impl(), ck_adamw_multi_parallel_work(), CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_threadpool_dispatch_n(), ck_threadpool_global(), ck_threadpool_n_threads(), gradient_global_norm_multi_f32(), and gradient_scale_f32_impl().
| void adamw_update_f32 | ( | const float * | grad, |
| float * | weight, | ||
| float * | m, | ||
| float * | v, | ||
| size_t | numel, | ||
| float | lr, | ||
| float | beta1, | ||
| float | beta2, | ||
| float | eps, | ||
| float | weight_decay, | ||
| int | step | ||
| ) |
Definition at line 592 of file optimizer_kernels.c.
References adamw_update_f32_impl(), ck_adamw_parallel_work(), CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_threadpool_dispatch_n(), ck_threadpool_global(), and ck_threadpool_n_threads().
|
static |
AdamW optimizer update (fp32 version)
Updates weights in-place using the AdamW algorithm. Momentum (m) and variance (v) are stored in fp32 for numerical stability.
| grad | Gradient tensor (fp32) [numel] |
| weight | Weight tensor to update (fp32, in-place) [numel] |
| m | First moment (momentum) buffer (fp32, in-place) [numel] |
| v | Second moment (variance) buffer (fp32, in-place) [numel] |
| numel | Number of elements |
| lr | Learning rate |
| beta1 | Exponential decay rate for first moment (typically 0.9) |
| beta2 | Exponential decay rate for second moment (typically 0.999) |
| eps | Small constant for numerical stability (typically 1e-8) |
| weight_decay | Weight decay coefficient (typically 0.01) |
| step | Current step number (1-indexed for bias correction) |
Definition at line 355 of file optimizer_kernels.c.
References ck_strict_parity_enabled().
Referenced by adamw_clip_update_multi_f32(), adamw_update_f32(), ck_adamw_multi_parallel_work(), and ck_adamw_parallel_work().
|
static |
Definition at line 192 of file optimizer_kernels.c.
References end, gradient_accumulate_f32_impl(), and start.
Referenced by gradient_accumulate_multi_f32().
|
static |
Definition at line 174 of file optimizer_kernels.c.
References end, gradient_accumulate_f32_impl(), and start.
Referenced by gradient_accumulate_f32().
|
static |
Definition at line 289 of file optimizer_kernels.c.
References adamw_update_f32_impl(), and gradient_scale_f32_impl().
Referenced by adamw_clip_update_multi_f32().
|
static |
Definition at line 145 of file optimizer_kernels.c.
References adamw_update_f32_impl(), end, and start.
Referenced by adamw_update_f32().
|
static |
Definition at line 130 of file optimizer_kernels.c.
Referenced by adamw_clip_update_multi_f32(), adamw_update_f32(), gradient_accumulate_f32(), gradient_accumulate_multi_f32(), gradient_clip_norm_f32(), gradient_global_norm_multi_f32(), and gradient_scale_f32().
|
static |
Definition at line 232 of file optimizer_kernels.c.
References end, gradient_scale_f32_impl(), and start.
Referenced by gradient_scale_f32().
|
static |
Definition at line 269 of file optimizer_kernels.c.
References CK_OPT_PAR_MAX_THREADS, and gradient_sum_sq_f32_impl().
Referenced by gradient_global_norm_multi_f32().
|
static |
Definition at line 250 of file optimizer_kernels.c.
References CK_OPT_PAR_MAX_THREADS, end, gradient_sum_sq_f32_impl(), and start.
Referenced by gradient_clip_norm_f32().
| void gradient_accumulate_f32 | ( | float * | dst, |
| const float * | src, | ||
| size_t | numel | ||
| ) |
Definition at line 925 of file optimizer_kernels.c.
References ck_accum_parallel_work(), CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_threadpool_dispatch_n(), ck_threadpool_global(), ck_threadpool_n_threads(), and gradient_accumulate_f32_impl().
|
static |
Accumulate gradients: dst += src (fp32)
Used for gradient accumulation across micro-batches.
| dst | Destination gradient buffer (in-place) [numel] |
| src | Source gradient buffer [numel] |
| numel | Number of elements |
Definition at line 878 of file optimizer_kernels.c.
Referenced by ck_accum_multi_parallel_work(), ck_accum_parallel_work(), gradient_accumulate_f32(), and gradient_accumulate_multi_f32().
| void gradient_accumulate_multi_f32 | ( | float *const * | dsts, |
| const float *const * | srcs, | ||
| const size_t * | numels, | ||
| int | tensor_count | ||
| ) |
Definition at line 951 of file optimizer_kernels.c.
References ck_accum_multi_parallel_work(), CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_threadpool_dispatch_n(), ck_threadpool_global(), ck_threadpool_n_threads(), and gradient_accumulate_f32_impl().
| float gradient_clip_norm_f32 | ( | float * | grad, |
| size_t | numel, | ||
| float | max_norm | ||
| ) |
Clip gradient norm (fp32)
If ||grad||_2 > max_norm, scale grad so that ||grad||_2 = max_norm
| grad | Gradient tensor to clip (in-place) [numel] |
| numel | Number of elements |
| max_norm | Maximum allowed L2 norm |
Definition at line 1169 of file optimizer_kernels.c.
References CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_sum_sq_parallel_work(), ck_threadpool_dispatch_n(), ck_threadpool_global(), ck_threadpool_n_threads(), gradient_scale_f32(), and gradient_sum_sq_f32_impl().
| float gradient_global_norm_multi_f32 | ( | const float *const * | grads, |
| const size_t * | numels, | ||
| int | tensor_count | ||
| ) |
Definition at line 1207 of file optimizer_kernels.c.
References CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_sum_sq_multi_parallel_work(), ck_threadpool_dispatch_n(), ck_threadpool_global(), ck_threadpool_n_threads(), and gradient_sum_sq_f32_impl().
Referenced by adamw_clip_update_multi_f32().
| void gradient_scale_f32 | ( | float * | grad, |
| size_t | numel, | ||
| float | scale | ||
| ) |
Definition at line 1073 of file optimizer_kernels.c.
References CK_OPT_PAR_MAX_THREADS, CK_OPT_PAR_MIN_NUMEL, ck_opt_pick_active_threads(), ck_scale_parallel_work(), ck_threadpool_dispatch_n(), ck_threadpool_global(), ck_threadpool_n_threads(), and gradient_scale_f32_impl().
Referenced by gradient_clip_norm_f32().
|
static |
Scale gradients by a constant: grad *= scale (fp32)
Used for averaging gradients after accumulation: grad /= batch_size
| grad | Gradient tensor to scale (in-place) [numel] |
| numel | Number of elements |
| scale | Scale factor (typically 1.0 / batch_size) |
Definition at line 1026 of file optimizer_kernels.c.
Referenced by adamw_clip_update_multi_f32(), ck_adamw_multi_parallel_work(), ck_scale_parallel_work(), and gradient_scale_f32().
|
static |
Definition at line 1099 of file optimizer_kernels.c.
Referenced by ck_sum_sq_multi_parallel_work(), ck_sum_sq_parallel_work(), gradient_clip_norm_f32(), and gradient_global_norm_multi_f32().
| void sgd_momentum_update_f32 | ( | const float * | grad, |
| float * | weight, | ||
| float * | velocity, | ||
| size_t | numel, | ||
| float | lr, | ||
| float | momentum, | ||
| float | weight_decay | ||
| ) |
SGD with momentum optimizer update (fp32 version)
v_t = momentum * v_{t-1} + g_t w_t = w_{t-1} - lr * (v_t + weight_decay * w_{t-1})
| grad | Gradient tensor (fp32) [numel] |
| weight | Weight tensor to update (fp32, in-place) [numel] |
| velocity | Velocity buffer (fp32, in-place) [numel] |
| numel | Number of elements |
| lr | Learning rate |
| momentum | Momentum coefficient (typically 0.9) |
| weight_decay | Weight decay coefficient |
Definition at line 753 of file optimizer_kernels.c.
| void zero_gradients_f32 | ( | float * | grad, |
| size_t | numel | ||
| ) |
Zero out gradient buffer (fp32)
| grad | Gradient tensor to zero [numel] |
| numel | Number of elements |
Definition at line 860 of file optimizer_kernels.c.