Class: Origen::Application::Runner

Inherits:
Object
  • Object
show all
Defined in:
lib/origen/application/runner.rb

Overview

The Runner is responsible for co-ordinating all compile and generate requests from the command line

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#optionsObject

Returns the value of attribute options.



9
10
11
# File 'lib/origen/application/runner.rb', line 9

def options
  @options
end

Instance Method Details

#confirm_production_ready(_options = {}) ⇒ Object



236
237
238
239
240
241
242
243
# File 'lib/origen/application/runner.rb', line 236

def confirm_production_ready(_options = {})
  # The caller would have already verified the status before submission
  if Origen.running_locally?
    if Origen.mode.production?
      Origen.app.cm.ensure_workspace_unmodified!
    end
  end
end

#expand_lists_and_directories(files, options = {}) ⇒ Object

Expands any list references in the supplied pattern array and returns an array of pattern names. No guarantee is made to whether the pattern names are valid at this stage. Any duplicates will be removed.



176
177
178
# File 'lib/origen/application/runner.rb', line 176

def expand_lists_and_directories(files, options = {})
  Origen.file_handler.expand_list(files, options)
end

#extract_action(options) ⇒ Object

The action to take should be set by the action option, but legacy code will pass things like :compile => true, the extract_action method handles the old code



143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/origen/application/runner.rb', line 143

def extract_action(options)
  return options[:action] if options[:action]
  if options[:compile]
    :compile
  elsif options[:program]
    :program
  elsif options[:job_type] == :merge
    :merge
  else
    :pattern
  end
end

#extract_files(options) ⇒ Object

Legacy file references can be input via :pattern, :patterns, etc. this cleans it up and forces them all to be in an array assigned to options



158
159
160
161
162
163
# File 'lib/origen/application/runner.rb', line 158

def extract_files(options)
  files = [options[:pattern]] + [options[:patterns]] + [options[:file]] + [options[:files]]
  files.flatten!
  files.compact!
  files
end

#launch(options = {}) ⇒ Object Also known as: generate

Launch Origen, any command which generates an output file should launch from here as it gives a common point for listeners to hook in and to establish output directories and so on.

Originally this method was called generate but that is now deprecated in favour of the more generic ‘launch’ as the Origen feature set has expanded.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/origen/application/runner.rb', line 17

def launch(options = {})
  # Clean up the input from legacy code
  options[:action] = extract_action(options)
  options[:files] = extract_files(options)
  @options = options
  prepare_and_validate_workspace(options)
  if options[:lsf]
    record_invocation(options) do
      prepare_for_lsf
      Origen.app.listeners_for(:before_lsf_submission).each(&:before_lsf_submission)
      expand_lists_and_directories(options[:files], options).each do |file|
        Origen.app.lsf_manager.submit_origen_job(file, options)
      end
    end
    Origen.log.info ''
    Origen.log.info 'Monitor status of remote jobs via:'
    Origen.log.info '  origen l'
  else
    Origen.log.info '*' * 70 unless options[:quiet]
    Origen.app.listeners_for(:before_generate).each do |listener|
      if listener.class.instance_method(:before_generate).arity == 0
        listener.before_generate
      else
        listener.before_generate(options)
      end
    end
    if Origen.running_remotely?
      Origen.app.listeners_for(:before_generate_remote).each do |listener|
        if listener.class.instance_method(:before_generate_remote).arity == 0
          listener.before_generate_remote
        else
          listener.before_generate_remote(options)
        end
      end
    else
      Origen.app.listeners_for(:before_generate_local).each do |listener|
        if listener.class.instance_method(:before_generate_local).arity == 0
          listener.before_generate_local
        else
          listener.before_generate_local(options)
        end
      end
    end

    record_invocation(options) do
      case options[:action]
      when :forecast_test_time
        Origen.time.forecast_test_time(options)
      else
        if options[:action] == :program
          Origen.generator.generate_program(expand_lists_and_directories(options[:files], options), options)
        else
          temporary_plugin_from_options = options[:current_plugin]
          expand_lists_and_directories(options[:files], options).each do |file|
            if temporary_plugin_from_options
              Origen.current_plugin.temporary = temporary_plugin_from_options
            end
            case options[:action]
            when :compile
              Origen.generator.compile_file_or_directory(file, options)
            when :merge
              Origen.generator.merge_file_or_directory(file, options)
            when :import_test_time
              Origen.time.import_test_time(file, options)
            when :import_test_flow
              Origen.time.import_test_flow(file, options)
            else
              Origen.generator.generate_pattern(file, options)
            end
            if temporary_plugin_from_options
              Origen.current_plugin.default
            end
          end
        end
      end
    end

    unless options[:quiet]
      Origen.log.info '*' * 70
      stats.print_summary unless options[:action] == :merge
    end
  end
