///|
/// Lifecycle status of a run.
pub(all) enum RunStatus {
Created
Running
Completed
Failed
Killed
} derive(Eq, Debug)
///|
/// A single experiment run recording parameters, metrics, and artifacts.
pub struct Run {
priv id : String
priv experiment_id : String
priv status : RunStatus
priv start_time : String
priv mut end_time : String
priv mut parameters : Array[Param]
priv mut metrics : Array[Metric]
priv mut artifacts : Array[Artifact]
priv tags : Array[String]
priv mut reproducibility : ReproducibilityInfo?
priv mut notes : Array[String]
priv mut error_message : String
} derive(Debug)
///|
/// Build a new run in `Created` status.
pub fn Run::new(id : String, experiment_id : String) -> Run {
{
id,
experiment_id,
status: Created,
start_time: "",
end_time: "",
parameters: [],
metrics: [],
artifacts: [],
tags: [],
reproducibility: None,
notes: [],
error_message: "",
}
}
///|
/// Return the run id.
pub fn Run::id(self : Run) -> String {
self.id
}
///|
/// Return the experiment id this run belongs to.
pub fn Run::experiment_id(self : Run) -> String {
self.experiment_id
}
///|
/// Return the current run status.
pub fn Run::status(self : Run) -> RunStatus {
self.status
}
///|
/// Return the start timestamp string.
pub fn Run::start_time(self : Run) -> String {
self.start_time
}
///|
/// Return the end timestamp string.
pub fn Run::end_time(self : Run) -> String {
self.end_time
}
///|
/// Return a detached copy of all parameters.
pub fn Run::parameters(self : Run) -> Array[Param] {
self.parameters.copy()
}
///|
/// Return a detached copy of all metrics.
pub fn Run::metrics(self : Run) -> Array[Metric] {
self.metrics.copy()
}
///|
/// Return a detached copy of all artifacts.
pub fn Run::artifacts(self : Run) -> Array[Artifact] {
self.artifacts.copy()
}
///|
/// Return a detached copy of run tags.
pub fn Run::tags(self : Run) -> Array[String] {
self.tags.copy()
}
///|
/// Return the reproducibility info if present.
pub fn Run::reproducibility(self : Run) -> ReproducibilityInfo? {
self.reproducibility
}
///|
/// Return a detached copy of run notes.
pub fn Run::notes(self : Run) -> Array[String] {
self.notes.copy()
}
///|
/// Return the error message attached to a failed run.
pub fn Run::error_message(self : Run) -> String {
self.error_message
}
///|
/// Set the start timestamp.
pub fn Run::with_start_time(self : Run, start_time : String) -> Run {
{ ..self, start_time, }
}
///|
/// Add tags to a run.
pub fn Run::with_tags(self : Run, tags : Array[String]) -> Run {
{ ..self, tags: tags.copy() }
}
///|
/// Set reproducibility information.
pub fn Run::with_reproducibility(self : Run, info : ReproducibilityInfo) -> Run {
{ ..self, reproducibility: Some(info) }
}
///|
/// Set the error message for a failed run.
pub fn Run::with_error_message(self : Run, msg : String) -> Run {
{ ..self, error_message: msg }
}
///|
/// Set the status directly. Intended for importers and replay tools.
pub fn Run::set_status(self : Run, status : RunStatus) -> Run {
{ ..self, status, }
}
///|
/// Set the end time directly.
pub fn Run::set_end_time(self : Run, end_time : String) -> Run {
{ ..self, end_time, }
}
///|
/// Append a parameter to this run.
pub fn Run::add_param(self : Run, param : Param) -> Unit {
self.parameters.push(param)
}
///|
/// Append a metric to this run.
pub fn Run::add_metric(self : Run, metric : Metric) -> Unit {
self.metrics.push(metric)
}
///|
/// Append an artifact to this run.
pub fn Run::add_artifact(self : Run, artifact : Artifact) -> Unit {
self.artifacts.push(artifact)
}
///|
/// Append a note to this run.
pub fn Run::add_note(self : Run, note : String) -> Unit {
self.notes.push(note)
}
///|
/// Set reproducibility info directly on this run.
pub fn Run::set_reproducibility(
self : Run,
info : ReproducibilityInfo?,
) -> Unit {
self.reproducibility = info
}
///|
/// Return the number of parameters.
pub fn Run::param_count(self : Run) -> Int {
self.parameters.length()
}
///|
/// Return the number of metrics.
pub fn Run::metric_count(self : Run) -> Int {
self.metrics.length()
}
///|
/// Return the number of artifacts.
pub fn Run::artifact_count(self : Run) -> Int {
self.artifacts.length()
}
///|
/// Find a parameter by key.
pub fn Run::find_param(self : Run, key : String) -> Param? {
for p in self.parameters {
if p.key() == key {
return Some(p)
}
}
None
}
///|
/// Find the latest metric value for a key.
pub fn Run::latest_metric(self : Run, key : String) -> Metric? {
let mut found : Metric? = None
for m in self.metrics {
if m.key() == key {
match found {
Some(prev) => if m.step() >= prev.step() { found = Some(m) }
None => found = Some(m)
}
}
}
found
}
///|
/// Return all metric values for a key in step order.
pub fn Run::metrics_for(self : Run, key : String) -> Array[Metric] {
let result : Array[Metric] = []
for m in self.metrics {
if m.key() == key {
result.push(m)
}
}
// Sort by step ascending using simple insertion sort.
for i = 1; i < result.length(); i = i + 1 {
let j = i
while j > 0 && result[j].step() < result[j - 1].step() {
let temp = result[j]
result[j] = result[j - 1]
result[j - 1] = temp
}
}
result
}
///|
/// Return a stable machine-readable status kind string.
pub fn RunStatus::kind(self : RunStatus) -> String {
match self {
Created => "created"
Running => "running"
Completed => "completed"
Failed => "failed"
Killed => "killed"
}
}
///|
/// Return a stable human-readable status label.
pub fn RunStatus::label(self : RunStatus) -> String {
match self {
Created => "created"
Running => "running"
Completed => "completed"
Failed => "failed"
Killed => "killed"
}
}
///|
/// Parse a run status from its string kind.
pub fn RunStatus::from_string(s : String) -> RunStatus? {
match s {
"created" => Some(Created)
"running" => Some(Running)
"completed" => Some(Completed)
"failed" => Some(Failed)
"killed" => Some(Killed)
_ => None
}
}