Setup


In [1]:
from tabulate import tabulate
import pandas as pd
from pathlib import Path
import json
import os
import altair as alt
from collections import defaultdict
from IPython.core.display import display, HTML
# alt.renderers.enable('html')

import matplotlib.pyplot as plt
%matplotlib inline
plt.style.use('ggplot')

In [2]:
VERSION = '0.4.1'  # before tf.function compatibility
VERSION = '0.5.0'  # after tf.function compatibility which cripple the perf currently
def load_benchmark_results(VERSION):
    tables = defaultdict(lambda: defaultdict(dict))
    res_dir = 'results/%s' % VERSION
    results = []
    for fname in Path(res_dir).glob('*.json'):
        for l in open(fname):
            d = json.loads(l)
            res = {}
            # flattenning
            for k, v in d.items():
                if k == 'timings':
                    for tn, tv in v.items():
                        if tn == 'raw':
                            continue
                        name = '%s_time' % (tn)
                        res[name] = tv
                else:
                        res[k] = v
            res['shape_str'] = "x".join([str(x) for x in d['shape']])
            res['test_name'] = "%s%s" % (d['group'], d['name'])

            tables[res['test_name']][res['shape_str']][res['backend']] = res['avg_time']

            results.append(res)
    return pd.DataFrame(results), tables
df, tables = load_benchmark_results(VERSION)
df.head()


