Skip to content
This repository
Browse code

replace ruby implementation with python

  • Loading branch information...
commit 499259981500115b8b4694004e2852c1a2cbe2fb 1 parent 7201037
Casey Robinson authored

Showing 26 changed files with 412 additions and 1,048 deletions. Show diff stats Hide diff stats

  1. 8  resource_monitor_visualizer/Makefile
  2. 11  resource_monitor_visualizer/bin/resource_monitor_visualizer
  3. 407  resource_monitor_visualizer/bin/resource_monitor_visualizer.py
  4. 0  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/css/style.css
  5. 0  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/img/arrow-next.png
  6. 0  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/img/arrow-prev.png
  7. 0  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/img/loading.gif
  8. 0  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/img/pagination.png
  9. 0  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/img/subtle_grunge.png
  10. 2  resource_monitor_visualizer/lib/{rmv_static → resource_monitor_visualizer_static}/js/slides.min.jquery.js
  11. 16  resource_monitor_visualizer/lib/rmv.rb
  12. 13  resource_monitor_visualizer/lib/rmv/black_hole.rb
  13. 161  resource_monitor_visualizer/lib/rmv/histogram_builder.rb
  14. 73  resource_monitor_visualizer/lib/rmv/makeflow_log.rb
  15. 67  resource_monitor_visualizer/lib/rmv/number.rb
  16. 67  resource_monitor_visualizer/lib/rmv/options.rb
  17. 46  resource_monitor_visualizer/lib/rmv/page.rb
  18. 400  resource_monitor_visualizer/lib/rmv/runner.rb
  19. 36  resource_monitor_visualizer/lib/rmv/summary.rb
  20. 28  resource_monitor_visualizer/lib/rmv/summary_collection.rb
  21. 38  resource_monitor_visualizer/lib/rmv/task.rb
  22. 30  resource_monitor_visualizer/lib/rmv/task_collection.rb
  23. 3  resource_monitor_visualizer/lib/rmv/version.rb
  24. 44  resource_monitor_visualizer/lib/rmv/writer.rb
  25. 5  resource_monitor_visualizer/lib/rmv_static/img/LICENSE
  26. 5  resource_monitor_visualizer/lib/rmv_static/js/LICENSE
8  resource_monitor_visualizer/Makefile
... ...
@@ -1,7 +1,7 @@
1 1
 include ../Makefile.config
2 2
 include ../Makefile.rules
3 3
 
4  
-SCRIPT = bin/resource_monitor_visualizer
  4
+SCRIPT = bin/resource_monitor_visualizer.py
5 5
 
6 6
 test:
7 7
 
@@ -10,13 +10,13 @@ all:
10 10
 clean:
11 11
 
12 12
 uninstall:
13  
-	rm -rf ${CCTOOLS_INSTALL_DIR}/lib/rmv ${CCTOOLS_INSTALL_DIR}/lib/rmv_static
  13
+	rm -rf ${CCTOOLS_INSTALL_DIR}/lib/resource_monitor_visualizer_static
14 14
 	rm -f ${CCTOOLS_INSTALL_DIR}/${SCRIPT}
15 15
 
16  
-install: 
  16
+install:
17 17
 	mkdir -p ${CCTOOLS_INSTALL_DIR}/bin
18 18
 	mkdir -p ${CCTOOLS_INSTALL_DIR}/lib
19 19
 	chmod 755 ${SCRIPT}
20 20
 	cp ${SCRIPT} ${CCTOOLS_INSTALL_DIR}/bin
21  
-	cp -r lib/rmv* ${CCTOOLS_INSTALL_DIR}/lib/
  21
