use std::{collections::HashMap, path::PathBuf};
use rayon::iter::{IntoParallelIterator, IntoParallelRefIterator};
use serde::{Deserialize, Serialize};
#[derive(Serialize)]
pub(super) struct EvalInstance {
root: PathBuf,
input: PathBuf,
output: PathBuf,
validation: PathBuf,
}
impl EvalInstance {
pub(super) fn new(
root: impl Into<PathBuf>,
input: impl Into<PathBuf>,
output: impl Into<PathBuf>,
validation: impl Into<PathBuf>,
) -> Self {
Self {
root: root.into(),
input: input.into(),
output: output.into(),
validation: validation.into(),
}
}
pub(super) fn root(&self) -> PathBuf {
self.root.to_path_buf()
}
pub(super) fn output(&self) -> PathBuf {
self.output.to_path_buf()
}
pub(super) fn validation(&self) -> PathBuf {
self.validation.to_path_buf()
}
}
#[derive(Serialize)]
pub(super) struct EvalGroup {
root: PathBuf,
runs: Vec<EvalInstance>, }
impl EvalGroup {
pub(super) fn new(
root: impl Into<PathBuf>,
runs: impl Into<Vec<EvalInstance>>,
) -> Self {
Self { root: root.into(), runs: runs.into() }
}
pub(super) fn runs(&self) -> &[EvalInstance] {
&self.runs
}
pub(super) fn par_runs(&self) -> rayon::slice::Iter<'_, EvalInstance> {
self.runs().par_iter()
}
}
impl<'a> IntoIterator for &'a EvalGroup {
type Item = &'a EvalInstance;
type IntoIter = std::slice::Iter<'a, EvalInstance>;
fn into_iter(self) -> Self::IntoIter {
self.runs().iter()
}
}
impl<'a> IntoParallelIterator for &'a EvalGroup
where
EvalInstance: Sync,
{
type Item = &'a EvalInstance;
type Iter = rayon::slice::Iter<'a, EvalInstance>;
fn into_par_iter(self) -> Self::Iter {
self.par_runs()
}
}
#[derive(Serialize, Eq, PartialEq, Hash, Clone)]
pub(super) struct EvalKey {
agent: String,
layer: String,
app: String,
source_framework: String,
target_framework: String,
}
impl EvalKey {
pub(super) fn new(
agent: impl Into<String>,
layer: impl Into<String>,
app: impl Into<String>,
source_framework: impl Into<String>,
target_framework: impl Into<String>,
) -> Self {
Self {
agent: agent.into(),
layer: layer.into(),
app: app.into(),
source_framework: source_framework.into(),
target_framework: target_framework.into(),
}
}
pub(super) fn agent(&self) -> String {
self.agent.to_string()
}
pub(super) fn layer(&self) -> String {
self.layer.to_string()
}
pub(super) fn app(&self) -> String {
self.app.to_string()
}
pub(super) fn source_framework(&self) -> String {
self.source_framework.to_string()
}
pub(super) fn target_framework(&self) -> String {
self.target_framework.to_string()
}
pub(super) fn repr(&self) -> String {
format!(
"{}__{}__{}__{}__{}",
&self.agent,
&self.layer,
&self.app,
&self.source_framework,
&self.target_framework
)
}
}
#[derive(Serialize)]
pub(super) struct EvalLayout {
evals: HashMap<EvalKey, EvalGroup>,
}
impl EvalLayout {
pub(super) fn new(evals: HashMap<EvalKey, EvalGroup>) -> Self {
Self { evals }
}
}
impl<'a> IntoIterator for &'a EvalLayout {
type Item = (&'a EvalKey, &'a EvalGroup);
type IntoIter = std::collections::hash_map::Iter<'a, EvalKey, EvalGroup>;
fn into_iter(self) -> Self::IntoIter {
self.evals.iter()
}
}
impl<'x> IntoParallelIterator for &'x EvalLayout
where
EvalKey: Sync,
EvalGroup: Sync,
{
type Item = (&'x EvalKey, &'x EvalGroup);
type Iter = rayon::collections::hash_map::Iter<'x, EvalKey, EvalGroup>;
fn into_par_iter(self) -> Self::Iter {
self.evals.par_iter()
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default)]
#[serde(rename_all = "UPPERCASE")]
pub(super) enum TriState {
True,
False,
#[default]
Unk,
}
#[allow(non_snake_case)]
fn UNK() -> String {
String::from("UNK")
}
#[derive(Serialize, Deserialize)]
pub(super) struct RunMetaData {
agent: String,
layer: String,
app: String,
status: String,
repeat: u32,
source_framework: String,
target_framework: String,
#[serde(default)]
compile_ok: TriState,
#[serde(default)]
deploy_ok: TriState,
#[serde(default = "UNK")]
test_pass_percent: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
model: Option<String>,
}
impl RunMetaData {
pub(super) fn new(
agent: impl Into<String>,
layer: impl Into<String>,
app: impl Into<String>,
status: impl Into<String>,
repeat: impl Into<u32>,
source_framework: impl Into<String>,
target_framework: impl Into<String>,
model: Option<String>,
) -> Self {
Self {
agent: agent.into(),
layer: layer.into(),
app: app.into(),
status: status.into(),
repeat: repeat.into(),
source_framework: source_framework.into(),
target_framework: target_framework.into(),
compile_ok: TriState::Unk,
deploy_ok: TriState::Unk,
test_pass_percent: UNK(),
model,
}
}
pub(super) fn source_framework(&self) -> String {
self.source_framework.to_string()
}
pub(super) fn target_framework(&self) -> String {
self.target_framework.to_string()
}
pub(super) fn set_status(&mut self, status: String) -> &mut Self {
self.status = status;
self
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct AgentConfig {
pub solution_name: String,
pub model: String,
pub entrypoint: String,
#[serde(default)]
pub description: Option<String>,
}