Skip to content
Snippets Groups Projects
01_tutorial_getting_started.ipynb 190 KiB
Newer Older
       "<ellipse fill=\"#a056db\" stroke=\"#000000\" cx=\"219.8449\" cy=\"-450\" rx=\"107.781\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"219.8449\" y=\"-446.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Func: kernel (dst,img,w_2)</text>\n",
       "<!-- 140495254318440 -->\n",
       "<g id=\"node11\" class=\"node\">\n",
       "<title>140495254318440</title>\n",
       "<ellipse fill=\"#dbc256\" stroke=\"#000000\" cx=\"219.8449\" cy=\"-378\" rx=\"31.6951\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"219.8449\" y=\"-374.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Block</text>\n",
       "<!-- 140495254316984&#45;&gt;140495254318440 -->\n",
       "<g id=\"edge10\" class=\"edge\">\n",
       "<title>140495254316984&#45;&gt;140495254318440</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M219.8449,-431.8314C219.8449,-424.131 219.8449,-414.9743 219.8449,-406.4166\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"223.345,-406.4132 219.8449,-396.4133 216.345,-406.4133 223.345,-406.4132\"/>\n",
       "<!-- 140495254317656 -->\n",
       "<g id=\"node2\" class=\"node\">\n",
       "<title>140495254317656</title>\n",
       "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"144.8449\" cy=\"-306\" rx=\"61.99\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"144.8449\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_img_22</text>\n",
       "<!-- 140495254316256 -->\n",
       "<g id=\"node3\" class=\"node\">\n",
       "<title>140495254316256</title>\n",
       "<ellipse fill=\"#3498db\" stroke=\"#000000\" cx=\"295.8449\" cy=\"-306\" rx=\"70.6878\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"295.8449\" y=\"-302.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Loop over dim 0</text>\n",
       "<!-- 140495254316032 -->\n",
       "<g id=\"node10\" class=\"node\">\n",
       "<title>140495254316032</title>\n",
       "<ellipse fill=\"#dbc256\" stroke=\"#000000\" cx=\"295.8449\" cy=\"-234\" rx=\"31.6951\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"295.8449\" y=\"-230.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Block</text>\n",
       "<!-- 140495254316256&#45;&gt;140495254316032 -->\n",
       "<g id=\"edge7\" class=\"edge\">\n",
       "<title>140495254316256&#45;&gt;140495254316032</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M295.8449,-287.8314C295.8449,-280.131 295.8449,-270.9743 295.8449,-262.4166\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"299.345,-262.4132 295.8449,-252.4133 292.345,-262.4133 299.345,-262.4132\"/>\n",
       "<!-- 140495254318496 -->\n",
       "<g id=\"node4\" class=\"node\">\n",
       "<title>140495254318496</title>\n",
       "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"57.8449\" cy=\"-162\" rx=\"57.6901\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"57.8449\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_dst_00</text>\n",
       "<!-- 140495254316592 -->\n",
       "<g id=\"node5\" class=\"node\">\n",
       "<title>140495254316592</title>\n",
       "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"208.8449\" cy=\"-162\" rx=\"74.9875\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"208.8449\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_img_22_01</text>\n",
       "<!-- 140495254317320 -->\n",
       "<g id=\"node6\" class=\"node\">\n",
       "<title>140495254317320</title>\n",
       "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"383.8449\" cy=\"-162\" rx=\"81.7856\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"383.8449\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_img_22_0m1</text>\n",
       "<!-- 140495254318664 -->\n",
       "<g id=\"node7\" class=\"node\">\n",
       "<title>140495254318664</title>\n",
       "<ellipse fill=\"#3498db\" stroke=\"#000000\" cx=\"554.8449\" cy=\"-162\" rx=\"70.6878\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"554.8449\" y=\"-158.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Loop over dim 1</text>\n",
       "<!-- 140495254318776 -->\n",
       "<g id=\"node9\" class=\"node\">\n",
       "<title>140495254318776</title>\n",
       "<ellipse fill=\"#dbc256\" stroke=\"#000000\" cx=\"554.8449\" cy=\"-90\" rx=\"31.6951\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"554.8449\" y=\"-86.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">Block</text>\n",
       "<!-- 140495254318664&#45;&gt;140495254318776 -->\n",
       "<g id=\"edge2\" class=\"edge\">\n",
       "<title>140495254318664&#45;&gt;140495254318776</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M554.8449,-143.8314C554.8449,-136.131 554.8449,-126.9743 554.8449,-118.4166\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"558.345,-118.4132 554.8449,-108.4133 551.345,-118.4133 558.345,-118.4132\"/>\n",
       "<!-- 140495254317040 -->\n",
       "<g id=\"node8\" class=\"node\">\n",
       "<title>140495254317040</title>\n",
       "<ellipse fill=\"#56db7f\" stroke=\"#000000\" cx=\"554.8449\" cy=\"-18\" rx=\"133.4768\" ry=\"18\"/>\n",
       "<text text-anchor=\"middle\" x=\"554.8449\" y=\"-14.3\" font-family=\"Times,serif\" font-size=\"14.00\" fill=\"#000000\">_data_dst_00[_stride_dst_1*ctr_1]</text>\n",
       "<!-- 140495254318776&#45;&gt;140495254317040 -->\n",
       "<g id=\"edge1\" class=\"edge\">\n",
       "<title>140495254318776&#45;&gt;140495254317040</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M554.8449,-71.8314C554.8449,-64.131 554.8449,-54.9743 554.8449,-46.4166\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"558.345,-46.4132 554.8449,-36.4133 551.345,-46.4133 558.345,-46.4132\"/>\n",
       "<!-- 140495254316032&#45;&gt;140495254318496 -->\n",
       "<g id=\"edge3\" class=\"edge\">\n",
       "<title>140495254316032&#45;&gt;140495254318496</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M267.6085,-225.4579C228.6723,-213.6789 157.8187,-192.2442 109.3243,-177.5736\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"110.2227,-174.1888 99.6376,-174.6432 108.1957,-180.8889 110.2227,-174.1888\"/>\n",
       "<!-- 140495254316032&#45;&gt;140495254316592 -->\n",
       "<g id=\"edge4\" class=\"edge\">\n",
       "<title>140495254316032&#45;&gt;140495254316592</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M277.8184,-219.0816C266.2777,-209.5306 251.0436,-196.9231 237.8284,-185.9864\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"239.8475,-183.1143 229.9121,-179.4349 235.3845,-188.507 239.8475,-183.1143\"/>\n",
       "<!-- 140495254316032&#45;&gt;140495254317320 -->\n",
       "<g id=\"edge5\" class=\"edge\">\n",
       "<title>140495254316032&#45;&gt;140495254317320</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M314.0785,-219.0816C325.7519,-209.5306 341.1611,-196.9231 354.5282,-185.9864\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"357.0123,-188.4762 362.5355,-179.4349 352.5796,-183.0585 357.0123,-188.4762\"/>\n",
       "<!-- 140495254316032&#45;&gt;140495254318664 -->\n",
       "<g id=\"edge6\" class=\"edge\">\n",
       "<title>140495254316032&#45;&gt;140495254318664</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M324.552,-226.0196C365.9645,-214.5073 443.366,-192.9903 496.9349,-178.0985\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"497.9488,-181.4495 506.646,-175.3989 496.0739,-174.7052 497.9488,-181.4495\"/>\n",
       "<!-- 140495254318440&#45;&gt;140495254317656 -->\n",
       "<g id=\"edge8\" class=\"edge\">\n",
       "<title>140495254318440&#45;&gt;140495254317656</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M203.571,-362.3771C193.8398,-353.0351 181.2651,-340.9635 170.2498,-330.3888\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"172.5648,-327.7594 162.9271,-323.3589 167.7171,-332.8091 172.5648,-327.7594\"/>\n",
       "<!-- 140495254318440&#45;&gt;140495254316256 -->\n",
       "<g id=\"edge9\" class=\"edge\">\n",
       "<title>140495254318440&#45;&gt;140495254316256</title>\n",
       "<path fill=\"none\" stroke=\"#000000\" d=\"M236.3357,-362.3771C246.1257,-353.1023 258.7558,-341.137 269.86,-330.6172\"/>\n",
       "<polygon fill=\"#000000\" stroke=\"#000000\" points=\"272.3977,-333.0344 277.2501,-323.6161 267.5835,-327.9527 272.3977,-333.0344\"/>\n",
       "</g>\n",
       "</g>\n",
       "</svg>\n"
      ],
      "text/plain": [
       "<graphviz.files.Source at 0x7fc798393fd0>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.to_dot(ast, graph_style={'size': \"9.5,12.5\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*pystencils* also builds a tree structure of the program, where each `Assignment` node internally again has a *sympy* AST which is not printed here. Out of this representation *C* code can be generated:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>.highlight .hll { background-color: #ffffcc }\n",
       ".highlight  { background: #f8f8f8; }\n",
       ".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666666 } /* Operator */\n",
       ".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
       ".highlight .go { color: #888888 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #880000 } /* Name.Constant */\n",
       ".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
       ".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #0000FF } /* Name.Function */\n",
       ".highlight .nl { color: #A0A000 } /* Name.Label */\n",
       ".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div class=\"highlight\"><pre><span></span><span class=\"n\">FUNC_PREFIX</span> <span class=\"kt\">void</span> <span class=\"nf\">kernel</span><span class=\"p\">(</span><span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst</span><span class=\"p\">,</span> <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_size_dst_0</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_size_dst_1</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_dst_0</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_dst_1</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_img_0</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_img_2</span><span class=\"p\">,</span> <span class=\"kt\">double</span> <span class=\"n\">w_2</span><span class=\"p\">)</span>\n",
       "<span class=\"p\">{</span>\n",
       "   <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img_22</span> <span class=\"o\">=</span> <span class=\"n\">_data_img</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"o\">*</span><span class=\"n\">_stride_img_2</span><span class=\"p\">;</span>\n",
       "   <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kt\">int</span> <span class=\"n\">ctr_0</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_0</span> <span class=\"o\">&lt;</span> <span class=\"n\">_size_dst_0</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_0</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "   <span class=\"p\">{</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst_00</span> <span class=\"o\">=</span> <span class=\"n\">_data_dst</span> <span class=\"o\">+</span> <span class=\"n\">_stride_dst_0</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img_22_01</span> <span class=\"o\">=</span> <span class=\"n\">_stride_img_0</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_0</span> <span class=\"o\">+</span> <span class=\"n\">_data_img_22</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img_22_0m1</span> <span class=\"o\">=</span> <span class=\"n\">_stride_img_0</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_0</span> <span class=\"o\">+</span> <span class=\"n\">_data_img_22</span><span class=\"p\">;</span>\n",
       "      <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kt\">int</span> <span class=\"n\">ctr_1</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_1</span> <span class=\"o\">&lt;</span> <span class=\"n\">_size_dst_1</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_1</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "      <span class=\"p\">{</span>\n",
       "         <span class=\"n\">_data_dst_00</span><span class=\"p\">[</span><span class=\"n\">_stride_dst_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">((</span><span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">])</span><span class=\"o\">*</span><span class=\"p\">(</span><span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]));</span>\n",
       "      <span class=\"p\">}</span>\n",
       "   <span class=\"p\">}</span>\n",
       "<span class=\"p\">}</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "FUNC_PREFIX void kernel(double * RESTRICT _data_dst, double * RESTRICT const _data_img, int64_t const _size_dst_0, int64_t const _size_dst_1, int64_t const _stride_dst_0, int64_t const _stride_dst_1, int64_t const _stride_img_0, int64_t const _stride_img_1, int64_t const _stride_img_2, double w_2)\n",
       "   double * RESTRICT const _data_img_22 = _data_img + 2*_stride_img_2;\n",
       "   for (int ctr_0 = 1; ctr_0 < _size_dst_0 - 1; ctr_0 += 1)\n",
       "      double * RESTRICT _data_dst_00 = _data_dst + _stride_dst_0*ctr_0;\n",
       "      double * RESTRICT const _data_img_22_01 = _stride_img_0*ctr_0 + _stride_img_0 + _data_img_22;\n",
       "      double * RESTRICT const _data_img_22_0m1 = _stride_img_0*ctr_0 - _stride_img_0 + _data_img_22;\n",
       "      for (int ctr_1 = 1; ctr_1 < _size_dst_1 - 1; ctr_1 += 1)\n",
       "         _data_dst_00[_stride_dst_1*ctr_1] = ((w_2*_data_img_22_01[_stride_img_1*ctr_1] - w_2*_data_img_22_0m1[_stride_img_1*ctr_1] - 0.5*_data_img_22_01[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 - _stride_img_1] + 0.5*_data_img_22_01[_stride_img_1*ctr_1 - _stride_img_1])*(w_2*_data_img_22_01[_stride_img_1*ctr_1] - w_2*_data_img_22_0m1[_stride_img_1*ctr_1] - 0.5*_data_img_22_01[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 - _stride_img_1] + 0.5*_data_img_22_01[_stride_img_1*ctr_1 - _stride_img_1]));\n",
       "      }\n",
       "   }\n",
       "}"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.show_code(ast)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Behind the scenes this code is compiled into a shared library and made available as a Python function. Before compiling this function we can modify the AST object, for example to parallelize it with OpenMP."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>.highlight .hll { background-color: #ffffcc }\n",
       ".highlight  { background: #f8f8f8; }\n",
       ".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666666 } /* Operator */\n",
       ".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
       ".highlight .go { color: #888888 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #880000 } /* Name.Constant */\n",
       ".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
       ".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #0000FF } /* Name.Function */\n",
       ".highlight .nl { color: #A0A000 } /* Name.Label */\n",
       ".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div class=\"highlight\"><pre><span></span><span class=\"n\">FUNC_PREFIX</span> <span class=\"kt\">void</span> <span class=\"nf\">kernel</span><span class=\"p\">(</span><span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst</span><span class=\"p\">,</span> <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_size_dst_0</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_size_dst_1</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_dst_0</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_dst_1</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_img_0</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">,</span> <span class=\"kt\">int64_t</span> <span class=\"k\">const</span> <span class=\"n\">_stride_img_2</span><span class=\"p\">,</span> <span class=\"kt\">double</span> <span class=\"n\">w_2</span><span class=\"p\">)</span>\n",
       "<span class=\"p\">{</span>\n",
       "   <span class=\"cp\">#pragma omp parallel num_threads(2)</span>\n",
       "   <span class=\"p\">{</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img_22</span> <span class=\"o\">=</span> <span class=\"n\">_data_img</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"o\">*</span><span class=\"n\">_stride_img_2</span><span class=\"p\">;</span>\n",
       "      <span class=\"cp\">#pragma omp for schedule(static)</span>\n",
       "      <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kt\">int</span> <span class=\"n\">ctr_0</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_0</span> <span class=\"o\">&lt;</span> <span class=\"n\">_size_dst_0</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_0</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "      <span class=\"p\">{</span>\n",
       "         <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst_00</span> <span class=\"o\">=</span> <span class=\"n\">_data_dst</span> <span class=\"o\">+</span> <span class=\"n\">_stride_dst_0</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span><span class=\"p\">;</span>\n",
       "         <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img_22_01</span> <span class=\"o\">=</span> <span class=\"n\">_stride_img_0</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_0</span> <span class=\"o\">+</span> <span class=\"n\">_data_img_22</span><span class=\"p\">;</span>\n",
       "         <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_img_22_0m1</span> <span class=\"o\">=</span> <span class=\"n\">_stride_img_0</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_0</span> <span class=\"o\">+</span> <span class=\"n\">_data_img_22</span><span class=\"p\">;</span>\n",
       "         <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kt\">int</span> <span class=\"n\">ctr_1</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_1</span> <span class=\"o\">&lt;</span> <span class=\"n\">_size_dst_1</span> <span class=\"o\">-</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_1</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "         <span class=\"p\">{</span>\n",
       "            <span class=\"n\">_data_dst_00</span><span class=\"p\">[</span><span class=\"n\">_stride_dst_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"p\">((</span><span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">])</span><span class=\"o\">*</span><span class=\"p\">(</span><span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">w_2</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_0m1</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mf\">0.5</span><span class=\"o\">*</span><span class=\"n\">_data_img_22_01</span><span class=\"p\">[</span><span class=\"n\">_stride_img_1</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"n\">_stride_img_1</span><span class=\"p\">]));</span>\n",
       "         <span class=\"p\">}</span>\n",
       "      <span class=\"p\">}</span>\n",
       "   <span class=\"p\">}</span>\n",
       "<span class=\"p\">}</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "FUNC_PREFIX void kernel(double * RESTRICT _data_dst, double * RESTRICT const _data_img, int64_t const _size_dst_0, int64_t const _size_dst_1, int64_t const _stride_dst_0, int64_t const _stride_dst_1, int64_t const _stride_img_0, int64_t const _stride_img_1, int64_t const _stride_img_2, double w_2)\n",
       "{\n",
       "   #pragma omp parallel num_threads(2)\n",
       "   {\n",
       "      double * RESTRICT const _data_img_22 = _data_img + 2*_stride_img_2;\n",
       "      #pragma omp for schedule(static)\n",
       "      for (int ctr_0 = 1; ctr_0 < _size_dst_0 - 1; ctr_0 += 1)\n",
       "         double * RESTRICT _data_dst_00 = _data_dst + _stride_dst_0*ctr_0;\n",
       "         double * RESTRICT const _data_img_22_01 = _stride_img_0*ctr_0 + _stride_img_0 + _data_img_22;\n",
       "         double * RESTRICT const _data_img_22_0m1 = _stride_img_0*ctr_0 - _stride_img_0 + _data_img_22;\n",
       "         for (int ctr_1 = 1; ctr_1 < _size_dst_1 - 1; ctr_1 += 1)\n",
       "            _data_dst_00[_stride_dst_1*ctr_1] = ((w_2*_data_img_22_01[_stride_img_1*ctr_1] - w_2*_data_img_22_0m1[_stride_img_1*ctr_1] - 0.5*_data_img_22_01[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 - _stride_img_1] + 0.5*_data_img_22_01[_stride_img_1*ctr_1 - _stride_img_1])*(w_2*_data_img_22_01[_stride_img_1*ctr_1] - w_2*_data_img_22_0m1[_stride_img_1*ctr_1] - 0.5*_data_img_22_01[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 + _stride_img_1] - 0.5*_data_img_22_0m1[_stride_img_1*ctr_1 - _stride_img_1] + 0.5*_data_img_22_01[_stride_img_1*ctr_1 - _stride_img_1]));\n",
       "         }\n",
       "      }\n",
       "   }\n",
       "}"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ast = ps.create_kernel(update_rule)\n",
    "ps.cpu.add_openmp(ast, num_threads=2)\n",
    "ps.show_code(ast)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "False"
      ]
     },
     "execution_count": 35,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "loops = list(ast.atoms(ps.astnodes.LoopOverCoordinate))\n",
    "l1 = loops[0]\n",
    "l1.prefix_lines.append(\"#pragma someting\")\n",
    "l1.is_outermost_loop"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Fixed array sizes\n",
    "\n",
    "Since we already know the arrays to which the kernel should be applied, we can \n",
    "create *Field* objects with fixed size, based on a numpy array:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>.highlight .hll { background-color: #ffffcc }\n",
       ".highlight  { background: #f8f8f8; }\n",
       ".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666666 } /* Operator */\n",
       ".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
       ".highlight .go { color: #888888 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #880000 } /* Name.Constant */\n",
       ".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
       ".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #0000FF } /* Name.Function */\n",
       ".highlight .nl { color: #A0A000 } /* Name.Label */\n",
       ".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div class=\"highlight\"><pre><span></span><span class=\"n\">FUNC_PREFIX</span> <span class=\"kt\">void</span> <span class=\"nf\">kernel</span><span class=\"p\">(</span><span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I</span><span class=\"p\">,</span> <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst</span><span class=\"p\">)</span>\n",
       "<span class=\"p\">{</span>\n",
       "   <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I_21</span> <span class=\"o\">=</span> <span class=\"n\">_data_I</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">;</span>\n",
       "   <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kt\">int</span> <span class=\"n\">ctr_0</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_0</span> <span class=\"o\">&lt;</span> <span class=\"mi\">81</span><span class=\"p\">;</span> <span class=\"n\">ctr_0</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "   <span class=\"p\">{</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst_00</span> <span class=\"o\">=</span> <span class=\"n\">_data_dst</span> <span class=\"o\">+</span> <span class=\"mi\">290</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I_21_01</span> <span class=\"o\">=</span> <span class=\"n\">_data_I_21</span> <span class=\"o\">+</span> <span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">+</span> <span class=\"mi\">1160</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I_21_0m1</span> <span class=\"o\">=</span> <span class=\"n\">_data_I_21</span> <span class=\"o\">+</span> <span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">-</span> <span class=\"mi\">1160</span><span class=\"p\">;</span>\n",
       "      <span class=\"k\">for</span> <span class=\"p\">(</span><span class=\"kt\">int</span> <span class=\"n\">ctr_1</span> <span class=\"o\">=</span> <span class=\"mi\">1</span><span class=\"p\">;</span> <span class=\"n\">ctr_1</span> <span class=\"o\">&lt;</span> <span class=\"mi\">289</span><span class=\"p\">;</span> <span class=\"n\">ctr_1</span> <span class=\"o\">+=</span> <span class=\"mi\">1</span><span class=\"p\">)</span>\n",
       "      <span class=\"p\">{</span>\n",
       "         <span class=\"n\">_data_dst_00</span><span class=\"p\">[</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"o\">*</span><span class=\"n\">_data_I_21_0m1</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"o\">*</span><span class=\"n\">_data_I_21_01</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">_data_I_21_01</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">_data_I_21_01</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">_data_I_21_0m1</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">_data_I_21_0m1</span><span class=\"p\">[</span><span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"mi\">4</span><span class=\"p\">];</span>\n",
       "      <span class=\"p\">}</span>\n",
       "   <span class=\"p\">}</span>\n",
       "<span class=\"p\">}</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "FUNC_PREFIX void kernel(double * RESTRICT const _data_I, double * RESTRICT _data_dst)\n",
       "   double * RESTRICT const _data_I_21 = _data_I + 1;\n",
       "   for (int ctr_0 = 1; ctr_0 < 81; ctr_0 += 1)\n",
       "   {\n",
       "      double * RESTRICT _data_dst_00 = _data_dst + 290*ctr_0;\n",
       "      double * RESTRICT const _data_I_21_01 = _data_I_21 + 1160*ctr_0 + 1160;\n",
       "      double * RESTRICT const _data_I_21_0m1 = _data_I_21 + 1160*ctr_0 - 1160;\n",
       "      for (int ctr_1 = 1; ctr_1 < 289; ctr_1 += 1)\n",
       "      {\n",
       "         _data_dst_00[ctr_1] = -2*_data_I_21_0m1[4*ctr_1] + 2*_data_I_21_01[4*ctr_1] - _data_I_21_01[4*ctr_1 + 4] + _data_I_21_01[4*ctr_1 - 4] - _data_I_21_0m1[4*ctr_1 + 4] - _data_I_21_0m1[4*ctr_1 - 4];\n",
       "      }\n",
       "   }\n",
       "}"
      ]
     },
     "execution_count": 36,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "img_field, dst_field = ps.fields(\"I(4), dst : [2D]\", I=img.astype(np.double), dst=filtered_image)\n",
    "\n",
    "sobel_x = -2 * img_field[-1,0](1) - img_field[-1,-1](1) - img_field[-1, +1](1) \\\n",
    "         +2 * img_field[+1,0](1) + img_field[+1,-1](1) - img_field[+1, +1](1)\n",
    "update_rule = ps.Assignment(dst_field[0,0], sobel_x)\n",
    "\n",
    "ast = create_kernel(update_rule)\n",
    "ps.show_code(ast)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Compare this code to the version above. In this code the loop bounds and array offsets are constants, which usually leads to faster kernels."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Running on GPU\n",
    "\n",
    "If you have a CUDA enabled graphics card and [pycuda](https://mathema.tician.de/software/pycuda/) installed, *pystencils* can run your kernel on the GPU as well. You can find more details about this in the GPU tutorial."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "gpu_ast = create_kernel(update_rule, target='gpu', gpu_indexing=ps.gpucuda.indexing.BlockIndexing, \n",
    "                        gpu_indexing_params={'blockSize': (8,8,4)})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>.highlight .hll { background-color: #ffffcc }\n",
       ".highlight  { background: #f8f8f8; }\n",
       ".highlight .c { color: #408080; font-style: italic } /* Comment */\n",
       ".highlight .err { border: 1px solid #FF0000 } /* Error */\n",
       ".highlight .k { color: #008000; font-weight: bold } /* Keyword */\n",
       ".highlight .o { color: #666666 } /* Operator */\n",
       ".highlight .ch { color: #408080; font-style: italic } /* Comment.Hashbang */\n",
       ".highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */\n",
       ".highlight .cp { color: #BC7A00 } /* Comment.Preproc */\n",
       ".highlight .cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */\n",
       ".highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */\n",
       ".highlight .cs { color: #408080; font-style: italic } /* Comment.Special */\n",
       ".highlight .gd { color: #A00000 } /* Generic.Deleted */\n",
       ".highlight .ge { font-style: italic } /* Generic.Emph */\n",
       ".highlight .gr { color: #FF0000 } /* Generic.Error */\n",
       ".highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */\n",
       ".highlight .gi { color: #00A000 } /* Generic.Inserted */\n",
       ".highlight .go { color: #888888 } /* Generic.Output */\n",
       ".highlight .gp { color: #000080; font-weight: bold } /* Generic.Prompt */\n",
       ".highlight .gs { font-weight: bold } /* Generic.Strong */\n",
       ".highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */\n",
       ".highlight .gt { color: #0044DD } /* Generic.Traceback */\n",
       ".highlight .kc { color: #008000; font-weight: bold } /* Keyword.Constant */\n",
       ".highlight .kd { color: #008000; font-weight: bold } /* Keyword.Declaration */\n",
       ".highlight .kn { color: #008000; font-weight: bold } /* Keyword.Namespace */\n",
       ".highlight .kp { color: #008000 } /* Keyword.Pseudo */\n",
       ".highlight .kr { color: #008000; font-weight: bold } /* Keyword.Reserved */\n",
       ".highlight .kt { color: #B00040 } /* Keyword.Type */\n",
       ".highlight .m { color: #666666 } /* Literal.Number */\n",
       ".highlight .s { color: #BA2121 } /* Literal.String */\n",
       ".highlight .na { color: #7D9029 } /* Name.Attribute */\n",
       ".highlight .nb { color: #008000 } /* Name.Builtin */\n",
       ".highlight .nc { color: #0000FF; font-weight: bold } /* Name.Class */\n",
       ".highlight .no { color: #880000 } /* Name.Constant */\n",
       ".highlight .nd { color: #AA22FF } /* Name.Decorator */\n",
       ".highlight .ni { color: #999999; font-weight: bold } /* Name.Entity */\n",
       ".highlight .ne { color: #D2413A; font-weight: bold } /* Name.Exception */\n",
       ".highlight .nf { color: #0000FF } /* Name.Function */\n",
       ".highlight .nl { color: #A0A000 } /* Name.Label */\n",
       ".highlight .nn { color: #0000FF; font-weight: bold } /* Name.Namespace */\n",
       ".highlight .nt { color: #008000; font-weight: bold } /* Name.Tag */\n",
       ".highlight .nv { color: #19177C } /* Name.Variable */\n",
       ".highlight .ow { color: #AA22FF; font-weight: bold } /* Operator.Word */\n",
       ".highlight .w { color: #bbbbbb } /* Text.Whitespace */\n",
       ".highlight .mb { color: #666666 } /* Literal.Number.Bin */\n",
       ".highlight .mf { color: #666666 } /* Literal.Number.Float */\n",
       ".highlight .mh { color: #666666 } /* Literal.Number.Hex */\n",
       ".highlight .mi { color: #666666 } /* Literal.Number.Integer */\n",
       ".highlight .mo { color: #666666 } /* Literal.Number.Oct */\n",
       ".highlight .sa { color: #BA2121 } /* Literal.String.Affix */\n",
       ".highlight .sb { color: #BA2121 } /* Literal.String.Backtick */\n",
       ".highlight .sc { color: #BA2121 } /* Literal.String.Char */\n",
       ".highlight .dl { color: #BA2121 } /* Literal.String.Delimiter */\n",
       ".highlight .sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */\n",
       ".highlight .s2 { color: #BA2121 } /* Literal.String.Double */\n",
       ".highlight .se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */\n",
       ".highlight .sh { color: #BA2121 } /* Literal.String.Heredoc */\n",
       ".highlight .si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */\n",
       ".highlight .sx { color: #008000 } /* Literal.String.Other */\n",
       ".highlight .sr { color: #BB6688 } /* Literal.String.Regex */\n",
       ".highlight .s1 { color: #BA2121 } /* Literal.String.Single */\n",
       ".highlight .ss { color: #19177C } /* Literal.String.Symbol */\n",
       ".highlight .bp { color: #008000 } /* Name.Builtin.Pseudo */\n",
       ".highlight .fm { color: #0000FF } /* Name.Function.Magic */\n",
       ".highlight .vc { color: #19177C } /* Name.Variable.Class */\n",
       ".highlight .vg { color: #19177C } /* Name.Variable.Global */\n",
       ".highlight .vi { color: #19177C } /* Name.Variable.Instance */\n",
       ".highlight .vm { color: #19177C } /* Name.Variable.Magic */\n",
       ".highlight .il { color: #666666 } /* Literal.Number.Integer.Long */</style>"
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/html": [
       "<div class=\"highlight\"><pre><span></span><span class=\"n\">FUNC_PREFIX</span> <span class=\"nf\">__launch_bounds__</span><span class=\"p\">(</span><span class=\"mi\">256</span><span class=\"p\">)</span> <span class=\"kt\">void</span> <span class=\"n\">kernel</span><span class=\"p\">(</span><span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I</span><span class=\"p\">,</span> <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst</span><span class=\"p\">)</span>\n",
       "<span class=\"p\">{</span>\n",
       "   <span class=\"k\">if</span> <span class=\"p\">(</span><span class=\"n\">blockDim</span><span class=\"p\">.</span><span class=\"n\">x</span><span class=\"o\">*</span><span class=\"n\">blockIdx</span><span class=\"p\">.</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">threadIdx</span><span class=\"p\">.</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\">&lt;</span> <span class=\"mi\">81</span> <span class=\"o\">&amp;&amp;</span> <span class=\"n\">blockDim</span><span class=\"p\">.</span><span class=\"n\">y</span><span class=\"o\">*</span><span class=\"n\">blockIdx</span><span class=\"p\">.</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">threadIdx</span><span class=\"p\">.</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"mi\">1</span> <span class=\"o\">&lt;</span> <span class=\"mi\">289</span><span class=\"p\">)</span>\n",
       "   <span class=\"p\">{</span>\n",
       "      <span class=\"k\">const</span> <span class=\"kt\">int64_t</span> <span class=\"n\">ctr_0</span> <span class=\"o\">=</span> <span class=\"n\">blockDim</span><span class=\"p\">.</span><span class=\"n\">x</span><span class=\"o\">*</span><span class=\"n\">blockIdx</span><span class=\"p\">.</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"n\">threadIdx</span><span class=\"p\">.</span><span class=\"n\">x</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">;</span>\n",
       "      <span class=\"k\">const</span> <span class=\"kt\">int64_t</span> <span class=\"n\">ctr_1</span> <span class=\"o\">=</span> <span class=\"n\">blockDim</span><span class=\"p\">.</span><span class=\"n\">y</span><span class=\"o\">*</span><span class=\"n\">blockIdx</span><span class=\"p\">.</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"n\">threadIdx</span><span class=\"p\">.</span><span class=\"n\">y</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"n\">_data_dst_10</span> <span class=\"o\">=</span> <span class=\"n\">_data_dst</span> <span class=\"o\">+</span> <span class=\"n\">ctr_1</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I_11_21</span> <span class=\"o\">=</span> <span class=\"n\">_data_I</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"mi\">5</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I_1m1_21</span> <span class=\"o\">=</span> <span class=\"n\">_data_I</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">-</span> <span class=\"mi\">3</span><span class=\"p\">;</span>\n",
       "      <span class=\"kt\">double</span> <span class=\"o\">*</span> <span class=\"n\">RESTRICT</span> <span class=\"k\">const</span> <span class=\"n\">_data_I_10_21</span> <span class=\"o\">=</span> <span class=\"n\">_data_I</span> <span class=\"o\">+</span> <span class=\"mi\">4</span><span class=\"o\">*</span><span class=\"n\">ctr_1</span> <span class=\"o\">+</span> <span class=\"mi\">1</span><span class=\"p\">;</span>\n",
       "      <span class=\"n\">_data_dst_10</span><span class=\"p\">[</span><span class=\"mi\">290</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span><span class=\"p\">]</span> <span class=\"o\">=</span> <span class=\"o\">-</span><span class=\"mi\">2</span><span class=\"o\">*</span><span class=\"n\">_data_I_10_21</span><span class=\"p\">[</span><span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">-</span> <span class=\"mi\">1160</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"mi\">2</span><span class=\"o\">*</span><span class=\"n\">_data_I_10_21</span><span class=\"p\">[</span><span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">+</span> <span class=\"mi\">1160</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">_data_I_11_21</span><span class=\"p\">[</span><span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">+</span> <span class=\"mi\">1160</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">_data_I_11_21</span><span class=\"p\">[</span><span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">-</span> <span class=\"mi\">1160</span><span class=\"p\">]</span> <span class=\"o\">+</span> <span class=\"n\">_data_I_1m1_21</span><span class=\"p\">[</span><span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">+</span> <span class=\"mi\">1160</span><span class=\"p\">]</span> <span class=\"o\">-</span> <span class=\"n\">_data_I_1m1_21</span><span class=\"p\">[</span><span class=\"mi\">1160</span><span class=\"o\">*</span><span class=\"n\">ctr_0</span> <span class=\"o\">-</span> <span class=\"mi\">1160</span><span class=\"p\">];</span>\n",
       "   <span class=\"p\">}</span> \n",
       "<span class=\"p\">}</span>\n",
       "</pre></div>\n"
      ],
      "text/plain": [
       "FUNC_PREFIX __launch_bounds__(256) void kernel(double * RESTRICT const _data_I, double * RESTRICT _data_dst)\n",
       "   if (blockDim.x*blockIdx.x + threadIdx.x + 1 < 81 && blockDim.y*blockIdx.y + threadIdx.y + 1 < 289)\n",
       "      const int64_t ctr_0 = blockDim.x*blockIdx.x + threadIdx.x + 1;\n",
       "      const int64_t ctr_1 = blockDim.y*blockIdx.y + threadIdx.y + 1;\n",
       "      double * RESTRICT _data_dst_10 = _data_dst + ctr_1;\n",
       "      double * RESTRICT const _data_I_11_21 = _data_I + 4*ctr_1 + 5;\n",
       "      double * RESTRICT const _data_I_1m1_21 = _data_I + 4*ctr_1 - 3;\n",
       "      double * RESTRICT const _data_I_10_21 = _data_I + 4*ctr_1 + 1;\n",
       "      _data_dst_10[290*ctr_0] = -2*_data_I_10_21[1160*ctr_0 - 1160] + 2*_data_I_10_21[1160*ctr_0 + 1160] - _data_I_11_21[1160*ctr_0 + 1160] - _data_I_11_21[1160*ctr_0 - 1160] + _data_I_1m1_21[1160*ctr_0 + 1160] - _data_I_1m1_21[1160*ctr_0 - 1160];\n",
       "   } \n",
       "}"
      ]
     },
     "execution_count": 38,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ps.show_code(gpu_ast)"
   ]
  }
 ],
 "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.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}