Source

cexp / run / plotbm_constinloop.py

import os
import numpy
from numpy.testing import assert_equal
import pylab
try:
    import cPickle as pickle
except:
    import pickle

from benchmark.benchmark import benchmark, mkdirp
from cexp.hgutils import getid


def benchmark_varying_repeat(repeat_base, repeat_expmax,
                             iter_num=10, global_kwds=''):
    list_repeat = int(repeat_base) ** numpy.arange(int(repeat_expmax))
    kwds_list = [
        'method="%s", repeat=%d' % (method, repeat)
        for method in ['with_const', 'without_const']
        for repeat in list_repeat
        ]

    data= benchmark(
        'cexp.bm_constinloop', 'run', kwds_list, global_kwds, iter_num)
    data.update(hg_rev=getid())
    return data


def fig_benchmark(data):
    fig = pylab.figure()
    kwds_time = data['kwds_time']
    ekwds_list = [eval('dict(%s)' % k) for k in data['kwds_list']]
    method_list = ['with_const', 'without_const']
    color_list = ['b', 'r']
    marker_list = ['+', 'x']

    def gather_time(method):
        return numpy.array([
            kwds_time[k] for (e, k) in zip(ekwds_list, data['kwds_list'])
            if e['method'] == method])

    def gather_repeat(method):
        return numpy.array(
            [e['repeat'] for e in ekwds_list if e['method'] == method])

    time = [gather_time(method) for method in method_list]
    repeat = [gather_repeat(method) for method in method_list]
    repeat0 = repeat[0]
    repeat1 = repeat[1]
    assert_equal(repeat0, repeat1)
    time_mean = [t.mean(axis=1) for t in time]
    time_min = [t.min(axis=1) for t in time]
    time_all_mean = numpy.concatenate(time, axis=1).mean(axis=1)

    pylab.subplot(211)
    for (i, method) in enumerate(method_list):
        for j in range(time[i].shape[1]):
            pylab.semilogx(
                repeat0, time[i][:,j] / time_all_mean, marker_list[i],
                color=color_list[i], markersize=12)
        pylab.semilogx(repeat0, time_mean[i] / time_all_mean, '-',
                       label=method, color=color_list[i])
    # draw horizontal line
    (xmin, xmax) = pylab.xlim()
    pylab.hlines(1, xmin, xmax, label="_nolegend_")
    pylab.xlim(xmin, xmax)
    # modify ymin
    (ymin, ymax) = pylab.ylim()
    pylab.ylim(ymin=1 - (1 - ymin) * 1.5)
    #
    pylab.legend(loc='best')
    pylab.ylabel('normalized time')

    pylab.subplot(212)
    pylab.semilogx(repeat0, time_mean[0] / time_mean[1], label='mean')
    pylab.semilogx(repeat0, time_min[0] / time_min[1], label='min')
    pylab.legend(loc='best')
    pylab.ylabel('%s / %s' % tuple(method_list))
    pylab.xlabel('repeat')

    data['datestr'] = data['date'].strftime('%Y-%m-%d %H:%M:%S')
    pylab.suptitle(
        'constinloop: kwds="%(global_kwds)s"'
        ' @%(node)s %(datestr)s (%(hg_rev)s)' % data)

    return fig


def main(datadir, repeat_base, repeat_expmax, iter_num, global_kwds):
    mkdirp(datadir)
    datapath = os.path.join(datadir, 'plotbm.pickle')
    figpath = os.path.join(datadir, 'plotbm.png')
    data = benchmark_varying_repeat(
        repeat_base, repeat_expmax, iter_num, global_kwds)
    fig = fig_benchmark(data)
    fig.savefig(figpath)
    pickle.dump(data, file(datapath, 'w'))
    print "saved to", datadir


if __name__ == '__main__':
    from optparse import OptionParser
    datadir_default = "Data/plotbm_constinloop"
    parser = OptionParser()
    parser.add_option("-d", "--datadir", default=None,
                      help=('if this starts with "+", it will be appended'
                            ' to the base directory "%s"' % datadir_default))
    parser.add_option("--repeat_base", default=4, type=int)
    parser.add_option("--repeat_expmax", default=5, type=int)
    parser.add_option("--iter_num", default=10, type=int)
    parser.add_option("--global_kwds", default='')

    (opts, args) = parser.parse_args()
    if opts.datadir is None:
        datadir = os.path.join(datadir_default, 'default')
    elif opts.datadir.startswith('+'):
        datadir = os.path.join(datadir_default, opts.datadir[1:])
    else:
        datadir = opts.datadir

    main(datadir, opts.repeat_base, opts.repeat_expmax,
         opts.iter_num, opts.global_kwds)