{ "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/latex": [ "$\\displaystyle {{dst}_{(0,0)}} \\leftarrow {{src}_{(0,0)}} \\left(1.0 - \\omega\\right) + \\frac{\\omega \\left({{src}_{(1,0)}} + {{src}_{(0,1)}} + {{src}_{(0,-1)}} + {{src}_{(-1,0)}}\\right)}{4}$" ], "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([_data_dst, _data_src, omega])\n", "\tBlock for(ctr_0=1; ctr_0<29; ctr_0+=1)\n", "\t\tBlock _data_dst_00 ← pointer_arithmetic_func(_data_dst, 20*ctr_0)\n", "\t\t_data_src_00 ← pointer_arithmetic_func(_data_src, 20*ctr_0)\n", "\t\t_data_src_01 ← pointer_arithmetic_func(_data_src, 20*ctr_0 + 20)\n", "\t\t_data_src_0m1 ← pointer_arithmetic_func(_data_src, 20*ctr_0 - 20)\n", "\t\tfor(ctr_1=1; ctr_1<19; ctr_1+=1)\n", "\t\t\tBlock _data_dst_00[ctr_1] ← omega*(_data_src_00[ctr_1 + 1] + _data_src_00[ctr_1 - 1] + _data_src_01[ctr_1] + _data_src_0m1[ctr_1])*cast_func(1/4, double) + (omega*cast_func(-1, double) + cast_func(1.0, double))*_data_src_00[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.40.1 (20161225.0304)\n", " -->\n", "<!-- Title: %3 Pages: 1 -->\n", "<svg width=\"864pt\" height=\"476pt\"\n", " viewBox=\"0.00 0.00 864.48 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=\"#ffffff\" stroke=\"transparent\" points=\"-4,4 -4,-472 860.4844,-472 860.4844,4 -4,4\"/>\n", "<!-- 139792163067600 -->\n", "<g id=\"node1\" class=\"node\">\n", "<title>139792163067600</title>\n", "<ellipse fill=\"#a056db\" stroke=\"#000000\" cx=\"396.1436\" cy=\"-450\" rx=\"145.6742\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"396.1436\" y=\"-446.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Func: kernel (dst,src,omega)</text>\n", "</g>\n", "<!-- 139791989624336 -->\n", "<g id=\"node11\" class=\"node\">\n", "<title>139791989624336</title>\n", "<ellipse fill=\"#dbc256\" stroke=\"#000000\" cx=\"396.1436\" cy=\"-378\" rx=\"37.0935\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"396.1436\" y=\"-374.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Block</text>\n", "</g>\n", "<!-- 139792163067600->139791989624336 -->\n", "<g id=\"edge10\" class=\"edge\">\n", "<title>139792163067600->139791989624336</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M396.1436,-431.8314C396.1436,-424.131 396.1436,-414.9743 396.1436,-406.4166\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"399.6437,-406.4132 396.1436,-396.4133 392.6437,-406.4133 399.6437,-406.4132\"/>\n", "</g>\n", "<!-- 139791989623376 -->\n", "<g id=\"node2\" class=\"node\">\n", "<title>139791989623376</title>\n", "<ellipse fill=\"#3498db\" stroke=\"#000000\" cx=\"396.1436\" cy=\"-306\" rx=\"86.3847\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"396.1436\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Loop over dim 0</text>\n", "</g>\n", "<!-- 139792050742160 -->\n", "<g id=\"node10\" class=\"node\">\n", "<title>139792050742160</title>\n", "<ellipse fill=\"#dbc256\" stroke=\"#000000\" cx=\"396.1436\" cy=\"-234\" rx=\"37.0935\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"396.1436\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Block</text>\n", "</g>\n", "<!-- 139791989623376->139792050742160 -->\n", "<g id=\"edge8\" class=\"edge\">\n", "<title>139791989623376->139792050742160</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M396.1436,-287.8314C396.1436,-280.131 396.1436,-270.9743 396.1436,-262.4166\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"399.6437,-262.4132 396.1436,-252.4133 392.6437,-262.4133 399.6437,-262.4132\"/>\n", "</g>\n", "<!-- 139791989188432 -->\n", "<g id=\"node3\" class=\"node\">\n", "<title>139791989188432</title>\n", "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"72.1436\" cy=\"-162\" rx=\"72.2875\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"72.1436\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_dst_00</text>\n", "</g>\n", "<!-- 139791989188752 -->\n", "<g id=\"node4\" class=\"node\">\n", "<title>139791989188752</title>\n", "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"234.1436\" cy=\"-162\" rx=\"72.2875\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"234.1436\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_src_00</text>\n", "</g>\n", "<!-- 139791989189072 -->\n", "<g id=\"node5\" class=\"node\">\n", "<title>139791989189072</title>\n", "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"396.1436\" cy=\"-162\" rx=\"72.2875\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"396.1436\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_src_01</text>\n", "</g>\n", "<!-- 139791989189456 -->\n", "<g id=\"node6\" class=\"node\">\n", "<title>139791989189456</title>\n", "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"567.1436\" cy=\"-162\" rx=\"81.4863\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"567.1436\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_src_0m1</text>\n", "</g>\n", "<!-- 139792198596368 -->\n", "<g id=\"node7\" class=\"node\">\n", "<title>139792198596368</title>\n", "<ellipse fill=\"#3498db\" stroke=\"#000000\" cx=\"753.1436\" cy=\"-162\" rx=\"86.3847\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"753.1436\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Loop over dim 1</text>\n", "</g>\n", "<!-- 139792198655632 -->\n", "<g id=\"node9\" class=\"node\">\n", "<title>139792198655632</title>\n", "<ellipse fill=\"#dbc256\" stroke=\"#000000\" cx=\"753.1436\" cy=\"-90\" rx=\"37.0935\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"753.1436\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Block</text>\n", "</g>\n", "<!-- 139792198596368->139792198655632 -->\n", "<g id=\"edge2\" class=\"edge\">\n", "<title>139792198596368->139792198655632</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M753.1436,-143.8314C753.1436,-136.131 753.1436,-126.9743 753.1436,-118.4166\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"756.6437,-118.4132 753.1436,-108.4133 749.6437,-118.4133 756.6437,-118.4132\"/>\n", "</g>\n", "<!-- 139791989208464 -->\n", "<g id=\"node8\" class=\"node\">\n", "<title>139791989208464</title>\n", "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"753.1436\" cy=\"-18\" rx=\"103.1819\" ry=\"18\"/>\n", "<text text-anchor=\"middle\" x=\"753.1436\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_dst_00[ctr_1]</text>\n", "</g>\n", "<!-- 139792198655632->139791989208464 -->\n", "<g id=\"edge1\" class=\"edge\">\n", "<title>139792198655632->139791989208464</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M753.1436,-71.8314C753.1436,-64.131 753.1436,-54.9743 753.1436,-46.4166\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"756.6437,-46.4132 753.1436,-36.4133 749.6437,-46.4133 756.6437,-46.4132\"/>\n", "</g>\n", "<!-- 139792050742160->139791989188432 -->\n", "<g id=\"edge3\" class=\"edge\">\n", "<title>139792050742160->139791989188432</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M362.3868,-226.4985C309.0457,-214.6449 204.358,-191.381 136.3723,-176.2731\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"136.7255,-172.7662 126.2043,-174.0135 135.2069,-179.5995 136.7255,-172.7662\"/>\n", "</g>\n", "<!-- 139792050742160->139791989188752 -->\n", "<g id=\"edge4\" class=\"edge\">\n", "<title>139792050742160->139791989188752</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M368.6625,-221.7862C344.1691,-210.9002 307.8582,-194.7621 279.1334,-181.9955\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"280.2705,-178.6708 269.7108,-177.8077 277.4275,-185.0674 280.2705,-178.6708\"/>\n", "</g>\n", "<!-- 139792050742160->139791989189072 -->\n", "<g id=\"edge5\" class=\"edge\">\n", "<title>139792050742160->139791989189072</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M396.1436,-215.8314C396.1436,-208.131 396.1436,-198.9743 396.1436,-190.4166\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"399.6437,-190.4132 396.1436,-180.4133 392.6437,-190.4133 399.6437,-190.4132\"/>\n", "</g>\n", "<!-- 139792050742160->139791989189456 -->\n", "<g id=\"edge6\" class=\"edge\">\n", "<title>139792050742160->139791989189456</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M424.3808,-222.1107C450.343,-211.1792 489.3422,-194.7585 520.0222,-181.8406\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"521.3947,-185.0604 529.2528,-177.954 518.6783,-178.6089 521.3947,-185.0604\"/>\n", "</g>\n", "<!-- 139792050742160->139792198596368 -->\n", "<g id=\"edge7\" class=\"edge\">\n", "<title>139792050742160->139792198596368</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M430.3743,-227.0963C487.746,-215.5256 604.5075,-191.977 680.7422,-176.602\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"681.6457,-179.9903 690.7564,-174.5823 680.2618,-173.1285 681.6457,-179.9903\"/>\n", "</g>\n", "<!-- 139791989624336->139791989623376 -->\n", "<g id=\"edge9\" class=\"edge\">\n", "<title>139791989624336->139791989623376</title>\n", "<path fill=\"none\" stroke=\"#000000\" d=\"M396.1436,-359.8314C396.1436,-352.131 396.1436,-342.9743 396.1436,-334.4166\"/>\n", "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"399.6437,-334.4132 396.1436,-324.4133 392.6437,-334.4133 399.6437,-334.4132\"/>\n", "</g>\n", "</g>\n", "</svg>\n" ], "text/plain": [ "<graphviz.files.Source at 0x7f23dbdc5c10>" ] }, "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": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "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.7.7" } }, "nbformat": 4, "nbformat_minor": 2 }