Skip to content

Commit 37acccb

Browse files
committed
Add numba-udf bench
1 parent 55b9d0a commit 37acccb

File tree

1 file changed

+108
-0
lines changed

1 file changed

+108
-0
lines changed

bench/ndarray/numba_bench.py

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#######################################################################
2+
# Copyright (c) 2019-present, Blosc Development Team <blosc@blosc.org>
3+
# All rights reserved.
4+
#
5+
# This source code is licensed under a BSD-style license (found in the
6+
# LICENSE file in the root directory of this source tree)
7+
#######################################################################
8+
9+
# Compare Numba-compiled UDF with standard UDF
10+
11+
import blosc2
12+
import numpy as np
13+
import numba
14+
import time
15+
import matplotlib.pyplot as plt
16+
plt.rcParams['figure.dpi'] = 300
17+
plt.rcParams['savefig.dpi'] = 300
18+
plt.style.use('seaborn-v0_8-paper')
19+
plt.rcParams.update({
20+
"font.size": 14,
21+
"axes.titlesize": 18,
22+
"axes.labelsize": 16,
23+
"xtick.labelsize": 12,
24+
"ytick.labelsize": 12,
25+
"legend.fontsize": 12,
26+
})
27+
nios = 4
28+
intensity_val = 147 / nios
29+
expr = "exp(sqrt((sin(a) ** 2 + (cos(b) + arctan(c)) ** 3) * (1 + sin(b) ** 2 + cos(c) ** 2)))"
30+
dtype = np.float64()
31+
32+
sizes = np.sqrt(1024 ** 3 * np.array([1 / 2**5, 1 / 2**4, 1 / 2**3, 1 / 2**2, 1 / 2, 1]) / dtype.itemsize) # operand size up to 1GB
33+
@numba.jit(nopython=True, parallel=True)
34+
def myudf_numba(inputs, output, offset):
35+
a, b, c = inputs
36+
output[:] = np.exp(np.sqrt((np.sin(a) ** 2 + (np.cos(b) + np.arctan(c)) ** 3) * (1 + np.sin(b) ** 2 + np.cos(c) ** 2)))
37+
38+
def myudf(inputs, output, offset):
39+
a, b, c = inputs
40+
output[:] = np.exp(np.sqrt((np.sin(a) ** 2 + (np.cos(b) + np.arctan(c)) ** 3) * (1 + np.sin(b) ** 2 + np.cos(c) ** 2)))
41+
42+
n = 10
43+
n = int(n)
44+
a = blosc2.arange(0, n**2, shape=(n, n), dtype=dtype)
45+
b = blosc2.arange(0, n**2, shape=(n, n), dtype=dtype)
46+
c = blosc2.arange(0, n**2, shape=(n, n), dtype=dtype)
47+
48+
larray_nb = blosc2.lazyudf(myudf_numba, (a, b, c), c.dtype)
49+
t0 = time.time()
50+
res = larray_nb.compute()
51+
dt = time.time() - t0
52+
53+
MAX_THREADS = numba.get_num_threads()
54+
55+
for nthreads, c_ in zip([MAX_THREADS], ['r']):
56+
numba.set_num_threads(nthreads)
57+
58+
blosc2_parallel_times = []
59+
np_parallel_times = []
60+
blosc2_times = []
61+
for n in sizes:
62+
n = int(n)
63+
a = blosc2.arange(0, n**2, shape=(n, n), dtype=dtype)
64+
b = blosc2.arange(0, n**2, shape=(n, n), dtype=dtype)
65+
c = blosc2.arange(0, n**2, shape=(n, n), dtype=dtype)
66+
67+
larray_nb = blosc2.lazyudf(myudf_numba, (a, b, c), c.dtype)
68+
t0 = time.time()
69+
res = larray_nb.compute()
70+
dt = time.time() - t0
71+
blosc2_parallel_times += [intensity_val * n ** 2 / dt / 1e9]
72+
if nthreads == MAX_THREADS:
73+
larray_nb = blosc2.lazyudf(myudf, (a, b, c), c.dtype)
74+
t0 = time.time()
75+
res = larray_nb.compute()
76+
dt = time.time() - t0
77+
blosc2_times += [intensity_val * n ** 2 / dt / 1e9]
78+
79+
# a, b, c, res = a[:], b[:], c[:], res[:]
80+
# t0 = time.time()
81+
# myudf((a, b, c), res, ())
82+
# dt = time.time() - t0
83+
# np_parallel_times += [intensity_val * n ** 2 / dt / 1e9]
84+
85+
# plt.loglog(4 * sizes**2 / 1024**3 * dtype.itemsize, np_parallel_times, color=c_, ls='--')
86+
87+
gigas = 4 * sizes**2 / 1024**3 * dtype.itemsize
88+
if nthreads == MAX_THREADS:
89+
plt.loglog(gigas, blosc2_times, color='b', ls='-', label=f'Blosc2', lw=3)
90+
boost = np.mean(np.divide(blosc2_parallel_times, blosc2_times))
91+
plt.loglog(gigas, blosc2_parallel_times, color=c_, ls='-', label=f'Blosc2 + Numba', lw=3)
92+
93+
plt.xlabel('Working set size (GB)')
94+
plt.ylabel("GFLOPS / s")
95+
plt.xticks([.1, .5, 1, 2, 4], [.1, .5, 1, 2, 4])
96+
plt.yticks([1, 2, 4, 8], [1, 2, 4, 8])
97+
# plt.plot([], [], 'k-', label='blosc2 + numba')
98+
# plt.plot([], [], 'k--', label='NumPy + numba')
99+
# plt.plot([], [], 'k:', label='blosc2')
100+
101+
plt.legend()
102+
plt.title('Accelerate with Blosc2 + Numba!')
103+
plt.annotate(f'Performance boost: {round(boost, 1)}x !', (0.31, .6), xycoords='figure fraction', bbox=dict(boxstyle="round", fc="0.8", color='b', alpha=.5))
104+
idx = len(gigas)//4
105+
plt.annotate("", xytext=(gigas[idx], blosc2_times[idx]), xy=(gigas[idx], blosc2_parallel_times[idx]),
106+
arrowprops=dict(arrowstyle="<->", lw=3))
107+
plt.tight_layout()
108+
plt.savefig('temp.png', format='png', bbox_inches='tight')

0 commit comments

Comments
 (0)