+	cp -r lib/* ${CCTOOLS_INSTALL_DIR}/lib/
22 22
 
11  resource_monitor_visualizer/bin/resource_monitor_visualizer
... ...
@@ -1,11 +0,0 @@
1  
-#!/usr/bin/env ruby
2  
-
3  
-min_release = "1.8.5"
4  
-abort "Resource Monitor Visualizer requires Ruby version #{min_release} or greater.\nUpgrade and try again." if RUBY_VERSION < min_release
5  
-
6  
-$:.unshift File.expand_path("../../lib",__FILE__)
7  
-
8  
-require 'rmv'
9  
-
10  
-runner = RMV::Runner.new ARGV
11  
-runner.run
407  resource_monitor_visualizer/bin/resource_monitor_visualizer.py
... ...
@@ -0,0 +1,407 @@
  1
+#!/usr/bin/env python
  2
+
  3
+import os
  4
+import argparse
  5
+
  6
+def make_path(path):
  7
+  try:
  8
+    os.makedirs(path)
  9
+  except:
  10
+    pass
  11
+
  12
+def find_gnuplot_version():
  13
+  return float(os.popen("gnuplot --version | awk '{print $2}'").read())
  14
+
  15
+def source_exists(path):
  16
+  if not os.path.isdir(path):
  17
+    print "source directory does not exist"
  18
+    exit(1)
  19
+
  20
+def get_args():
  21
+  option_parser = argparse.ArgumentParser(description='Visualize resource monitor data')
  22
+  option_parser.add_argument("source", help="the directory containing your data")
  23
+  option_parser.add_argument("destination", help="the desired output directory")
  24
+  option_parser.add_argument("name", help="the name of the workflow")
  25
+  args = option_parser.parse_args()
  26
+  return args.source, args.destination, args.name
  27
+
  28
+def find_summary_paths(source):
  29
+  summary_paths = []
  30
+  for r, d, f in os.walk(source):
  31
+    for files in f:
  32
+      if files.endswith(".summary"):
  33
+        summary_paths.append(os.path.join(r, files))
  34
+  return summary_paths
  35
+
  36
+def load_summaries_by_group(paths):
  37
+  groups = {}
  38
+  for sp in paths:
  39
+    data_stream = open(sp, 'r')
  40
+    summary = {}
  41
+    for line in data_stream:
  42
+      data = line.strip().split(':', 2)
  43
+      data = [x.strip() for x in data]
  44
+      key = data[0]
  45
+      value = data[1]
  46
+      summary[key] = value
  47
+    summary['filename'] = os.path.basename(sp)
  48
+
  49
+    group_name = summary.get('command').split(' ')[0]
  50
+    while group_name[0] == '.' or group_name[0] == '/':
  51
+      group_name = group_name[1:]
  52
+
  53
+    if groups.get(group_name) == None:
  54
+      groups[group_name] = [summary]
  55
+    else:
  56
+      groups[group_name].append(summary)
  57
+
  58
+    data_stream.close()
  59
+  return groups
  60
+
  61
+def gnuplot(commands):
  62
+  (child_stdin, child_stdout, child_stderr) = os.popen3("gnuplot")
  63
+  child_stdin.write("%s\n" % commands)
  64
+  child_stdin.close()
  65
+  child_stdout.close()
  66
+  child_stderr.close()
  67
+
  68
+def fill_histogram_template(width, height, image_path, binwidth, resource_name, unit, data_path):
  69
+  result  = "set terminal png transparent size " + str(width) + "," + str(height) + "\n"
  70
+  result += "unset key\n"
  71
+  result += "set ylabel \"Frequency\"\n"
  72
+  result += "set output \"" + image_path + "\"\n"
  73
+  result += "binwidth=" + str(binwidth) + "\n"
  74
+  result += "set boxwidth binwidth*0.9 absolute\n"
  75
+  result += "set style fill solid 0.5\n"
  76
+  result += "bin(x,width)=width*floor(x/width)\n"
  77
+  result += "set yrange [0:*]\n"
  78
+  result += "set xrange [0:*]\n"
  79
+  result += "set xlabel \"" + resource_name
  80
+  if unit != " ":
  81
+    result += " (" + unit + ")"
  82
+  result += "\"\n"
  83
+  result += "plot \"" + data_path + "\" using (bin($1,binwidth)):(1.0) smooth freq w boxes\n"
  84
+  return result
  85
+
  86
+def rule_id_for_task(task):
  87
+  rule_id = task.get('filename').split('.')
  88
+  rule_id = rule_id[0].split('-')[-1]
  89
+  return rule_id
  90
+
  91
+def resource_group_page(name, group_name, resource, width, height, tasks, out_path):
  92
+  page  = "<!doctype html>\n"
  93
+  page += "<meta name=\"viewport\" content=\"initial-scale=1.0, width=device-width\" />\n"
  94
+  page += '<link rel="stylesheet" type="text/css" media="screen, projection" href="../../css/style.css" />' + "\n"
  95
+  page += "<title>Workflow</title>\n"
  96
+  page += "<div class=\"content\">\n"
  97
+  page += "<h1><a href=\"../../index.html\">" + name + "</a> - " + group_name + " - " + resource + "</h1>\n"
  98
+  page += "<img src=\"../" + resource + "_" + str(width) + "x" + str(height) + "_hist.png\" class=\"center\" />\n"
  99
+  page += "<table>\n"
  100
+  page += "<tr><th>Rule Id</th><th>Maximum " + resource +  "</th></tr>\n"
  101
+  comp = lambda x,y: cmp(float(x.get(resource).split(' ')[0]), float(y.get(resource).split(' ')[0]))
  102
+  sorted_tasks = sorted(tasks, comp, reverse=True)
  103
+  for d in sorted_tasks:
  104
+    rule_id = rule_id_for_task(d)
  105
+    page += "<tr><td><a href=\"../" + rule_id + ".html\">" + rule_id + "</a></td><td>" + str(d.get(resource)) + "</td></tr>\n"
  106
+  page += "</table>\n"
  107
+  page += "</div>\n"
  108
+
  109
+  index_path = out_path + "/" + resource
  110
+  make_path(index_path)
  111
+  index_path += "/" + "index.html"
  112
+  f = open(index_path, "w")
  113
+  f.write("%s\n" % page)
  114
+  f.close()
  115
+
  116
+def compute_binwidth(maximum_value):
  117
+  if maximum_value > 40:
  118
+    binwidth = maximum_value/40.0
  119
+  else:
  120
+    binwidth = 1
  121
+  return binwidth
  122
+
  123
+def find_maximums(tasks, resource):
  124
+  maximums = []
  125
+  for d in tasks:
  126
+    maximums.append(d.get(resource))
  127
+  return maximums
  128
+
  129
+def write_maximums(maximums, resource, group_name, base_directory):
  130
+  directory = base_directory + "/" + group_name
  131
+  make_path(directory)
  132
+  data_path = directory + "/" + resource
  133
+  f = open(data_path, "w")
  134
+  for m in maximums:
  135
+    f.write("%d\n" % m)
  136
+  f.close()
  137
+  return data_path
  138
+
  139
+def scale_maximums(maximums, unit):
  140
+  result = []
  141
+  for m in maximums:
  142
+    m = scale_value(m, unit)
  143
+    result.append(m)
  144
+  return result
  145
+
  146
+def task_has_timeseries(task, source_directory):
  147
+  base_name = task.get('filename').split('.')[0]
  148
+  timeseries_name = base_name + '.series'
  149
+  try:
  150
+    f = open(source_directory + "/" + timeseries_name)
  151
+    f.close()
  152
+  except:
  153
+    return None
  154
+  return timeseries_name
  155
+
  156
+def fill_in_time_series_format(resource, unit, data_path, column, out_path, width=1250, height=500):
  157
+  if unit != " ":
  158
+    unit = ' (' + unit + ')'
  159
+  commands  = 'set terminal png transparent size ' + str(width) + ',' + str(height) + "\n"
  160
+  commands += "set bmargin 4\n"
  161
+  commands += "unset key\n"
  162
+  commands += 'set xlabel "Time (seconds)" offset 0,-2 character' + "\n"
  163
+  commands += 'set ylabel "' + resource + unit + '" offset 0,-2 character' + "\n"
  164
+  commands += 'set output "' + out_path + '"' + "\n"
  165
+  commands += "set yrange [0:*]\n"
  166
+  commands += "set xrange [0:*]\n"
  167
+  commands += "set xtics right rotate by -45\n"
  168
+  commands += "set bmargin 7\n"
  169
+  commands += 'plot"' + data_path + '" using 1:' + str(column) + ' w lines lw 5 lc rgb"#465510"' + "\n"
  170
+  return commands
  171
+
  172
+def generate_time_series_plot(resource, unit, data_path, column, out_path, width, height):
  173
+  commands = fill_in_time_series_format(resource, unit, data_path, column, out_path, width, height)
  174
+  gnuplot(commands)
  175
+
  176
+def scale_time_series(source_directory, data_file, units, aggregate_data):
  177
+  start = -1
  178
+  out_file_path = '/tmp/rmv/' + data_file + '.scaled'
  179
+  out_stream = open(out_file_path, 'w')
  180
+  data_stream = open(source_directory + '/' + data_file, 'r')
  181
+  for line in data_stream:
  182
+    if line[0] == '#':
  183
+      continue
  184
+    data = line.split()
  185
+    if start < 0:
  186
+      start = data[0]
  187
+    data[6] = str(scale_value(data[6] + ' B', 'GB'))
  188
+    data[7] = str(scale_value(data[7] + ' B', 'GB'))
  189
+
  190
+    # store in aggregate_data
  191
+    key = round(int(data[0])/1000000)
  192
+    previous_values = aggregate_data.get(key, [0,0,0,0,0,0,0,0,0])
  193
+    for x in range(0,8):
  194
+      previous_values[x] = previous_values[x] + float(data[x+1])
  195
+    aggregate_data[key]  = previous_values
  196
+
  197
+    data[0] = str((float(data[0]) - float(start))/10e5)
  198
+    out_stream.write("%s\n" % str.join(' ', data))
  199
+  data_stream.close()
  200
+  out_stream.close()
  201
+  return out_file_path, aggregate_data
  202
+
  203
+def create_individual_pages(groups, destination_directory, name, resources, units, source_directory):
  204
+  aggregate_data = {}
  205
+  for group_name in groups:
  206
+    for task in groups[group_name]:
  207
+      timeseries_file = task_has_timeseries(task, source_directory)
  208
+      has_timeseries = False
  209
+      if timeseries_file != None:
  210
+        has_timeseries = True
  211
+        data_path, aggregate_data = scale_time_series(source_directory, timeseries_file, units, aggregate_data)
  212
+        column = 1
  213
+        for r in resources:
  214
+          out_path = destination_directory + '/' + group_name + '/' + r + '/' + rule_id_for_task(task) + '.png'
  215
+          if column > 1:
  216
+            generate_time_series_plot(r, units.get(r), data_path, column, out_path, 600, 300)
  217
+          column += 1
  218
+      page  = "<html>\n"
  219
+      page += '<link rel="stylesheet" type="text/css" media="screen, projection" href="../css/style.css" />' + "\n"
  220
+      page += "<h1><a href=\"../index.html\">" + name + "</a> - " + group_name + " - " + rule_id_for_task(task) + "</h1>\n"
  221
+      page += "<table>\n"
  222
+      page += "<tr><td>command</td><td>" + task.get('command') + "</td></tr>\n"
  223
+      for r in resources:
  224
+        page += "<tr><td><a href=\"" + r + "/index.html\">" + r + "</a></td><td>" + task.get(r) + "</td>"
  225
+        if has_timeseries and r != 'wall_time':
  226
+          image_path = r + '/' + rule_id_for_task(task) + '.png'
  227
+          page += '<td><img src="' + image_path +'" /></td>'
  228
+        page += "</tr>\n"
  229
+      page += "</html>\n"
  230
+      f = open(destination_directory + "/" + group_name + "/" + rule_id_for_task(task) + ".html", "w")
  231
+      f.write("%s\n" % page)
  232
+      f.close()
  233
+  return aggregate_data
  234
+
  235
+def write_aggregate_data(data, resources, work_directory):
  236
+  sorted_keys = sorted(data.keys(), key=lambda x: float(x))
  237
+  start_time = float(sorted_keys[0])
  238
+  files = []
  239
+  for index, r in enumerate(resources):
  240
+    if index != 0:
  241
+      f = open(work_directory + '/' + r + '.aggregate', 'w')
  242
+      files.append(f)
  243
+  for k in sorted_keys:
  244
+    for index, f in enumerate(files):
  245
+      f.write("%s %d\n" % ((k-start_time), data.get(k)[index]))
  246
+  for f in files:
  247
+    f.close()
  248
+
  249
+def create_aggregate_plots(resources, units, work_directory, destination_directory):
  250
+  for r in resources:
  251
+    unit = units.get(r)
  252
+    data_path = work_directory + '/' + r + '.aggregate'
  253
+    column = 2
  254
+    out_path = destination_directory + '/' + r + '_aggregate.png'
  255
+    commands = fill_in_time_series_format(r, unit, data_path, column, out_path, 1250, 500)
  256
+    gnuplot(commands)
  257
+
  258
+def create_main_page(group_names, name, resources, destination, hist_height=600, hist_width=600, timeseries_height=1250, timeseries_width=500, has_timeseries=False):
  259
+  out_path = destination + "/index.html"
  260
+  f = open(out_path, "w")
  261
+  content  = "<!doctype html>\n"
  262
+  content += "<meta charset=\"UTF-8\">\n"
  263
+  content += '<meta name="viewport" content="initial-scale=1.0, width=device-width" />' + "\n"
  264
+  content += '<link rel="stylesheet" type="text/css" media="screen, projection" href="css/style.css" />' + "\n"
  265
+  content += '<title>' + name + "Workflow</title>\n"
  266
+  content += '<div class="content">' + "\n"
  267
+  content += '<h1>' + name + "Workflow</h1>\n"
  268
+  if has_timeseries:
  269
+    content += '<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>' + "\n"
  270
+    content += '<script src="js/slides.min.jquery.js"></script>' + "\n"
  271
+    content += '<script>' + "\n" + '  $(function(){' + "\n" + "    $('#slides').slides({ preload: true, });\n  });\n</script>\n"
  272
+    content += '<!-- javascript and some images licensed under Apache-2.0 by Nathan Searles (http://nathansearles.com/) -->' + "\n"
  273
+    content += '<section class="summary">' + "\n"
  274
+    content += '  <div id="slides">' + "\n"
  275
+    content += '    <div class="slides_container">' + "\n"
  276
+    for index, r in enumerate(resources):
  277
+      if index != 0:
  278
+        content += '<div class="slide"><div class="item"><img src = "' + r + '_aggregate.png" /></div></div>' + "\n"
  279
+    content += "</div>\n"
  280
+    content += '<a href="#" class="prev"><img src="img/arrow-prev.png" width="24" height="43" alt="Arrow Prev"></a>' + "\n"
  281
+    content += '<a href="#" class="next"><img src="img/arrow-next.png" width="24" height="43" alt="Arrow Next"></a>' + "\n"
  282
+    content += "  </div>\n</section>\n"
  283
+
  284
+  for g in group_names:
  285
+    content += '<h2>' + g + "</h2>\n"
  286
+    for r in resources:
  287
+      content += '<a href="' + g + '/' + r + '/index.html"><img src="' + g + "/" + r + "_" + str(hist_width) + "x" + str(hist_height) + '_hist.png" /></a>\n'
  288
+    content += "<hr />\n\n"
  289
+  content += "</div>\n"
  290
+  f.write("%s\n" % content)
  291
+  f.close()
  292
+
  293
+def to_base(value, unit):
  294
+  prefix = unit[0]
  295
+  if   prefix == "K":
  296
+    value *= 1024
  297
+  elif prefix == "M":
  298
+    value *= 1024**2
  299
+  elif prefix == "G":
  300
+    value *= 1024**3
  301
+  elif prefix == "T":
  302
+    value *= 1024**4
  303
+  return value
  304
+
  305
+def to_target(value, target):
  306
+  prefix = target[0]
  307
+  if   prefix == "K":
  308
+    value /= 1024
  309
+  elif prefix == "M":
  310
+    value /= 1024**2
  311
+  elif prefix == "G":
  312
+    value /= 1024**3
  313
+  elif prefix == "T":
  314
+    value /= 1024**4
  315
+  return value
  316
+
  317
+def scale_value(initial, target_unit=" "):
  318
+  value, unit = initial.split(' ', 2)
  319
+  value = float(value)
  320
+  unit = unit.strip()
  321
+
  322
+  v = to_target(to_base(value, unit), target_unit)
  323
+
  324
+  return v
  325
+
  326
+
  327
+def main():
  328
+  GNUPLOT_VERSION = find_gnuplot_version()
  329
+
  330
+  (source_directory,
  331
+  destination_directory,
  332
+  name) = get_args()
  333
+
  334
+  source_exists(source_directory)
  335
+
  336
+  make_path(destination_directory)
  337
+
  338
+  workspace = '/tmp/rmv'
  339
+  make_path(workspace)
  340
+
  341
+  summary_paths = find_summary_paths(source_directory)
  342
+
  343
+  resource_units = {"wall_time": "s",
  344
+                    "cpu_time": "s",
  345
+                    "max_concurrent_processes": " ",
  346
+                    "virtual_memory":  "MB",
  347
+                    "resident_memory": "MB",
  348
+                    "swap_memory":     "MB",
  349
+                    "bytes_read":      "GB",
  350
+                    "bytes_written":   "GB",
  351
+                    "workdir_num_files": " ",
  352
+                    "workdir_footprint": "GB"
  353
+                   }
  354
+  resources = [ "wall_time",
  355
+                "cpu_time",
  356
+                "max_concurrent_processes",
  357
+                "virtual_memory",
  358
+                "resident_memory",
  359
+                "swap_memory",
  360
+                "bytes_read",
  361
+                "bytes_written",
  362
+                "workdir_num_files",
  363
+                "workdir_footprint"
  364
+              ]
  365
+
  366
+  groups = load_summaries_by_group(summary_paths)
  367
+
  368
+  hist_large = 600
  369
+  hist_small = 250
  370
+  for r in resources:
  371
+    unit = resource_units.get(r)
  372
+    for group_name in groups:
  373
+      maximums = find_maximums(groups[group_name], r)
  374
+      maximums = scale_maximums(maximums, unit)
  375
+      data_path = write_maximums(maximums, r, group_name, workspace)
  376
+
  377
+      out_path = destination_directory + "/" + group_name
  378
+      make_path(out_path)
  379
+      binwidth = compute_binwidth(max(maximums))
  380
+
  381
+      image_path = out_path + "/" + r + "_" + str(hist_large) + "x" + str(hist_large) + "_hist.png"
  382
+      gnuplot_format = fill_histogram_template(hist_large, hist_large, image_path, binwidth, r, unit, data_path)
  383
+      gnuplot(gnuplot_format)
  384
+
  385
+      image_path = out_path + "/" + r + "_" + str(hist_small) + "x" + str(hist_small) + "_hist.png"
  386
+      gnuplot_format = fill_histogram_template(hist_small, hist_small, image_path, binwidth, r, unit, data_path)
  387
+      gnuplot(gnuplot_format)
  388
+
  389
+      resource_group_page(name, group_name, r, hist_large, hist_large, groups[group_name], out_path)
  390
+
  391
+  aggregate_height = 500
  392
+  aggregate_width = 1250
  393
+  aggregate_data = create_individual_pages(groups, destination_directory, name, resources, resource_units, source_directory)
  394
+
  395
+  time_series_exist = False
  396
+  if aggregate_data != {}:
  397
+    time_series_exist = True
  398
+    write_aggregate_data(aggregate_data, resources, workspace)
  399
+    create_aggregate_plots(resources, resource_units, workspace, destination_directory)
  400
+
  401
+  create_main_page(groups.keys(), name, resources, destination_directory, hist_small, hist_small, aggregate_height, aggregate_width, time_series_exist)
  402
+
  403
+  os.system("cp -r ../lib/resource_monitor_static/* " + destination_directory)
  404
+
  405
+  os.system("rm -rf " + workspace)
  406
+
  407
+main()
0  ...e_monitor_visualizer/lib/rmv_static/css/style.css → .../resource_monitor_visualizer_static/css/style.css
File renamed without changes
0  ...itor_visualizer/lib/rmv_static/img/arrow-next.png → ...urce_monitor_visualizer_static/img/arrow-next.png
File renamed without changes
0  ...itor_visualizer/lib/rmv_static/img/arrow-prev.png → ...urce_monitor_visualizer_static/img/arrow-prev.png
File renamed without changes
0  ...monitor_visualizer/lib/rmv_static/img/loading.gif → ...esource_monitor_visualizer_static/img/loading.gif
File renamed without changes
0  ...itor_visualizer/lib/rmv_static/img/pagination.png → ...urce_monitor_visualizer_static/img/pagination.png
File renamed without changes
0  ...r_visualizer/lib/rmv_static/img/subtle_grunge.png → ...e_monitor_visualizer_static/img/subtle_grunge.png
File renamed without changes
2  ...visualizer/lib/rmv_static/js/slides.min.jquery.js → ...monitor_visualizer_static/js/slides.min.jquery.js
... ...
@@ -1 +1 @@
1  
-(function(a){a.fn.slides=function(b){return b=a.extend({},a.fn.slides.option,b),this.each(function(){function w(g,h,i){if(!p&&o){switch(p=!0,b.animationStart(n+1),g){case"next":l=n,k=n+1,k=e===k?0:k,r=2*f,g=2*-f,n=k;break;case"prev":l=n,k=n-1,k=-1===k?e-1:k,r=0,g=0,n=k;break;case"pagination":k=parseInt(i,10),l=a("."+b.paginationClass+" li."+b.currentClass+" a",c).attr("href").match("[^#/]+$"),k>l?(r=2*f,g=2*-f):(r=0,g=0),n=k}"fade"===h?b.crossfade?d.children(":eq("+k+")",c).css({zIndex:10}).fadeIn(b.fadeSpeed,b.fadeEasing,function(){b.autoHeight?d.animate({height:d.children(":eq("+k+")",c).outerHeight()},b.autoHeightSpeed,function(){d.children(":eq("+l+")",c).css({display:"none",zIndex:0}),d.children(":eq("+k+")",c).css({zIndex:0}),b.animationComplete(k+1),p=!1}):(d.children(":eq("+l+")",c).css({display:"none",zIndex:0}),d.children(":eq("+k+")",c).css({zIndex:0}),b.animationComplete(k+1),p=!1)}):d.children(":eq("+l+")",c).fadeOut(b.fadeSpeed,b.fadeEasing,function(){b.autoHeight?d.animate({height:d.children(":eq("+k+")",c).outerHeight()},b.autoHeightSpeed,function(){d.children(":eq("+k+")",c).fadeIn(b.fadeSpeed,b.fadeEasing)}):d.children(":eq("+k+")",c).fadeIn(b.fadeSpeed,b.fadeEasing,function(){}),b.animationComplete(k+1),p=!1}):(d.children(":eq("+k+")").css({left:r,display:"block"}),b.autoHeight?d.animate({left:g,height:d.children(":eq("+k+")").outerHeight()},b.slideSpeed,b.slideEasing,function(){d.css({left:-f}),d.children(":eq("+k+")").css({left:f,zIndex:5}),d.children(":eq("+l+")").css({left:f,display:"none",zIndex:0}),b.animationComplete(k+1),p=!1}):d.animate({left:g},b.slideSpeed,b.slideEasing,function(){d.css({left:-f}),d.children(":eq("+k+")").css({left:f,zIndex:5}),d.children(":eq("+l+")").css({left:f,display:"none",zIndex:0}),b.animationComplete(k+1),p=!1})),b.pagination&&(a("."+b.paginationClass+" li."+b.currentClass,c).removeClass(b.currentClass),a("."+b.paginationClass+" li:eq("+k+")",c).addClass(b.currentClass))}}function x(){clearInterval(c.data("interval"))}function y(){b.pause?(clearTimeout(c.data("pause")),clearInterval(c.data("interval")),u=setTimeout(function(){clearTimeout(c.data("pause")),v=setInterval(function(){w("next",i)},b.play),c.data("interval",v)},b.pause),c.data("pause",u)):x()}a("."+b.container,a(this)).children().wrapAll('<div class="slides_control"/>');var o,p,q,r,t,u,v,c=a(this),d=a(".slides_control",c),e=d.children().size(),f=d.children().outerWidth(),g=d.children().outerHeight(),h=b.start-1,i=0>b.effect.indexOf(",")?b.effect:b.effect.replace(" ","").split(",")[0],j=0>b.effect.indexOf(",")?i:b.effect.replace(" ","").split(",")[1],k=0,l=0,m=0,n=0;if(2>e)return a("."+b.container,a(this)).fadeIn(b.fadeSpeed,b.fadeEasing,function(){o=!0,b.slidesLoaded()}),a("."+b.next+", ."+b.prev).fadeOut(0),!1;if(!(2>e)){if(0>h&&(h=0),h>e&&(h=e-1),b.start&&(n=h),b.randomize&&d.randomize(),a("."+b.container,c).css({overflow:"hidden",position:"relative"}),d.children().css({position:"absolute",top:0,left:d.children().outerWidth(),zIndex:0,display:"none"}),d.css({position:"relative",width:3*f,height:g,left:-f}),a("."+b.container,c).css({display:"block"}),b.autoHeight&&(d.children().css({height:"auto"}),d.animate({height:d.children(":eq("+h+")").outerHeight()},b.autoHeightSpeed)),b.preload&&d.find("img:eq("+h+")").length){a("."+b.container,c).css({background:"url("+b.preloadImage+") no-repeat 50% 50%"});var z=d.find("img:eq("+h+")").attr("src")+"?"+(new Date).getTime();t="slides_control"!=a("img",c).parent().attr("class")?d.children(":eq(0)")[0].tagName.toLowerCase():d.find("img:eq("+h+")"),d.find("img:eq("+h+")").attr("src",z).load(function(){d.find(t+":eq("+h+")").fadeIn(b.fadeSpeed,b.fadeEasing,function(){a(this).css({zIndex:5}),a("."+b.container,c).css({background:""}),o=!0,b.slidesLoaded()})})}else d.children(":eq("+h+")").fadeIn(b.fadeSpeed,b.fadeEasing,function(){o=!0,b.slidesLoaded()});b.bigTarget&&(d.children().css({cursor:"pointer"}),d.children().on("click",function(){return w("next",i),!1})),b.hoverPause&&b.play&&(d.bind("mouseover",function(){x()}),d.bind("mouseleave",function(){y()})),b.generateNextPrev&&(a("."+b.container,c).after('<a href="#" class="'+b.prev+'">Prev</a>'),a("."+b.prev,c).after('<a href="#" class="'+b.next+'">Next</a>')),a("."+b.next,c).on("click",function(a){a.preventDefault(),b.play&&y(),w("next",i)}),a("."+b.prev,c).on("click",function(a){a.preventDefault(),b.play&&y(),w("prev",i)}),b.generatePagination?(b.prependPagination?c.prepend("<ul class="+b.paginationClass+"></ul>"):c.append("<ul class="+b.paginationClass+"></ul>"),d.children().each(function(){a("."+b.paginationClass,c).append('<li><a href="#'+m+'">'+(m+1)+"</a></li>"),m++})):a("."+b.paginationClass+" li a",c).each(function(){a(this).attr("href","#"+m),m++}),a("."+b.paginationClass+" li:eq("+h+")",c).addClass(b.currentClass),a("."+b.paginationClass+" li a",c).on("click",function(){return b.play&&y(),q=a(this).attr("href").match("[^#/]+$"),n!=q&&w("pagination",j,q),!1}),a("a.link",c).on("click",function(){return b.play&&y(),q=a(this).attr("href").match("[^#/]+$")-1,n!=q&&w("pagination",j,q),!1}),b.play&&(v=setInterval(function(){w("next",i)},b.play),c.data("interval",v))}})},a.fn.slides.option={preload:!1,preloadImage:"../img/loading.gif",container:"slides_container",generateNextPrev:!1,next:"next",prev:"prev",pagination:!0,generatePagination:!0,prependPagination:!1,paginationClass:"pagination",currentClass:"current",fadeSpeed:350,fadeEasing:"",slideSpeed:350,slideEasing:"",start:1,effect:"slide",crossfade:!1,randomize:!1,play:0,pause:0,hoverPause:!1,autoHeight:!1,autoHeightSpeed:350,bigTarget:!1,animationStart:function(){},animationComplete:function(){},slidesLoaded:function(){}},a.fn.randomize=function(b){function c(){return Math.round(Math.random())-.5}return a(this).each(function(){var d=a(this),e=d.children(),f=e.length;if(f>1){e.hide();var g=[];for(i=0;f>i;i++)g[g.length]=i;g=g.sort(c),a.each(g,function(a,c){var f=e.eq(c),g=f.clone(!0);g.show().appendTo(d),void 0!==b&&b(f,g),f.remove()})}})}})(jQuery);
  1
+(function(a){a.fn.slides=function(b){return b=a.extend({},a.fn.slides.option,b),this.each(function(){function w(g,h,i){if(!p&&o){switch(p=!0,b.animationStart(n+1),g){case"next":l=n,k=n+1,k=e===k?0:k,r=2*f,g=2*-f,n=k;break;case"prev":l=n,k=n-1,k=-1===k?e-1:k,r=0,g=0,n=k;break;case"pagination":k=parseInt(i,10),l=a("."+b.paginationClass+" li."+b.currentClass+" a",c).attr("href").match("[^#/]+$"),k>l?(r=2*f,g=2*-f):(r=0,g=0),n=k}"fade"===h?b.crossfade?d.children(":eq("+k+")",c).css({zIndex:10}).fadeIn(b.fadeSpeed,b.fadeEasing,function(){b.autoHeight?d.animate({height:d.children(":eq("+k+")",c).outerHeight()},b.autoHeightSpeed,function(){d.children(":eq("+l+")",c).css({display:"none",zIndex:0}),d.children(":eq("+k+")",c).css({zIndex:0}),b.animationComplete(k+1),p=!1}):(d.children(":eq("+l+")",c).css({display:"none",zIndex:0}),d.children(":eq("+k+")",c).css({zIndex:0}),b.animationComplete(k+1),p=!1)}):d.children(":eq("+l+")",c).fadeOut(b.fadeSpeed,b.fadeEasing,function(){b.autoHeight?d.animate({height:d.children(":eq("+k+")",c).outerHeight()},b.autoHeightSpeed,function(){d.children(":eq("+k+")",c).fadeIn(b.fadeSpeed,b.fadeEasing)}):d.children(":eq("+k+")",c).fadeIn(b.fadeSpeed,b.fadeEasing,function(){}),b.animationComplete(k+1),p=!1}):(d.children(":eq("+k+")").css({left:r,display:"block"}),b.autoHeight?d.animate({left:g,height:d.children(":eq("+k+")").outerHeight()},b.slideSpeed,b.slideEasing,function(){d.css({left:-f}),d.children(":eq("+k+")").css({left:f,zIndex:5}),d.children(":eq("+l+")").css({left:f,display:"none",zIndex:0}),b.animationComplete(k+1),p=!1}):d.animate({left:g},b.slideSpeed,b.slideEasing,function(){d.css({left:-f}),d.children(":eq("+k+")").css({left:f,zIndex:5}),d.children(":eq("+l+")").css({left:f,display:"none",zIndex:0}),b.animationComplete(k+1),p=!1})),b.pagination&&(a("."+b.paginationClass+" li."+b.currentClass,c).removeClass(b.currentClass),a("."+b.paginationClass+" li:eq("+k+")",c).addClass(b.currentClass))}}function x(){clearInterval(c.data("interval"))}function y(){b.pause?(clearTimeout(c.data("pause")),clearInterval(c.data("interval")),u=setTimeout(function(){clearTimeout(c.data("pause")),v=setInterval(function(){w("next",i)},b.play),c.data("interval",v)},b.pause),c.data("pause",u)):x()}a("."+b.container,a(this)).children().wrapAll('<div class="slides_control"/>');var o,p,q,r,t,u,v,c=a(this),d=a(".slides_control",c),e=d.children().size(),f=d.children().outerWidth(),g=d.children().outerHeight(),h=b.start-1,i=0>b.effect.indexOf(",")?b.effect:b.effect.replace(" ","").split(",")[0],j=0>b.effect.indexOf(",")?i:b.effect.replace(" ","").split(",")[1],k=0,l=0,m=0,n=0;if(2>e)return a("."+b.container,a(this)).fadeIn(b.fadeSpeed,b.fadeEasing,function(){o=!0,b.slidesLoaded()}),a("."+b.next+", ."+b.prev).fadeOut(0),!1;if(!(2>e)){if(0>h&&(h=0),h>e&&(h=e-1),b.start&&(n=h),b.randomize&&d.randomize(),a("."+b.container,c).css({overflow:"hidden",position:"relative"}),d.children().css({position:"absolute",top:0,left:d.children().outerWidth(),zIndex:0,display:"none"}),d.css({position:"relative",width:3*f,height:g,left:-f}),a("."+b.container,c).css({display:"block"}),b.autoHeight&&(d.children().css({height:"auto"}),d.animate({height:d.children(":eq("+h+")").outerHeight()},b.autoHeightSpeed)),b.preload&&d.find("img:eq("+h+")").length){a("."+b.container,c).css({background:"url("+b.preloadImage+") no-repeat 50% 50%"});var z=d.find("img:eq("+h+")").attr("src")+"?"+(new Date).getTime();t="slides_control"!=a("img",c).parent().attr("class")?d.children(":eq(0)")[0].tagName.toLowerCase():d.find("img:eq("+h+")"),d.find("img:eq("+h+")").attr("src",z).load(function(){d.find(t+":eq("+h+")").fadeIn(b.fadeSpeed,b.fadeEasing,function(){a(this).css({zIndex:5}),a("."+b.container,c).css({background:""}),o=!0,b.slidesLoaded()})})}else d.children(":eq("+h+")").fadeIn(b.fadeSpeed,b.fadeEasing,function(){o=!0,b.slidesLoaded()});b.bigTarget&&(d.children().css({cursor:"pointer"}),d.children().on("click",function(){return w("next",i),!1})),b.hoverPause&&b.play&&(d.bind("mouseover",function(){x()}),d.bind("mouseleave",function(){y()})),b.generateNextPrev&&(a("."+b.container,c).after('<a href="#" class="'+b.prev+'">Prev</a>'),a("."+b.prev,c).after('<a href="#" class="'+b.next+'">Next</a>')),a("."+b.next,c).on("click",function(a){a.preventDefault(),b.play&&y(),w("next",i)}),a("."+b.prev,c).on("click",function(a){a.preventDefault(),b.play&&y(),w("prev",i)}),b.generatePagination?(b.prependPagination?c.prepend("<ul class="+b.paginationClass+"></ul>"):c.append("<ul class="+b.paginationClass+"></ul>"),d.children().each(function(){a("."+b.paginationClass,c).append('<li><a href="#'+m+'">'+(m+1)+"</a></li>"),m++})):a("."+b.paginationClass+" li a",c).each(function(){a(this).attr("href","#"+m),m++}),a("."+b.paginationClass+" li:eq("+h+")",c).addClass(b.currentClass),a("."+b.paginationClass+" li a",c).on("click",function(){return b.play&&y(),q=a(this).attr("href").match("[^#/]+$"),n!=q&&w("pagination",j,q),!1}),a("a.link",c).on("click",function(){return b.play&&y(),q=a(this).attr("href").match("[^#/]+$")-1,n!=q&&w("pagination",j,q),!1}),b.play&&(v=setInterval(function(){w("next",i)},b.play),c.data("interval",v))}})},a.fn.slides.option={preload:!1,preloadImage:"img/loading.gif",container:"slides_container",generateNextPrev:!1,next:"next",prev:"prev",pagination:!0,generatePagination:!0,prependPagination:!1,paginationClass:"pagination",currentClass:"current",fadeSpeed:350,fadeEasing:"",slideSpeed:350,slideEasing:"",start:1,effect:"slide",crossfade:!1,randomize:!1,play:0,pause:0,hoverPause:!1,autoHeight:!1,autoHeightSpeed:350,bigTarget:!1,animationStart:function(){},animationComplete:function(){},slidesLoaded:function(){}},a.fn.randomize=function(b){function c(){return Math.round(Math.random())-.5}return a(this).each(function(){var d=a(this),e=d.children(),f=e.length;if(f>1){e.hide();var g=[];for(i=0;f>i;i++)g[g.length]=i;g=g.sort(c),a.each(g,function(a,c){var f=e.eq(c),g=f.clone(!0);g.show().appendTo(d),void 0!==b&&b(f,g),f.remove()})}})}})(jQuery);
16  resource_monitor_visualizer/lib/rmv.rb
... ...
@@ -1,16 +0,0 @@
1  
-require "rmv/version"
2  
-require "rmv/black_hole"
3  
-require "rmv/number"
4  
-require "rmv/runner"
5  
-require "rmv/makeflow_log"
6  
-require "rmv/summary"
7  
-require "rmv/summary_collection"
8  
-require "rmv/histogram_builder"
9  
-require "rmv/options"
10  
-require "rmv/task"
11  
-require "rmv/task_collection"
12  
-require "rmv/page"
13  
-require "rmv/writer"
14  
-
15  
-module RMV
16  
-end
13  resource_monitor_visualizer/lib/rmv/black_hole.rb
... ...
@@ -1,13 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-module RMV
4  
-  class BlackHole
5  
-    def nil?
6  
-      true
7  
-    end
8  
-
9  
-    def method_missing m, *a, &b
10  
-      self
11  
-    end
12  
-  end
13  
-end
161  resource_monitor_visualizer/lib/rmv/histogram_builder.rb
... ...
@@ -1,161 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-module RMV
4  
-  class HistogramBuilder
5  
-    def initialize resources, workspace, destination, tasks
6  
-      @resources = resources
7  
-      @workspace = workspace
8  
-      @destination = destination
9  
-      @tasks = tasks
10  
-    end
11  
-
12  
-    def build sizes=[[600,600]], output=""
13  
-      groups = find_groups
14  
-      @grouped_maximums = groups.map {|g| find_maximums g}
15  
-      results = []
16  
-      @grouped_maximums.each_with_index do |g, i|
17  
-        write_maximum_values(g, i){|a,b| scale_maximum a, b}
18  
-        results.concat(format_histograms(sizes, i, groups[i]))
19  
-      end
20  
-      results
21  
-    end
22  
-
23  
-    def find_groups
24  
-      groups = []
25  
-      tasks.each do |t|
26  
-        exe = group_heuristic t
27  
-        groups << exe unless groups.include? exe
28  
-      end
29  
-      groups
30  
-    end
31  
-
32  
-    private
33  
-      attr_reader :resources, :workspace, :destination, :tasks
34  
-
35  
-      def group_heuristic task
36  
-        task.executable_name
37  
-      end
38  
-
39  
-      def find_maximums group
40  
-        max = Hash.new
41  
-        @resources.each { |r| max[r] = [] }
42  
-        tasks.each do |t|
43  
-          resources.each do |r|
44  
-            if group_heuristic(t) == group
45  
-              tmp = t.max r.to_sym
46  
-              max[r].push tmp
47  
-            end
48  
-          end
49  
-        end
50  
-        max
51  
-      end
52  
-
53  
-      def scale_maximum name, value
54  
-        case name
55  
-        when /byte/
56  
-          value.in('GB')
57  
-        when /footprint/
58  
-          value.in('GB')
59  
-        when /memory/
60  
-          value.in('MB')
61  
-        else
62  
-          value.value
63  
-        end
64  
-      end
65  
-
66  
-      def write_maximum_values maximum_list, index
67  
-        base_path = workspace + "group#{index}"
68  
-        base_path.mkpath
69  
-        maximum_list.each do |m|
70  
-          path = base_path + m.first.to_s
71  
-          File.open(path, 'w') do |f|
72  
-            m.last.each do |line|
73  
-              line = yield( m.first, line) if block_given?
74  
-              f.puts line
75  
-            end
76  
-          end
77  
-        end
78  
-      end
79  
-
80  
-      def format_histograms sizes, group, group_name
81  
-        formatted = []
82  
-        sizes.each do |s|
83  
-          width = s.first
84  
-          height = s.last
85  
-          resources.each do |r|
86  
-            formatted << gnuplot_format(width, height, r, workspace+"group#{group}"+r.to_s, group, group_name)
87  
-          end
88  
-        end
89  
-        formatted
90  
-      end
91  
-
92  
-      def gnuplot_format(width=600, height=600, resource="", data_path="/tmp", group=0, group_name="a")
93  
-        max = scale_maximum resource.to_s, @grouped_maximums[group][resource].max
94  
-        unit = case resource
95  
-        when /time/
96  
-          "s"
97  
-        when /footprint/
98  
-          "GB"
99  
-        when /byte/
100  
-          "GB"
101  
-        when /memory/
102  
-          "MB"
103  
-        else
104  
-          ""
105  
-        end
106  
-        unit = " (#{unit}) " if unit != ""
107  
-        image_path = destination + "#{group_name}"
108  
-        image_path.mkpath
109  
-        image_path += "#{resource.to_s}_#{width}x#{height}_hist.png"
110  
-        if max.to_f > 40
111  
-          binwidth = max.to_f/40
112  
-        else
113  
-          binwidth = 1
114  
-        end
115  
-        if RMV::GNUPLOT_VERSION >= 4.6
116  
-          enhanced_format width, height, resource.to_s, unit, data_path, image_path, binwidth
117  
-        else
118  
-          simple_format width, height, resource.to_s, unit, data_path, image_path, binwidth
119  
-        end
120  
-      end
121  
-
122  
-      def enhanced_format width, height, resource_name, resource_unit, data_path, image_path, binwidth
123  
-        %Q{set terminal png transparent size #{width},#{height}
124  
-        set bmargin 4
125  
-        unset key
126  
-
127  
-        set ylabel "Frequency"
128  
-        set output "#{image_path}"
129  
-        binwidth=#{binwidth}
130  
-        set boxwidth binwidth*0.9
131  
-        set style fill solid 0.5
132  
-        bin(x,width)=width*floor(x/width)
133  
-        set yrange [0:*]
134  
-        set xrange [0:*]
135  
-        set xtics right rotate by -45
136  
-        set xlabel "#{resource_name}#{resource_unit}" offset 0,-2 character
137  
-        set bmargin 7
138  
-        plot "#{data_path.to_s}" using (bin(\$1,binwidth)):(1.0) smooth freq w boxes lc rgb"#5aabbc"
139  
-        }
140  
-      end
141  
-
142  
-      def simple_format width, height, resource_name, resource_unit, data_path, image_path, binwidth
143  
-        %Q{set terminal png transparent size #{width},#{height}
144  
-        set bmargin 4
145  
-        unset key
146  
-
147  
-        set ylabel "Frequency"
148  
-        set output "#{image_path}"
149  
-        binwidth=#{binwidth}
150  
-        set boxwidth binwidth*0.9 absolute
151  
-        set style fill solid 0.5
152  
-        bin(x,width)=width*floor(x/width)
153  
-        set yrange [0:*]
154  
-        set xrange [0:*]
155  
-        set xlabel "#{resource_name}#{resource_unit}"
156  
-        plot "#{data_path.to_s}" using (bin(\$1,binwidth)):1 smooth freq w boxes
157  
-        }
158  
-      end
159  
-  end
160  
-end
161  
-
73  resource_monitor_visualizer/lib/rmv/makeflow_log.rb
... ...
@@ -1,73 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-module RMV
4  
-  class MakeflowLog
5  
-    class << self
6  
-      def from_file path
7  
-        lines = []
8  
-        path.open.each { |l| lines << l }
9  
-        data = process_lines lines
10  
-        MakeflowLog.new data
11  
-      end
12  
-
13  
-      private
14  
-        def process_lines lines
15  
-          start = find_start_time lines
16  
-          lines.map {|l| process_line l, start}.compact
17  
-        end
18  
-
19  
-        def find_start_time lines
20  
-          start = lines.select {|l| !comment?(l)}.first
21  
-          start = start.split(' ').first
22  
-          scale_time start
23  
-        end
24  
-
25  
-        def scale_time t
26  
-          t.to_f/1000000.0
27  
-        end
28  
-
29  
-        def process_line line, start
30  
-          unless comment? line
31  
-            l = line.split(' ')
32  
-            time = scale_time(l[0]) - start
33  
-            submitted = l[5..8].map{|a| a.to_i}.inject(0){|sum, n| sum + n}
34  
-            running = l[5]
35  
-            complete = l[6]
36  
-            "#{time} #{submitted} #{running} #{complete}"
37  
-          end
38  
-        end
39  
-
40  
-        def comment? line
41  
-          line.match /^#/
42  
-        end
43  
-    end
44  
-
45  
-    def initialize data
46  
-      @data = data
47  
-    end
48  
-
49  
-    def to_s
50  
-      data.join "\n"
51  
-    end
52  
-
53  
-    def gnuplot_format(width=1250, height=500, data_path="/tmp", output_path="")
54  
-      %Q{set terminal png transparent size #{width},#{height}
55  
-      set bmargin 4
56  
-      set key ins left top
57  
-      set xlabel "Time (seconds)" offset 0,-2 character
58  
-      set ylabel "Number of Jobs" offset 0,-2 character
59  
-      set output "#{output_path + 'makeflowlog'}_#{width}x#{height}.png"
60  
-      set xrange [0:*]
61  
-      set yrange [0:*]
62  
-      set xtics right rotate by -45
63  
-      set bmargin 7
64  
-      plot "#{data_path.to_s}" using 1:2 title "submitted" w lines lw 5 lc rgb"#465510", "" using 1:3 title "running" w lines lw 5 lc rgb"#BA6F2E", "" using 1:4 title "complete" w lines lw 5 lc rgb"#AA272F"
65  
-      }
66  
-    end
67  
-
68  
-    private
69  
-      def data
70  
-        @data
71  
-      end
72  
-  end
73  
-end
67  resource_monitor_visualizer/lib/rmv/number.rb
... ...
@@ -1,67 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-module RMV
4  
-  class Number
5  
-    attr_reader :value, :unit
6  
-
7  
-    def initialize value, unit
8  
-      @value = value.to_f
9  
-      if unit.to_s.length == 2
10  
-        @unit = unit
11  
-      else
12  
-        @unit = ""
13  
-      end
14  
-    end
15  
-
16  
-    def to_f
17  
-      value.to_f
18  
-    end
19  
-
20  
-    def <=> other
21  
-      value <=> other.value
22  
-    end
23  
-
24  
-    def < other
25  
-      value < other.value
26  
-    end
27  
-
28  
-    def prefix
29  
-      unit[0]
30  
-    end
31  
-
32  
-    def base_value
33  
-      case prefix
34  
-      when 'u'
35  
-        value * 10**(-6)
36  
-      when 'K'
37  
-        value * 1024
38  
-      when 'M'
39  
-        value * 1024**2
40  
-      when 'G'
41  
-        value * 1024**3
42  
-      when 'T'
43  
-        value * 1024**4
44  
-      else
45  
-        value
46  
-      end
47  
-    end
48  
-
49  
-    def in new_unit
50  
-      new_prefix = new_unit.to_s[0]
51  
-      case new_prefix
52  
-      when 'u'
53  
-        base_value * 10**6
54  
-      when 'K'
55  
-        base_value / 1024.0
56  
-      when 'M'
57  
-        base_value / 1024.0**2
58  
-      when 'G'
59  
-        base_value / 1024.0**3
60  
-      when 'T'
61  
-        base_value / 1024.0**4
62  
-      else
63  
-        value
64  
-      end
65  
-    end
66  
-  end
67  
-end
67  resource_monitor_visualizer/lib/rmv/options.rb
... ...
@@ -1,67 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-require 'optparse'
4  
-require 'pathname'
5  
-
6  
-module RMV
7  
-  class Options
8  
-
9  
-    def initialize argv
10  
-      @config = {:source => nil,
11  
-                 :debug => false,
12  
-                 :destination => nil,
13  
-                 :name => "",
14  
-                 :overwrite => false,
15  
-                 :workspace => Pathname.new("/tmp/rmv")}
16  
-      parse argv
17  
-      mandatory = [:source, :destination]
18  
-      missing = mandatory.select { |param| config[param].nil? }
19  
-      unless missing.empty?
20  
-        STDERR.puts "Missing options: #{missing.join(', ')}"
21  
-        exit -1
22  
-      end
23  
-    end
24  
-
25  
-    def method_missing m, *a, &b
26  
-      @config.fetch(m){ super }
27  
-    end
28  
-
29  
-    def parse argv
30  
-      OptionParser.new do |opts|
31  
-        opts.banner = "Usage:    rmv [options] "
32  
-        opts.on("-D", "--debug", "Keep intermediate files and produce more verbose output") do
33  
-          config[:debug] = true
34  
-        end
35  
-        opts.on("-d", "--destination path", String, "Directory in which to place the output") do |d|
36  
-          config[:destination] = Pathname.new(d).expand_path
37  
-        end
38  
-        opts.on("-h", "--help", "Show this message") do
39  
-          puts opts
40  
-          exit
41  
-        end
42  
-        opts.on("-n", "--name name", String, "Set the name of the workflow") do |n|
43  
-          config[:name] = n
44  
-        end
45  
-        opts.on("-o", "--overwrite", String, "Overwrite existing output files") { config[:overwrite] = true }
46  
-        opts.on("-s", "--source path", String, "Directory to the log files for visualizing") do |s|
47  
-          config[:source] = Pathname.new(s).expand_path
48  
-        end
49  
-        opts.on("-w", "--workspace path", String, "Directory for storing temporary files. Default: /tmp/rmv") do
50  
-          config[:workspace] = Pathname.new(w).expand_path
51  
-        end
52  
-
53  
-        begin
54  
-          argv = ["-h"] if argv.empty?
55  
-          opts.parse! argv
56  
-        rescue OptionParser::ParseError => e
57  
-          STDERR.puts e.message, "\n", opts
58  
-          exit(-1)
59  
-        end
60  
-      end
61  
-    end
62  
-
63  
-    private
64  
-      attr_accessor :config
65  
-  end
66  
-end
67  
-
46  resource_monitor_visualizer/lib/rmv/page.rb
... ...
@@ -1,46 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-module RMV
4  
-  class Page
5  
-    def initialize title="", base_path="/"
6  
-      @title = title
7  
-      @base = Pathname.new base_path
8  
-      @content = ""
9  
-      @path = ""
10  
-    end
11  
-
12  
-    def to_s
13  
-      header << content << footer
14  
-    end
15  
-
16  
-    def << s
17  
-      @content << s
18  
-    end
19  
-
20  
-    def path= path
21  
-      path = Pathname.new path
22  
-      @path = base.relative_path_from path
23  
-    end
24  
-
25  
-    def base= path
26  
-      @base = Pathname.new path
27  
-    end
28  
-
29  
-    private
30  
-      attr_reader :title, :content, :base
31  
-
32  
-      def header
33  
-        %Q{<!doctype html>
34  
-           <meta name="viewport" content="initial-scale=1.0, width=device-width" />
35  
-           <link rel="stylesheet" type="text/css" media="screen, projection" href="#{@path}/css/style.css" />
36  
-           <title>#{title}</title>
37  
-
38  
-           <div class="content">
39  
-        }
40  
-      end
41  
-
42  
-      def footer
43  
-        %Q{ </div> }
44  
-      end
45  
-  end
46  
-end
400  resource_monitor_visualizer/lib/rmv/runner.rb
... ...
@@ -1,400 +0,0 @@
1  
-require 'rmv'
2  
-
3  
-require 'pathname'
4  
-require 'yaml'
5  
-require 'open3'
6  
-
7  
-module RMV
8  
-  class Runner
9  
-    attr_reader :debug, :source, :overwrite, :time_series, :resources, :workspace, :name, :tasks, :writer
10  
-
11  
-    def initialize argv
12  
-      options = Options.new argv
13  
-      process_arguments options
14  
-      initialize_writers
15  
-    end
16  
-
17  
-    def run
18  
-      find_files
19  
-      find_resources
20  
-      create_histograms
21  
-      create_group_resource_summaries
22  
-      make_combined_time_series
23  
-      @makeflow_log_exists = plot_makeflow_log source + 'Makeflow.makeflowlog'
24  
-      make_index [[1250,500]], [[600,600],[250,250]]
25  
-      copy_static_files
26  
-      remove_temp_files unless debug
27  
-    end
28  
-
29  
-    private
30  
-      def remove_temp_files
31  
-        `rm -rf #{workspace}`
32  
-      end
33  
-
34  
-      def initialize_writers
35  
-        @destination_writer = Writer.new @destination, overwrite
36  
-        @workspace_writer = Writer.new workspace, overwrite
37  
-      end
38  
-
39  
-      def make_directories
40  
-        @groups.each do |g|
41  
-          resources.each { |r| (@destination + "#{g}" + "#{r}").mkpath }
42  
-        end
43  
-      end
44  
-
45  
-      def create_group_resource_summaries histogram_size=[600,600]
46  
-        make_directories
47  
-        @groups.each do |g|
48  
-          @resources.each do |r|
49  
-            page = Page.new "#{name} Workflow"
50  
-            page << <<-INDEX
51  
-            <h1><a href="../../index.html">#{name}</a> - #{g} - #{r}</h1>
52  
-            <img src="../#{r.to_s}_#{histogram_size.first}x#{histogram_size.last}_hist.png" class="center" />
53  
-            <table>
54  
-            <tr><th>Rule Id</th><th>Maximum #{r}</th></tr>
55  
-            INDEX
56  
-
57  
-            tasks.select{ |t| t.executable_name == g }.sort_by{ |t| t.grab r }.each do |t|
58  
-              rule_path = "#{g}/#{t.rule_id}.html"
59  
-              create_rule_page t, rule_path
60  
-
61  
-              unit = case r
62  
-                     when /time/
63  
-                       "s"
64  
-                     when /bytes/
65  
-                       "GB"
66  
-                     when /footprint/
67  
-                       "GB"
68  
-                     when /memory/
69  
-                       "MB"
70  
-                     else
71  
-                       ""
72  
-                     end
73  
-              scaled_resource = t.grab(r).in(unit)
74  
-              page << "<tr><td><a href=\"../#{t.rule_id}.html\">#{t.rule_id}</a></td><td>#{(scaled_resource*1000).round/1000.0}</td></tr>\n"
75  
-            end
76  
-
77  
-            page << "</table>\n"
78  
-
79  
-            write "#{g}/#{r}/index.html", page
80  
-          end
81  
-        end
82  
-      end
83  
-
84  
-      def write path, content, location=:destination
85  
-        case location
86  
-        when :destination
87  
-          @destination_writer.file path, content
88  
-        when :workspace
89  
-          @workspace_writer.file path, content
90  
-        else
91  
-          STDERR.puts "Cannot write to #{location}."
92  
-        end
93  
-      end
94  
-
95  
-      def run_if_not_exist path
96  
-        yield if overwrite or !path.exist?
97  
-      end
98  
-
99