Out[2]:
avg_time backend evoflow_version generations group input_size max_time min_time name num_runs shape shape_str std_time system test_name test_type ts
0 0.002992 cupy 0.5.0 10 Shuffle 10000 0.006981 0.000997 1D 3 [100, 100] 100x100 0.002821 {'os': {'name': 'Windows', 'version': '10.0.18... Shuffle1D OP 1590449607
1 0.003657 cupy 0.5.0 10 RandomMutation 10000 0.007978 0.000998 1D 3 [100, 100] 100x100 0.003083 {'os': {'name': 'Windows', 'version': '10.0.18... RandomMutation1D OP 1590449607
2 0.051196 cupy 0.5.0 10 UniformCrossover 10000 0.149600 0.001995 1D 3 [100, 100] 100x100 0.069582 {'os': {'name': 'Windows', 'version': '10.0.18... UniformCrossover1D OP 1590449607
3 0.001330 cupy 0.5.0 10 SingleCrossover 10000 0.001995 0.000997 1D 3 [100, 100] 100x100 0.000470 {'os': {'name': 'Windows', 'version': '10.0.18... SingleCrossover1D OP 1590449607
4 0.002659 cupy 0.5.0 10 DualCrossover 10000 0.003989 0.001994 1D 3 [100, 100] 100x100 0.000940 {'os': {'name': 'Windows', 'version': '10.0.18... DualCrossover1D OP 1590449607

In [ ]:


In [3]:
def htmlout(data):
    display(HTML(data))

def display_table(group_name):
    BACKENDS = ['numpy', 'tensorflow-cpu', 'tensorflow-gpu', 'cupy']
    headers = ['shape', 'numpy', 'tf-cpu', 'tf-gpu', 'cupy' ]
    # htmlout('<h3>%s</h3>' % group_name)
    for dim in ['1D', '2D', '3D']:
        prob_name = group_name + dim
        if prob_name in tables:
            raw = tables[prob_name]
            rows = []
            for shape, data in tables[prob_name].items():
                row = [shape]
                baseline = data['numpy']
                for b in  BACKENDS:
                    ts  = round(data[b], 3)
                    perf = round(baseline / (data[b] + 0.000001), 2)
                    val = "%s (%.2fx)" % (ts, perf)
                    row.append(val)
                rows.append(row)
            htmlout('<br/><b>%s</b>' % dim)
            htmlout(tabulate(rows, headers=headers, tablefmt='html'))

In [4]:
def display_chart(group_name):
    data = df[df['group']==group_name].sort_values('input_size')
    chart = alt.Chart(data, title='').mark_bar().encode(
            x=alt.X('backend', axis=alt.Axis(title='')), 
            y=alt.Y('avg_time', sort='-x', axis=alt.Axis(title='')),
            color=alt.Color('backend', legend=None), 
            column=alt.Column('shape_str', title='', sort=alt.EncodingSortField(field='input_size', order='ascending'))
            ).resolve_scale(y='independent')
    chart = chart.facet(column='name', spacing=50, title=group_name).configure_title(fontSize=20, offset=5, orient='top', anchor='middle')
    return chart

End to End problems


In [5]:
display_chart('OneMax')


Out[5]:

In [6]:
display_table('OneMax')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.01 (1.00x) 1.539 (0.01x) 1.534 (0.01x) 0.043 (0.24x)
100x1000 0.036 (1.00x)12.675 (0.00x) 11.663 (0.00x) 0.039 (0.94x)
1000x10000.359 (1.00x)117.155 (0.00x)139.118 (0.00x)0.04 (8.96x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.01 (1.00x) 1.77 (0.01x) 1.772 (0.01x) 0.056 (0.18x)
100x100x10 0.027 (1.00x)14.372 (0.00x)13.745 (0.00x)0.055 (0.49x)
100x100x1000.415 (1.00x)82.772 (0.01x)93.053 (0.00x)0.065 (6.41x)

In [7]:
display_chart('TSP')


Out[7]:

In [8]:
display_table('TSP')



1D
shape numpy tf-cpu tf-gpu cupy
50x10 0.013 (1.00x)2.308 (0.01x) 3.257 (0.00x) 0.093 (0.14x)
250x50 0.031 (1.00x)11.5 (0.00x) 33.499 (0.00x) 0.152 (0.21x)
500x100 0.057 (1.00x)26.079 (0.00x)102.721 (0.00x)0.198 (0.29x)
1000x2000.155 (1.00x)62.35 (0.00x) 411.515 (0.00x)0.165 (0.94x)

Evolution OPs


In [9]:
display_chart('RandomMutation')


Out[9]:

In [10]:
display_table('RandomMutation')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.0 (1.00x) 0.101 (0.00x)0.125 (0.00x) 0.004 (0.09x)
100x1000 0.002 (1.00x)1.539 (0.00x)1.232 (0.00x) 0.001 (1.25x)
1000x10000.011 (1.00x)7.816 (0.00x)14.655 (0.00x)0.001 (8.49x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.0 (1.00x) 0.135 (0.00x)0.102 (0.00x)0.003 (0.11x)
100x100x10 0.001 (1.00x)2.05 (0.00x) 1.117 (0.00x)0.002 (0.43x)
100x100x1000.014 (1.00x)8.921 (0.00x)4.501 (0.00x)0.003 (4.67x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.001 (1.00x)0.582 (0.00x) 0.428 (0.00x) 0.003 (0.40x)
100x100x10x10 0.011 (1.00x)1.934 (0.01x) 4.925 (0.00x) 0.004 (3.00x)
100x100x100x100.174 (1.00x)63.999 (0.00x)12.225 (0.01x)0.005 (37.39x)

In [11]:
display_chart('UniformCrossover')


Out[11]:

In [12]:
display_table('UniformCrossover')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.001 (1.00x)0.06 (0.01x) 0.038 (0.02x)0.051 (0.01x)
100x1000 0.002 (1.00x)0.492 (0.00x)0.268 (0.01x)0.002 (1.00x)
1000x10000.018 (1.00x)3.326 (0.01x)4.011 (0.00x)0.002 (10.79x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.001 (1.00x)0.047 (0.01x)0.062 (0.01x)0.002 (0.29x)
100x100x10 0.002 (1.00x)0.294 (0.01x)0.276 (0.01x)0.003 (0.59x)
100x100x1000.02 (1.00x) 2.171 (0.01x)2.129 (0.01x)0.003 (7.44x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.001 (1.00x)0.073 (0.02x)0.062 (0.02x)0.003 (0.44x)
100x100x10x10 0.017 (1.00x)0.637 (0.03x)0.464 (0.04x)0.004 (3.92x)
100x100x100x100.236 (1.00x)1.332 (0.18x)5.285 (0.04x)0.007 (33.81x)

In [13]:
display_chart('SingleCrossover')


Out[13]:

In [14]:
display_table('SingleCrossover')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.0 (1.00x) 0.025 (0.01x)0.03 (0.01x) 0.001 (0.25x)
100x1000 0.0 (1.00x) 0.442 (0.00x)0.283 (0.00x)0.001 (0.33x)
1000x10000.003 (1.00x)4.292 (0.00x)2.658 (0.00x)0.001 (2.25x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.001 (1.00x)0.067 (0.01x)0.053 (0.01x)0.002 (0.33x)
100x100x10 0.0 (1.00x) 0.245 (0.00x)0.256 (0.00x)0.002 (0.20x)
100x100x1000.002 (1.00x)0.551 (0.00x)1.376 (0.00x)0.002 (1.00x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.0 (1.00x) 0.078 (0.00x)0.066 (0.01x)0.002 (0.17x)
100x100x10x10 0.002 (1.00x)0.766 (0.00x)0.348 (0.01x)0.002 (1.00x)
100x100x100x100.022 (1.00x)5.964 (0.00x)3.775 (0.01x)0.003 (7.39x)

In [15]:
display_chart('DualCrossover')


Out[15]:

In [16]:
display_table('DualCrossover')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.0 (1.00x) 3.648 (0.00x) 4.085 (0.00x) 0.003 (0.12x)
100x1000 0.001 (1.00x)3.548 (0.00x) 7.432 (0.00x) 0.001 (0.67x)
1000x10000.003 (1.00x)37.285 (0.00x)67.295 (0.00x)0.001 (2.50x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.0 (1.00x) 0.163 (0.00x)0.363 (0.00x)0.003 (0.12x)
100x100x10 0.0 (1.00x) 0.175 (0.00x)1.516 (0.00x)0.003 (0.11x)
100x100x1000.002 (1.00x)0.21 (0.01x) 4.948 (0.00x)0.004 (0.50x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.001 (1.00x)0.213 (0.00x)0.627 (0.00x)0.003 (0.20x)
100x100x10x10 0.003 (1.00x)0.305 (0.01x)2.287 (0.00x)0.004 (0.73x)
100x100x100x100.022 (1.00x)1.153 (0.02x)7.267 (0.00x)0.005 (4.40x)

In [17]:
display_chart('Reverse')


Out[17]:

In [18]:
display_table('Reverse')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.001 (1.00x)3.604 (0.00x) 3.991 (0.00x) 0.002 (0.25x)
100x1000 0.0 (1.00x) 3.404 (0.00x) 9.073 (0.00x) 0.002 (0.20x)
1000x10000.002 (1.00x)39.884 (0.00x)86.923 (0.00x)0.001 (1.25x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.0 (1.00x) 0.171 (0.00x)0.434 (0.00x)0.002 (0.14x)
100x100x10 0.0 (1.00x) 0.214 (0.00x)1.407 (0.00x)0.004 (0.09x)
100x100x1000.001 (1.00x)0.255 (0.00x)2.592 (0.00x)0.003 (0.20x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.0 (1.00x) 0.24 (0.00x) 0.785 (0.00x)0.004 (0.08x)
100x100x10x10 0.001 (1.00x)0.34 (0.00x) 2.628 (0.00x)0.004 (0.25x)
100x100x100x100.006 (1.00x)0.619 (0.01x)6.48 (0.00x) 0.005 (1.24x)

In [19]:
display_chart('Shuffle')


Out[19]:

In [20]:
display_table('Shuffle')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.001 (1.00x)0.466 (0.00x)0.491 (0.00x)0.003 (0.22x)
100x1000 0.001 (1.00x)0.296 (0.00x)0.303 (0.00x)0.001 (1.00x)
1000x10000.008 (1.00x)0.279 (0.03x)0.334 (0.02x)0.002 (4.16x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.001 (1.00x)0.432 (0.00x)0.433 (0.00x)0.002 (0.33x)
100x100x10 0.001 (1.00x)0.404 (0.00x)0.421 (0.00x)0.001 (0.75x)
100x100x1000.01 (1.00x) 0.357 (0.03x)0.41 (0.02x) 0.002 (6.00x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.001 (1.00x)0.585 (0.00x)0.5 (0.00x) 0.002 (0.60x)
100x100x10x10 0.007 (1.00x)0.522 (0.01x)0.5 (0.01x) 0.002 (4.40x)
100x100x100x100.153 (1.00x)0.516 (0.30x)0.488 (0.31x)0.003 (50.98x)

Other


In [21]:
display_chart('Fittest')


Out[21]:

In [22]:
display_table('Shuffle')



1D
shape numpy tf-cpu tf-gpu cupy
100x100 0.001 (1.00x)0.466 (0.00x)0.491 (0.00x)0.003 (0.22x)
100x1000 0.001 (1.00x)0.296 (0.00x)0.303 (0.00x)0.001 (1.00x)
1000x10000.008 (1.00x)0.279 (0.03x)0.334 (0.02x)0.002 (4.16x)

2D
shape numpy tf-cpu tf-gpu cupy
100x10x10 0.001 (1.00x)0.432 (0.00x)0.433 (0.00x)0.002 (0.33x)
100x100x10 0.001 (1.00x)0.404 (0.00x)0.421 (0.00x)0.001 (0.75x)
100x100x1000.01 (1.00x) 0.357 (0.03x)0.41 (0.02x) 0.002 (6.00x)

3D
shape numpy tf-cpu tf-gpu cupy
100x10x10x10 0.001 (1.00x)0.585 (0.00x)0.5 (0.00x) 0.002 (0.60x)
100x100x10x10 0.007 (1.00x)0.522 (0.01x)0.5 (0.01x) 0.002 (4.40x)
100x100x100x100.153 (1.00x)0.516 (0.30x)0.488 (0.31x)0.003 (50.98x)

In [23]:
sorted(set(df[df['test_type']=='Selection']['group']))


Out[23]:
['Fittest']