Module: Benchcc

Defined in:
lib/benchcc/mpl.rb,
lib/benchcc/plot.rb,
lib/benchcc/fusion.rb,
lib/benchcc/version.rb,
lib/benchcc/compiler.rb,
lib/benchcc/benchmark.rb

Defined Under Namespace

Modules: Fusion, MPL Classes: Clang, CompilationError, CompilationTimeout, ExecutionError, ExecutionTimeout, Renderer

Constant Summary collapse

Y_FEATURES =
[:memory_usage, :compilation_time, :execution_time]
DEFAULT_TWEAK =

How do I make this private?

{
  memory_usage: -> (plot) {
    plot.ylabel   'Memory usage'
    plot.decimal  'locale \'en_US.UTF-8\''
    plot.format   'y \'%.2e kb\''
  },

  compilation_time: -> (plot) {
    plot.ylabel   'Compilation time'
    plot.format   'y \'%.2g s\''
  },

  execution_time: -> (plot) {
    plot.ylabel   'Execution time'
    plot.format   'y \'%.0f µs\''
  }
}
VERSION =
"0.0.17"

Class Method Summary collapse

Class Method Details

.benchmark(erb_file:, environments:, compilation_timeout:, execution_timeout:, evaluate_erb_relative_to:, features:, compiler_executable:, compiler_id:, compiler_options:) ⇒ Object



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
# File 'lib/benchcc/benchmark.rb', line 23

def benchmark(
    erb_file:, # String or Pathname
    environments:, # Array of Hash
    compilation_timeout:, # Int
    execution_timeout:, # Int
    evaluate_erb_relative_to:, # String or Pathname
    features:, # Array of Symbol
    compiler_executable:, # String
    compiler_id:, # String
    compiler_options: # Array of String
  )
  erb_file = Pathname.new(erb_file)
  progress = ProgressBar.create(format: '%p%% | %B |', total: environments.size)
  compiler = Benchcc::which(compiler_id)

  data = CSV.generate({headers: :first_row}) do |csv|
    csv << [:input_size] + features

    environments.each do |env|
      code = Renderer.new(evaluate_erb_relative_to).render(erb_file, **env)
      begin
        row = {input_size: env[:input_size]}
        Tempfile.create([erb_file.basename, '.cpp']) do |tmp|
          tmp.write(code) && tmp.close

          row.merge!(
            compiler.call(
              input_file: tmp.path,
              features: features,
              compiler_executable: compiler_executable,
              compiler_options: compiler_options,
              compilation_timeout: compilation_timeout,
              execution_timeout: execution_timeout
            )
          )
        end

      rescue CompilationError, CompilationTimeout => e
        $stderr << e
        break

      rescue ExecutionError, ExecutionTimeout => e
        $stderr << e
        break unless features.include?(:compilation_time) || features.include?(:memory_usage)

      ensure
        csv << row
        progress.increment
      end
    end
  end
  return data
ensure
  progress.finish
end

.plot(title, output, curves, x_feature: :input_size, y_feature: :compilation_time, &tweak) ⇒ Object

title:

The title used for the plot.

output:

The name of the file in which the plot is written.

curves:

An array of hashes of the form
  { title: <curve title>, input: <data set file> }
representing the curves to draw on the plot.

Raises:

  • (ArgumentError)


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
# File 'lib/benchcc/plot.rb', line 37

def plot(title, output, curves, x_feature: :input_size, y_feature: :compilation_time, &tweak)
  x_feature, y_feature = x_feature.to_sym, y_feature.to_sym
  raise ArgumentError if not Benchcc::Y_FEATURES.include?(y_feature)
  tweak ||= Benchcc::DEFAULT_TWEAK[y_feature]

  Gnuplot.open do |io|
    Gnuplot::Plot.new(io) do |plot|
      plot.title    title
      plot.term     'png'
      plot.output   output
      plot.data = curves.map { |curve|
        csv = CSV.table(curve[:input])
        ys = csv[y_feature]
        xs = csv[x_feature]

        # Remove trailing nils from the y-axis. nils can arise when e.g.
        # runtime execution failed but we still kept on gathering info
        # for the compilation, so the execution_time column has some
        # trailing empty values.
        ys.pop until ys.last

        # Restrict the x-axis to the number of valid y-axis values.
        xs = xs[0...ys.size]

        Gnuplot::DataSet.new([xs, ys]) { |ds|
          ds.title = curve[:title]
          ds.with = 'lines'
        }
      }
      tweak.call(plot)
    end
  end
end

.which(compiler_id) ⇒ Object



110
111
112
113
114
115
116
117
# File 'lib/benchcc/compiler.rb', line 110

def which(compiler_id)
  case compiler_id
  when 'Clang'
    return Clang.new
  else
    raise ArgumentError.new("Unsupported compiler id: #{compiler_id}")
  end
end