| 18248 | // |
| 18249 | |
| 18250 | static enum ggml_opt_result ggml_opt_adam( |
| 18251 | struct ggml_context * ctx, |
| 18252 | struct ggml_opt_context * opt, |
| 18253 | struct ggml_opt_params params, |
| 18254 | struct ggml_tensor * f, |
| 18255 | struct ggml_cgraph * gf, |
| 18256 | struct ggml_cgraph * gb, |
| 18257 | ggml_opt_callback callback, |
| 18258 | void * callback_data) { |
| 18259 | GGML_ASSERT(ggml_is_scalar(f)); |
| 18260 | |
| 18261 | // these will store the parameters we want to optimize |
| 18262 | struct ggml_tensor * ps[GGML_MAX_PARAMS]; |
| 18263 | |
| 18264 | int np = 0; |
| 18265 | int64_t nx = 0; |
| 18266 | for (int i = 0; i < gf->n_nodes; ++i) { |
| 18267 | if (gf->nodes[i]->is_param) { |
| 18268 | GGML_PRINT_DEBUG("found param %d: grad->op = %d\n", np, gf->nodes[i]->grad->op); |
| 18269 | |
| 18270 | GGML_ASSERT(np < GGML_MAX_PARAMS); |
| 18271 | |
| 18272 | ps[np++] = gf->nodes[i]; |
| 18273 | nx += ggml_nelements(gf->nodes[i]); |
| 18274 | } |
| 18275 | } |
| 18276 | |
| 18277 | if ((opt->params.type != params.type) || (opt->nx != nx) || (opt->params.past != params.past)) { |
| 18278 | int iter = opt->iter; |
| 18279 | ggml_opt_init(opt->ctx, opt, params, nx); |
| 18280 | opt->iter = iter; |
| 18281 | } |
| 18282 | |
| 18283 | // constants |
| 18284 | float sched = params.adam.sched; |
| 18285 | const float alpha = params.adam.alpha; |
| 18286 | const float decay = params.adam.decay * alpha; |
| 18287 | const float beta1 = params.adam.beta1; |
| 18288 | const float beta2 = params.adam.beta2; |
| 18289 | const float eps = params.adam.eps; |
| 18290 | const float gclip = params.adam.gclip; |
| 18291 | const int decay_min_ndim = params.adam.decay_min_ndim; |
| 18292 | const int n_accum = MAX(1, params.n_gradient_accumulation); |
| 18293 | const float accum_norm = 1.0f / (float) n_accum; |
| 18294 | |
| 18295 | float * g = opt->adam.g->data; // gradients |
| 18296 | float * m = opt->adam.m->data; // first moment |
| 18297 | float * v = opt->adam.v->data; // second moment |
| 18298 | |
| 18299 | float * pf = params.past > 0 ? opt->adam.pf->data : NULL; // past function values |
| 18300 | |
| 18301 | struct ggml_cplan cplan = ggml_graph_plan(gb, params.n_threads); |
| 18302 | struct ggml_object * obj = ggml_new_object(ctx, GGML_OBJECT_WORK_BUFFER, cplan.work_size); |
| 18303 | cplan.work_data = (uint8_t *)ctx->mem_buffer + obj->offs; |
| 18304 | |
| 18305 | bool cancel = false; |
| 18306 | |
| 18307 | // compute the function value |
no test coverage detected