File: performance_comparison.py

package info (click to toggle)
compyle 0.8.1-11
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,100 kB
  • sloc: python: 12,337; makefile: 21
file content (144 lines) | stat: -rw-r--r-- 4,683 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import numpy as np
import time
import md_simple
import md_nnps

from compyle.config import get_config


def solve(n, backend, solver_algo, tf=0.5, dt=0.02, use_count_sort=False):
    solver = solver_algo(n, backend=backend.replace("_omp", ""))
    start = time.time()
    solver.solve(tf, dt)
    end = time.time()
    print("Time taken for backend = %s, N = %i is %g secs" %
          (backend, n, (end - start)))
    return end - start


def compare(backends, n_list, solver_algo, niter=3):
    t_list = {b: [] for b in backends}
    speedups = {b: [] for b in backends}
    for n in n_list:
        print("Running for N = %i" % n)
        for backend in backends:
            if "omp" in backend:
                get_config().use_openmp = True
            t = 1e9
            for it in range(niter):
                t = min(t, solve(n, backend, solver_algo))
            t_list[backend].append(t)
            if "omp" in backend:
                get_config().use_openmp = False

    if 'cython' in backends:
        for backend in backends:
            for i, n in enumerate(n_list):
                speedups[backend].append(
                    t_list["cython"][i] / t_list[backend][i])
    else:
        speedups = None

    return speedups, t_list


def compare_implementations(backend, n_list, niter=3):
    import matplotlib.pyplot as plt
    sp, nnps_tlist = compare([backend], n_list,
                             md_nnps.MDSolver, niter=niter)
    sp, simple_tlist = compare([backend], n_list,
                               md_simple.MDSolver, niter=niter)

    speedup = [simple_tlist[backend][i] / nnps_tlist[backend][i]
               for i in range(len(n_list))]

    plt.loglog(n_list, nnps_tlist[backend], 'x-', label="Linear")
    plt.loglog(n_list, simple_tlist[backend], 'x-', label="Simple")

    plt.xlabel("Number of particles")
    plt.ylabel("Time (secs)")
    plt.legend()
    plt.grid(True)
    plt.savefig("time_comp_impl.png", dpi=300)

    plt.clf()

    plt.loglog(n_list, speedup, 'x-')

    plt.xlabel("Number of particles")
    plt.ylabel("Speedup")
    plt.grid(True)
    plt.savefig("speedup_comp_impl.png", dpi=300)


def plot(n_list, speedups, t_list, label):
    backend_label_map = {'cython': 'Cython', 'cython_omp': 'OpenMP',
                         'opencl': 'OpenCL', 'cuda': 'CUDA'}
    import matplotlib.pyplot as plt
    plt.figure()

    if speedups:
        for backend, arr in speedups.items():
            if backend == "cython":
                continue
            plt.semilogx(n_list, arr, 'x-', label=backend_label_map[backend])

        plt.xlabel("Number of particles")
        plt.ylabel("Speedup")
        plt.legend()
        plt.grid(True)
        plt.savefig("%s_speedup_%s.png" %
                    (label, "_".join(speedups.keys())), dpi=300)

    plt.clf()

    for backend, arr in t_list.items():
        plt.loglog(n_list, arr, 'x-', label=backend_label_map[backend])

    plt.xlabel("Number of particles")
    plt.ylabel("Time (secs)")
    plt.legend()
    plt.grid(True)
    plt.savefig("%s_time_%s.png" % (label, "_".join(t_list.keys())), dpi=300)


if __name__ == "__main__":
    from argparse import ArgumentParser
    p = ArgumentParser()
    p.add_argument(
        '-c', '--comparison', action='store', dest='comp', default='gpu_comp',
        choices=['gpu_comp', 'omp_comp', 'comp_algo'],
        help='Choose the comparison.'
    )
    p.add_argument(
        '--nnps', action='store', dest='nnps', default='linear',
        choices=['linear', 'simple'],
        help='Choose algorithm.'
    )
    p.add_argument(
        '--use-double', action='store_true', dest='use_double',
        default=False,  help='Use double precision on the GPU.'
    )

    o = p.parse_args()
    get_config().use_double = o.use_double
    solver_algo = (md_nnps.MDNNPSSolver if o.nnps == 'linear'
                   else md_simple.MDSolver)
    n_list = [10000 * (2 ** i) for i in range(10)] if o.nnps == 'linear' else \
        [500 * (2 ** i) for i in range(8)]

    if o.comp == "gpu_comp":
        backends = ["opencl", "cuda", "cython"]
        print("Running for", n_list)
        speedups, t_list = compare(backends, n_list, solver_algo)
        plot(n_list, speedups, t_list, o.nnps)
    elif o.comp == "omp_comp":
        backends = ["cython_omp", "cython"]
        print("Running for", n_list)
        speedups, t_list = compare(backends, n_list, solver_algo)
        plot(n_list, speedups, t_list, o.nnps)
    elif o.comp == "comp_algo":
        backend = "cython"
        n_list = [500, 1000, 2000, 4000, 8000, 16000, 32000]
        print("Running for", n_list)
        compare_implementations(backend, n_list)