Newer
Older
{
"cells": [
{
"cell_type": "code",
"metadata": {},
"outputs": [],
"source": [
"from pystencils.session import *\n",
"from time import perf_counter\n",
"from statistics import median\n",
"from functools import partial"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Benchmark for Python call overhead"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"$\\displaystyle \\left[ 2, \\ 4, \\ 8, \\ 16, \\ 32, \\ 64, \\ 128\\right]$"
],
"text/plain": [
"[2, 4, 8, 16, 32, 64, 128]"
]
},
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"inner_repeats = 100\n",
"outer_repeats = 5\n",
"sizes = [2**i for i in range(1, 8)]\n",
"sizes"
]
},
{
"cell_type": "code",
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
"metadata": {},
"outputs": [],
"source": [
"def benchmark_pure(domain_size, extract_first=False):\n",
" src = np.zeros(domain_size)\n",
" dst = np.zeros_like(src)\n",
" f_src, f_dst = ps.fields(\"src, dst\", src=src, dst=dst)\n",
" kernel = ps.create_kernel(ps.Assignment(f_dst.center, f_src.center)).compile()\n",
" if extract_first:\n",
" kernel = kernel.kernel\n",
" start = perf_counter()\n",
" for i in range(inner_repeats):\n",
" kernel(src=src, dst=dst)\n",
" src, dst = dst, src\n",
" end = perf_counter()\n",
" else:\n",
" start = perf_counter()\n",
" for i in range(inner_repeats):\n",
" kernel(src=src, dst=dst)\n",
" src, dst = dst, src\n",
" end = perf_counter()\n",
" return (end - start) / inner_repeats\n",
"\n",
"def benchmark_datahandling(domain_size, parallel=False):\n",
" dh = ps.create_data_handling(domain_size, parallel=parallel)\n",
" f_src = dh.add_array('src')\n",
" f_dst = dh.add_array('dst')\n",
" kernel = ps.create_kernel(ps.Assignment(f_dst.center, f_src.center)).compile()\n",
" start = perf_counter()\n",
" for i in range(inner_repeats):\n",
" dh.run_kernel(kernel)\n",
" dh.swap('src', 'dst')\n",
" end = perf_counter()\n",
" return (end - start) / inner_repeats\n",
" \n",
" \n",
"name_to_func = {\n",
" 'pure_extract': partial(benchmark_pure, extract_first=True),\n",
" 'pure_no_extract': partial(benchmark_pure, extract_first=False),\n",
" 'dh_serial': partial(benchmark_datahandling, parallel=False),\n",
" 'dh_parallel': partial(benchmark_datahandling, parallel=True),\n",
"}"
]
},
{
"cell_type": "code",
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
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Computing size 2\n",
"Computing size 4\n",
"Computing size 8\n",
"Computing size 16\n",
"Computing size 32\n",
"Computing size 64\n",
"Computing size 128\n"
]
}
],
"source": [
"result = {'block_size': [],\n",
" 'name': [],\n",
" 'time': []}\n",
"\n",
"for bs in sizes:\n",
" print(\"Computing size \", bs)\n",
" for name, func in name_to_func.items():\n",
" for i in range(outer_repeats):\n",
" time = func((bs, bs))\n",
" result['block_size'].append(bs)\n",
" result['name'].append(name)\n",
" result['time'].append(time)"
]
},
{
"cell_type": "code",
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 1152x432 with 2 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
"output_type": "display_data"
}
],
"source": [
"if 'is_test_run' not in globals():\n",
" import pandas as pd\n",
" import seaborn as sns\n",
" \n",
" data = pd.DataFrame.from_dict(result)\n",
"\n",
" plt.subplot(1,2,1)\n",
" sns.barplot(x='block_size', y='time', hue='name', data=data, alpha=0.6)\n",
" plt.yscale('log')\n",
"\n",
" plt.subplot(1,2,2)\n",
" data = pd.DataFrame.from_dict(result)\n",
" sns.barplot(x='block_size', y='time', hue='name', data=data, alpha=0.6)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
}
},
"nbformat": 4,
"nbformat_minor": 2
}