Skip to content

Instantly share code, notes, and snippets.

@mscroggs
Created October 14, 2022 10:36
Show Gist options
  • Save mscroggs/c0074d8c62114a3293b8f6b5c038a4d6 to your computer and use it in GitHub Desktop.
Save mscroggs/c0074d8c62114a3293b8f6b5c038a4d6 to your computer and use it in GitHub Desktop.
lecture2.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"colab": {
"provenance": [],
"authorship_tag": "ABX9TyPLhKWLmZFdbAjTag6O+k4z",
"include_colab_link": true
},
"kernelspec": {
"name": "python3",
"display_name": "Python 3"
},
"language_info": {
"name": "python"
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/mscroggs/c0074d8c62114a3293b8f6b5c038a4d6/lecture2.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {
"id": "yGFxsFfNuXDa"
},
"outputs": [],
"source": [
"import numba\n",
"import numpy as np\n",
"import matplotlib.pylab as plt\n",
"import time"
]
},
{
"cell_type": "code",
"source": [
"@numba.njit\n",
"def square(c):\n",
" n = 0\n",
" for i in range(100):\n",
" n = n ** 2 + c\n",
" if abs(n) > 100:\n",
" return i\n",
" return 100"
],
"metadata": {
"id": "2LNjgEg0uceE"
},
"execution_count": 77,
"outputs": []
},
{
"cell_type": "code",
"source": [
"@numba.njit\n",
"def compute_data():\n",
" data = np.zeros((1001, 1001))\n",
" for x in range(1001):\n",
" for y in range(1001):\n",
" c = (-2 + 4 * x/1000) + 1j * (-2 + 4 * y/1000)\n",
" data[-1-y, x] = square(c)\n",
" return data"
],
"metadata": {
"id": "HcChZDjDxVyt"
},
"execution_count": 78,
"outputs": []
},
{
"cell_type": "code",
"source": [
"start = time.time()\n",
"data = compute_data()\n",
"end = time.time()\n",
"print(\"Time taken:\", end-start)\n",
"plt.imshow(data, extent=[-2, 2, -2, 2])"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/",
"height": 304
},
"id": "z-gsqlXRxrTb",
"outputId": "f525011d-e4f0-4e21-e0c4-beffb3875e52"
},
"execution_count": 79,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"Time taken: 0.49483704566955566\n"
]
},
{
"output_type": "execute_result",
"data": {
"text/plain": [
"<matplotlib.image.AxesImage at 0x7f89352342d0>"
]
},
"metadata": {},
"execution_count": 79
},
{
"output_type": "display_data",
"data": {
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
],
"image/png": "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\n"
},
"metadata": {
"needs_background": "light"
}
}
]
},
{
"cell_type": "code",
"source": [
"@numba.njit\n",
"def f(a):\n",
" return a[0] * a[1]\n",
"\n",
"print(f([5, 4]))"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "CXRPt-ffyTUM",
"outputId": "b7371d3a-5339-4bd8-a411-02750f8cd808"
},
"execution_count": 80,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"20\n"
]
},
{
"output_type": "stream",
"name": "stderr",
"text": [
"/usr/local/lib/python3.7/dist-packages/numba/core/ir_utils.py:2147: NumbaPendingDeprecationWarning: \n",
"Encountered the use of a type that is scheduled for deprecation: type 'reflected list' found for argument 'a' of function 'f'.\n",
"\n",
"For more information visit https://numba.readthedocs.io/en/stable/reference/deprecation.html#deprecation-of-reflection-for-list-and-set-types\n",
"\n",
"File \"<ipython-input-80-3734cf0a4217>\", line 2:\n",
"@numba.njit\n",
"def f(a):\n",
"^\n",
"\n",
" warnings.warn(NumbaPendingDeprecationWarning(msg, loc=loc))\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"print(list(f.inspect_llvm().values())[0])"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ryvxwR4V11bR",
"outputId": "b01c5c2e-8c28-4430-b410-2fd5f5b70fd0"
},
"execution_count": 81,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"; ModuleID = 'f'\n",
"source_filename = \"<string>\"\n",
"target datalayout = \"e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128\"\n",
"target triple = \"x86_64-unknown-linux-gnu\"\n",
"\n",
"@_ZN08NumbaEnv8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e = common local_unnamed_addr global i8* null\n",
"@.const.picklebuf.140227282864320 = internal constant { i8*, i32, i8* } { i8* getelementptr inbounds ([66 x i8], [66 x i8]* @.const.pickledata.140227282864320, i32 0, i32 0), i32 66, i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.const.pickledata.140227282864320.sha1, i32 0, i32 0) }\n",
"@.const.pickledata.140227282864320 = internal constant [66 x i8] c\"\\80\\04\\957\\00\\00\\00\\00\\00\\00\\00\\8C\\08builtins\\94\\8C\\0AIndexError\\94\\93\\94\\8C\\14getitem out of range\\94\\85\\94N\\87\\94.\"\n",
"@.const.pickledata.140227282864320.sha1 = internal constant [20 x i8] c\"WSA\\9F|<\\9D\\9EA\\A5\\1CzW,\\CE\\16$\\A3\\9A\\7F\"\n",
"@.const.f = internal constant [2 x i8] c\"f\\00\"\n",
"@PyExc_RuntimeError = external global i8\n",
"@\".const.missing Environment: _ZN08NumbaEnv8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e\" = internal constant [137 x i8] c\"missing Environment: _ZN08NumbaEnv8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e\\00\"\n",
"@.const.numba = internal constant [6 x i8] c\"numba\\00\"\n",
"@.const.typeof = internal constant [7 x i8] c\"typeof\\00\"\n",
"@PyExc_TypeError = external global i8\n",
"@\".const.can't unbox heterogeneous list: %S != %S\" = internal constant [41 x i8] c\"can't unbox heterogeneous list: %S != %S\\00\"\n",
"@PyExc_SystemError = external global i8\n",
"@\".const.unknown error when calling native function\" = internal constant [43 x i8] c\"unknown error when calling native function\\00\"\n",
"@\".const.<numba.core.cpu.CPUContext object at 0x7f893539a490>\" = internal constant [53 x i8] c\"<numba.core.cpu.CPUContext object at 0x7f893539a490>\\00\"\n",
"@\".const.unknown error when calling native function.1\" = internal constant [43 x i8] c\"unknown error when calling native function\\00\"\n",
"\n",
"; Function Attrs: nofree norecurse nounwind\n",
"define i32 @_ZN8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e(i64* noalias nocapture %retptr, { i8*, i32, i8* }** noalias nocapture %excinfo, i8* nocapture readonly %arg.a.0, i8* nocapture readnone %arg.a.1) local_unnamed_addr #0 {\n",
"entry:\n",
" %.5.i9 = getelementptr i8, i8* %arg.a.0, i64 24\n",
" %0 = bitcast i8* %.5.i9 to { i64, i64, i8, i64 }**\n",
" %.6.i1011 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %0, align 8\n",
" %.2515 = bitcast { i64, i64, i8, i64 }* %.6.i1011 to i64*\n",
" %.26 = load i64, i64* %.2515, align 8\n",
" %.27 = icmp slt i64 %.26, 1\n",
" br i1 %.27, label %B0.if, label %B0.endif, !prof !1\n",
"\n",
"B0.if: ; preds = %entry\n",
" store { i8*, i32, i8* }* @.const.picklebuf.140227282864320, { i8*, i32, i8* }** %excinfo, align 8\n",
" ret i32 1, !ret_is_raise !2\n",
"\n",
"B0.endif: ; preds = %entry\n",
" %.64 = icmp eq i64 %.26, 1\n",
" br i1 %.64, label %B0.endif.if, label %B0.endif.endif, !prof !1\n",
"\n",
"B0.endif.if: ; preds = %B0.endif\n",
" store { i8*, i32, i8* }* @.const.picklebuf.140227282864320, { i8*, i32, i8* }** %excinfo, align 8\n",
" ret i32 1, !ret_is_raise !2\n",
"\n",
"B0.endif.endif: ; preds = %B0.endif\n",
" %.41 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i1011, i64 0, i32 3\n",
" %.43 = load i64, i64* %.41, align 8\n",
" %.77 = getelementptr i64, i64* %.41, i64 1\n",
" %.78 = load i64, i64* %.77, align 8\n",
" %.80 = mul nsw i64 %.78, %.43\n",
" store i64 %.80, i64* %retptr, align 8\n",
" ret i32 0\n",
"}\n",
"\n",
"define i8* @_ZN7cpython8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e(i8* nocapture readnone %py_closure, i8* %py_args, i8* nocapture readnone %py_kws) local_unnamed_addr {\n",
"entry:\n",
" %.5 = alloca i8*, align 8\n",
" %.6 = call i32 (i8*, i8*, i64, i64, ...) @PyArg_UnpackTuple(i8* %py_args, i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.const.f, i64 0, i64 0), i64 1, i64 1, i8** nonnull %.5)\n",
" %.7 = icmp eq i32 %.6, 0\n",
" %.331 = alloca i64, align 8\n",
" store i64 0, i64* %.331, align 8\n",
" %excinfo = alloca { i8*, i32, i8* }*, align 8\n",
" store { i8*, i32, i8* }* null, { i8*, i32, i8* }** %excinfo, align 8\n",
" br i1 %.7, label %entry.if, label %entry.endif, !prof !1\n",
"\n",
"entry.if: ; preds = %entry.endif.endif.endif, %entry.endif.endif.endif.endif.endif.endif.endif.if, %entry.endif.endif.endif.endif.endif.endif.endif.if.if, %entry.endif.endif.endif.e...endif.endif, %entry\n",
" ret i8* null\n",
"\n",
"entry.endif: ; preds = %entry\n",
" %.11 = load i8*, i8** @_ZN08NumbaEnv8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e, align 8\n",
" %.16 = icmp eq i8* %.11, null\n",
" br i1 %.16, label %entry.endif.if, label %entry.endif.endif, !prof !1\n",
"\n",
"entry.endif.if: ; preds = %entry.endif\n",
" call void @PyErr_SetString(i8* nonnull @PyExc_RuntimeError, i8* getelementptr inbounds ([137 x i8], [137 x i8]* @\".const.missing Environment: _ZN08NumbaEnv8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e\", i64 0, i64 0))\n",
" ret i8* null\n",
"\n",
"entry.endif.endif: ; preds = %entry.endif\n",
" %.20 = load i8*, i8** %.5, align 8\n",
" %.21 = call i64 @PyList_Size(i8* %.20)\n",
" %.27 = call i8* @numba_get_pyobject_private_data(i8* %.20)\n",
" %.28.not = icmp eq i8* %.27, null\n",
" br i1 %.28.not, label %entry.endif.endif.else, label %entry.endif.endif.if\n",
"\n",
"entry.endif.endif.if: ; preds = %entry.endif.endif\n",
" call void @NRT_incref(i8* nonnull %.27)\n",
" %.5.i = getelementptr i8, i8* %.27, i64 24\n",
" %0 = bitcast i8* %.5.i to { i64, i64, i8, i64 }**\n",
" %.6.i62 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %0, align 8\n",
" %.43120 = bitcast { i64, i64, i8, i64 }* %.6.i62 to i64*\n",
" store i64 %.21, i64* %.43120, align 8\n",
" br label %entry.endif.endif.endif.endif\n",
"\n",
"entry.endif.endif.else: ; preds = %entry.endif.endif\n",
" %.56 = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 %.21, i64 8)\n",
" %.57 = extractvalue { i64, i1 } %.56, 0\n",
" %.58 = extractvalue { i64, i1 } %.56, 1\n",
" %.59 = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 %.57, i64 24)\n",
" %.61 = extractvalue { i64, i1 } %.59, 1\n",
" %.62 = or i1 %.58, %.61\n",
" br i1 %.62, label %entry.endif.endif.endif, label %entry.endif.endif.else.endif.if, !prof !1\n",
"\n",
"entry.endif.endif.endif: ; preds = %entry.endif.endif.else, %entry.endif.endif.else.endif.if, %entry.endif.endif.else.endif.endif.endif.thread77\n",
" %.53.sroa.0.07076 = phi i8* [ %.69, %entry.endif.endif.else.endif.endif.endif.thread77 ], [ null, %entry.endif.endif.else.endif.if ], [ null, %entry.endif.endif.else ]\n",
" call void @NRT_decref(i8* %.53.sroa.0.07076)\n",
" br label %entry.if\n",
"\n",
"entry.endif.endif.else.endif.if: ; preds = %entry.endif.endif.else\n",
" %.60 = extractvalue { i64, i1 } %.59, 0\n",
" %.69 = call i8* @NRT_MemInfo_new_varsize_dtor(i64 %.60, i8* bitcast (void (i8*)* @.dtor.list.int64 to i8*))\n",
" %.70 = icmp eq i8* %.69, null\n",
" br i1 %.70, label %entry.endif.endif.endif, label %entry.endif.endif.else.endif.endif.if, !prof !1\n",
"\n",
"entry.endif.endif.else.endif.endif.if: ; preds = %entry.endif.endif.else.endif.if\n",
" %.5.i9 = getelementptr i8, i8* %.69, i64 24\n",
" %1 = bitcast i8* %.5.i9 to { i64, i64, i8, i64 }**\n",
" %.6.i1057 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %1, align 8\n",
" %.82 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i1057, i64 0, i32 1\n",
" store i64 %.21, i64* %.82, align 8\n",
" %.6.i1658 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %1, align 8\n",
" %.88121 = bitcast { i64, i64, i8, i64 }* %.6.i1658 to i64*\n",
" store i64 0, i64* %.88121, align 8\n",
" %.6.i1859 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %1, align 8\n",
" %.94 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i1859, i64 0, i32 2\n",
" store i8 0, i8* %.94, align 1\n",
" %.6.i3260 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %1, align 8\n",
" %.107 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i3260, i64 0, i32 3\n",
" %.114.idx = shl nsw i64 %.21, 3\n",
" %.118 = bitcast i64* %.107 to i8*\n",
" call void @llvm.memset.p0i8.i64(i8* nonnull align 1 %.118, i8 0, i64 %.114.idx, i1 false)\n",
" %.6.i2853 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %1, align 8\n",
" %.128122 = bitcast { i64, i64, i8, i64 }* %.6.i2853 to i64*\n",
" store i64 %.21, i64* %.128122, align 8\n",
" %.130 = icmp sgt i64 %.21, 0\n",
" br i1 %.130, label %entry.endif.endif.else.endif.endif.if.if, label %entry.endif.endif.else.endif.endif.endif, !prof !3\n",
"\n",
"entry.endif.endif.else.endif.endif.endif.critedge: ; preds = %for.body.endif.endif.endif.endif\n",
" call void @Py_DecRef(i8* %.136)\n",
" call void @Py_DecRef(i8* %.133)\n",
" br label %entry.endif.endif.else.endif.endif.endif\n",
"\n",
"entry.endif.endif.else.endif.endif.endif: ; preds = %entry.endif.endif.else.endif.endif.endif.critedge, %entry.endif.endif.else.endif.endif.if\n",
" %2 = bitcast i8* %.5.i9 to { i64, i64, i8, i64 }**\n",
" call void @numba_set_pyobject_private_data(i8* %.20, i8* nonnull %.69)\n",
" %sunkaddr = getelementptr i8, i8* %.69, i64 24\n",
" %3 = bitcast i8* %sunkaddr to { i64, i64, i8, i64 }**\n",
" %.6.i2054 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %3, align 8\n",
" %.207 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i2054, i64 0, i32 2\n",
" store i8 0, i8* %.207, align 1\n",
" br label %entry.endif.endif.endif.endif\n",
"\n",
"entry.endif.endif.else.endif.endif.if.if: ; preds = %entry.endif.endif.else.endif.endif.if\n",
" %.132 = call i8* @PyImport_ImportModuleNoBlock(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.const.numba, i64 0, i64 0))\n",
" %.133 = call i8* @PyObject_GetAttrString(i8* %.132, i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.const.typeof, i64 0, i64 0))\n",
" call void @Py_DecRef(i8* %.132)\n",
" %.135 = call i8* @PyList_GetItem(i8* %.20, i64 0)\n",
" %.136 = call i8* (i8*, ...) @PyObject_CallFunctionObjArgs(i8* %.133, i8* %.135, i8* null)\n",
" br label %for.body\n",
"\n",
"entry.endif.endif.else.endif.endif.endif.thread77: ; preds = %for.body.endif.endif.endif, %for.body, %for.body.endif.if\n",
" %4 = bitcast i8* %.5.i9 to { i64, i64, i8, i64 }**\n",
" call void @Py_DecRef(i8* %.136)\n",
" call void @Py_DecRef(i8* %.133)\n",
" %.6.i205479 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %4, align 8\n",
" %.20780 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i205479, i64 0, i32 2\n",
" store i8 0, i8* %.20780, align 1\n",
" br label %entry.endif.endif.endif\n",
"\n",
"for.body: ; preds = %for.body.endif.endif.endif.endif, %entry.endif.endif.else.endif.endif.if.if\n",
" %loop.index46 = phi i64 [ 0, %entry.endif.endif.else.endif.endif.if.if ], [ %.189, %for.body.endif.endif.endif.endif ]\n",
" %.153.045 = phi i64 [ 0, %entry.endif.endif.else.endif.endif.if.if ], [ %.153.1, %for.body.endif.endif.endif.endif ]\n",
" %.140 = call i8* @PyList_GetItem(i8* %.20, i64 %loop.index46)\n",
" %.141 = call i8* (i8*, ...) @PyObject_CallFunctionObjArgs(i8* %.133, i8* %.140, i8* null)\n",
" %.142 = icmp eq i8* %.141, null\n",
" br i1 %.142, label %entry.endif.endif.else.endif.endif.endif.thread77, label %for.body.endif, !prof !1\n",
"\n",
"for.body.endif: ; preds = %for.body\n",
" %.146.not = icmp eq i8* %.141, %.136\n",
" br i1 %.146.not, label %for.body.endif.endif, label %for.body.endif.if, !prof !3\n",
"\n",
"for.body.endif.if: ; preds = %for.body.endif\n",
" call void (i8*, i8*, ...) @PyErr_Format(i8* nonnull @PyExc_TypeError, i8* getelementptr inbounds ([41 x i8], [41 x i8]* @\".const.can't unbox heterogeneous list: %S != %S\", i64 0, i64 0), i8* %.136, i8* nonnull %.141)\n",
" call void @Py_DecRef(i8* nonnull %.141)\n",
" br label %entry.endif.endif.else.endif.endif.endif.thread77\n",
"\n",
"for.body.endif.endif: ; preds = %for.body.endif\n",
" call void @Py_DecRef(i8* nonnull %.136)\n",
" %.155 = call i8* @PyNumber_Long(i8* %.140)\n",
" %.156.not = icmp eq i8* %.155, null\n",
" br i1 %.156.not, label %for.body.endif.endif.endif, label %for.body.endif.endif.if, !prof !1\n",
"\n",
"for.body.endif.endif.if: ; preds = %for.body.endif.endif\n",
" %.158 = call i64 @PyLong_AsLongLong(i8* nonnull %.155)\n",
" call void @Py_DecRef(i8* nonnull %.155)\n",
" br label %for.body.endif.endif.endif\n",
"\n",
"for.body.endif.endif.endif: ; preds = %for.body.endif.endif, %for.body.endif.endif.if\n",
" %.153.1 = phi i64 [ %.158, %for.body.endif.endif.if ], [ %.153.045, %for.body.endif.endif ]\n",
" %.163 = call i8* @PyErr_Occurred()\n",
" %.164.not = icmp eq i8* %.163, null\n",
" br i1 %.164.not, label %for.body.endif.endif.endif.endif, label %entry.endif.endif.else.endif.endif.endif.thread77, !prof !3\n",
"\n",
"for.body.endif.endif.endif.endif: ; preds = %for.body.endif.endif.endif\n",
" %5 = bitcast i8* %.5.i9 to { i64, i64, i8, i64 }**\n",
" %.6.i2455 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %5, align 8\n",
" %scevgep118 = getelementptr { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i2455, i64 0, i32 3\n",
" %scevgep119 = getelementptr i64, i64* %scevgep118, i64 %loop.index46\n",
" store i64 %.153.1, i64* %scevgep119, align 8\n",
" %.6.i2256 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %5, align 8\n",
" %.186 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i2256, i64 0, i32 2\n",
" store i8 1, i8* %.186, align 1\n",
" %.189 = add nuw nsw i64 %loop.index46, 1\n",
" %exitcond90.not = icmp eq i64 %.21, %.189\n",
" br i1 %exitcond90.not, label %entry.endif.endif.else.endif.endif.endif.critedge, label %for.body, !prof !4\n",
"\n",
"entry.endif.endif.endif.endif: ; preds = %entry.endif.endif.if, %entry.endif.endif.else.endif.endif.endif\n",
" %.pre-phi = phi { i64, i64, i8, i64 }** [ %0, %entry.endif.endif.if ], [ %2, %entry.endif.endif.else.endif.endif.endif ]\n",
" %.25.sroa.0.0.ph = phi i8* [ %.27, %entry.endif.endif.if ], [ %.69, %entry.endif.endif.else.endif.endif.endif ]\n",
" store i64 0, i64* %.331, align 8\n",
" %.335 = call i32 @_ZN8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e(i64* nonnull %.331, { i8*, i32, i8* }** nonnull %excinfo, i8* nonnull %.25.sroa.0.0.ph, i8* %.20) #4\n",
" %.336 = load { i8*, i32, i8* }*, { i8*, i32, i8* }** %excinfo, align 8\n",
" %.345 = load i64, i64* %.331, align 8\n",
" %sunkaddr123 = getelementptr i8, i8* %.25.sroa.0.0.ph, i64 24\n",
" %6 = bitcast i8* %sunkaddr123 to { i64, i64, i8, i64 }**\n",
" %.6.i1447 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %6, align 8\n",
" %.357 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i1447, i64 0, i32 2\n",
" %.358 = load i8, i8* %.357, align 1\n",
" %.361.not = icmp eq i8 %.358, 0\n",
" br i1 %.361.not, label %entry.endif.endif.endif.endif.endif.endif, label %entry.endif.endif.endif.endif.endif.if, !prof !3\n",
"\n",
"entry.endif.endif.endif.endif.endif.if: ; preds = %entry.endif.endif.endif.endif\n",
" %.371 = call i64 @PyList_Size(i8* %.20)\n",
" %.6.i1248 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %.pre-phi, align 8\n",
" %.376124 = bitcast { i64, i64, i8, i64 }* %.6.i1248 to i64*\n",
" %.377 = load i64, i64* %.376124, align 8\n",
" %.378 = sub i64 %.377, %.371\n",
" %.379 = icmp sgt i64 %.378, -1\n",
" br i1 %.379, label %for.cond.4.preheader, label %entry.endif.endif.endif.endif.endif.if.else\n",
"\n",
"for.cond.4.preheader: ; preds = %entry.endif.endif.endif.endif.endif.if\n",
" %.38240 = icmp sgt i64 %.371, 0\n",
" br i1 %.38240, label %for.body.4.preheader, label %for.cond.5.preheader\n",
"\n",
"for.body.4.preheader: ; preds = %for.cond.4.preheader\n",
" %.38898 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i1248, i64 0, i32 3\n",
" %.39099 = load i64, i64* %.38898, align 8\n",
" %.393100 = call i8* @PyLong_FromLongLong(i64 %.39099)\n",
" %.396101 = call i32 @PyList_SetItem(i8* %.20, i64 0, i8* %.393100)\n",
" %exitcond88.not102 = icmp eq i64 %.371, 1\n",
" br i1 %exitcond88.not102, label %for.cond.5.preheader, label %for.body.4.for.body.4_crit_edge.preheader\n",
"\n",
"for.body.4.for.body.4_crit_edge.preheader: ; preds = %for.body.4.preheader\n",
" %7 = add i64 %.371, -1\n",
" br label %for.body.4.for.body.4_crit_edge\n",
"\n",
"entry.endif.endif.endif.endif.endif.endif: ; preds = %entry.endif.endif.endif.endif, %entry.endif.endif.endif.endif.endif.if.endif\n",
" call void @numba_reset_pyobject_private_data(i8* %.20)\n",
" call void @NRT_decref(i8* nonnull %.25.sroa.0.0.ph)\n",
" switch i32 %.335, label %entry.endif.endif.endif.endif.endif.endif.endif [\n",
" i32 -2, label %entry.endif.endif.endif.endif.endif.endif.if.endif\n",
" i32 0, label %entry.endif.endif.endif.endif.endif.endif.if.endif\n",
" ]\n",
"\n",
"entry.endif.endif.endif.endif.endif.if.else: ; preds = %entry.endif.endif.endif.endif.endif.if\n",
" %.420 = call i32 @PyList_SetSlice(i8* %.20, i64 %.377, i64 %.371, i8* null)\n",
" %.42242 = icmp sgt i64 %.377, 0\n",
" br i1 %.42242, label %for.body.6.preheader, label %entry.endif.endif.endif.endif.endif.if.endif\n",
"\n",
"for.body.6.preheader: ; preds = %entry.endif.endif.endif.endif.endif.if.else\n",
" br label %for.body.6\n",
"\n",
"entry.endif.endif.endif.endif.endif.if.endif: ; preds = %for.body.6, %for.body.5, %entry.endif.endif.endif.endif.endif.if.else, %for.cond.5.preheader\n",
" %.6.i849 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %.pre-phi, align 8\n",
" %.444 = getelementptr inbounds { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i849, i64 0, i32 2\n",
" store i8 0, i8* %.444, align 1\n",
" br label %entry.endif.endif.endif.endif.endif.endif\n",
"\n",
"for.cond.5.preheader: ; preds = %for.body.4.for.body.4_crit_edge, %for.body.4.preheader, %for.cond.4.preheader\n",
" %.40038 = icmp sgt i64 %.378, 0\n",
" br i1 %.40038, label %for.body.5.preheader, label %entry.endif.endif.endif.endif.endif.if.endif\n",
"\n",
"for.body.5.preheader: ; preds = %for.cond.5.preheader\n",
" br label %for.body.5\n",
"\n",
"for.body.4.for.body.4_crit_edge: ; preds = %for.body.4.for.body.4_crit_edge.preheader, %for.body.4.for.body.4_crit_edge\n",
" %lsr.iv111 = phi i64 [ 0, %for.body.4.for.body.4_crit_edge.preheader ], [ %lsr.iv.next112, %for.body.4.for.body.4_crit_edge ]\n",
" %8 = add i64 %lsr.iv111, 1\n",
" %.6.i652.pre = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %.pre-phi, align 8\n",
" %scevgep113 = getelementptr { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i652.pre, i64 1\n",
" %scevgep113114 = bitcast { i64, i64, i8, i64 }* %scevgep113 to i8*\n",
" %9 = shl i64 %lsr.iv111, 3\n",
" %uglygep = getelementptr i8, i8* %scevgep113114, i64 %9\n",
" %uglygep115 = bitcast i8* %uglygep to i64*\n",
" %.390 = load i64, i64* %uglygep115, align 8\n",
" %.393 = call i8* @PyLong_FromLongLong(i64 %.390)\n",
" %.396 = call i32 @PyList_SetItem(i8* %.20, i64 %8, i8* %.393)\n",
" %lsr.iv.next112 = add nuw nsw i64 %lsr.iv111, 1\n",
" %exitcond88.not = icmp eq i64 %7, %lsr.iv.next112\n",
" br i1 %exitcond88.not, label %for.cond.5.preheader, label %for.body.4.for.body.4_crit_edge\n",
"\n",
"for.body.5: ; preds = %for.body.5.preheader, %for.body.5\n",
" %lsr.iv = phi i64 [ %.371, %for.body.5.preheader ], [ %lsr.iv.next, %for.body.5 ]\n",
" %.6.i451 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %.pre-phi, align 8\n",
" %scevgep = getelementptr { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i451, i64 0, i32 3\n",
" %scevgep110 = getelementptr i64, i64* %scevgep, i64 %lsr.iv\n",
" %.409 = load i64, i64* %scevgep110, align 8\n",
" %.412 = call i8* @PyLong_FromLongLong(i64 %.409)\n",
" %.415 = call i32 @PyList_Append(i8* %.20, i8* %.412)\n",
" call void @Py_DecRef(i8* %.412)\n",
" %lsr.iv.next = add i64 %lsr.iv, 1\n",
" %exitcond.not = icmp eq i64 %.377, %lsr.iv.next\n",
" br i1 %exitcond.not, label %entry.endif.endif.endif.endif.endif.if.endif, label %for.body.5\n",
"\n",
"for.body.6: ; preds = %for.body.6.preheader, %for.body.6\n",
" %loop.index.643 = phi i64 [ %.437, %for.body.6 ], [ 0, %for.body.6.preheader ]\n",
" %.6.i250 = load { i64, i64, i8, i64 }*, { i64, i64, i8, i64 }** %.pre-phi, align 8\n",
" %scevgep116 = getelementptr { i64, i64, i8, i64 }, { i64, i64, i8, i64 }* %.6.i250, i64 0, i32 3\n",
" %scevgep117 = getelementptr i64, i64* %scevgep116, i64 %loop.index.643\n",
" %.430 = load i64, i64* %scevgep117, align 8\n",
" %.433 = call i8* @PyLong_FromLongLong(i64 %.430)\n",
" %.436 = call i32 @PyList_SetItem(i8* %.20, i64 %loop.index.643, i8* %.433)\n",
" %.437 = add nuw nsw i64 %loop.index.643, 1\n",
" %exitcond89.not = icmp eq i64 %.377, %.437\n",
" br i1 %exitcond89.not, label %entry.endif.endif.endif.endif.endif.if.endif, label %for.body.6\n",
"\n",
"entry.endif.endif.endif.endif.endif.endif.endif: ; preds = %entry.endif.endif.endif.endif.endif.endif\n",
" %10 = icmp sgt i32 %.335, 0\n",
" br i1 %10, label %entry.endif.endif.endif.endif.endif.endif.endif.if, label %entry.endif.endif.endif.e...endif.endif\n",
"\n",
"entry.endif.endif.endif.endif.endif.endif.if.endif: ; preds = %entry.endif.endif.endif.endif.endif.endif, %entry.endif.endif.endif.endif.endif.endif\n",
" %.457 = call i8* @PyLong_FromLongLong(i64 %.345)\n",
" ret i8* %.457\n",
"\n",
"entry.endif.endif.endif.endif.endif.endif.endif.if: ; preds = %entry.endif.endif.endif.endif.endif.endif.endif\n",
" call void @PyErr_Clear()\n",
" %.464 = load { i8*, i32, i8* }, { i8*, i32, i8* }* %.336, align 8\n",
" %.465 = extractvalue { i8*, i32, i8* } %.464, 0\n",
" %.467 = extractvalue { i8*, i32, i8* } %.464, 1\n",
" %.469 = extractvalue { i8*, i32, i8* } %.464, 2\n",
" %.470 = call i8* @numba_unpickle(i8* %.465, i32 %.467, i8* %.469)\n",
" %.471.not = icmp eq i8* %.470, null\n",
" br i1 %.471.not, label %entry.if, label %entry.endif.endif.endif.endif.endif.endif.endif.if.if, !prof !1\n",
"\n",
"entry.endif.endif.endif.endif.endif.endif.endif.if.if: ; preds = %entry.endif.endif.endif.endif.endif.endif.endif.if\n",
" call void @numba_do_raise(i8* nonnull %.470)\n",
" br label %entry.if\n",
"\n",
"entry.endif.endif.endif.e...endif.endif: ; preds = %entry.endif.endif.endif.endif.endif.endif.endif\n",
" call void @PyErr_SetString(i8* nonnull @PyExc_SystemError, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @\".const.unknown error when calling native function\", i64 0, i64 0))\n",
" br label %entry.if\n",
"}\n",
"\n",
"declare i32 @PyArg_UnpackTuple(i8*, i8*, i64, i64, ...) local_unnamed_addr\n",
"\n",
"declare void @PyErr_SetString(i8*, i8*) local_unnamed_addr\n",
"\n",
"declare i64 @PyList_Size(i8*) local_unnamed_addr\n",
"\n",
"declare i8* @numba_get_pyobject_private_data(i8*) local_unnamed_addr\n",
"\n",
"; Function Attrs: nounwind readnone speculatable willreturn\n",
"declare { i64, i1 } @llvm.smul.with.overflow.i64(i64, i64) #1\n",
"\n",
"; Function Attrs: nounwind readnone speculatable willreturn\n",
"declare { i64, i1 } @llvm.sadd.with.overflow.i64(i64, i64) #1\n",
"\n",
"define linkonce_odr void @.dtor.list.int64(i8* %.1) {\n",
".3:\n",
" ret void\n",
"}\n",
"\n",
"declare i8* @NRT_MemInfo_new_varsize_dtor(i64, i8*) local_unnamed_addr\n",
"\n",
"; Function Attrs: argmemonly nounwind willreturn writeonly\n",
"declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i1 immarg) #2\n",
"\n",
"declare i8* @PyImport_ImportModuleNoBlock(i8*) local_unnamed_addr\n",
"\n",
"declare i8* @PyObject_GetAttrString(i8*, i8*) local_unnamed_addr\n",
"\n",
"declare void @Py_DecRef(i8*) local_unnamed_addr\n",
"\n",
"declare i8* @PyList_GetItem(i8*, i64) local_unnamed_addr\n",
"\n",
"declare i8* @PyObject_CallFunctionObjArgs(i8*, ...) local_unnamed_addr\n",
"\n",
"declare void @PyErr_Format(i8*, i8*, ...) local_unnamed_addr\n",
"\n",
"declare i8* @PyNumber_Long(i8*) local_unnamed_addr\n",
"\n",
"declare i64 @PyLong_AsLongLong(i8*) local_unnamed_addr\n",
"\n",
"declare i8* @PyErr_Occurred() local_unnamed_addr\n",
"\n",
"declare void @numba_set_pyobject_private_data(i8*, i8*) local_unnamed_addr\n",
"\n",
"declare void @numba_reset_pyobject_private_data(i8*) local_unnamed_addr\n",
"\n",
"declare i32 @PyList_SetSlice(i8*, i64, i64, i8*) local_unnamed_addr\n",
"\n",
"declare i8* @PyLong_FromLongLong(i64) local_unnamed_addr\n",
"\n",
"declare i32 @PyList_SetItem(i8*, i64, i8*) local_unnamed_addr\n",
"\n",
"declare i32 @PyList_Append(i8*, i8*) local_unnamed_addr\n",
"\n",
"declare void @PyErr_Clear() local_unnamed_addr\n",
"\n",
"declare i8* @numba_unpickle(i8*, i32, i8*) local_unnamed_addr\n",
"\n",
"declare void @numba_do_raise(i8*) local_unnamed_addr\n",
"\n",
"define i64 @cfunc._ZN8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e({ i8*, i8* } %.1) local_unnamed_addr {\n",
"entry:\n",
" %.3 = alloca i64, align 8\n",
" store i64 0, i64* %.3, align 8\n",
" %excinfo = alloca { i8*, i32, i8* }*, align 8\n",
" store { i8*, i32, i8* }* null, { i8*, i32, i8* }** %excinfo, align 8\n",
" %extracted.meminfo = extractvalue { i8*, i8* } %.1, 0\n",
" %extracted.parent = extractvalue { i8*, i8* } %.1, 1\n",
" %.7 = call i32 @_ZN8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e(i64* nonnull %.3, { i8*, i32, i8* }** nonnull %excinfo, i8* %extracted.meminfo, i8* %extracted.parent) #4\n",
" %.8 = load { i8*, i32, i8* }*, { i8*, i32, i8* }** %excinfo, align 8\n",
" %.9.not = icmp eq i32 %.7, 0\n",
" %.17 = load i64, i64* %.3, align 8\n",
" %.19 = alloca i32, align 4\n",
" store i32 0, i32* %.19, align 4\n",
" br i1 %.9.not, label %entry.endif, label %entry.if, !prof !3\n",
"\n",
"entry.if: ; preds = %entry\n",
" %.15 = icmp sgt i32 %.7, 0\n",
" call void @numba_gil_ensure(i32* nonnull %.19)\n",
" br i1 %.15, label %entry.if.if, label %entry.if.endif.endif.endif\n",
"\n",
"entry.endif: ; preds = %entry, %.22\n",
" ret i64 %.17\n",
"\n",
".22: ; preds = %entry.if.if, %entry.if.if.if, %entry.if.endif.endif.endif\n",
" %.44 = call i8* @PyUnicode_FromString(i8* getelementptr inbounds ([53 x i8], [53 x i8]* @\".const.<numba.core.cpu.CPUContext object at 0x7f893539a490>\", i64 0, i64 0))\n",
" call void @PyErr_WriteUnraisable(i8* %.44)\n",
" call void @Py_DecRef(i8* %.44)\n",
" call void @numba_gil_release(i32* nonnull %.19)\n",
" br label %entry.endif\n",
"\n",
"entry.if.if: ; preds = %entry.if\n",
" call void @PyErr_Clear()\n",
" %.25 = load { i8*, i32, i8* }, { i8*, i32, i8* }* %.8, align 8\n",
" %.26 = extractvalue { i8*, i32, i8* } %.25, 0\n",
" %.28 = extractvalue { i8*, i32, i8* } %.25, 1\n",
" %.30 = extractvalue { i8*, i32, i8* } %.25, 2\n",
" %.31 = call i8* @numba_unpickle(i8* %.26, i32 %.28, i8* %.30)\n",
" %.32.not = icmp eq i8* %.31, null\n",
" br i1 %.32.not, label %.22, label %entry.if.if.if, !prof !1\n",
"\n",
"entry.if.if.if: ; preds = %entry.if.if\n",
" call void @numba_do_raise(i8* nonnull %.31)\n",
" br label %.22\n",
"\n",
"entry.if.endif.endif.endif: ; preds = %entry.if\n",
" call void @PyErr_SetString(i8* nonnull @PyExc_SystemError, i8* getelementptr inbounds ([43 x i8], [43 x i8]* @\".const.unknown error when calling native function.1\", i64 0, i64 0))\n",
" br label %.22\n",
"}\n",
"\n",
"declare void @numba_gil_ensure(i32*) local_unnamed_addr\n",
"\n",
"declare i8* @PyUnicode_FromString(i8*) local_unnamed_addr\n",
"\n",
"declare void @PyErr_WriteUnraisable(i8*) local_unnamed_addr\n",
"\n",
"declare void @numba_gil_release(i32*) local_unnamed_addr\n",
"\n",
"; Function Attrs: nofree noinline norecurse nounwind\n",
"define linkonce_odr void @NRT_incref(i8* %.1) local_unnamed_addr #3 {\n",
".3:\n",
" %.4 = icmp eq i8* %.1, null\n",
" br i1 %.4, label %.3.if, label %.3.endif, !prof !1\n",
"\n",
".3.if: ; preds = %.3\n",
" ret void\n",
"\n",
".3.endif: ; preds = %.3\n",
" %.7 = bitcast i8* %.1 to i64*\n",
" %.4.i = atomicrmw add i64* %.7, i64 1 monotonic\n",
" ret void\n",
"}\n",
"\n",
"; Function Attrs: noinline\n",
"define linkonce_odr void @NRT_decref(i8* %.1) local_unnamed_addr #4 {\n",
".3:\n",
" %.4 = icmp eq i8* %.1, null\n",
" br i1 %.4, label %.3.if, label %.3.endif, !prof !1\n",
"\n",
".3.if: ; preds = %.3.endif, %.3\n",
" ret void\n",
"\n",
".3.endif: ; preds = %.3\n",
" fence release\n",
" %.8 = bitcast i8* %.1 to i64*\n",
" %.4.i = atomicrmw sub i64* %.8, i64 1 monotonic\n",
" %.10 = icmp eq i64 %.4.i, 1\n",
" br i1 %.10, label %.3.endif.if, label %.3.if, !prof !1\n",
"\n",
".3.endif.if: ; preds = %.3.endif\n",
" fence acquire\n",
" tail call void @NRT_MemInfo_call_dtor(i8* nonnull %.1)\n",
" ret void\n",
"}\n",
"\n",
"declare void @NRT_MemInfo_call_dtor(i8*) local_unnamed_addr\n",
"\n",
"; Function Attrs: nounwind\n",
"declare void @llvm.stackprotector(i8*, i8**) #5\n",
"\n",
"attributes #0 = { nofree norecurse nounwind }\n",
"attributes #1 = { nounwind readnone speculatable willreturn }\n",
"attributes #2 = { argmemonly nounwind willreturn writeonly }\n",
"attributes #3 = { nofree noinline norecurse nounwind }\n",
"attributes #4 = { noinline }\n",
"attributes #5 = { nounwind }\n",
"\n",
"!numba_args_may_always_need_nrt = !{!0}\n",
"\n",
"!0 = !{i32 (i64*, { i8*, i32, i8* }**, i8*, i8*)* @_ZN8__main__1fB3v20B38c8tJTIcFHzwl2ILiXkcBV0KBSgP9CGZpAgA_3dE42reflected_20list_28int64_29_3civ_3dNone_3e}\n",
"!1 = !{!\"branch_weights\", i32 1, i32 99}\n",
"!2 = !{i1 true}\n",
"!3 = !{!\"branch_weights\", i32 99, i32 1}\n",
"!4 = !{!\"branch_weights\", i32 21474836, i32 2126008812}\n",
"\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"import numexpr as ne\n",
"import numpy as np"
],
"metadata": {
"id": "Wdo295Ba2QQg"
},
"execution_count": 82,
"outputs": []
},
{
"cell_type": "code",
"source": [
"a = np.random.rand(100000)\n",
"b = np.random.rand(100000)"
],
"metadata": {
"id": "17Sm1O5G2ybn"
},
"execution_count": 83,
"outputs": []
},
{
"cell_type": "code",
"source": [
"start = time.time()\n",
"c = a - b > 0\n",
"end = time.time()\n",
"print(end - start)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Y86P21jE269Q",
"outputId": "3f904cb8-95b2-464b-9b70-6473bd4362b1"
},
"execution_count": 84,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"0.0020880699157714844\n"
]
}
]
},
{
"cell_type": "code",
"source": [
"start = time.time()\n",
"c = ne.evaluate(\"a - b > 0\")\n",
"end = time.time()\n",
"print(end - start)"
],
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "25Y6MYOp3Ezd",
"outputId": "a8a08fa5-6775-4a84-bef7-0758b1ac75d8"
},
"execution_count": 86,
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"0.0019371509552001953\n"
]
}
]
},
{
"cell_type": "code",
"source": [],
"metadata": {
"id": "jVZ9k1Ku3NRx"
},
"execution_count": null,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment