| 18482 | }; |
| 18483 | |
| 18484 | static enum ggml_opt_result linesearch_backtracking( |
| 18485 | const struct ggml_opt_params * params, |
| 18486 | int nx, |
| 18487 | float * x, |
| 18488 | float * fx, |
| 18489 | float * g, |
| 18490 | float * d, |
| 18491 | float * step, |
| 18492 | const float * xp, |
| 18493 | struct ggml_tensor * f, |
| 18494 | struct ggml_cgraph * gb, |
| 18495 | struct ggml_cplan * cplan, |
| 18496 | const int np, |
| 18497 | struct ggml_tensor * ps[], |
| 18498 | bool * cancel, |
| 18499 | ggml_opt_callback callback, |
| 18500 | void * callback_data) { |
| 18501 | int count = 0; |
| 18502 | |
| 18503 | float width = 0.0f; |
| 18504 | float dg = 0.0f; |
| 18505 | float finit = 0.0f; |
| 18506 | float dginit = 0.0f; |
| 18507 | float dgtest = 0.0f; |
| 18508 | |
| 18509 | const float dec = 0.5f; |
| 18510 | const float inc = 2.1f; |
| 18511 | |
| 18512 | const int n_accum = MAX(1, params->n_gradient_accumulation); |
| 18513 | const float accum_norm = 1.0f / (float) n_accum; |
| 18514 | |
| 18515 | if (*step <= 0.f) { |
| 18516 | return GGML_LINESEARCH_INVALID_PARAMETERS; |
| 18517 | } |
| 18518 | |
| 18519 | // compute the initial gradient in the search direction |
| 18520 | ggml_vec_dot_f32(nx, &dginit, g, d); |
| 18521 | |
| 18522 | // make sure that d points to a descent direction |
| 18523 | if (0 < dginit) { |
| 18524 | return GGML_LINESEARCH_FAIL; |
| 18525 | } |
| 18526 | |
| 18527 | // initialize local variables |
| 18528 | finit = *fx; |
| 18529 | dgtest = params->lbfgs.ftol*dginit; |
| 18530 | |
| 18531 | while (true) { |
| 18532 | ggml_vec_cpy_f32(nx, x, xp); |
| 18533 | ggml_vec_mad_f32(nx, x, d, *step); |
| 18534 | |
| 18535 | // evaluate the function and gradient values |
| 18536 | { |
| 18537 | ggml_opt_set_params(np, ps, x); |
| 18538 | |
| 18539 | *fx = 0; |
| 18540 | memset(g, 0, sizeof(float)*nx); |
| 18541 | for (int accum_step = 0; accum_step < n_accum; ++accum_step) { |
no test coverage detected