Created
August 15, 2012 19:07
-
-
Save alexbw/3362653 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"metadata": { | |
"name": "memview_bench_withnumba" | |
}, | |
"nbformat": 3, | |
"nbformat_minor": 0, | |
"worksheets": [ | |
{ | |
"cells": [ | |
{ | |
"cell_type": "heading", | |
"level": 1, | |
"metadata": {}, | |
"source": [ | |
"Typed Memoryview Benchmark" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"This contains the implementations of the benchmarks described at http://jakevdp.github.com/blog/2012/08/08/memoryview-benchmarks.\n", | |
"\n", | |
"Here we'll use ipython's cython magic to compile and run the benchmarks." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%load_ext cythonmagic\n", | |
"\n", | |
"# Define our test array\n", | |
"import numpy as np\n", | |
"X = np.random.random((500, 3))\n", | |
"output = np.random.random((500,500)) # only used for Numba, declared here so we make sure the dimensions remain consistent" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 4 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Python-only Version" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import numpy as np\n", | |
"\n", | |
"def euclidean_distance(x1, x2):\n", | |
" x1 = np.asarray(x1)\n", | |
" x2 = np.asarray(x2)\n", | |
" return np.sqrt(np.sum((x1 - x2) ** 2))\n", | |
"\n", | |
"def pairwise_v1(X, metric=euclidean_distance):\n", | |
" X = np.asarray(X)\n", | |
" \n", | |
" n_samples, n_dim = X.shape\n", | |
"\n", | |
" D = np.empty((n_samples, n_samples))\n", | |
"\n", | |
" for i in range(n_samples):\n", | |
" for j in range(n_samples):\n", | |
" \t D[i, j] = metric(X[i], X[j])\n", | |
"\n", | |
" return D" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%timeit pairwise_v1(X)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1 loops, best of 3: 5.19 s per loop\n" | |
] | |
} | |
], | |
"prompt_number": 3 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Cython + numpy" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%cython\n", | |
"\n", | |
"import numpy as np\n", | |
"\n", | |
"cimport numpy as np\n", | |
"from libc.math cimport sqrt\n", | |
"cimport cython\n", | |
"\n", | |
"# define a function pointer to a metric\n", | |
"ctypedef double (*metric_ptr)(np.ndarray, np.ndarray)\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"cdef double euclidean_distance(np.ndarray[double, ndim=1, mode='c'] x1,\n", | |
" np.ndarray[double, ndim=1, mode='c'] x2):\n", | |
" cdef double tmp, d\n", | |
" cdef np.intp_t i, N\n", | |
"\n", | |
" d = 0\n", | |
" N = x1.shape[0]\n", | |
" # assume x2 has the same shape as x1. This could be dangerous!\n", | |
"\n", | |
" for i in range(N):\n", | |
" tmp = x1[i] - x2[i]\n", | |
" d += tmp * tmp\n", | |
"\n", | |
" return sqrt(d)\n", | |
"\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"def pairwise_v2(np.ndarray[double, ndim=2, mode='c'] X not None,\n", | |
" metric = 'euclidean'):\n", | |
" cdef metric_ptr dist_func\n", | |
" if metric == 'euclidean':\n", | |
" dist_func = &euclidean_distance\n", | |
" else:\n", | |
" raise ValueError(\"unrecognized metric\")\n", | |
"\n", | |
" cdef np.intp_t i, j, n_samples\n", | |
" n_samples = X.shape[0]\n", | |
"\n", | |
" cdef np.ndarray[double, ndim=2, mode='c'] D = np.empty((n_samples,\n", | |
" n_samples))\n", | |
" for i in range(n_samples):\n", | |
" for j in range(n_samples):\n", | |
" D[i, j] = dist_func(X[i], X[j])\n", | |
"\n", | |
" return D" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 5 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%timeit pairwise_v2(X)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"1 loops, best of 3: 804 ms per loop\n" | |
] | |
} | |
], | |
"prompt_number": 6 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Cython + memviews (with slicing)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%cython\n", | |
"import numpy as np\n", | |
"\n", | |
"cimport numpy as np\n", | |
"from libc.math cimport sqrt\n", | |
"cimport cython\n", | |
"\n", | |
"# define a function pointer to a metric\n", | |
"ctypedef double (*metric_ptr)(double[::1], double[::1])\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"cdef double euclidean_distance(double[::1] x1,\n", | |
" double[::1] x2):\n", | |
" cdef double tmp, d\n", | |
" cdef np.intp_t i, N\n", | |
"\n", | |
" d = 0\n", | |
" N = x1.shape[0]\n", | |
" # assume x2 has the same shape as x1. This could be dangerous!\n", | |
"\n", | |
" for i in range(N):\n", | |
" tmp = x1[i] - x2[i]\n", | |
" d += tmp * tmp\n", | |
"\n", | |
" return sqrt(d)\n", | |
"\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"def pairwise_v3(double[:, ::1] X,\n", | |
" metric = 'euclidean'):\n", | |
" cdef metric_ptr dist_func\n", | |
" if metric == 'euclidean':\n", | |
" dist_func = &euclidean_distance\n", | |
" else:\n", | |
" raise ValueError(\"unrecognized metric\")\n", | |
"\n", | |
" cdef np.intp_t i, j, n_samples\n", | |
" n_samples = X.shape[0]\n", | |
"\n", | |
" cdef double[:, ::1] D = np.empty((n_samples, n_samples))\n", | |
"\n", | |
" for i in range(n_samples):\n", | |
" for j in range(n_samples):\n", | |
" D[i, j] = dist_func(X[i], X[j])\n", | |
"\n", | |
" return D" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 10 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%timeit pairwise_v3(X)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"10 loops, best of 3: 22.4 ms per loop\n" | |
] | |
} | |
], | |
"prompt_number": 11 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Cython + raw pointers" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%cython\n", | |
"\n", | |
"import numpy as np\n", | |
"\n", | |
"cimport numpy as np\n", | |
"from libc.math cimport sqrt\n", | |
"cimport cython\n", | |
"\n", | |
"# define a function pointer to a metric\n", | |
"ctypedef double (*metric_ptr)(double*, double*, int)\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"cdef double euclidean_distance(double* x1,\n", | |
" double* x2,\n", | |
" int N):\n", | |
" cdef double tmp, d\n", | |
" cdef np.intp_t i\n", | |
"\n", | |
" d = 0\n", | |
"\n", | |
" for i in range(N):\n", | |
" tmp = x1[i] - x2[i]\n", | |
" d += tmp * tmp\n", | |
"\n", | |
" return sqrt(d)\n", | |
"\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"def pairwise_v4(double[:, ::1] X,\n", | |
" metric = 'euclidean'):\n", | |
" cdef metric_ptr dist_func\n", | |
" if metric == 'euclidean':\n", | |
" dist_func = &euclidean_distance\n", | |
" else:\n", | |
" raise ValueError(\"unrecognized metric\")\n", | |
"\n", | |
" cdef np.intp_t i, j, n_samples, n_dim\n", | |
" n_samples = X.shape[0]\n", | |
" n_dim = X.shape[1]\n", | |
"\n", | |
" cdef double[:, ::1] D = np.empty((n_samples, n_samples))\n", | |
"\n", | |
" cdef double* Dptr = &D[0, 0]\n", | |
" cdef double* Xptr = &X[0, 0]\n", | |
"\n", | |
" for i in range(n_samples):\n", | |
" for j in range(n_samples):\n", | |
" Dptr[i * n_samples + j] = dist_func(Xptr + i * n_dim,\n", | |
" Xptr + j * n_dim,\n", | |
" n_dim)\n", | |
" return D" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 18 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%timeit pairwise_v4(X)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"100 loops, best of 3: 4.82 ms per loop\n" | |
] | |
} | |
], | |
"prompt_number": 19 | |
}, | |
{ | |
"cell_type": "heading", | |
"level": 2, | |
"metadata": {}, | |
"source": [ | |
"Cython + memviews (no slicing)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%%cython\n", | |
"\n", | |
"import numpy as np\n", | |
"\n", | |
"cimport numpy as np\n", | |
"from libc.math cimport sqrt\n", | |
"cimport cython\n", | |
"\n", | |
"# define a function pointer to a metric\n", | |
"ctypedef double (*metric_ptr)(double[:, ::1], np.intp_t, np.intp_t)\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"cdef inline double euclidean_distance(double[:, ::1] X,\n", | |
" np.intp_t i1, np.intp_t i2):\n", | |
" cdef double tmp, d\n", | |
" cdef np.intp_t j\n", | |
"\n", | |
" d = 0\n", | |
"\n", | |
" for j in range(X.shape[1]):\n", | |
" tmp = X[i1, j] - X[i2, j]\n", | |
" d += tmp * tmp\n", | |
"\n", | |
" return sqrt(d)\n", | |
"\n", | |
"\n", | |
"@cython.boundscheck(False)\n", | |
"@cython.wraparound(False)\n", | |
"def pairwise_v5(double[:, ::1] X,\n", | |
" metric = 'euclidean'):\n", | |
" cdef metric_ptr dist_func\n", | |
" if metric == 'euclidean':\n", | |
" dist_func = &euclidean_distance\n", | |
" else:\n", | |
" raise ValueError(\"unrecognized metric\")\n", | |
"\n", | |
" cdef np.intp_t i, j, n_samples, n_dim\n", | |
" n_samples = X.shape[0]\n", | |
" n_dim = X.shape[1]\n", | |
"\n", | |
" cdef double[:, ::1] D = np.empty((n_samples, n_samples))\n", | |
"\n", | |
" for i in range(n_samples):\n", | |
" for j in range(n_samples):\n", | |
" D[i, j] = dist_func(X, i, j)\n", | |
"\n", | |
" return D" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [], | |
"prompt_number": 14 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"%timeit pairwise_v5(X)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"100 loops, best of 3: 4.88 ms per loop\n" | |
] | |
} | |
], | |
"prompt_number": 15 | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Numba" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": true, | |
"input": [ | |
"from numba.decorators import jit as jit\n", | |
"\n", | |
"@jit(arg_types=[[['d']], [['d']]], ret_type=[['d']])\n", | |
"def pairwise_numba(X, output):\n", | |
" n_samples, n_dim = X.shape\n", | |
" n_samples1, n_samples2 = output.shape\n", | |
" \n", | |
" for ii in range(n_samples):\n", | |
" for jj in range(n_samples):\n", | |
" result = 0.0;\n", | |
" for kk in range(n_dim):\n", | |
" result += (X[ii,kk] - X[jj,kk]) * (X[ii,kk] - X[jj,kk])\n", | |
" output[ii,jj] = result\n", | |
" \n", | |
" return output\n" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"{'blocks': {0: <llvm.core.BasicBlock object at 0x10595f710>,\n", | |
" 33: <llvm.core.BasicBlock object at 0x10595f790>,\n", | |
" 43: <llvm.core.BasicBlock object at 0x10595f490>,\n", | |
" 46: <llvm.core.BasicBlock object at 0x10595ff50>,\n", | |
" 49: <llvm.core.BasicBlock object at 0x10595f290>,\n", | |
" 52: <llvm.core.BasicBlock object at 0x10595f690>,\n", | |
" 62: <llvm.core.BasicBlock object at 0x10595f510>,\n", | |
" 65: <llvm.core.BasicBlock object at 0x106033390>,\n", | |
" 68: <llvm.core.BasicBlock object at 0x106033510>,\n", | |
" 77: <llvm.core.BasicBlock object at 0x106033590>,\n", | |
" 87: <llvm.core.BasicBlock object at 0x106033610>,\n", | |
" 90: <llvm.core.BasicBlock object at 0x106033690>,\n", | |
" 93: <llvm.core.BasicBlock object at 0x106033790>,\n", | |
" 158: <llvm.core.BasicBlock object at 0x106033710>,\n", | |
" 178: <llvm.core.BasicBlock object at 0x106033490>,\n", | |
" 182: <llvm.core.BasicBlock object at 0x10595fa10>},\n", | |
" 'blocks_dom': {0: set([0]),\n", | |
" 33: set([0, 33]),\n", | |
" 43: set([0, 33, 43, 46, 49, 52, 65, 178]),\n", | |
" 46: set([0, 33, 46]),\n", | |
" 49: set([0, 33, 46, 49]),\n", | |
" 52: set([0, 33, 46, 49, 52]),\n", | |
" 62: set([0, 33, 46, 49, 52, 62, 65, 68, 77, 90, 158]),\n", | |
" 65: set([0, 33, 46, 49, 52, 65]),\n", | |
" 68: set([0, 33, 46, 49, 52, 65, 68]),\n", | |
" 77: set([0, 33, 46, 49, 52, 65, 68, 77]),\n", | |
" 87: set([0, 33, 46, 49, 52, 65, 68, 77, 87, 90, 93]),\n", | |
" 90: set([0, 33, 46, 49, 52, 65, 68, 77, 90]),\n", | |
" 93: set([0, 33, 46, 49, 52, 65, 68, 77, 90, 93]),\n", | |
" 158: set([0, 33, 46, 49, 52, 65, 68, 77, 90, 158]),\n", | |
" 178: set([0, 33, 46, 49, 52, 65, 178]),\n", | |
" 182: set([0, 33, 46, 182])},\n", | |
" 'blocks_in': {0: set(),\n", | |
" 33: set([0]),\n", | |
" 43: set([178]),\n", | |
" 46: set([33, 43]),\n", | |
" 49: set([46]),\n", | |
" 52: set([49]),\n", | |
" 62: set([158]),\n", | |
" 65: set([52, 62]),\n", | |
" 68: set([65]),\n", | |
" 77: set([68]),\n", | |
" 87: set([93]),\n", | |
" 90: set([77, 87]),\n", | |
" 93: set([90]),\n", | |
" 158: set([90]),\n", | |
" 178: set([65]),\n", | |
" 182: set([46])},\n", | |
" 'blocks_out': {0: set([33]),\n", | |
" 33: set([46]),\n", | |
" 43: set([46]),\n", | |
" 46: set([49, 182]),\n", | |
" 49: set([52]),\n", | |
" 52: set([65]),\n", | |
" 62: set([65]),\n", | |
" 65: set([68, 178]),\n", | |
" 68: set([77]),\n", | |
" 77: set([90]),\n", | |
" 87: set([90]),\n", | |
" 90: set([93, 158]),\n", | |
" 93: set([87]),\n", | |
" 158: set([62]),\n", | |
" 178: set([43]),\n", | |
" 182: set()},\n", | |
" 'blocks_reaching': {0: set([0]),\n", | |
" 33: set([0, 33]),\n", | |
" 43: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 46: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 49: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 52: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 62: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 65: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 68: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 77: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 87: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 90: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 93: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 158: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 178: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178]),\n", | |
" 182: set([0,\n", | |
" 33,\n", | |
" 43,\n", | |
" 46,\n", | |
" 49,\n", | |
" 52,\n", | |
" 62,\n", | |
" 65,\n", | |
" 68,\n", | |
" 77,\n", | |
" 87,\n", | |
" 90,\n", | |
" 93,\n", | |
" 158,\n", | |
" 178,\n", | |
" 182])},\n", | |
" 'blocks_reads': {0: set([0, 1]),\n", | |
" 33: set([2]),\n", | |
" 43: set(),\n", | |
" 46: set([6]),\n", | |
" 49: set(),\n", | |
" 52: set([2]),\n", | |
" 62: set(),\n", | |
" 65: set([7]),\n", | |
" 68: set(),\n", | |
" 77: set([3]),\n", | |
" 87: set(),\n", | |
" 90: set([9]),\n", | |
" 93: set([0, 6, 7, 8, 9]),\n", | |
" 158: set([1, 6, 7, 8]),\n", | |
" 178: set(),\n", | |
" 182: set([1])},\n", | |
" 'blocks_writer': {0: {2: 9, 3: 12, 4: 24, 5: 27},\n", | |
" 33: {6: 42},\n", | |
" 43: {6: 43},\n", | |
" 46: {6: 46},\n", | |
" 49: {},\n", | |
" 52: {7: 61},\n", | |
" 62: {7: 62},\n", | |
" 65: {7: 65},\n", | |
" 68: {8: 71},\n", | |
" 77: {9: 86},\n", | |
" 87: {9: 87},\n", | |
" 90: {8: 90, 9: 90},\n", | |
" 93: {8: 152},\n", | |
" 158: {},\n", | |
" 178: {},\n", | |
" 182: {}},\n", | |
" 'blocks_writes': {0: set([0, 1, 2, 3, 4, 5]),\n", | |
" 33: set([6]),\n", | |
" 43: set([6]),\n", | |
" 46: set([6]),\n", | |
" 49: set(),\n", | |
" 52: set([7]),\n", | |
" 62: set([7]),\n", | |
" 65: set([7]),\n", | |
" 68: set([8]),\n", | |
" 77: set([9]),\n", | |
" 87: set([9]),\n", | |
" 90: set([8, 9]),\n", | |
" 93: set([8]),\n", | |
" 158: set(),\n", | |
" 178: set(),\n", | |
" 182: set()},\n", | |
" 'translator': <numba.translate.Translate object at 0x106033410>}\n", | |
"op_LOAD_ATTR(): 3 106 shape <Variable(val=<llvm.core.Argument object at 0x10595f610>, _llvm=<llvm.core.Argument object at 0x10595f610>, typ='arr[f64]')> arr[f64]\n", | |
"op_LOAD_ATTR(): { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }*\n", | |
"op_LOAD_ATTR(): 18 106 shape <Variable(val=<llvm.core.Argument object at 0x10595f810>, _llvm=<llvm.core.Argument object at 0x10595f810>, typ='arr[f64]')> arr[f64]\n", | |
"op_LOAD_ATTR(): { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }*\n", | |
"('op_CALL_FUNCTION():', <Variable(val=<built-in function range>, _llvm=None, typ=['func'])>)\n", | |
"str_to_llvmtype(): str = 'i64'\n", | |
"add_phi_incomming(): reaching_defs = {33: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 33},\n", | |
" 43: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 43, 7: 65}}\n", | |
" crnt_block=46, pred=43, local=6\n", | |
"op_BINARY_ADD(): <Variable(val=<llvm.core.PHINode object at 0x106033b10>, _llvm=<llvm.core.PHINode object at 0x106033b10>, typ='i64')> + <Variable(val=<llvm.core.ConstantInt object at 0x106033c50>, _llvm=<llvm.core.ConstantInt object at 0x106033c50>, typ='i64')>\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x106033b10>, _llvm=<llvm.core.PHINode object at 0x106033b10>, typ='i64')>, arg2 = <Variable(val=<llvm.core.ConstantInt object at 0x106033c50>, _llvm=<llvm.core.ConstantInt object at 0x106033c50>, typ='i64')>\n", | |
"resolve_type() ==> 'i64'\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x106033b10>, _llvm=<llvm.core.PHINode object at 0x106033b10>, typ='i64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x106033950>, _llvm=<llvm.core.Instruction object at 0x106033950>, typ='i64')>\n", | |
"resolve_type() ==> 'i64'\n", | |
"('op_CALL_FUNCTION():', <Variable(val=<built-in function range>, _llvm=None, typ=['func'])>)\n", | |
"str_to_llvmtype(): str = 'i64'\n", | |
"add_phi_incomming(): reaching_defs = {52: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 46, 7: 52},\n", | |
" 62: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 46, 7: 62, 8: 90, 9: 90}}\n", | |
" crnt_block=65, pred=62, local=7\n", | |
"op_BINARY_ADD(): <Variable(val=<llvm.core.PHINode object at 0x106033f50>, _llvm=<llvm.core.PHINode object at 0x106033f50>, typ='i64')> + <Variable(val=<llvm.core.ConstantInt object at 0x106033e50>, _llvm=<llvm.core.ConstantInt object at 0x106033e50>, typ='i64')>\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x106033f50>, _llvm=<llvm.core.PHINode object at 0x106033f50>, typ='i64')>, arg2 = <Variable(val=<llvm.core.ConstantInt object at 0x106033e50>, _llvm=<llvm.core.ConstantInt object at 0x106033e50>, typ='i64')>\n", | |
"resolve_type() ==> 'i64'\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x106033f50>, _llvm=<llvm.core.PHINode object at 0x106033f50>, typ='i64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x106033950>, _llvm=<llvm.core.Instruction object at 0x106033950>, typ='i64')>\n", | |
"resolve_type() ==> 'i64'\n", | |
"('op_CALL_FUNCTION():', <Variable(val=<built-in function range>, _llvm=None, typ=['func'])>)\n", | |
"str_to_llvmtype(): str = 'f64'\n", | |
"add_phi_incomming(): reaching_defs = {77: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 46, 7: 65, 8: 68, 9: 77},\n", | |
" 87: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 46, 7: 65, 8: 93, 9: 87}}\n", | |
" crnt_block=90, pred=87, local=8\n", | |
"str_to_llvmtype(): str = 'i64'\n", | |
"add_phi_incomming(): reaching_defs = {77: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 46, 7: 65, 8: 68, 9: 77},\n", | |
" 87: {0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0, 6: 46, 7: 65, 8: 93, 9: 87}}\n", | |
" crnt_block=90, pred=87, local=9\n", | |
"op_BINARY_ADD(): <Variable(val=<llvm.core.PHINode object at 0x105971090>, _llvm=<llvm.core.PHINode object at 0x105971090>, typ='i64')> + <Variable(val=<llvm.core.ConstantInt object at 0x105971150>, _llvm=<llvm.core.ConstantInt object at 0x105971150>, typ='i64')>\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x105971090>, _llvm=<llvm.core.PHINode object at 0x105971090>, typ='i64')>, arg2 = <Variable(val=<llvm.core.ConstantInt object at 0x105971150>, _llvm=<llvm.core.ConstantInt object at 0x105971150>, typ='i64')>\n", | |
"resolve_type() ==> 'i64'\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x105971090>, _llvm=<llvm.core.PHINode object at 0x105971090>, typ='i64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x1060339d0>, _llvm=<llvm.core.Instruction object at 0x1060339d0>, typ='i64')>\n", | |
"resolve_type() ==> 'i64'\n", | |
"op_BINARY_SUBSCR(): arr_var.typ = arr[f64]\n", | |
"str_to_llvmtype(): str = 'f64'\n", | |
" %32 = load double* %31\n", | |
"op_BINARY_SUBSCR(): arr_var.typ = arr[f64]\n", | |
"str_to_llvmtype(): str = 'f64'\n", | |
" %43 = load double* %42\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.Instruction object at 0x105971450>, _llvm=<llvm.core.Instruction object at 0x105971450>, typ='f64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x1059715d0>, _llvm=<llvm.core.Instruction object at 0x1059715d0>, typ='f64')>\n", | |
"resolve_type() ==> 'f64'\n", | |
"op_BINARY_SUBSCR(): arr_var.typ = arr[f64]\n", | |
"str_to_llvmtype(): str = 'f64'\n", | |
" %55 = load double* %54\n", | |
"op_BINARY_SUBSCR(): arr_var.typ = arr[f64]\n", | |
"str_to_llvmtype(): str = 'f64'\n", | |
" %66 = load double* %65\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.Instruction object at 0x105971410>, _llvm=<llvm.core.Instruction object at 0x105971410>, typ='f64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x105971690>, _llvm=<llvm.core.Instruction object at 0x105971690>, typ='f64')>\n", | |
"resolve_type() ==> 'f64'\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.Instruction object at 0x105971290>, _llvm=<llvm.core.Instruction object at 0x105971290>, typ='f64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x105971510>, _llvm=<llvm.core.Instruction object at 0x105971510>, typ='f64')>\n", | |
"resolve_type() ==> 'f64'\n", | |
"op_BINARY_ADD(): <Variable(val=<llvm.core.PHINode object at 0x106033e10>, _llvm=<llvm.core.PHINode object at 0x106033e10>, typ='f64')> + <Variable(val=<llvm.core.Instruction object at 0x105971410>, _llvm=<llvm.core.Instruction object at 0x105971410>, typ='f64')>\n", | |
"resolve_type(): arg1 = <Variable(val=<llvm.core.PHINode object at 0x106033e10>, _llvm=<llvm.core.PHINode object at 0x106033e10>, typ='f64')>, arg2 = <Variable(val=<llvm.core.Instruction object at 0x105971410>, _llvm=<llvm.core.Instruction object at 0x105971410>, typ='f64')>\n", | |
"resolve_type() ==> 'f64'\n", | |
"op_STORE_SUBSCR(): 174 60 None\n", | |
"op_STORE_SUBSCR(): <Variable(val=<llvm.core.Argument object at 0x10595f810>, _llvm=<llvm.core.Argument object at 0x10595f810>, typ='arr[f64]')>[<Variable(val=(<Variable(val=<llvm.core.PHINode object at 0x106033b10>, _llvm=<llvm.core.PHINode object at 0x106033b10>, typ='i64')>, <Variable(val=<llvm.core.PHINode object at 0x106033f50>, _llvm=<llvm.core.PHINode object at 0x106033f50>, typ='i64')>), _llvm=None, typ='tuple')>] = <Variable(val=<llvm.core.PHINode object at 0x106033e10>, _llvm=<llvm.core.PHINode object at 0x106033e10>, typ='f64')>\n", | |
"op_STORE_SUBSCR(): arr_lval = '{ i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %output', arr_ltype = '{ i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }*'\n", | |
"str_to_llvmtype(): str = 'f64'\n", | |
"str_to_llvmtype(): str = 'arr[]'\n", | |
"; ModuleID = 'pairwise_numba_mod_106033410'\n", | |
"\n", | |
"define { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* @pairwise_numba({ i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %output) {\n", | |
"Entry:\n", | |
" %0 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 4\n", | |
" %1 = load i64** %0\n", | |
" %2 = getelementptr i64* %1, i32 0\n", | |
" %3 = load i64* %2\n", | |
" %4 = getelementptr i64* %1, i32 1\n", | |
" %5 = load i64* %4\n", | |
" %6 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %output, i32 0, i32 4\n", | |
" %7 = load i64** %6\n", | |
" %8 = getelementptr i64* %7, i32 0\n", | |
" %9 = load i64* %8\n", | |
" %10 = getelementptr i64* %7, i32 1\n", | |
" %11 = load i64* %10\n", | |
" br label %BLOCK_33\n", | |
"\n", | |
"BLOCK_33: ; preds = %Entry\n", | |
" br label %BLOCK_46\n", | |
"\n", | |
"BLOCK_43: ; preds = %BLOCK_178\n", | |
" %12 = add i64 %13, 1\n", | |
" br label %BLOCK_46\n", | |
"\n", | |
"BLOCK_46: ; preds = %BLOCK_43, %BLOCK_33\n", | |
" %13 = phi i64 [ 0, %BLOCK_33 ], [ %12, %BLOCK_43 ]\n", | |
" %14 = icmp slt i64 %13, %3\n", | |
" br i1 %14, label %BLOCK_49, label %BLOCK_182\n", | |
"\n", | |
"BLOCK_182: ; preds = %BLOCK_46\n", | |
" ret { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %output\n", | |
"\n", | |
"BLOCK_49: ; preds = %BLOCK_46\n", | |
" br label %BLOCK_52\n", | |
"\n", | |
"BLOCK_52: ; preds = %BLOCK_49\n", | |
" br label %BLOCK_65\n", | |
"\n", | |
"BLOCK_62: ; preds = %BLOCK_158\n", | |
" %15 = add i64 %16, 1\n", | |
" br label %BLOCK_65\n", | |
"\n", | |
"BLOCK_65: ; preds = %BLOCK_62, %BLOCK_52\n", | |
" %16 = phi i64 [ 0, %BLOCK_52 ], [ %15, %BLOCK_62 ]\n", | |
" %17 = icmp slt i64 %16, %3\n", | |
" br i1 %17, label %BLOCK_68, label %BLOCK_178\n", | |
"\n", | |
"BLOCK_178: ; preds = %BLOCK_65\n", | |
" br label %BLOCK_43\n", | |
"\n", | |
"BLOCK_68: ; preds = %BLOCK_65\n", | |
" br label %BLOCK_77\n", | |
"\n", | |
"BLOCK_77: ; preds = %BLOCK_68\n", | |
" br label %BLOCK_90\n", | |
"\n", | |
"BLOCK_87: ; preds = %BLOCK_93\n", | |
" %18 = add i64 %20, 1\n", | |
" br label %BLOCK_90\n", | |
"\n", | |
"BLOCK_90: ; preds = %BLOCK_87, %BLOCK_77\n", | |
" %19 = phi double [ 0.000000e+00, %BLOCK_77 ], [ %79, %BLOCK_87 ]\n", | |
" %20 = phi i64 [ 0, %BLOCK_77 ], [ %18, %BLOCK_87 ]\n", | |
" %21 = icmp slt i64 %20, %5\n", | |
" br i1 %21, label %BLOCK_93, label %BLOCK_158\n", | |
"\n", | |
"BLOCK_158: ; preds = %BLOCK_90\n", | |
" %22 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %output, i32 0, i32 5\n", | |
" %23 = load i64** %22\n", | |
" %24 = getelementptr i64* %23, i32 0\n", | |
" %25 = load i64* %24\n", | |
" %26 = mul i64 %13, %25\n", | |
" %27 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %output, i32 0, i32 2\n", | |
" %28 = load i8** %27\n", | |
" %29 = getelementptr i8* %28, i64 %26\n", | |
" %30 = bitcast i8* %29 to double*\n", | |
" %31 = getelementptr double* %30, i64 %16\n", | |
" store double %19, double* %31\n", | |
" br label %BLOCK_62\n", | |
"\n", | |
"BLOCK_93: ; preds = %BLOCK_90\n", | |
" %32 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 5\n", | |
" %33 = load i64** %32\n", | |
" %34 = getelementptr i64* %33, i32 0\n", | |
" %35 = load i64* %34\n", | |
" %36 = mul i64 %13, %35\n", | |
" %37 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 2\n", | |
" %38 = load i8** %37\n", | |
" %39 = getelementptr i8* %38, i64 %36\n", | |
" %40 = bitcast i8* %39 to double*\n", | |
" %41 = getelementptr double* %40, i64 %20\n", | |
" %42 = load double* %41\n", | |
" %43 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 5\n", | |
" %44 = load i64** %43\n", | |
" %45 = getelementptr i64* %44, i32 0\n", | |
" %46 = load i64* %45\n", | |
" %47 = mul i64 %16, %46\n", | |
" %48 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 2\n", | |
" %49 = load i8** %48\n", | |
" %50 = getelementptr i8* %49, i64 %47\n", | |
" %51 = bitcast i8* %50 to double*\n", | |
" %52 = getelementptr double* %51, i64 %20\n", | |
" %53 = load double* %52\n", | |
" %54 = fsub double %42, %53\n", | |
" %55 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 5\n", | |
" %56 = load i64** %55\n", | |
" %57 = getelementptr i64* %56, i32 0\n", | |
" %58 = load i64* %57\n", | |
" %59 = mul i64 %13, %58\n", | |
" %60 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 2\n", | |
" %61 = load i8** %60\n", | |
" %62 = getelementptr i8* %61, i64 %59\n", | |
" %63 = bitcast i8* %62 to double*\n", | |
" %64 = getelementptr double* %63, i64 %20\n", | |
" %65 = load double* %64\n", | |
" %66 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 5\n", | |
" %67 = load i64** %66\n", | |
" %68 = getelementptr i64* %67, i32 0\n", | |
" %69 = load i64* %68\n", | |
" %70 = mul i64 %16, %69\n", | |
" %71 = getelementptr { i64, i32*, i8*, i32, i64*, i64*, i8*, i8*, i32, i8*, i8*, i8*, i64* }* %X, i32 0, i32 2\n", | |
" %72 = load i8** %71\n", | |
" %73 = getelementptr i8* %72, i64 %70\n", | |
" %74 = bitcast i8* %73 to double*\n", | |
" %75 = getelementptr double* %74, i64 %20\n", | |
" %76 = load double* %75\n", | |
" %77 = fsub double %65, %76\n", | |
" %78 = fmul double %54, %77\n", | |
" %79 = fadd double %19, %78\n", | |
" br label %BLOCK_87\n", | |
"}\n", | |
"\n" | |
] | |
} | |
], | |
"prompt_number": 2 | |
}, | |
{ | |
"cell_type": "code", | |
"collapsed": false, | |
"input": [ | |
"import time\n", | |
"start = time.time()\n", | |
"pairwise_numba(X, output)\n", | |
"end = time.time()\n", | |
"print \"Result from compiled is in %s (msec)\" % ((end-start)*1000)" | |
], | |
"language": "python", | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"stream": "stdout", | |
"text": [ | |
"Result from compiled is in 2.77519226074 (msec)\n" | |
] | |
} | |
], | |
"prompt_number": 5 | |
} | |
], | |
"metadata": {} | |
} | |
] | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment