fn solve()

in resctl-bench/src/bench/iocost_tune.rs [666:830]


    fn solve(
        &self,
        data: &BTreeMap<DataSel, DataSeries>,
        (scale_min, scale_max): (f64, f64),
    ) -> Result<Option<(IoCostQoSParams, f64)>> {
        let ds = |sel: &DataSel| -> Result<&DataSeries> {
            data.get(sel)
                .ok_or(anyhow!("Required data series {:?} unavailable", sel))
        };

        // When detecting inflection point for solutions, if the slope is
        // steep and the error bar is wild, picking the exact inflection
        // point can be dangerous as a small amount of error can lead to a
        // large deviation from the target. Let's offset the result by some
        // amount proportional to the slope * relative error. The scaling
        // factor was determined empricially and the maximum offsetting is
        // limited to 10%. We calculate infl_offset based on MOF and use it
        // everywhere. There likely is a better way of determining the
        // offset amount.
        let mof_ds = ds(&DataSel::MOF)?;
        let infl_offset = || {
            let mof_max = mof_ds.lines.right.y;
            if mof_max == 0.0 {
                0.0
            } else {
                (mof_ds.lines.slope() * (mof_ds.error / mof_ds.lines.right.y) * 800.0).min(0.1)
            }
        };

        // Helper to create fixed vrate result. {r|w}pct's are zero as the
        // vrate won't be modulated but let's still fill in {r|w}lat's as
        // iocost uses those values to determine the period.
        let (rlat_99_dl, wlat_99_dl) = (
            &ds(&DataSel::RLat("99".into(), "mean".into()))?.lines,
            &ds(&DataSel::WLat("99".into(), "mean".into()))?.lines,
        );
        let params_at_vrate = |vrate| {
            (
                IoCostQoSParams {
                    min: vrate,
                    max: vrate,
                    rpct: 0.0,
                    wpct: 0.0,
                    rlat: (rlat_99_dl.eval(vrate) * 1_000_000.0).round() as u64,
                    wlat: (wlat_99_dl.eval(vrate) * 1_000_000.0).round() as u64,
                },
                vrate,
            )
        };

        // Find min vrate at max val for @sel. If the line is flat, use the
        // min vrate at max val for @no_sig_sel.
        let solve_max = |sel, no_sig_sel| -> Result<Option<f64>> {
            let no_sig_vrate = match no_sig_sel {
                Some(nssel) => Self::find_max_vrate_at_min_val(
                    ds(nssel)?,
                    (scale_min, scale_max),
                    infl_offset(),
                ),
                None => None,
            };
            Ok(Self::find_min_vrate_at_max_val(
                ds(sel)?,
                (scale_min, scale_max),
                infl_offset(),
                no_sig_vrate,
            ))
        };

        // Find the max vrate at min val.
        let solve_min = |sel| -> Result<Option<f64>> {
            Ok(Self::find_max_vrate_at_min_val(
                ds(sel)?,
                (scale_min, scale_max),
                infl_offset(),
            ))
        };

        // Find the rightmost valid vrate.
        let solve_max_vrate = |sel| -> Result<Option<f64>> {
            Ok(ds(sel)?
                .lines
                .clamped(scale_min, scale_max)
                .map(|dl| dl.range.1))
        };

        Ok(match self {
            Self::VrateRange((scale_min, scale_max), (rpct, wpct)) => {
                let (rpct, rlat) = Self::solve_vrate_range(*scale_max, READ, rpct.as_deref(), data);
                let (wpct, wlat) =
                    Self::solve_vrate_range(*scale_max, WRITE, wpct.as_deref(), data);
                Some((
                    IoCostQoSParams {
                        rpct,
                        rlat,
                        wpct,
                        wlat,
                        min: *scale_min,
                        max: *scale_max,
                    },
                    *scale_max,
                ))
            }

            // Min vrate still at max MOF. If MOF is flat, max vrate at min
            // LatImp.
            Self::MOFMax => solve_max(&DataSel::MOF, Some(&DataSel::LatImp))?.map(params_at_vrate),

            // Min vrate still at max aMOF. If MOF is flat, max vrate at min
            // LatImp.
            Self::AMOFMax => {
                solve_max(&DataSel::AMOF, Some(&DataSel::LatImp))?.map(params_at_vrate)
            }

            // Rightmost vrate with valid aMOF.
            Self::AMOFMaxVrate => solve_max_vrate(&DataSel::AMOF)?.map(params_at_vrate),

            // clamp(max vrate at min LatImp, isolation, bandwidth)
            Self::IsolatedBandwidth => match (
                solve_min(&DataSel::AMOFDelta)?,
                solve_max_vrate(&DataSel::AMOF)?,
            ) {
                (Some(min), Some(max)) => {
                    solve_min(&DataSel::LatImp)?.map(|v| params_at_vrate(v.clamp(min, max)))
                }
                _ => None,
            },

            Self::AMOFDeltaMin => solve_min(&DataSel::AMOFDelta)?.map(params_at_vrate),

            Self::LatRange(sel, lat_rel_range) => {
                if let Some((lat_target, vrate_range)) =
                    Self::solve_lat_range(ds(&sel)?, *lat_rel_range, (scale_min, scale_max))
                {
                    Some(match sel {
                        DataSel::RLat(pct, _) => (
                            IoCostQoSParams {
                                rpct: pct.parse::<f64>().unwrap(),
                                rlat: lat_target,
                                wpct: 0.0,
                                wlat: 0,
                                min: vrate_range.0,
                                max: vrate_range.1,
                            },
                            vrate_range.1,
                        ),
                        DataSel::WLat(pct, _) => (
                            IoCostQoSParams {
                                rpct: 0.0,
                                rlat: 0,
                                wpct: pct.parse::<f64>().unwrap(),
                                wlat: lat_target,
                                min: vrate_range.0,
                                max: vrate_range.1,
                            },
                            vrate_range.1,
                        ),
                        _ => panic!(),
                    })
                } else {
                    None
                }
            }
        })
    }