end

#mkdir(dir) ⇒ Object

Make the given directory if it doesn’t exist, must be a full path



230
231
232
233
234
# File 'lib/origen/application/runner.rb', line 230

def mkdir(dir)
  unless File.exist?(dir)
    FileUtils.mkdir_p(dir)
  end
end

#prepare_and_validate_workspace(options = {}) ⇒ Object



102
103
104
105
# File 'lib/origen/application/runner.rb', line 102

def prepare_and_validate_workspace(options = {})
  confirm_production_ready(options)
  prepare_directories(options)
end

#prepare_directories(options = {}) ⇒ Object



211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/origen/application/runner.rb', line 211

def prepare_directories(options = {})
  # When running remotely on the LSF never create directories to
  # prevent race conditions as multiple processes run concurrently,
  # instead assume they were already created by the runner who
  # submitted the job.
  Origen.file_handler.set_output_directory(options.merge(create: Origen.running_locally?))
  Origen.file_handler.set_reference_directory(options.merge(create: Origen.running_locally?))
  tmp = "#{Origen.root}/tmp"
  FileUtils.mkdir(tmp) unless File.exist?(tmp)
  if Origen.running_locally?
    mkdir Origen::Log.log_file_directory
    mkdir "#{Origen.root}/.lsf"
  end
  if options[:lsf]
    mkdir Origen.app.lsf_manager.log_file_directory
  end
end

#prepare_for_lsfObject



185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/origen/application/runner.rb', line 185

def prepare_for_lsf
  if options[:lsf]
    # Build an options string for saving with the LSF job that represents this runtime environment
    str = "-t #{Origen.target.file.basename}"
    if Origen.environment.file
      str += " --environment #{Origen.environment.file.basename}"
    end
    if options[:output]
      str += " -o #{options[:output]}"
    end
    if options[:reference]
      str += " -r #{options[:reference]}"
    end
    options[:lsf_option_string] = str
    # Clear the LSF manager job list if specifically requested or if that is the default action and
    # no specific action has been requested
    if options[:lsf_action]
      if options[:lsf_action] == :clear
        Origen.app.lsf_manager.clear_all
      end
    elsif Origen.config.default_lsf_action == :clear
      Origen.app.lsf_manager.clear_all
    end
  end
end

#record_invocation(options) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Post an invocation to the Origen server for usage statistics tracking.

Posting an invocation was found to add ~0.5s to all command times, so here we run it in a separate thread to try and hide it behind the user’s command.



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/origen/application/runner.rb', line 114

def record_invocation(options)
  record_invocation = false
  begin
    # Only record user invocations at this time, also bypass windows since it seems
    # that threads can't be trusted not to block
    unless Origen.running_remotely? # || Origen.running_on_windows?
      record_invocation = Thread.new do
        Origen.client.record_invocation(options[:action]) if options[:action]
      end
    end
  rescue
    # Don't allow this to kill an origen command
  end
  yield
  begin
    unless Origen.running_remotely?
      # Wait for a server response, ideally would like to not wait here, but it seems if not
      # then invocation postings can be dropped, especially on windows
      Origen.profile 'waiting for recording invocation' do
        record_invocation.value
      end
    end
  rescue
    # Don't allow this to kill an origen command
  end
end

#shutdownObject



165
166
167
168
169
170
# File 'lib/origen/application/runner.rb', line 165

def shutdown
  if Origen.app.stats.failed_files > 0 ||
     Origen.app.stats.failed_patterns > 0
    exit 1
  end
end

#statisticsObject Also known as: stats



180
181
182
# File 'lib/origen/application/runner.rb', line 180

def statistics
  @statistics ||= Statistics.new(options)
end