Skip to content

Instantly share code, notes, and snippets.

@seibert
Created March 1, 2021 15:02
Show Gist options
  • Save seibert/0be8825985400acbae5681aef2b2ee79 to your computer and use it in GitHub Desktop.
Save seibert/0be8825985400acbae5681aef2b2ee79 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "confidential-vancouver",
"metadata": {},
"outputs": [],
"source": [
"from mlir_graphblas import MlirOptCli\n",
"import logging\n",
"logging.basicConfig()\n",
"logging.getLogger('mlir_graphblas').setLevel(logging.DEBUG)"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "dutch-diagnosis",
"metadata": {},
"outputs": [],
"source": [
"opt = MlirOptCli()"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "cardiac-cabin",
"metadata": {},
"outputs": [],
"source": [
"add_sd_mlir = b'''\\\n",
"#trait_add = {\n",
" indexing_maps = [\n",
" affine_map<(i,j) -> (i,j)>, // A\n",
" affine_map<(i,j) -> (i,j)>, // B\n",
" affine_map<(i,j) -> (i,j)> // X (out)\n",
" ],\n",
" //sparse = [\n",
" // [ \"D\", \"D\" ], // A\n",
" // [ \"D\", \"D\" ], // B\n",
" // [ \"D\", \"D\" ] // X\n",
" //],\n",
" iterator_types = [\"parallel\", \"parallel\"],\n",
" doc = \"X(i,j) = A(i,j) OP B(i,j)\"\n",
"}\n",
"func @add_func(%arga: tensor<32x16xf32>, %argb: tensor<32x16xf32>) -> tensor<32x16xf32> {\n",
" %0 = linalg.generic #trait_add\n",
" ins(%arga, %argb: tensor<32x16xf32>, tensor<32x16xf32>)\n",
" outs(%arga: tensor<32x16xf32>) {\n",
" ^bb(%a: f32, %b: f32, %s: f32):\n",
" %0 = addf %a, %b : f32\n",
" linalg.yield %0 : f32\n",
" } -> tensor<32x16xf32>\n",
" return %0 : tensor<32x16xf32>\n",
"}\n",
"'''"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "driven-medium",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"DEBUG:mlir_graphblas:RUN: ['mlir-opt', '--linalg-bufferize']\n",
"DEBUG:mlir_graphblas:RUN: ['mlir-opt', '--func-bufferize']\n",
"DEBUG:mlir_graphblas:RUN: ['mlir-opt', '--finalizing-bufferize']\n",
"DEBUG:mlir_graphblas:RUN: ['mlir-opt', '--convert-linalg-to-loops']\n",
"DEBUG:mlir_graphblas:RUN: ['mlir-opt', '--convert-scf-to-std']\n",
"DEBUG:mlir_graphblas:RUN: ['mlir-opt', '--convert-std-to-llvm']\n"
]
}
],
"source": [
"passes = [\n",
" '--linalg-bufferize',\n",
" '--func-bufferize',\n",
" '--finalizing-bufferize',\n",
" '--convert-linalg-to-loops',\n",
" '--convert-scf-to-std',\n",
" '--convert-std-to-llvm',\n",
"]\n",
"result = opt.debug_passes(add_sd_mlir, passes)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "absent-oakland",
"metadata": {
"scrolled": false
},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
"(function(root) {\n",
" function now() {\n",
" return new Date();\n",
" }\n",
"\n",
" var force = true;\n",
"\n",
" if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n",
" root._bokeh_onload_callbacks = [];\n",
" root._bokeh_is_loading = undefined;\n",
" }\n",
"\n",
" if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n",
" root._bokeh_timeout = Date.now() + 5000;\n",
" root._bokeh_failed_load = false;\n",
" }\n",
"\n",
" function run_callbacks() {\n",
" try {\n",
" root._bokeh_onload_callbacks.forEach(function(callback) {\n",
" if (callback != null)\n",
" callback();\n",
" });\n",
" } finally {\n",
" delete root._bokeh_onload_callbacks\n",
" }\n",
" console.debug(\"Bokeh: all callbacks have finished\");\n",
" }\n",
"\n",
" function load_libs(css_urls, js_urls, callback) {\n",
" if (css_urls == null) css_urls = [];\n",
" if (js_urls == null) js_urls = [];\n",
"\n",
" root._bokeh_onload_callbacks.push(callback);\n",
" if (root._bokeh_is_loading > 0) {\n",
" console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n",
" return null;\n",
" }\n",
" if (js_urls == null || js_urls.length === 0) {\n",
" run_callbacks();\n",
" return null;\n",
" }\n",
" console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n",
" root._bokeh_is_loading = css_urls.length + js_urls.length;\n",
"\n",
" function on_load() {\n",
" root._bokeh_is_loading--;\n",
" if (root._bokeh_is_loading === 0) {\n",
" console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n",
" run_callbacks()\n",
" }\n",
" }\n",
"\n",
" function on_error() {\n",
" console.error(\"failed to load \" + url);\n",
" }\n",
"\n",
" for (var i = 0; i < css_urls.length; i++) {\n",
" var url = css_urls[i];\n",
" const element = document.createElement(\"link\");\n",
" element.onload = on_load;\n",
" element.onerror = on_error;\n",
" element.rel = \"stylesheet\";\n",
" element.type = \"text/css\";\n",
" element.href = url;\n",
" console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n",
" document.body.appendChild(element);\n",
" }\n",
"\n",
" var skip = [];\n",
" if (window.requirejs) {\n",
" require([], function() {\n",
" })\n",
" }\n",
" for (var i = 0; i < js_urls.length; i++) {\n",
" var url = js_urls[i];\n",
" if (skip.indexOf(url) >= 0) { on_load(); continue; }\n",
" var element = document.createElement('script');\n",
" element.onload = on_load;\n",
" element.onerror = on_error;\n",
" element.async = false;\n",
" element.src = url;\n",
" console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n",
" document.head.appendChild(element);\n",
" }\n",
"\tif (!js_urls.length) {\n",
" on_load()\n",
" }\n",
" };\n",
"\n",
" function inject_raw_css(css) {\n",
" const element = document.createElement(\"style\");\n",
" element.appendChild(document.createTextNode(css));\n",
" document.body.appendChild(element);\n",
" }\n",
"\n",
" var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.2.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.2.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.2.3.min.js\", \"https://unpkg.com/@holoviz/panel@^0.10.3/dist/panel.min.js\"];\n",
" var css_urls = [\"https://unpkg.com/@holoviz/[email protected]/dist/css/alerts.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/card.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/widgets.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/markdown.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/json.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/dataframe.css\"];\n",
"\n",
" var inline_js = [\n",
" function(Bokeh) {\n",
" Bokeh.set_log_level(\"info\");\n",
" },\n",
" function(Bokeh) {} // ensure no trailing comma for IE\n",
" ];\n",
"\n",
" function run_inline_js() {\n",
" if ((root.Bokeh !== undefined) || (force === true)) {\n",
" for (var i = 0; i < inline_js.length; i++) {\n",
" inline_js[i].call(root, root.Bokeh);\n",
" }} else if (Date.now() < root._bokeh_timeout) {\n",
" setTimeout(run_inline_js, 100);\n",
" } else if (!root._bokeh_failed_load) {\n",
" console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n",
" root._bokeh_failed_load = true;\n",
" }\n",
" }\n",
"\n",
" if (root._bokeh_is_loading === 0) {\n",
" console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n",
" run_inline_js();\n",
" } else {\n",
" load_libs(css_urls, js_urls, function() {\n",
" console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n",
" run_inline_js();\n",
" });\n",
" }\n",
"}(window));"
],
"application/vnd.holoviews_load.v0+json": "\n(function(root) {\n function now() {\n return new Date();\n }\n\n var force = true;\n\n if (typeof root._bokeh_onload_callbacks === \"undefined\" || force === true) {\n root._bokeh_onload_callbacks = [];\n root._bokeh_is_loading = undefined;\n }\n\n if (typeof (root._bokeh_timeout) === \"undefined\" || force === true) {\n root._bokeh_timeout = Date.now() + 5000;\n root._bokeh_failed_load = false;\n }\n\n function run_callbacks() {\n try {\n root._bokeh_onload_callbacks.forEach(function(callback) {\n if (callback != null)\n callback();\n });\n } finally {\n delete root._bokeh_onload_callbacks\n }\n console.debug(\"Bokeh: all callbacks have finished\");\n }\n\n function load_libs(css_urls, js_urls, callback) {\n if (css_urls == null) css_urls = [];\n if (js_urls == null) js_urls = [];\n\n root._bokeh_onload_callbacks.push(callback);\n if (root._bokeh_is_loading > 0) {\n console.debug(\"Bokeh: BokehJS is being loaded, scheduling callback at\", now());\n return null;\n }\n if (js_urls == null || js_urls.length === 0) {\n run_callbacks();\n return null;\n }\n console.debug(\"Bokeh: BokehJS not loaded, scheduling load and callback at\", now());\n root._bokeh_is_loading = css_urls.length + js_urls.length;\n\n function on_load() {\n root._bokeh_is_loading--;\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: all BokehJS libraries/stylesheets loaded\");\n run_callbacks()\n }\n }\n\n function on_error() {\n console.error(\"failed to load \" + url);\n }\n\n for (var i = 0; i < css_urls.length; i++) {\n var url = css_urls[i];\n const element = document.createElement(\"link\");\n element.onload = on_load;\n element.onerror = on_error;\n element.rel = \"stylesheet\";\n element.type = \"text/css\";\n element.href = url;\n console.debug(\"Bokeh: injecting link tag for BokehJS stylesheet: \", url);\n document.body.appendChild(element);\n }\n\n var skip = [];\n if (window.requirejs) {\n require([], function() {\n })\n }\n for (var i = 0; i < js_urls.length; i++) {\n var url = js_urls[i];\n if (skip.indexOf(url) >= 0) { on_load(); continue; }\n var element = document.createElement('script');\n element.onload = on_load;\n element.onerror = on_error;\n element.async = false;\n element.src = url;\n console.debug(\"Bokeh: injecting script tag for BokehJS library: \", url);\n document.head.appendChild(element);\n }\n\tif (!js_urls.length) {\n on_load()\n }\n };\n\n function inject_raw_css(css) {\n const element = document.createElement(\"style\");\n element.appendChild(document.createTextNode(css));\n document.body.appendChild(element);\n }\n\n var js_urls = [\"https://cdn.bokeh.org/bokeh/release/bokeh-2.2.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-widgets-2.2.3.min.js\", \"https://cdn.bokeh.org/bokeh/release/bokeh-tables-2.2.3.min.js\", \"https://unpkg.com/@holoviz/panel@^0.10.3/dist/panel.min.js\"];\n var css_urls = [\"https://unpkg.com/@holoviz/[email protected]/dist/css/alerts.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/card.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/widgets.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/markdown.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/json.css\", \"https://unpkg.com/@holoviz/[email protected]/dist/css/dataframe.css\"];\n\n var inline_js = [\n function(Bokeh) {\n Bokeh.set_log_level(\"info\");\n },\n function(Bokeh) {} // ensure no trailing comma for IE\n ];\n\n function run_inline_js() {\n if ((root.Bokeh !== undefined) || (force === true)) {\n for (var i = 0; i < inline_js.length; i++) {\n inline_js[i].call(root, root.Bokeh);\n }} else if (Date.now() < root._bokeh_timeout) {\n setTimeout(run_inline_js, 100);\n } else if (!root._bokeh_failed_load) {\n console.log(\"Bokeh: BokehJS failed to load within specified timeout.\");\n root._bokeh_failed_load = true;\n }\n }\n\n if (root._bokeh_is_loading === 0) {\n console.debug(\"Bokeh: BokehJS loaded, going straight to plotting\");\n run_inline_js();\n } else {\n load_libs(css_urls, js_urls, function() {\n console.debug(\"Bokeh: BokehJS plotting callback run at\", now());\n run_inline_js();\n });\n }\n}(window));"
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
"if ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n",
" window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n",
"}\n",
"\n",
"\n",
" function JupyterCommManager() {\n",
" }\n",
"\n",
" JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n",
" if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
" var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
" comm_manager.register_target(comm_id, function(comm) {\n",
" comm.on_msg(msg_handler);\n",
" });\n",
" } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
" window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n",
" comm.onMsg = msg_handler;\n",
" });\n",
" } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
" google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n",
" var messages = comm.messages[Symbol.asyncIterator]();\n",
" function processIteratorResult(result) {\n",
" var message = result.value;\n",
" console.log(message)\n",
" var content = {data: message.data, comm_id};\n",
" var buffers = []\n",
" for (var buffer of message.buffers || []) {\n",
" buffers.push(new DataView(buffer))\n",
" }\n",
" var metadata = message.metadata || {};\n",
" var msg = {content, buffers, metadata}\n",
" msg_handler(msg);\n",
" return messages.next().then(processIteratorResult);\n",
" }\n",
" return messages.next().then(processIteratorResult);\n",
" })\n",
" }\n",
" }\n",
"\n",
" JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n",
" if (comm_id in window.PyViz.comms) {\n",
" return window.PyViz.comms[comm_id];\n",
" } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n",
" var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n",
" var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n",
" if (msg_handler) {\n",
" comm.on_msg(msg_handler);\n",
" }\n",
" } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n",
" var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n",
" comm.open();\n",
" if (msg_handler) {\n",
" comm.onMsg = msg_handler;\n",
" }\n",
" } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n",
" var comm_promise = google.colab.kernel.comms.open(comm_id)\n",
" comm_promise.then((comm) => {\n",
" window.PyViz.comms[comm_id] = comm;\n",
" if (msg_handler) {\n",
" var messages = comm.messages[Symbol.asyncIterator]();\n",
" function processIteratorResult(result) {\n",
" var message = result.value;\n",
" var content = {data: message.data};\n",
" var metadata = message.metadata || {comm_id};\n",
" var msg = {content, metadata}\n",
" msg_handler(msg);\n",
" return messages.next().then(processIteratorResult);\n",
" }\n",
" return messages.next().then(processIteratorResult);\n",
" }\n",
" }) \n",
" var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n",
" return comm_promise.then((comm) => {\n",
" comm.send(data, metadata, buffers, disposeOnDone);\n",
" });\n",
" };\n",
" var comm = {\n",
" send: sendClosure\n",
" };\n",
" }\n",
" window.PyViz.comms[comm_id] = comm;\n",
" return comm;\n",
" }\n",
" window.PyViz.comm_manager = new JupyterCommManager();\n",
" \n",
"\n",
"\n",
"var JS_MIME_TYPE = 'application/javascript';\n",
"var HTML_MIME_TYPE = 'text/html';\n",
"var EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\n",
"var CLASS_NAME = 'output';\n",
"\n",
"/**\n",
" * Render data to the DOM node\n",
" */\n",
"function render(props, node) {\n",
" var div = document.createElement(\"div\");\n",
" var script = document.createElement(\"script\");\n",
" node.appendChild(div);\n",
" node.appendChild(script);\n",
"}\n",
"\n",
"/**\n",
" * Handle when a new output is added\n",
" */\n",
"function handle_add_output(event, handle) {\n",
" var output_area = handle.output_area;\n",
" var output = handle.output;\n",
" if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n",
" return\n",
" }\n",
" var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n",
" var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n",
" if (id !== undefined) {\n",
" var nchildren = toinsert.length;\n",
" var html_node = toinsert[nchildren-1].children[0];\n",
" html_node.innerHTML = output.data[HTML_MIME_TYPE];\n",
" var scripts = [];\n",
" var nodelist = html_node.querySelectorAll(\"script\");\n",
" for (var i in nodelist) {\n",
" if (nodelist.hasOwnProperty(i)) {\n",
" scripts.push(nodelist[i])\n",
" }\n",
" }\n",
"\n",
" scripts.forEach( function (oldScript) {\n",
" var newScript = document.createElement(\"script\");\n",
" var attrs = [];\n",
" var nodemap = oldScript.attributes;\n",
" for (var j in nodemap) {\n",
" if (nodemap.hasOwnProperty(j)) {\n",
" attrs.push(nodemap[j])\n",
" }\n",
" }\n",
" attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n",
" newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n",
" oldScript.parentNode.replaceChild(newScript, oldScript);\n",
" });\n",
" if (JS_MIME_TYPE in output.data) {\n",
" toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n",
" }\n",
" output_area._hv_plot_id = id;\n",
" if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n",
" window.PyViz.plot_index[id] = Bokeh.index[id];\n",
" } else {\n",
" window.PyViz.plot_index[id] = null;\n",
" }\n",
" } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n",
" var bk_div = document.createElement(\"div\");\n",
" bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n",
" var script_attrs = bk_div.children[0].attributes;\n",
" for (var i = 0; i < script_attrs.length; i++) {\n",
" toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n",
" }\n",
" // store reference to server id on output_area\n",
" output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n",
" }\n",
"}\n",
"\n",
"/**\n",
" * Handle when an output is cleared or removed\n",
" */\n",
"function handle_clear_output(event, handle) {\n",
" var id = handle.cell.output_area._hv_plot_id;\n",
" var server_id = handle.cell.output_area._bokeh_server_id;\n",
" if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n",
" var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n",
" if (server_id !== null) {\n",
" comm.send({event_type: 'server_delete', 'id': server_id});\n",
" return;\n",
" } else if (comm !== null) {\n",
" comm.send({event_type: 'delete', 'id': id});\n",
" }\n",
" delete PyViz.plot_index[id];\n",
" if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n",
" var doc = window.Bokeh.index[id].model.document\n",
" doc.clear();\n",
" const i = window.Bokeh.documents.indexOf(doc);\n",
" if (i > -1) {\n",
" window.Bokeh.documents.splice(i, 1);\n",
" }\n",
" }\n",
"}\n",
"\n",
"/**\n",
" * Handle kernel restart event\n",
" */\n",
"function handle_kernel_cleanup(event, handle) {\n",
" delete PyViz.comms[\"hv-extension-comm\"];\n",
" window.PyViz.plot_index = {}\n",
"}\n",
"\n",
"/**\n",
" * Handle update_display_data messages\n",
" */\n",
"function handle_update_output(event, handle) {\n",
" handle_clear_output(event, {cell: {output_area: handle.output_area}})\n",
" handle_add_output(event, handle)\n",
"}\n",
"\n",
"function register_renderer(events, OutputArea) {\n",
" function append_mime(data, metadata, element) {\n",
" // create a DOM node to render to\n",
" var toinsert = this.create_output_subarea(\n",
" metadata,\n",
" CLASS_NAME,\n",
" EXEC_MIME_TYPE\n",
" );\n",
" this.keyboard_manager.register_events(toinsert);\n",
" // Render to node\n",
" var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n",
" render(props, toinsert[0]);\n",
" element.append(toinsert);\n",
" return toinsert\n",
" }\n",
"\n",
" events.on('output_added.OutputArea', handle_add_output);\n",
" events.on('output_updated.OutputArea', handle_update_output);\n",
" events.on('clear_output.CodeCell', handle_clear_output);\n",
" events.on('delete.Cell', handle_clear_output);\n",
" events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n",
"\n",
" OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n",
" safe: true,\n",
" index: 0\n",
" });\n",
"}\n",
"\n",
"if (window.Jupyter !== undefined) {\n",
" try {\n",
" var events = require('base/js/events');\n",
" var OutputArea = require('notebook/js/outputarea').OutputArea;\n",
" if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n",
" register_renderer(events, OutputArea);\n",
" }\n",
" } catch(err) {\n",
" }\n",
"}\n"
],
"application/vnd.holoviews_load.v0+json": "\nif ((window.PyViz === undefined) || (window.PyViz instanceof HTMLElement)) {\n window.PyViz = {comms: {}, comm_status:{}, kernels:{}, receivers: {}, plot_index: []}\n}\n\n\n function JupyterCommManager() {\n }\n\n JupyterCommManager.prototype.register_target = function(plot_id, comm_id, msg_handler) {\n if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n comm_manager.register_target(comm_id, function(comm) {\n comm.on_msg(msg_handler);\n });\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n window.PyViz.kernels[plot_id].registerCommTarget(comm_id, function(comm) {\n comm.onMsg = msg_handler;\n });\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n google.colab.kernel.comms.registerTarget(comm_id, (comm) => {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n console.log(message)\n var content = {data: message.data, comm_id};\n var buffers = []\n for (var buffer of message.buffers || []) {\n buffers.push(new DataView(buffer))\n }\n var metadata = message.metadata || {};\n var msg = {content, buffers, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n })\n }\n }\n\n JupyterCommManager.prototype.get_client_comm = function(plot_id, comm_id, msg_handler) {\n if (comm_id in window.PyViz.comms) {\n return window.PyViz.comms[comm_id];\n } else if (window.comm_manager || ((window.Jupyter !== undefined) && (Jupyter.notebook.kernel != null))) {\n var comm_manager = window.comm_manager || Jupyter.notebook.kernel.comm_manager;\n var comm = comm_manager.new_comm(comm_id, {}, {}, {}, comm_id);\n if (msg_handler) {\n comm.on_msg(msg_handler);\n }\n } else if ((plot_id in window.PyViz.kernels) && (window.PyViz.kernels[plot_id])) {\n var comm = window.PyViz.kernels[plot_id].connectToComm(comm_id);\n comm.open();\n if (msg_handler) {\n comm.onMsg = msg_handler;\n }\n } else if (typeof google != 'undefined' && google.colab.kernel != null) {\n var comm_promise = google.colab.kernel.comms.open(comm_id)\n comm_promise.then((comm) => {\n window.PyViz.comms[comm_id] = comm;\n if (msg_handler) {\n var messages = comm.messages[Symbol.asyncIterator]();\n function processIteratorResult(result) {\n var message = result.value;\n var content = {data: message.data};\n var metadata = message.metadata || {comm_id};\n var msg = {content, metadata}\n msg_handler(msg);\n return messages.next().then(processIteratorResult);\n }\n return messages.next().then(processIteratorResult);\n }\n }) \n var sendClosure = (data, metadata, buffers, disposeOnDone) => {\n return comm_promise.then((comm) => {\n comm.send(data, metadata, buffers, disposeOnDone);\n });\n };\n var comm = {\n send: sendClosure\n };\n }\n window.PyViz.comms[comm_id] = comm;\n return comm;\n }\n window.PyViz.comm_manager = new JupyterCommManager();\n \n\n\nvar JS_MIME_TYPE = 'application/javascript';\nvar HTML_MIME_TYPE = 'text/html';\nvar EXEC_MIME_TYPE = 'application/vnd.holoviews_exec.v0+json';\nvar CLASS_NAME = 'output';\n\n/**\n * Render data to the DOM node\n */\nfunction render(props, node) {\n var div = document.createElement(\"div\");\n var script = document.createElement(\"script\");\n node.appendChild(div);\n node.appendChild(script);\n}\n\n/**\n * Handle when a new output is added\n */\nfunction handle_add_output(event, handle) {\n var output_area = handle.output_area;\n var output = handle.output;\n if ((output.data == undefined) || (!output.data.hasOwnProperty(EXEC_MIME_TYPE))) {\n return\n }\n var id = output.metadata[EXEC_MIME_TYPE][\"id\"];\n var toinsert = output_area.element.find(\".\" + CLASS_NAME.split(' ')[0]);\n if (id !== undefined) {\n var nchildren = toinsert.length;\n var html_node = toinsert[nchildren-1].children[0];\n html_node.innerHTML = output.data[HTML_MIME_TYPE];\n var scripts = [];\n var nodelist = html_node.querySelectorAll(\"script\");\n for (var i in nodelist) {\n if (nodelist.hasOwnProperty(i)) {\n scripts.push(nodelist[i])\n }\n }\n\n scripts.forEach( function (oldScript) {\n var newScript = document.createElement(\"script\");\n var attrs = [];\n var nodemap = oldScript.attributes;\n for (var j in nodemap) {\n if (nodemap.hasOwnProperty(j)) {\n attrs.push(nodemap[j])\n }\n }\n attrs.forEach(function(attr) { newScript.setAttribute(attr.name, attr.value) });\n newScript.appendChild(document.createTextNode(oldScript.innerHTML));\n oldScript.parentNode.replaceChild(newScript, oldScript);\n });\n if (JS_MIME_TYPE in output.data) {\n toinsert[nchildren-1].children[1].textContent = output.data[JS_MIME_TYPE];\n }\n output_area._hv_plot_id = id;\n if ((window.Bokeh !== undefined) && (id in Bokeh.index)) {\n window.PyViz.plot_index[id] = Bokeh.index[id];\n } else {\n window.PyViz.plot_index[id] = null;\n }\n } else if (output.metadata[EXEC_MIME_TYPE][\"server_id\"] !== undefined) {\n var bk_div = document.createElement(\"div\");\n bk_div.innerHTML = output.data[HTML_MIME_TYPE];\n var script_attrs = bk_div.children[0].attributes;\n for (var i = 0; i < script_attrs.length; i++) {\n toinsert[toinsert.length - 1].childNodes[1].setAttribute(script_attrs[i].name, script_attrs[i].value);\n }\n // store reference to server id on output_area\n output_area._bokeh_server_id = output.metadata[EXEC_MIME_TYPE][\"server_id\"];\n }\n}\n\n/**\n * Handle when an output is cleared or removed\n */\nfunction handle_clear_output(event, handle) {\n var id = handle.cell.output_area._hv_plot_id;\n var server_id = handle.cell.output_area._bokeh_server_id;\n if (((id === undefined) || !(id in PyViz.plot_index)) && (server_id !== undefined)) { return; }\n var comm = window.PyViz.comm_manager.get_client_comm(\"hv-extension-comm\", \"hv-extension-comm\", function () {});\n if (server_id !== null) {\n comm.send({event_type: 'server_delete', 'id': server_id});\n return;\n } else if (comm !== null) {\n comm.send({event_type: 'delete', 'id': id});\n }\n delete PyViz.plot_index[id];\n if ((window.Bokeh !== undefined) & (id in window.Bokeh.index)) {\n var doc = window.Bokeh.index[id].model.document\n doc.clear();\n const i = window.Bokeh.documents.indexOf(doc);\n if (i > -1) {\n window.Bokeh.documents.splice(i, 1);\n }\n }\n}\n\n/**\n * Handle kernel restart event\n */\nfunction handle_kernel_cleanup(event, handle) {\n delete PyViz.comms[\"hv-extension-comm\"];\n window.PyViz.plot_index = {}\n}\n\n/**\n * Handle update_display_data messages\n */\nfunction handle_update_output(event, handle) {\n handle_clear_output(event, {cell: {output_area: handle.output_area}})\n handle_add_output(event, handle)\n}\n\nfunction register_renderer(events, OutputArea) {\n function append_mime(data, metadata, element) {\n // create a DOM node to render to\n var toinsert = this.create_output_subarea(\n metadata,\n CLASS_NAME,\n EXEC_MIME_TYPE\n );\n this.keyboard_manager.register_events(toinsert);\n // Render to node\n var props = {data: data, metadata: metadata[EXEC_MIME_TYPE]};\n render(props, toinsert[0]);\n element.append(toinsert);\n return toinsert\n }\n\n events.on('output_added.OutputArea', handle_add_output);\n events.on('output_updated.OutputArea', handle_update_output);\n events.on('clear_output.CodeCell', handle_clear_output);\n events.on('delete.Cell', handle_clear_output);\n events.on('kernel_ready.Kernel', handle_kernel_cleanup);\n\n OutputArea.prototype.register_mime_type(EXEC_MIME_TYPE, append_mime, {\n safe: true,\n index: 0\n });\n}\n\nif (window.Jupyter !== undefined) {\n try {\n var events = require('base/js/events');\n var OutputArea = require('notebook/js/outputarea').OutputArea;\n if (OutputArea.prototype.mime_types().indexOf(EXEC_MIME_TYPE) == -1) {\n register_renderer(events, OutputArea);\n }\n } catch(err) {\n }\n}\n"
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/vnd.holoviews_exec.v0+json": "",
"text/html": [
"<div id='1001'>\n",
"\n",
"\n",
"\n",
"\n",
"\n",
" <div class=\"bk-root\" id=\"06327318-09b9-4fc5-977f-e92aba9d7588\" data-root-id=\"1001\"></div>\n",
"</div>\n",
"<script type=\"application/javascript\">(function(root) {\n",
" function embed_document(root) {\n",
" var docs_json = {\"3edfffc3-603e-4fff-9a0e-b7b33a9cc9e7\":{\"roots\":{\"references\":[{\"attributes\":{\"button_type\":\"primary\",\"icon\":null,\"label\":\"\\u25c0\",\"margin\":[5,10,5,10],\"min_width\":200,\"subscribed_events\":[\"button_click\"],\"width\":200},\"id\":\"1005\",\"type\":\"Button\"},{\"attributes\":{\"children\":[{\"id\":\"1003\"},{\"id\":\"1004\"},{\"id\":\"1007\"}],\"margin\":[0,0,0,0],\"name\":\"Column00017\"},\"id\":\"1002\",\"type\":\"Column\"},{\"attributes\":{\"margin\":[0,0,0,0],\"tabs\":[{\"id\":\"1010\"},{\"id\":\"1014\"},{\"id\":\"1022\"}]},\"id\":\"1001\",\"type\":\"Tabs\"},{\"attributes\":{\"client_comm_id\":\"e53f4b8724be440d9d0577c84e459a0c\",\"comm_id\":\"2ee34e3606cc490c987ae8772c048076\",\"plot_id\":\"1001\"},\"id\":\"1023\",\"type\":\"panel.models.comm_manager.CommManager\"},{\"attributes\":{\"reload\":false},\"id\":\"1024\",\"type\":\"panel.models.location.Location\"},{\"attributes\":{\"children\":[{\"id\":\"1016\"},{\"id\":\"1019\"}],\"margin\":[0,0,0,0],\"name\":\"Row00030\"},\"id\":\"1015\",\"type\":\"Row\"},{\"attributes\":{\"margin\":[5,10,5,10],\"options\":[\"Initial\",\"linalg-bufferize\",\"func-bufferize\",\"finalizing-bufferize\",\"convert-linalg-to-loops\",\"convert-scf-to-std\",\"convert-std-to-llvm\"],\"title\":\"Passes\",\"value\":\"Initial\"},\"id\":\"1012\",\"type\":\"Select\"},{\"attributes\":{\"children\":[{\"id\":\"1008\"},{\"id\":\"1009\"}],\"margin\":[0,0,0,0],\"max_width\":400,\"name\":\"Row00016\"},\"id\":\"1007\",\"type\":\"Row\"},{\"attributes\":{\"child\":{\"id\":\"1011\"},\"name\":\"Column00021\",\"title\":\"Single\"},\"id\":\"1014\",\"type\":\"Panel\"},{\"attributes\":{\"margin\":[5,5,5,5],\"name\":\"HTML00027\",\"text\":\"\\n&lt;html&gt;\\n&lt;head&gt;\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/codemirror.min.js&quot;&gt;\\n&lt;/script&gt;\\n\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/mode/javascript/javascript.min.js&quot;&gt;\\n&lt;/script&gt;\\n&lt;/head&gt;\\n&lt;body&gt;\\n\\n&lt;div&gt;\\n&lt;textarea id=&quot;foobar_double2&quot;&gt;\\n#map = affine_map&lt;(d0, d1) -&gt; (d0, d1)&gt;\\nmodule {\\n func @add_func(%arg0: tensor&lt;32x16xf32&gt;, %arg1: tensor&lt;32x16xf32&gt;) -&gt; tensor&lt;32x16xf32&gt; {\\n %0 = tensor_to_memref %arg0 : memref&lt;32x16xf32&gt;\\n %1 = tensor_to_memref %arg1 : memref&lt;32x16xf32&gt;\\n %2 = tensor_to_memref %arg0 : memref&lt;32x16xf32&gt;\\n %3 = alloc() : memref&lt;32x16xf32&gt;\\n linalg.generic {doc = &quot;X(i,j) = A(i,j) OP B(i,j)&quot;, indexing_maps = [#map, #map, #map], iterator_types = [&quot;parallel&quot;, &quot;parallel&quot;]} ins(%0, %1 : memref&lt;32x16xf32&gt;, memref&lt;32x16xf32&gt;) outs(%3 : memref&lt;32x16xf32&gt;) {\\n ^bb0(%arg2: f32, %arg3: f32, %arg4: f32): // no predecessors\\n %5 = addf %arg2, %arg3 : f32\\n linalg.yield %5 : f32\\n }\\n %4 = tensor_load %3 : memref&lt;32x16xf32&gt;\\n return %4 : tensor&lt;32x16xf32&gt;\\n }\\n}\\n\\n\\n&lt;/textarea&gt;\\n&lt;/div&gt;\\n\\n&lt;script&gt;\\nvar config = {\\n lineNumbers: true,\\n tabSize: 2,\\n readOnly: true,\\n mode: &#x27;javascript&#x27;,\\n};\\nvar myTextArea = document.querySelector(&#x27;#foobar_double2&#x27;);\\nvar cm = CodeMirror.fromTextArea(myTextArea, config);\\n&lt;/script&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n\"},\"id\":\"1021\",\"type\":\"panel.models.markup.HTML\"},{\"attributes\":{\"children\":[{\"id\":\"1017\"},{\"id\":\"1018\"}],\"margin\":[0,0,0,0],\"name\":\"Column00025\"},\"id\":\"1016\",\"type\":\"Column\"},{\"attributes\":{\"child\":{\"id\":\"1002\"},\"name\":\"Column00017\",\"title\":\"Sequential\"},\"id\":\"1010\",\"type\":\"Panel\"},{\"attributes\":{\"margin\":[5,10,5,10],\"options\":[\"Initial\",\"linalg-bufferize\",\"func-bufferize\",\"finalizing-bufferize\",\"convert-linalg-to-loops\",\"convert-scf-to-std\",\"convert-std-to-llvm\"],\"title\":\"Passes\",\"value\":\"Initial\"},\"id\":\"1017\",\"type\":\"Select\"},{\"attributes\":{\"children\":[{\"id\":\"1005\"},{\"id\":\"1006\"}],\"margin\":[0,0,0,0],\"name\":\"Row00011\"},\"id\":\"1004\",\"type\":\"Row\"},{\"attributes\":{\"button_type\":\"primary\",\"icon\":null,\"label\":\"\\u25b6\",\"margin\":[5,10,5,10],\"min_width\":200,\"subscribed_events\":[\"button_click\"],\"width\":200},\"id\":\"1006\",\"type\":\"Button\"},{\"attributes\":{\"children\":[{\"id\":\"1020\"},{\"id\":\"1021\"}],\"margin\":[0,0,0,0],\"name\":\"Column00029\"},\"id\":\"1019\",\"type\":\"Column\"},{\"attributes\":{\"margin\":[5,10,5,10],\"options\":[\"linalg-bufferize\",\"func-bufferize\",\"finalizing-bufferize\",\"convert-linalg-to-loops\",\"convert-scf-to-std\",\"convert-std-to-llvm\"],\"title\":\"Passes\",\"value\":\"linalg-bufferize\"},\"id\":\"1003\",\"type\":\"Select\"},{\"attributes\":{\"child\":{\"id\":\"1015\"},\"name\":\"Row00030\",\"title\":\"Double\"},\"id\":\"1022\",\"type\":\"Panel\"},{\"attributes\":{\"children\":[{\"id\":\"1012\"},{\"id\":\"1013\"}],\"margin\":[0,0,0,0],\"name\":\"Column00021\"},\"id\":\"1011\",\"type\":\"Column\"},{\"attributes\":{\"margin\":[5,5,5,5],\"name\":\"HTML00014\",\"text\":\"\\n&lt;html&gt;\\n&lt;head&gt;\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/codemirror.min.js&quot;&gt;\\n&lt;/script&gt;\\n\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/mode/javascript/javascript.min.js&quot;&gt;\\n&lt;/script&gt;\\n&lt;/head&gt;\\n&lt;body&gt;\\n\\n&lt;div&gt;\\n&lt;textarea id=&quot;foobar_seq2&quot;&gt;\\n#map = affine_map&lt;(d0, d1) -&gt; (d0, d1)&gt;\\nmodule {\\n func @add_func(%arg0: tensor&lt;32x16xf32&gt;, %arg1: tensor&lt;32x16xf32&gt;) -&gt; tensor&lt;32x16xf32&gt; {\\n %0 = tensor_to_memref %arg0 : memref&lt;32x16xf32&gt;\\n %1 = tensor_to_memref %arg1 : memref&lt;32x16xf32&gt;\\n %2 = tensor_to_memref %arg0 : memref&lt;32x16xf32&gt;\\n %3 = alloc() : memref&lt;32x16xf32&gt;\\n linalg.generic {doc = &quot;X(i,j) = A(i,j) OP B(i,j)&quot;, indexing_maps = [#map, #map, #map], iterator_types = [&quot;parallel&quot;, &quot;parallel&quot;]} ins(%0, %1 : memref&lt;32x16xf32&gt;, memref&lt;32x16xf32&gt;) outs(%3 : memref&lt;32x16xf32&gt;) {\\n ^bb0(%arg2: f32, %arg3: f32, %arg4: f32): // no predecessors\\n %5 = addf %arg2, %arg3 : f32\\n linalg.yield %5 : f32\\n }\\n %4 = tensor_load %3 : memref&lt;32x16xf32&gt;\\n return %4 : tensor&lt;32x16xf32&gt;\\n }\\n}\\n\\n\\n&lt;/textarea&gt;\\n&lt;/div&gt;\\n\\n&lt;script&gt;\\nvar config = {\\n lineNumbers: true,\\n tabSize: 2,\\n readOnly: true,\\n mode: &#x27;javascript&#x27;,\\n};\\nvar myTextArea = document.querySelector(&#x27;#foobar_seq2&#x27;);\\nvar cm = CodeMirror.fromTextArea(myTextArea, config);\\n&lt;/script&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n\"},\"id\":\"1009\",\"type\":\"panel.models.markup.HTML\"},{\"attributes\":{\"margin\":[5,5,5,5],\"name\":\"HTML00012\",\"text\":\"\\n&lt;html&gt;\\n&lt;head&gt;\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/codemirror.min.js&quot;&gt;\\n&lt;/script&gt;\\n\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/mode/javascript/javascript.min.js&quot;&gt;\\n&lt;/script&gt;\\n&lt;/head&gt;\\n&lt;body&gt;\\n\\n&lt;div&gt;\\n&lt;textarea id=&quot;foobar_seq1&quot;&gt;\\n#trait_add = {\\n indexing_maps = [\\n affine_map&lt;(i,j) -&gt; (i,j)&gt;, // A\\n affine_map&lt;(i,j) -&gt; (i,j)&gt;, // B\\n affine_map&lt;(i,j) -&gt; (i,j)&gt; // X (out)\\n ],\\n //sparse = [\\n // [ &quot;D&quot;, &quot;D&quot; ], // A\\n // [ &quot;D&quot;, &quot;D&quot; ], // B\\n // [ &quot;D&quot;, &quot;D&quot; ] // X\\n //],\\n iterator_types = [&quot;parallel&quot;, &quot;parallel&quot;],\\n doc = &quot;X(i,j) = A(i,j) OP B(i,j)&quot;\\n}\\nfunc @add_func(%arga: tensor&lt;32x16xf32&gt;, %argb: tensor&lt;32x16xf32&gt;) -&gt; tensor&lt;32x16xf32&gt; {\\n %0 = linalg.generic #trait_add\\n ins(%arga, %argb: tensor&lt;32x16xf32&gt;, tensor&lt;32x16xf32&gt;)\\n outs(%arga: tensor&lt;32x16xf32&gt;) {\\n ^bb(%a: f32, %b: f32, %s: f32):\\n %0 = addf %a, %b : f32\\n linalg.yield %0 : f32\\n } -&gt; tensor&lt;32x16xf32&gt;\\n return %0 : tensor&lt;32x16xf32&gt;\\n}\\n\\n&lt;/textarea&gt;\\n&lt;/div&gt;\\n\\n&lt;script&gt;\\nvar config = {\\n lineNumbers: true,\\n tabSize: 2,\\n readOnly: true,\\n mode: &#x27;javascript&#x27;,\\n};\\nvar myTextArea = document.querySelector(&#x27;#foobar_seq1&#x27;);\\nvar cm = CodeMirror.fromTextArea(myTextArea, config);\\n&lt;/script&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n\"},\"id\":\"1008\",\"type\":\"panel.models.markup.HTML\"},{\"attributes\":{\"margin\":[5,10,5,10],\"options\":[\"Initial\",\"linalg-bufferize\",\"func-bufferize\",\"finalizing-bufferize\",\"convert-linalg-to-loops\",\"convert-scf-to-std\",\"convert-std-to-llvm\"],\"title\":\"Passes\",\"value\":\"linalg-bufferize\"},\"id\":\"1020\",\"type\":\"Select\"},{\"attributes\":{\"margin\":[5,5,5,5],\"name\":\"HTML00023\",\"text\":\"\\n&lt;html&gt;\\n&lt;head&gt;\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/codemirror.min.js&quot;&gt;\\n&lt;/script&gt;\\n\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/mode/javascript/javascript.min.js&quot;&gt;\\n&lt;/script&gt;\\n&lt;/head&gt;\\n&lt;body&gt;\\n\\n&lt;div&gt;\\n&lt;textarea id=&quot;foobar_double1&quot;&gt;\\n#trait_add = {\\n indexing_maps = [\\n affine_map&lt;(i,j) -&gt; (i,j)&gt;, // A\\n affine_map&lt;(i,j) -&gt; (i,j)&gt;, // B\\n affine_map&lt;(i,j) -&gt; (i,j)&gt; // X (out)\\n ],\\n //sparse = [\\n // [ &quot;D&quot;, &quot;D&quot; ], // A\\n // [ &quot;D&quot;, &quot;D&quot; ], // B\\n // [ &quot;D&quot;, &quot;D&quot; ] // X\\n //],\\n iterator_types = [&quot;parallel&quot;, &quot;parallel&quot;],\\n doc = &quot;X(i,j) = A(i,j) OP B(i,j)&quot;\\n}\\nfunc @add_func(%arga: tensor&lt;32x16xf32&gt;, %argb: tensor&lt;32x16xf32&gt;) -&gt; tensor&lt;32x16xf32&gt; {\\n %0 = linalg.generic #trait_add\\n ins(%arga, %argb: tensor&lt;32x16xf32&gt;, tensor&lt;32x16xf32&gt;)\\n outs(%arga: tensor&lt;32x16xf32&gt;) {\\n ^bb(%a: f32, %b: f32, %s: f32):\\n %0 = addf %a, %b : f32\\n linalg.yield %0 : f32\\n } -&gt; tensor&lt;32x16xf32&gt;\\n return %0 : tensor&lt;32x16xf32&gt;\\n}\\n\\n&lt;/textarea&gt;\\n&lt;/div&gt;\\n\\n&lt;script&gt;\\nvar config = {\\n lineNumbers: true,\\n tabSize: 2,\\n readOnly: true,\\n mode: &#x27;javascript&#x27;,\\n};\\nvar myTextArea = document.querySelector(&#x27;#foobar_double1&#x27;);\\nvar cm = CodeMirror.fromTextArea(myTextArea, config);\\n&lt;/script&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n\"},\"id\":\"1018\",\"type\":\"panel.models.markup.HTML\"},{\"attributes\":{\"margin\":[5,5,5,5],\"name\":\"HTML00019\",\"text\":\"\\n&lt;html&gt;\\n&lt;head&gt;\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/codemirror.min.js&quot;&gt;\\n&lt;/script&gt;\\n\\n&lt;script type=&quot;text/javascript&quot;\\n src=&quot;https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.52.2/mode/javascript/javascript.min.js&quot;&gt;\\n&lt;/script&gt;\\n&lt;/head&gt;\\n&lt;body&gt;\\n\\n&lt;div&gt;\\n&lt;textarea id=&quot;foobar_single&quot;&gt;\\n#trait_add = {\\n indexing_maps = [\\n affine_map&lt;(i,j) -&gt; (i,j)&gt;, // A\\n affine_map&lt;(i,j) -&gt; (i,j)&gt;, // B\\n affine_map&lt;(i,j) -&gt; (i,j)&gt; // X (out)\\n ],\\n //sparse = [\\n // [ &quot;D&quot;, &quot;D&quot; ], // A\\n // [ &quot;D&quot;, &quot;D&quot; ], // B\\n // [ &quot;D&quot;, &quot;D&quot; ] // X\\n //],\\n iterator_types = [&quot;parallel&quot;, &quot;parallel&quot;],\\n doc = &quot;X(i,j) = A(i,j) OP B(i,j)&quot;\\n}\\nfunc @add_func(%arga: tensor&lt;32x16xf32&gt;, %argb: tensor&lt;32x16xf32&gt;) -&gt; tensor&lt;32x16xf32&gt; {\\n %0 = linalg.generic #trait_add\\n ins(%arga, %argb: tensor&lt;32x16xf32&gt;, tensor&lt;32x16xf32&gt;)\\n outs(%arga: tensor&lt;32x16xf32&gt;) {\\n ^bb(%a: f32, %b: f32, %s: f32):\\n %0 = addf %a, %b : f32\\n linalg.yield %0 : f32\\n } -&gt; tensor&lt;32x16xf32&gt;\\n return %0 : tensor&lt;32x16xf32&gt;\\n}\\n\\n&lt;/textarea&gt;\\n&lt;/div&gt;\\n\\n&lt;script&gt;\\nvar config = {\\n lineNumbers: true,\\n tabSize: 2,\\n readOnly: true,\\n mode: &#x27;javascript&#x27;,\\n};\\nvar myTextArea = document.querySelector(&#x27;#foobar_single&#x27;);\\nvar cm = CodeMirror.fromTextArea(myTextArea, config);\\n&lt;/script&gt;\\n&lt;/body&gt;\\n&lt;/html&gt;\\n\"},\"id\":\"1013\",\"type\":\"panel.models.markup.HTML\"}],\"root_ids\":[\"1001\",\"1023\",\"1024\"]},\"title\":\"Bokeh Application\",\"version\":\"2.2.3\"}};\n",
" var render_items = [{\"docid\":\"3edfffc3-603e-4fff-9a0e-b7b33a9cc9e7\",\"root_ids\":[\"1001\"],\"roots\":{\"1001\":\"06327318-09b9-4fc5-977f-e92aba9d7588\"}}];\n",
" root.Bokeh.embed.embed_items_notebook(docs_json, render_items);\n",
" }\n",
" if (root.Bokeh !== undefined && root.Bokeh.Panel !== undefined) {\n",
" embed_document(root);\n",
" } else {\n",
" var attempts = 0;\n",
" var timer = setInterval(function(root) {\n",
" if (root.Bokeh !== undefined && root.Bokeh.Panel !== undefined) {\n",
" clearInterval(timer);\n",
" embed_document(root);\n",
" } else if (document.readyState == \"complete\") {\n",
" attempts++;\n",
" if (attempts > 100) {\n",
" clearInterval(timer);\n",
" console.log(\"Bokeh: ERROR: Unable to run BokehJS code because BokehJS library is missing\");\n",
" }\n",
" }\n",
" }, 10, root)\n",
" }\n",
"})(window);</script>"
],
"text/plain": [
"Tabs\n",
" [0] Column\n",
" [0] Select(name='Passes', options=['linalg-bufferize', ...], value='linalg-bufferize')\n",
" [1] Row\n",
" [0] Button(button_type='primary', name='◀', width=200)\n",
" [1] Button(button_type='primary', name='▶', width=200)\n",
" [2] Row(max_width=400)\n",
" [0] HTML(str)\n",
" [1] HTML(str)\n",
" [1] Column\n",
" [0] Select(name='Passes', options=['Initial', 'linalg-buffer...], value='Initial')\n",
" [1] HTML(str)\n",
" [2] Row\n",
" [0] Column\n",
" [0] Select(name='Passes', options=['Initial', 'linalg-buffer...], value='Initial')\n",
" [1] HTML(str)\n",
" [1] Column\n",
" [0] Select(name='Passes', options=['Initial', 'linalg-buffer...], value='linalg-bufferize')\n",
" [1] HTML(str)"
]
},
"execution_count": 33,
"metadata": {
"application/vnd.holoviews_exec.v0+json": {
"id": "1001"
}
},
"output_type": "execute_result"
}
],
"source": [
"result.explore()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "continued-allocation",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"module attributes {llvm.data_layout = \"\"} {\n",
" llvm.func @malloc(i64) -> !llvm.ptr<i8>\n",
" llvm.func @add_func(%arg0: !llvm.ptr<f32>, %arg1: !llvm.ptr<f32>, %arg2: i64, %arg3: i64, %arg4: i64, %arg5: i64, %arg6: i64, %arg7: !llvm.ptr<f32>, %arg8: !llvm.ptr<f32>, %arg9: i64, %arg10: i64, %arg11: i64, %arg12: i64, %arg13: i64) -> !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)> {\n",
" %0 = llvm.mlir.undef : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %1 = llvm.insertvalue %arg0, %0[0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %2 = llvm.insertvalue %arg1, %1[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %3 = llvm.insertvalue %arg2, %2[2] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %4 = llvm.insertvalue %arg3, %3[3, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %5 = llvm.insertvalue %arg5, %4[4, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %6 = llvm.insertvalue %arg4, %5[3, 1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %7 = llvm.insertvalue %arg6, %6[4, 1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %8 = llvm.mlir.undef : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %9 = llvm.insertvalue %arg7, %8[0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %10 = llvm.insertvalue %arg8, %9[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %11 = llvm.insertvalue %arg9, %10[2] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %12 = llvm.insertvalue %arg10, %11[3, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %13 = llvm.insertvalue %arg12, %12[4, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %14 = llvm.insertvalue %arg11, %13[3, 1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %15 = llvm.insertvalue %arg13, %14[4, 1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %16 = llvm.mlir.constant(32 : index) : i64\n",
" %17 = llvm.mlir.constant(16 : index) : i64\n",
" %18 = llvm.mlir.constant(0 : index) : i64\n",
" %19 = llvm.mlir.constant(1 : index) : i64\n",
" %20 = llvm.mlir.constant(32 : index) : i64\n",
" %21 = llvm.mlir.constant(16 : index) : i64\n",
" %22 = llvm.mlir.constant(1 : index) : i64\n",
" %23 = llvm.mlir.constant(512 : index) : i64\n",
" %24 = llvm.mlir.null : !llvm.ptr<f32>\n",
" %25 = llvm.getelementptr %24[%23] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>\n",
" %26 = llvm.ptrtoint %25 : !llvm.ptr<f32> to i64\n",
" %27 = llvm.call @malloc(%26) : (i64) -> !llvm.ptr<i8>\n",
" %28 = llvm.bitcast %27 : !llvm.ptr<i8> to !llvm.ptr<f32>\n",
" %29 = llvm.mlir.undef : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %30 = llvm.insertvalue %28, %29[0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %31 = llvm.insertvalue %28, %30[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %32 = llvm.mlir.constant(0 : index) : i64\n",
" %33 = llvm.insertvalue %32, %31[2] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %34 = llvm.insertvalue %20, %33[3, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %35 = llvm.insertvalue %21, %34[3, 1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %36 = llvm.insertvalue %21, %35[4, 0] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %37 = llvm.insertvalue %22, %36[4, 1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" llvm.br ^bb1(%18 : i64)\n",
" ^bb1(%38: i64): // 2 preds: ^bb0, ^bb5\n",
" %39 = llvm.icmp \"slt\" %38, %16 : i64\n",
" llvm.cond_br %39, ^bb2, ^bb6\n",
" ^bb2: // pred: ^bb1\n",
" llvm.br ^bb3(%18 : i64)\n",
" ^bb3(%40: i64): // 2 preds: ^bb2, ^bb4\n",
" %41 = llvm.icmp \"slt\" %40, %17 : i64\n",
" llvm.cond_br %41, ^bb4, ^bb5\n",
" ^bb4: // pred: ^bb3\n",
" %42 = llvm.extractvalue %7[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %43 = llvm.mlir.constant(16 : index) : i64\n",
" %44 = llvm.mul %38, %43 : i64\n",
" %45 = llvm.add %44, %40 : i64\n",
" %46 = llvm.getelementptr %42[%45] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>\n",
" %47 = llvm.load %46 : !llvm.ptr<f32>\n",
" %48 = llvm.extractvalue %15[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %49 = llvm.mlir.constant(16 : index) : i64\n",
" %50 = llvm.mul %38, %49 : i64\n",
" %51 = llvm.add %50, %40 : i64\n",
" %52 = llvm.getelementptr %48[%51] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>\n",
" %53 = llvm.load %52 : !llvm.ptr<f32>\n",
" %54 = llvm.fadd %47, %53 : f32\n",
" %55 = llvm.extractvalue %37[1] : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" %56 = llvm.mlir.constant(16 : index) : i64\n",
" %57 = llvm.mul %38, %56 : i64\n",
" %58 = llvm.add %57, %40 : i64\n",
" %59 = llvm.getelementptr %55[%58] : (!llvm.ptr<f32>, i64) -> !llvm.ptr<f32>\n",
" llvm.store %54, %59 : !llvm.ptr<f32>\n",
" %60 = llvm.add %40, %19 : i64\n",
" llvm.br ^bb3(%60 : i64)\n",
" ^bb5: // pred: ^bb3\n",
" %61 = llvm.add %38, %19 : i64\n",
" llvm.br ^bb1(%61 : i64)\n",
" ^bb6: // pred: ^bb1\n",
" llvm.return %37 : !llvm.struct<(ptr<f32>, ptr<f32>, i64, array<2 x i64>, array<2 x i64>)>\n",
" }\n",
"}\n",
"\n",
"\n"
]
}
],
"source": [
"print(result.stages[-1])"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "consecutive-prisoner",
"metadata": {},
"outputs": [],
"source": [
"with open('out.mlir', 'w') as f:\n",
" f.write(result.stages[-1])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "filled-portal",
"metadata": {},
"outputs": [],
"source": [
"! mlir-translate --mlir-to-llvmir out.mlir > out.llvm"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "verbal-unknown",
"metadata": {},
"outputs": [],
"source": [
"import llvmlite.binding as llvm\n",
"\n",
"llvm.initialize()\n",
"llvm.initialize_native_target()\n",
"llvm.initialize_native_asmprinter() # yes, even this one"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "civil-homework",
"metadata": {},
"outputs": [],
"source": [
"with open('out.llvm') as f:\n",
" llvm_ir = f.read()"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "plastic-irrigation",
"metadata": {},
"outputs": [],
"source": [
"def create_execution_engine():\n",
" \"\"\"\n",
" Create an ExecutionEngine suitable for JIT code generation on\n",
" the host CPU. The engine is reusable for an arbitrary number of\n",
" modules.\n",
" \"\"\"\n",
" # Create a target machine representing the host\n",
" target = llvm.Target.from_default_triple()\n",
" target_machine = target.create_target_machine()\n",
" # And an execution engine with an empty backing module\n",
" backing_mod = llvm.parse_assembly(\"\")\n",
" engine = llvm.create_mcjit_compiler(backing_mod, target_machine)\n",
" return engine\n",
"\n",
"def compile_ir(engine, llvm_ir):\n",
" \"\"\"\n",
" Compile the LLVM IR string with the given engine.\n",
" The compiled module object is returned.\n",
" \"\"\"\n",
" # Create a LLVM module object from the IR\n",
" mod = llvm.parse_assembly(llvm_ir)\n",
" mod.verify()\n",
" # Now add the module and make sure it is ready for execution\n",
" engine.add_module(mod)\n",
" engine.finalize_object()\n",
" engine.run_static_constructors()\n",
" return mod"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "flying-charter",
"metadata": {},
"outputs": [],
"source": [
"engine = create_execution_engine()"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "awful-clearance",
"metadata": {},
"outputs": [],
"source": [
"mod = compile_ir(engine, llvm_ir)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "activated-template",
"metadata": {},
"outputs": [],
"source": [
"func_ptr = engine.get_function_address('add_func')"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "anonymous-potter",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"; ModuleID = 'LLVMDialectModule'\n",
"source_filename = \"LLVMDialectModule\"\n",
"\n",
"declare i8* @malloc(i64)\n",
"\n",
"declare void @free(i8*)\n",
"\n",
"define { float*, float*, i64, [2 x i64], [2 x i64] } @add_func(float* %0, float* %1, i64 %2, i64 %3, i64 %4, i64 %5, i64 %6, float* %7, float* %8, i64 %9, i64 %10, i64 %11, i64 %12, i64 %13) !dbg !3 {\n",
" %15 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } undef, float* %0, 0, !dbg !7\n",
" %16 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %15, float* %1, 1, !dbg !9\n",
" %17 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %16, i64 %2, 2, !dbg !10\n",
" %18 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %17, i64 %3, 3, 0, !dbg !11\n",
" %19 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %18, i64 %5, 4, 0, !dbg !12\n",
" %20 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %19, i64 %4, 3, 1, !dbg !13\n",
" %21 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %20, i64 %6, 4, 1, !dbg !14\n",
" %22 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } undef, float* %7, 0, !dbg !15\n",
" %23 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %22, float* %8, 1, !dbg !16\n",
" %24 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %23, i64 %9, 2, !dbg !17\n",
" %25 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %24, i64 %10, 3, 0, !dbg !18\n",
" %26 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %25, i64 %12, 4, 0, !dbg !19\n",
" %27 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %26, i64 %11, 3, 1, !dbg !20\n",
" %28 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %27, i64 %13, 4, 1, !dbg !21\n",
" %29 = call i8* @malloc(i64 mul (i64 ptrtoint (float* getelementptr (float, float* null, i32 1) to i64), i64 512)), !dbg !22\n",
" %30 = bitcast i8* %29 to float*, !dbg !23\n",
" %31 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } undef, float* %30, 0, !dbg !24\n",
" %32 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %31, float* %30, 1, !dbg !25\n",
" %33 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %32, i64 0, 2, !dbg !26\n",
" %34 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %33, i64 32, 3, 0, !dbg !27\n",
" %35 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %34, i64 16, 3, 1, !dbg !28\n",
" %36 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %35, i64 16, 4, 0, !dbg !29\n",
" %37 = insertvalue { float*, float*, i64, [2 x i64], [2 x i64] } %36, i64 1, 4, 1, !dbg !30\n",
" br label %38, !dbg !31\n",
"\n",
"38: ; preds = %62, %14\n",
" %39 = phi i64 [ %63, %62 ], [ 0, %14 ]\n",
" %40 = icmp slt i64 %39, 32, !dbg !32\n",
" br i1 %40, label %41, label %64, !dbg !33\n",
"\n",
"41: ; preds = %38\n",
" br label %42, !dbg !34\n",
"\n",
"42: ; preds = %45, %41\n",
" %43 = phi i64 [ %61, %45 ], [ 0, %41 ]\n",
" %44 = icmp slt i64 %43, 16, !dbg !35\n",
" br i1 %44, label %45, label %62, !dbg !36\n",
"\n",
"45: ; preds = %42\n",
" %46 = extractvalue { float*, float*, i64, [2 x i64], [2 x i64] } %21, 1, !dbg !37\n",
" %47 = mul i64 %39, 16, !dbg !38\n",
" %48 = add i64 %47, %43, !dbg !39\n",
" %49 = getelementptr float, float* %46, i64 %48, !dbg !40\n",
" %50 = load float, float* %49, align 4, !dbg !41\n",
" %51 = extractvalue { float*, float*, i64, [2 x i64], [2 x i64] } %28, 1, !dbg !42\n",
" %52 = mul i64 %39, 16, !dbg !43\n",
" %53 = add i64 %52, %43, !dbg !44\n",
" %54 = getelementptr float, float* %51, i64 %53, !dbg !45\n",
" %55 = load float, float* %54, align 4, !dbg !46\n",
" %56 = fadd float %50, %55, !dbg !47\n",
" %57 = extractvalue { float*, float*, i64, [2 x i64], [2 x i64] } %37, 1, !dbg !48\n",
" %58 = mul i64 %39, 16, !dbg !49\n",
" %59 = add i64 %58, %43, !dbg !50\n",
" %60 = getelementptr float, float* %57, i64 %59, !dbg !51\n",
" store float %56, float* %60, align 4, !dbg !52\n",
" %61 = add i64 %43, 1, !dbg !53\n",
" br label %42, !dbg !54\n",
"\n",
"62: ; preds = %42\n",
" %63 = add i64 %39, 1, !dbg !55\n",
" br label %38, !dbg !56\n",
"\n",
"64: ; preds = %38\n",
" ret { float*, float*, i64, [2 x i64], [2 x i64] } %37, !dbg !57\n",
"}\n",
"\n",
"!llvm.dbg.cu = !{!0}\n",
"!llvm.module.flags = !{!2}\n",
"\n",
"!0 = distinct !DICompileUnit(language: DW_LANG_C, file: !1, producer: \"mlir\", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug)\n",
"!1 = !DIFile(filename: \"LLVMDialectModule\", directory: \"/\")\n",
"!2 = !{i32 2, !\"Debug Info Version\", i32 3}\n",
"!3 = distinct !DISubprogram(name: \"add_func\", linkageName: \"add_func\", scope: null, file: !4, line: 3, type: !5, scopeLine: 3, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !6)\n",
"!4 = !DIFile(filename: \"out.mlir\", directory: \"/Users/sseibert/continuum/mlir-graphblas\")\n",
"!5 = !DISubroutineType(types: !6)\n",
"!6 = !{}\n",
"!7 = !DILocation(line: 5, column: 10, scope: !8)\n",
"!8 = !DILexicalBlockFile(scope: !3, file: !4, discriminator: 0)\n",
"!9 = !DILocation(line: 6, column: 10, scope: !8)\n",
"!10 = !DILocation(line: 7, column: 10, scope: !8)\n",
"!11 = !DILocation(line: 8, column: 10, scope: !8)\n",
"!12 = !DILocation(line: 9, column: 10, scope: !8)\n",
"!13 = !DILocation(line: 10, column: 10, scope: !8)\n",
"!14 = !DILocation(line: 11, column: 10, scope: !8)\n",
"!15 = !DILocation(line: 13, column: 10, scope: !8)\n",
"!16 = !DILocation(line: 14, column: 11, scope: !8)\n",
"!17 = !DILocation(line: 15, column: 11, scope: !8)\n",
"!18 = !DILocation(line: 16, column: 11, scope: !8)\n",
"!19 = !DILocation(line: 17, column: 11, scope: !8)\n",
"!20 = !DILocation(line: 18, column: 11, scope: !8)\n",
"!21 = !DILocation(line: 19, column: 11, scope: !8)\n",
"!22 = !DILocation(line: 31, column: 11, scope: !8)\n",
"!23 = !DILocation(line: 32, column: 11, scope: !8)\n",
"!24 = !DILocation(line: 34, column: 11, scope: !8)\n",
"!25 = !DILocation(line: 35, column: 11, scope: !8)\n",
"!26 = !DILocation(line: 37, column: 11, scope: !8)\n",
"!27 = !DILocation(line: 38, column: 11, scope: !8)\n",
"!28 = !DILocation(line: 39, column: 11, scope: !8)\n",
"!29 = !DILocation(line: 40, column: 11, scope: !8)\n",
"!30 = !DILocation(line: 41, column: 11, scope: !8)\n",
"!31 = !DILocation(line: 42, column: 5, scope: !8)\n",
"!32 = !DILocation(line: 44, column: 11, scope: !8)\n",
"!33 = !DILocation(line: 45, column: 5, scope: !8)\n",
"!34 = !DILocation(line: 47, column: 5, scope: !8)\n",
"!35 = !DILocation(line: 49, column: 11, scope: !8)\n",
"!36 = !DILocation(line: 50, column: 5, scope: !8)\n",
"!37 = !DILocation(line: 52, column: 11, scope: !8)\n",
"!38 = !DILocation(line: 54, column: 11, scope: !8)\n",
"!39 = !DILocation(line: 55, column: 11, scope: !8)\n",
"!40 = !DILocation(line: 56, column: 11, scope: !8)\n",
"!41 = !DILocation(line: 57, column: 11, scope: !8)\n",
"!42 = !DILocation(line: 58, column: 11, scope: !8)\n",
"!43 = !DILocation(line: 60, column: 11, scope: !8)\n",
"!44 = !DILocation(line: 61, column: 11, scope: !8)\n",
"!45 = !DILocation(line: 62, column: 11, scope: !8)\n",
"!46 = !DILocation(line: 63, column: 11, scope: !8)\n",
"!47 = !DILocation(line: 64, column: 11, scope: !8)\n",
"!48 = !DILocation(line: 65, column: 11, scope: !8)\n",
"!49 = !DILocation(line: 67, column: 11, scope: !8)\n",
"!50 = !DILocation(line: 68, column: 11, scope: !8)\n",
"!51 = !DILocation(line: 69, column: 11, scope: !8)\n",
"!52 = !DILocation(line: 70, column: 5, scope: !8)\n",
"!53 = !DILocation(line: 71, column: 11, scope: !8)\n",
"!54 = !DILocation(line: 72, column: 5, scope: !8)\n",
"!55 = !DILocation(line: 74, column: 11, scope: !8)\n",
"!56 = !DILocation(line: 75, column: 5, scope: !8)\n",
"!57 = !DILocation(line: 77, column: 5, scope: !8)\n",
"\n"
]
}
],
"source": [
"print(llvm_ir)"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "alpha-scott",
"metadata": {},
"outputs": [],
"source": [
"import ctypes\n",
"from ctypes import CFUNCTYPE, c_float, c_int64, Structure, POINTER\n",
"import numpy as np"
]
},
{
"cell_type": "code",
"execution_count": 73,
"id": "conservative-uniform",
"metadata": {},
"outputs": [],
"source": [
"c_float_p = np.ctypeslib.ndpointer(np.float32)\n",
"class ReturnType(Structure):\n",
" _fields_ = [\n",
" ('alloc', POINTER(c_float)),\n",
" ('base', POINTER(c_float)),\n",
" ('offset', c_int64),\n",
" ('size0', c_int64),\n",
" ('size1', c_int64),\n",
" ('stride0', c_int64),\n",
" ('stride1', c_int64),\n",
" ]\n",
"\n",
"cfunc = CFUNCTYPE(\n",
" ReturnType,\n",
" # see https://mlir.llvm.org/docs/ConversionToLLVMDialect/#default-convention for how ranked memrefs are passed\n",
" # arg0\n",
" c_float_p, # allocated pointer (for free())\n",
" c_float_p, # base pointer\n",
" c_int64, # offset from base\n",
" c_int64, # dim0 size (elements)\n",
" c_int64, # dim1 size (elements)\n",
" c_int64, # dim0 stride (elements)\n",
" c_int64, # dim1 stride (elements)\n",
" # arg1\n",
" c_float_p, # same as above\n",
" c_float_p,\n",
" c_int64,\n",
" c_int64,\n",
" c_int64,\n",
" c_int64,\n",
" c_int64,\n",
")(func_ptr)"
]
},
{
"cell_type": "code",
"execution_count": 88,
"id": "ongoing-craps",
"metadata": {},
"outputs": [],
"source": [
"a = np.arange(32*16, dtype=np.float32).reshape((32,16))\n",
"b = a * 2"
]
},
{
"cell_type": "code",
"execution_count": 89,
"id": "fifty-regard",
"metadata": {},
"outputs": [],
"source": [
"ret = cfunc(\n",
" a,\n",
" a,\n",
" 0,\n",
" a.shape[0],\n",
" a.shape[1],\n",
" a.strides[0] // a.itemsize,\n",
" a.strides[1] // a.itemsize,\n",
"\n",
" b,\n",
" b,\n",
" 0,\n",
" b.shape[0],\n",
" b.shape[1],\n",
" b.strides[0] // b.itemsize,\n",
" b.strides[1] // b.itemsize,\n",
")"
]
},
{
"cell_type": "code",
"execution_count": 119,
"id": "continent-layout",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"alloc : <__main__.LP_c_float object at 0x7fec59e93b00>\n",
"base : <__main__.LP_c_float object at 0x7fec59e93b00>\n",
"offset : 0\n",
"size0 : 32\n",
"size1 : 16\n",
"stride0 : 16\n",
"stride1 : 1\n"
]
}
],
"source": [
"for attr in ['alloc', 'base', 'offset', 'size0', 'size1', 'stride0', 'stride1']:\n",
" print(attr, ':', getattr(ret, attr))"
]
},
{
"cell_type": "code",
"execution_count": 129,
"id": "identical-chicago",
"metadata": {},
"outputs": [],
"source": [
"out = np.frombuffer(\n",
" (ctypes.c_float * (32 * 16)).from_address(\n",
" ctypes.addressof(ret.base.contents)\n",
" ),\n",
" dtype=np.float32\n",
").reshape((32, 16))"
]
},
{
"cell_type": "code",
"execution_count": 130,
"id": "acquired-entertainment",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[ 0., 3., 6., 9., 12., 15., 18., 21., 24.,\n",
" 27., 30., 33., 36., 39., 42., 45.],\n",
" [ 48., 51., 54., 57., 60., 63., 66., 69., 72.,\n",
" 75., 78., 81., 84., 87., 90., 93.],\n",
" [ 96., 99., 102., 105., 108., 111., 114., 117., 120.,\n",
" 123., 126., 129., 132., 135., 138., 141.],\n",
" [ 144., 147., 150., 153., 156., 159., 162., 165., 168.,\n",
" 171., 174., 177., 180., 183., 186., 189.],\n",
" [ 192., 195., 198., 201., 204., 207., 210., 213., 216.,\n",
" 219., 222., 225., 228., 231., 234., 237.],\n",
" [ 240., 243., 246., 249., 252., 255., 258., 261., 264.,\n",
" 267., 270., 273., 276., 279., 282., 285.],\n",
" [ 288., 291., 294., 297., 300., 303., 306., 309., 312.,\n",
" 315., 318., 321., 324., 327., 330., 333.],\n",
" [ 336., 339., 342., 345., 348., 351., 354., 357., 360.,\n",
" 363., 366., 369., 372., 375., 378., 381.],\n",
" [ 384., 387., 390., 393., 396., 399., 402., 405., 408.,\n",
" 411., 414., 417., 420., 423., 426., 429.],\n",
" [ 432., 435., 438., 441., 444., 447., 450., 453., 456.,\n",
" 459., 462., 465., 468., 471., 474., 477.],\n",
" [ 480., 483., 486., 489., 492., 495., 498., 501., 504.,\n",
" 507., 510., 513., 516., 519., 522., 525.],\n",
" [ 528., 531., 534., 537., 540., 543., 546., 549., 552.,\n",
" 555., 558., 561., 564., 567., 570., 573.],\n",
" [ 576., 579., 582., 585., 588., 591., 594., 597., 600.,\n",
" 603., 606., 609., 612., 615., 618., 621.],\n",
" [ 624., 627., 630., 633., 636., 639., 642., 645., 648.,\n",
" 651., 654., 657., 660., 663., 666., 669.],\n",
" [ 672., 675., 678., 681., 684., 687., 690., 693., 696.,\n",
" 699., 702., 705., 708., 711., 714., 717.],\n",
" [ 720., 723., 726., 729., 732., 735., 738., 741., 744.,\n",
" 747., 750., 753., 756., 759., 762., 765.],\n",
" [ 768., 771., 774., 777., 780., 783., 786., 789., 792.,\n",
" 795., 798., 801., 804., 807., 810., 813.],\n",
" [ 816., 819., 822., 825., 828., 831., 834., 837., 840.,\n",
" 843., 846., 849., 852., 855., 858., 861.],\n",
" [ 864., 867., 870., 873., 876., 879., 882., 885., 888.,\n",
" 891., 894., 897., 900., 903., 906., 909.],\n",
" [ 912., 915., 918., 921., 924., 927., 930., 933., 936.,\n",
" 939., 942., 945., 948., 951., 954., 957.],\n",
" [ 960., 963., 966., 969., 972., 975., 978., 981., 984.,\n",
" 987., 990., 993., 996., 999., 1002., 1005.],\n",
" [1008., 1011., 1014., 1017., 1020., 1023., 1026., 1029., 1032.,\n",
" 1035., 1038., 1041., 1044., 1047., 1050., 1053.],\n",
" [1056., 1059., 1062., 1065., 1068., 1071., 1074., 1077., 1080.,\n",
" 1083., 1086., 1089., 1092., 1095., 1098., 1101.],\n",
" [1104., 1107., 1110., 1113., 1116., 1119., 1122., 1125., 1128.,\n",
" 1131., 1134., 1137., 1140., 1143., 1146., 1149.],\n",
" [1152., 1155., 1158., 1161., 1164., 1167., 1170., 1173., 1176.,\n",
" 1179., 1182., 1185., 1188., 1191., 1194., 1197.],\n",
" [1200., 1203., 1206., 1209., 1212., 1215., 1218., 1221., 1224.,\n",
" 1227., 1230., 1233., 1236., 1239., 1242., 1245.],\n",
" [1248., 1251., 1254., 1257., 1260., 1263., 1266., 1269., 1272.,\n",
" 1275., 1278., 1281., 1284., 1287., 1290., 1293.],\n",
" [1296., 1299., 1302., 1305., 1308., 1311., 1314., 1317., 1320.,\n",
" 1323., 1326., 1329., 1332., 1335., 1338., 1341.],\n",
" [1344., 1347., 1350., 1353., 1356., 1359., 1362., 1365., 1368.,\n",
" 1371., 1374., 1377., 1380., 1383., 1386., 1389.],\n",
" [1392., 1395., 1398., 1401., 1404., 1407., 1410., 1413., 1416.,\n",
" 1419., 1422., 1425., 1428., 1431., 1434., 1437.],\n",
" [1440., 1443., 1446., 1449., 1452., 1455., 1458., 1461., 1464.,\n",
" 1467., 1470., 1473., 1476., 1479., 1482., 1485.],\n",
" [1488., 1491., 1494., 1497., 1500., 1503., 1506., 1509., 1512.,\n",
" 1515., 1518., 1521., 1524., 1527., 1530., 1533.]], dtype=float32)"
]
},
"execution_count": 130,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"out"
]
},
{
"cell_type": "code",
"execution_count": 131,
"id": "residential-shock",
"metadata": {},
"outputs": [],
"source": [
"np.testing.assert_array_equal(out, a + b)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "appropriate-floating",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.9"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment