in resctl-bench/src/bench/iocost_tune.rs [2002:2077]
fn solve(
&self,
_rec_json: serde_json::Value,
res_json: serde_json::Value,
) -> Result<serde_json::Value> {
let mut res: IoCostTuneResult = parse_json_value_or_dump(res_json)?;
// We might be called multiple times on the same intermediate
// result. Reset data serieses and solutions.
for (_, ds) in res.data.iter_mut() {
ds.reset();
}
res.solutions = Default::default();
// isol may be used in solving other data series, solve it first. We
// take it out of @data to avoid conflict with the mutable
// iteration below.
let isol_series = match res.data.remove(&DataSel::Isol) {
Some(mut series) => {
self.solve_data_series(&DataSel::Isol, &mut series, None, 0.0)?;
Some(series)
}
None => None,
};
for (sel, series) in res.data.iter_mut() {
self.solve_data_series(sel, series, isol_series.as_ref(), res.isol_thr)?;
}
// We're done solving. Put the isol series back in.
if let Some(isol_series) = isol_series {
res.data.insert(DataSel::Isol, isol_series);
}
for rule in self.rules.iter() {
let solution = match rule
.target
.solve(&res.data, (self.scale_min, self.scale_max))
{
Ok(v) => v,
Err(e) => {
warn!("iocost-tune: Failed to solve {:?} ({:?})", rule, &e);
continue;
}
};
if let Some((mut qos, target_vrate)) = solution {
debug!(
"rule={:?} qos={:?} target_vrate={}",
rule, &qos, target_vrate
);
let scale_factor = target_vrate / 100.0;
let model = res.base_model.clone() * scale_factor;
qos.min /= scale_factor;
qos.max /= scale_factor;
qos.sanitize();
res.solutions.insert(
rule.name.clone(),
QoSSolution::new(
&rule.target,
&model,
&qos,
target_vrate,
scale_factor,
res.mem_profile,
&res.data,
),
);
}
}
res.remarks = self.remarks(&res);
Ok(serde_json::to_value(res)?)
}