| 18604 | } |
| 18605 | |
| 18606 | static enum ggml_opt_result ggml_opt_lbfgs( |
| 18607 | struct ggml_context * ctx, |
| 18608 | struct ggml_opt_context * opt, |
| 18609 | struct ggml_opt_params params, |
| 18610 | struct ggml_tensor * f, |
| 18611 | struct ggml_cgraph * gf, |
| 18612 | struct ggml_cgraph * gb, |
| 18613 | ggml_opt_callback callback, |
| 18614 | void * callback_data) { |
| 18615 | if (params.lbfgs.linesearch == GGML_LINESEARCH_BACKTRACKING_WOLFE || |
| 18616 | params.lbfgs.linesearch == GGML_LINESEARCH_BACKTRACKING_STRONG_WOLFE) { |
| 18617 | if (params.lbfgs.wolfe <= params.lbfgs.ftol || 1.f <= params.lbfgs.wolfe) { |
| 18618 | return GGML_OPT_INVALID_WOLFE; |
| 18619 | } |
| 18620 | } |
| 18621 | |
| 18622 | const int m = params.lbfgs.m; |
| 18623 | |
| 18624 | // these will store the parameters we want to optimize |
| 18625 | struct ggml_tensor * ps[GGML_MAX_PARAMS]; |
| 18626 | |
| 18627 | int np = 0; |
| 18628 | int nx = 0; |
| 18629 | for (int i = 0; i < gf->n_nodes; ++i) { |
| 18630 | if (gf->nodes[i]->is_param) { |
| 18631 | GGML_PRINT_DEBUG("found param %d: grad->op = %d\n", np, gf->nodes[i]->grad->op); |
| 18632 | |
| 18633 | GGML_ASSERT(np < GGML_MAX_PARAMS); |
| 18634 | |
| 18635 | ps[np++] = gf->nodes[i]; |
| 18636 | nx += ggml_nelements(gf->nodes[i]); |
| 18637 | } |
| 18638 | } |
| 18639 | |
| 18640 | if ((opt->params.type != params.type) || (opt->nx != nx) || (opt->params.past != params.past) || (opt->params.lbfgs.m != params.lbfgs.m)) { |
| 18641 | int iter = opt->iter; |
| 18642 | ggml_opt_init(ctx, opt, params, nx); |
| 18643 | opt->iter = iter; |
| 18644 | } |
| 18645 | |
| 18646 | struct ggml_cplan cplan = ggml_graph_plan(gb, params.n_threads); |
| 18647 | struct ggml_object * obj = ggml_new_object(ctx, GGML_OBJECT_WORK_BUFFER, cplan.work_size); |
| 18648 | cplan.work_data = (uint8_t *)ctx->mem_buffer + obj->offs; |
| 18649 | |
| 18650 | float * x = opt->lbfgs.x->data; // current parameters |
| 18651 | float * xp = opt->lbfgs.xp->data; // previous parameters |
| 18652 | float * g = opt->lbfgs.g->data; // current gradient |
| 18653 | float * gp = opt->lbfgs.gp->data; // previous gradient |
| 18654 | float * d = opt->lbfgs.d->data; // search direction |
| 18655 | |
| 18656 | float * pf = params.past > 0 ? opt->lbfgs.pf->data : NULL; // past function values |
| 18657 | |
| 18658 | const int n_accum = MAX(1, params.n_gradient_accumulation); |
| 18659 | const float accum_norm = 1.0f / (float) n_accum; |
| 18660 | |
| 18661 | float fx = 0.0f; // cost function value |
| 18662 | float xnorm = 0.0f; // ||x|| |
| 18663 | float gnorm = 0.0f; // ||g|| |
no test coverage detected