utils/flowmon/bench-all.py
author Gustavo J. A. M. Carneiro <gjc@inescporto.pt>
Mon, 04 May 2009 18:35:43 +0100
changeset 3949 6304adcb5326
child 3976 d875e681c296
permissions -rw-r--r--
FlowMonitor benchmarking scripts

import subprocess
import sys
import resource
from optparse import OptionParser
import time
import re
import tempfile
import os
from xml.dom import minidom

DATA_LIMIT = None
CPU_LIMIT = None



def run_sim(args):
    argv = ['python', 'flowmon-bench.py'] + args

    results_fname = tempfile.mktemp(prefix='results', suffix='.xml')
    argv.append("--Results=%s" % results_fname)

    print >> sys.stderr, "popen ", repr(argv)
    start_time = time.time()

    def preexec_fn(*dummy_args):
        resource.setrlimit(resource.RLIMIT_DATA, (DATA_LIMIT, -1))
        resource.setrlimit(resource.RLIMIT_AS, (DATA_LIMIT, -1))
        resource.setrlimit(resource.RLIMIT_CPU, (CPU_LIMIT, -1))
    proc = subprocess.Popen(argv, preexec_fn=preexec_fn)
    max_mem = 0
    while 1:
        if proc.poll() is not None:
            break
        time.sleep(1.0)
        mem = int(open("/proc/%i/statm" % proc.pid, "rt").read().split()[0])*4
        if mem > max_mem:
            max_mem = mem
    retval = proc.wait()
    end_time = time.time()

    if retval:
        raise RuntimeError("Simulation exited with code %i.\t" % (retval,))

    if os.path.exists(results_fname):
        results = minidom.parse(results_fname)
        os.unlink(results_fname)
    else:
        results = None
    
    return max_mem, (end_time - start_time), results


def main():

    parser = OptionParser()
    parser.add_option("-j", None, dest="concurrency", default="2",
                      help="Number of tasks to run in parallel")
    parser.add_option("-c", "--cpu-limit", dest="cpu_limit", default="5",
                      help="CPU limit, in hours")
    parser.add_option("-m", "--memory-limit", dest="mem_limit", default="detect",
                      help="Memory limit, total, in GigaBytes.  "
                      "Actual per-process memory limit will be this value divided"
                      " by the concurrency level setting.")
    parser.add_option("-s", "--stop-time", dest="stop_time", default="300",
                      help="Simulation stop time (s)")
    (options, args) = parser.parse_args()

    global CPU_LIMIT, DATA_LIMIT
    CPU_LIMIT = long(float(options.cpu_limit)*60*60)

    if options.mem_limit == 'detect':
        for line in file("/proc/meminfo"):
            m = re.match("MemTotal:\s+(\d+) kB", line)
            if m:
                DATA_LIMIT = 1024*long(m.group(1))
                print >> sys.stderr, "Detected DATA_LIMIT = ", DATA_LIMIT, "(%s GiB)" % (DATA_LIMIT/1024.0/1024.0/1024.0)
                break
        else:
            print >> sys.stderr, "Could not detect DATA_LIMIT => fallback to 512 MB."
            DATA_LIMIT = long(float(0.5)*1024*1024*1024)
    else:
        DATA_LIMIT = long(float(options.mem_limit)*1024*1024*1024)
    DATA_LIMIT /= int(int(options.concurrency)*1.25)
    print >> sys.stderr, "Per-process data limit: %.3f GiB (%r)" % (DATA_LIMIT/1024.0/1024.0/1024.0, DATA_LIMIT)

    newdoc = minidom.getDOMImplementation().createDocument(None, "flowmon-bench-results", None)
    results_root_el = newdoc.documentElement

    for num_nodes_side in range(2,11):
        for run_number in range(10):
            for enable_monitor in [False, True]:
                args = ["--NumNodesSide=%i" % num_nodes_side,
                        "--RunNumber=%i" % run_number,
                        "--EnableMonitor=%i" % enable_monitor,
                        "--StopTime=%s" % options.stop_time,
                        ]
                max_mem, duration, results = run_sim(args)
                simulation_el = results_root_el.appendChild(newdoc.createElement('simulation'))

                simulation_el.setAttribute("num-nodes-side", str(num_nodes_side))
                simulation_el.setAttribute("run-number", str(run_number))
                simulation_el.setAttribute("enable-monitor", str(enable_monitor))
                simulation_el.setAttribute("max-memory", str(max_mem))
                simulation_el.setAttribute("cpu-time", str(duration))

                if enable_monitor:
                    simulation_el.appendChild(results.documentElement.cloneNode(True))

    out = open("results.xml", "wt")
    newdoc.writexml(out, addindent='  ', newl='\n', encoding='utf-8')
    out.close()



if __name__ == '__main__':
    main()