Newer
Older
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
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
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# pystencils - LLVM generation\n",
"The generation of LLVM code is simliar but not identical as seen with the C++ version. For the generation itself a python module ``llvmlite`` is used. This module provides the necessary support and bindings for LLVM. In order to generate from the AST to llvm, the AST needs to be transformed to support type conversions. This is the biggest difference to the C++ version. C++ doesn't need that since the language itself handles the casts.\n",
"\n",
"In this example a simple weighted Jacobi kernel is generated, so the focus remains on the part of LLVM generation."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import sympy as sp\n",
"import numpy as np\n",
"import ctypes\n",
"from pystencils import Field, Assignment\n",
"from pystencils import create_kernel\n",
"from pystencils.display_utils import to_dot\n",
"\n",
"sp.init_printing()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The numpy arrays (with inital values) create *Field*s for the update Rule. Later those arrays are used for the computation itself."
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"src_arr = np.zeros((30, 20))\n",
"src_arr[0,:] = 1.0\n",
"src_arr[:,0] = 1.0\n",
"dst_arr = src_arr.copy()\n",
"\n",
"src_field = Field.create_from_numpy_array('src', src_arr)\n",
"dst_field = Field.create_from_numpy_array('dst', dst_arr)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the *Field* objects and the additional *Symbol* $\\omega$ for the weight the update rule is specified as a *sympy* equation."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
" ω⋅(src_E + src_N + src_S + src_W)\n",
"dst_C := src_C⋅(-ω + 1.0) + ─────────────────────────────────\n",
" 4 "
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"omega = sp.symbols(\"omega\")\n",
"update_rule = Assignment(dst_field[0,0], omega * (src_field[0,1] + src_field[0,-1] + src_field[1,0] + src_field[-1,0]) / 4\n",
" + (1.-omega)*src_field[0,0])\n",
"update_rule"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With this update rule an abstract syntax tree (AST) can be created. This AST can be used to print the LLVM code. The creation follows the same routines as the C++ version does. However at the end there are two more steps. In order to generate LLVM, type casting and pointer arithmetic had to be introduced (which C++ does for you)."
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"KernelFunction kernel([<double * RESTRICT fd_dst>, <double * RESTRICT const fd_src>, <double omega>])\n",
"\tBlock for(ctr_0=1; ctr_0<29; ctr_0+=1)\n",
"\t\tBlock fd_dst_C ← pointer_arithmetic_func(fd_dst, 20*ctr_0)\n",
"\t\tfd_src_C ← pointer_arithmetic_func(fd_src, 20*ctr_0)\n",
"\t\tfd_src_E ← pointer_arithmetic_func(fd_src, 20*ctr_0 + 20)\n",
"\t\tfd_src_W ← pointer_arithmetic_func(fd_src, 20*ctr_0 - 20)\n",
"\t\tfor(ctr_1=1; ctr_1<19; ctr_1+=1)\n",
"\t\t\tBlock fd_dst_C[ctr_1] ← omega*(fd_src_C[ctr_1 + 1] + fd_src_C[ctr_1 - 1] + fd_src_E[ctr_1] + fd_src_W[ctr_1])/4 + (omega*cast_func(-1, double) + 1.0)*fd_src_C[ctr_1]\n",
"\t\t\n",
"\t\n",
"\n"
]
}
],
"source": [
"ast = create_kernel([update_rule], target='llvm')\n",
"print(str(ast))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is possible to examine the AST further."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"570pt\" height=\"476pt\"\n",
" viewBox=\"0.00 0.00 569.74 476.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 472)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-472 565.74,-472 565.74,4 -4,4\"/>\n",
"<!-- 139831602112104 -->\n",
"<g id=\"node1\" class=\"node\"><title>139831602112104</title>\n",
"<ellipse fill=\"#a056db\" stroke=\"black\" cx=\"249.896\" cy=\"-450\" rx=\"112.38\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"249.896\" y=\"-446.3\" font-family=\"Times,serif\" font-size=\"14.00\">Func: kernel (dst,src,omega)</text>\n",
"</g>\n",
"<!-- 139831601760856 -->\n",
"<g id=\"node11\" class=\"node\"><title>139831601760856</title>\n",
"<ellipse fill=\"#dbc256\" stroke=\"black\" cx=\"249.896\" cy=\"-378\" rx=\"31.6951\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"249.896\" y=\"-374.3\" font-family=\"Times,serif\" font-size=\"14.00\">Block</text>\n",
"</g>\n",
"<!-- 139831602112104->139831601760856 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>139831602112104->139831601760856</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M249.896,-431.697C249.896,-423.983 249.896,-414.712 249.896,-406.112\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"253.396,-406.104 249.896,-396.104 246.396,-406.104 253.396,-406.104\"/>\n",
"</g>\n",
"<!-- 139831601760688 -->\n",
"<g id=\"node2\" class=\"node\"><title>139831601760688</title>\n",
"<ellipse fill=\"#3498db\" stroke=\"black\" cx=\"249.896\" cy=\"-306\" rx=\"70.6878\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"249.896\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\">Loop over dim 0</text>\n",
"</g>\n",
"<!-- 139831601760296 -->\n",
"<g id=\"node10\" class=\"node\"><title>139831601760296</title>\n",
"<ellipse fill=\"#dbc256\" stroke=\"black\" cx=\"249.896\" cy=\"-234\" rx=\"31.6951\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"249.896\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\">Block</text>\n",
"</g>\n",
"<!-- 139831601760688->139831601760296 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>139831601760688->139831601760296</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M249.896,-287.697C249.896,-279.983 249.896,-270.712 249.896,-262.112\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"253.396,-262.104 249.896,-252.104 246.396,-262.104 253.396,-262.104\"/>\n",
"</g>\n",
"<!-- 139832610576760 -->\n",
"<g id=\"node3\" class=\"node\"><title>139832610576760</title>\n",
"<ellipse fill=\"#56db7f\" stroke=\"black\" cx=\"42.8962\" cy=\"-162\" rx=\"42.7926\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"42.8962\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">fd_dst_C</text>\n",
"</g>\n",
"<!-- 139832610531536 -->\n",
"<g id=\"node4\" class=\"node\"><title>139832610531536</title>\n",
"<ellipse fill=\"#56db7f\" stroke=\"black\" cx=\"146.896\" cy=\"-162\" rx=\"42.7926\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"146.896\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">fd_src_C</text>\n",
"</g>\n",
"<!-- 139831601689544 -->\n",
"<g id=\"node5\" class=\"node\"><title>139831601689544</title>\n",
"<ellipse fill=\"#56db7f\" stroke=\"black\" cx=\"249.896\" cy=\"-162\" rx=\"42.4939\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"249.896\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">fd_src_E</text>\n",
"</g>\n",
"<!-- 139831601689432 -->\n",
"<g id=\"node6\" class=\"node\"><title>139831601689432</title>\n",
"<ellipse fill=\"#56db7f\" stroke=\"black\" cx=\"355.896\" cy=\"-162\" rx=\"46.2923\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"355.896\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">fd_src_W</text>\n",
"</g>\n",
"<!-- 139831601761472 -->\n",
"<g id=\"node7\" class=\"node\"><title>139831601761472</title>\n",
"<ellipse fill=\"#3498db\" stroke=\"black\" cx=\"490.896\" cy=\"-162\" rx=\"70.6878\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"490.896\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\">Loop over dim 1</text>\n",
"</g>\n",
"<!-- 139831601761360 -->\n",
"<g id=\"node9\" class=\"node\"><title>139831601761360</title>\n",
"<ellipse fill=\"#dbc256\" stroke=\"black\" cx=\"490.896\" cy=\"-90\" rx=\"31.6951\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"490.896\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\">Block</text>\n",
"</g>\n",
"<!-- 139831601761472->139831601761360 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>139831601761472->139831601761360</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M490.896,-143.697C490.896,-135.983 490.896,-126.712 490.896,-118.112\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"494.396,-118.104 490.896,-108.104 487.396,-118.104 494.396,-118.104\"/>\n",
"</g>\n",
"<!-- 139831601222656 -->\n",
"<g id=\"node8\" class=\"node\"><title>139831601222656</title>\n",
"<ellipse fill=\"#56db7f\" stroke=\"black\" cx=\"490.896\" cy=\"-18\" rx=\"66.8882\" ry=\"18\"/>\n",
"<text text-anchor=\"middle\" x=\"490.896\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\">fd_dst_C[ctr_1]</text>\n",
"</g>\n",
"<!-- 139831601761360->139831601222656 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>139831601761360->139831601222656</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M490.896,-71.6966C490.896,-63.9827 490.896,-54.7125 490.896,-46.1124\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"494.396,-46.1043 490.896,-36.1043 487.396,-46.1044 494.396,-46.1043\"/>\n",
"</g>\n",
"<!-- 139831601760296->139832610576760 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>139831601760296->139832610576760</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M223.258,-223.992C188.18,-212.13 126.117,-191.142 84.7403,-177.15\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"85.8067,-173.816 75.2124,-173.928 83.5642,-180.447 85.8067,-173.816\"/>\n",
"</g>\n",
"<!-- 139831601760296->139832610531536 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>139831601760296->139832610531536</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M230.037,-219.503C215.003,-209.286 194.096,-195.077 177.009,-183.465\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"178.711,-180.39 168.473,-177.664 174.776,-186.179 178.711,-180.39\"/>\n",
"</g>\n",
"<!-- 139831601760296->139831601689544 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>139831601760296->139831601689544</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M249.896,-215.697C249.896,-207.983 249.896,-198.712 249.896,-190.112\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"253.396,-190.104 249.896,-180.104 246.396,-190.104 253.396,-190.104\"/>\n",
"</g>\n",
"<!-- 139831601760296->139831601689432 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>139831601760296->139831601689432</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M269.834,-219.834C285.399,-209.555 307.297,-195.094 325.109,-183.331\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"327.063,-186.235 333.479,-177.804 323.206,-180.394 327.063,-186.235\"/>\n",
"</g>\n",
"<!-- 139831601760296->139831601761472 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>139831601760296->139831601761472</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M277.542,-224.97C316.06,-213.782 386.695,-193.266 436.102,-178.915\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"437.367,-182.193 445.994,-176.042 435.415,-175.47 437.367,-182.193\"/>\n",
"</g>\n",
"<!-- 139831601760856->139831601760688 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>139831601760856->139831601760688</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M249.896,-359.697C249.896,-351.983 249.896,-342.712 249.896,-334.112\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"253.396,-334.104 249.896,-324.104 246.396,-334.104 253.396,-334.104\"/>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.files.Source at 0x7f2d14f276a0>"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"to_dot(ast)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With transformed AST it is now possible to generate and compile the AST into LLVM. Notice that unlike in C++ version, no files are writen to the hard drive (although it is possible).\n",
"\n",
"There are multiple ways how to generate and compile the AST. The most simple one is simillar to the C++ version. Using the ``compile()`` function of the generated AST\n",
"\n",
"You can also manually create a python function with ``make_python_function``.\n",
"\n",
"Another option is obtaining the jit itself with ``generate_and_jit``.\n",
"The function ``generate_and_jit`` first generates and the compiles the AST.\n",
"\n",
"If even more controll is needed, it is possible to use the functions ``generateLLVM`` and ``compileLLVM`` to achieve the same. For further controll, instead of calling ``compileLLVM`` the jit object itself can be created and its necessary functions for the compilation have to be run manually (``parse``, (``optimize``,) ``compile``)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"scrolled": false
},
"outputs": [],
"source": [
"kernel = ast.compile()\n",
"\n",
"#kernel = make_python_function(ast)\n",
"\n",
"# Or alternativally\n",
"#jit = generate_and_jit(ast)\n",
"# Call: jit('kernel', src_arr, dst_arr)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The compiled function(s) can be used now. Either call the function (with arguments, if not given before) or call the jit object with the function's name and its arguments. Here, numpy arrays are automatically adjusted with ctypes.\n",
"\n",
"The functions and arguments can be read as well.\n",
"\n",
"**All of the information the jit object has comes from the module which was parsed. If you parse a second module and don't run the compilation step, the module and the compiled code are not the same anymore, thus leading to false information**"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"#jit.print_functions()"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
"for i in range(100):\n",
" kernel(src=src_arr, dst=dst_arr, omega=2/3)\n",
" src_arr, dst_arr = dst_arr, src_arr\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The output is drawn with matplotlib."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import matplotlib.pyplot as plt\n",
"from matplotlib import cm\n",
"fig = plt.figure()\n",
"ax = fig.add_subplot(111)\n",
"ax.imshow(dst_arr, cmap=cm.jet)\n",
"plt.show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"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",
"version": "3.6.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}