Class: Toy::RunLog

Inherits:
Object
  • Object
show all
Defined in:
lib/toy/core/run_log.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(dir) ⇒ RunLog

Returns a new instance of RunLog.

Raises:

  • (ArgumentError)


55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/toy/core/run_log.rb', line 55

def initialize(dir)
  @dir    = dir
  events  = File.join(dir, "events.jsonl")
  raise ArgumentError, "RunLog: no events.jsonl in #{dir}" unless File.file?(events)

  @config  = nil
  @steps   = []
  @run_end = nil
  File.foreach(events).with_index(1) do |line, lineno|
    next if line.strip.empty?
    begin
      ev = JSON.parse(line)
    rescue JSON::ParserError => e
      raise ArgumentError, "RunLog: #{events}:#{lineno}: malformed JSON line (#{e.message})"
    end
    case ev["kind"]
    when "run_start" then @config  = ev
    when "step"      then @steps  << ev
    when "run_end"   then @run_end = ev
    end
  end
  raise ArgumentError, "RunLog: #{events} has no run_start event" if @config.nil?
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



34
35
36
# File 'lib/toy/core/run_log.rb', line 34

def config
  @config
end

#dirObject (readonly)

Returns the value of attribute dir.



34
35
36
# File 'lib/toy/core/run_log.rb', line 34

def dir
  @dir
end

#run_endObject (readonly)

Returns the value of attribute run_end.



34
35
36
# File 'lib/toy/core/run_log.rb', line 34

def run_end
  @run_end
end

#stepsObject (readonly)

Returns the value of attribute steps.



34
35
36
# File 'lib/toy/core/run_log.rb', line 34

def steps
  @steps
end

Class Method Details

.open(dir) ⇒ Object



36
37
38
# File 'lib/toy/core/run_log.rb', line 36

def self.open(dir)
  new(dir)
end

.scan(root) ⇒ Object

Scan a runs/ root for run bundles. Subdirs without an events.jsonl are skipped (a runs/ root legitimately holds non-run dirs); a PRESENT but unparseable events.jsonl raises. Sorted by final_loss ascending; runs without a final loss last.

Raises:

  • (ArgumentError)


44
45
46
47
48
49
50
51
52
53
# File 'lib/toy/core/run_log.rb', line 44

def self.scan(root)
  raise ArgumentError, "RunLog.scan: no such directory: #{root}" unless Dir.exist?(root)
  logs = Dir.children(root).sort.filter_map do |entry|
    dir = File.join(root, entry)
    next unless File.directory?(dir)
    next unless File.file?(File.join(dir, "events.jsonl"))
    new(dir)
  end
  logs.sort_by { |l| l.final_loss || Float::INFINITY }
end

Instance Method Details

#final_lossObject

run_end’s final_loss when the run completed; else the last step loss (an interrupted run); else nil (a run that never stepped).



89
90
91
92
# File 'lib/toy/core/run_log.rb', line 89

def final_loss
  return @run_end["final_loss"] if @run_end && @run_end["final_loss"]
  @steps.empty? ? nil : @steps.last["loss"]
end

#loss_curveObject



83
84
85
# File 'lib/toy/core/run_log.rb', line 83

def loss_curve
  @steps.map { |s| s["loss"] }
end

#run_idObject



79
80
81
# File 'lib/toy/core/run_log.rb', line 79

def run_id
  @config["run_id"]
end