Last active
August 29, 2015 14:19
-
-
Save oyamad/e709f92f7522eb1df3d3 to your computer and use it in GitHub Desktop.
Numba: C-oder v.s. Fortran-oder
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
{ | |
"cells": [ | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"# Numba: C-oder v.s. Fortran-oder, without `func_jit(np.array([[1.]]))`" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"from __future__ import print_function\n", | |
"import numpy as np\n", | |
"from numba import jit" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Consider the following simple function, where `A` is supposed to be an $n \\times n$ np.array:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 2, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"def func(A):\n", | |
" n = A.shape[0]\n", | |
" for k in range(n-1):\n", | |
" print(np.sum(A[k, k+1:n]))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Consider the following two arrays, with C-contiguous order and Fortran-contiguous order:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 3, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"A_C = np.array([[0., 1.],\n", | |
" [2., 3.]], order='C')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 4, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"A_F = np.array([[0., 1.],\n", | |
" [2., 3.]], order='F')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 5, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"[[ 0. 1.]\n", | |
" [ 2. 3.]]\n" | |
] | |
} | |
], | |
"source": [ | |
"print(A_C)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 6, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": true | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"[[ 0. 1.]\n", | |
" [ 2. 3.]]\n" | |
] | |
} | |
], | |
"source": [ | |
"print(A_F)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"`func` prints the same number for both arrays:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 7, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1.0\n" | |
] | |
} | |
], | |
"source": [ | |
"func(A_C)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 8, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1.0\n" | |
] | |
} | |
], | |
"source": [ | |
"func(A_F)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Now consider the JIT complied version of `func`:" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 9, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"@jit\n", | |
"def func_jit(A):\n", | |
" n = A.shape[0]\n", | |
" for k in range(n-1):\n", | |
" print(np.sum(A[k, k+1:n]))" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"**Without `func_jit(np.array([[1.]]))`\n", | |
"`func_jit` prints the same number for `A_C` and `A_F`:**" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 10, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"# func_jit(np.array([[1.]]))" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1.0\n" | |
] | |
} | |
], | |
"source": [ | |
"func_jit(A_C)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 12, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1.0\n" | |
] | |
} | |
], | |
"source": [ | |
"func_jit(A_F)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 13, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"Darwin-13.4.0-x86_64-i386-64bit\n" | |
] | |
} | |
], | |
"source": [ | |
"import platform\n", | |
"print(platform.platform())" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 14, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"2.7.9 |Continuum Analytics, Inc.| (default, Dec 15 2014, 10:37:34) \n", | |
"[GCC 4.2.1 (Apple Inc. build 5577)]\n" | |
] | |
} | |
], | |
"source": [ | |
"import sys\n", | |
"print(sys.version)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 15, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"1.9.2\n" | |
] | |
} | |
], | |
"source": [ | |
"print(np.__version__)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 16, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"'0.18.2'" | |
] | |
}, | |
"execution_count": 16, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"import numba\n", | |
"numba.__version__" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 17, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"name": "stdout", | |
"output_type": "stream", | |
"text": [ | |
"func_jit (array(float64, 2d, F),)\n", | |
"--------------------------------------------------------------------------------\n", | |
"# File: <ipython-input-9-ee604f27fd2b>\n", | |
"# --- LINE 1 --- \n", | |
"\n", | |
"@jit\n", | |
"\n", | |
"# --- LINE 2 --- \n", | |
"\n", | |
"def func_jit(A):\n", | |
"\n", | |
" # --- LINE 3 --- \n", | |
" # label 0\n", | |
" # A = arg(0, name=A) :: array(float64, 2d, F)\n", | |
" # $0.2 = getattr(attr=shape, value=A) :: (int64 x 2)\n", | |
" # $const0.3 = const(int, 0) :: int32\n", | |
" # $0.4 = getitem(index=$const0.3, value=$0.2) :: int64\n", | |
" # del $const0.3\n", | |
" # del $0.2\n", | |
" # n = $0.4 :: int64\n", | |
" # del $0.4\n", | |
"\n", | |
" n = A.shape[0]\n", | |
"\n", | |
" # --- LINE 4 --- \n", | |
" # jump 13\n", | |
" # label 13\n", | |
" # $13.1 = global(range: <built-in function range>) :: range\n", | |
" # $const13.3 = const(int, 1) :: int32\n", | |
" # $13.4 = n - $const13.3 :: int64\n", | |
" # del $const13.3\n", | |
" # $13.5 = call $13.1($13.4, ) :: (int64,) -> range_state64\n", | |
" # del $13.4\n", | |
" # del $13.1\n", | |
" # $13.6 = getiter(value=$13.5) :: range_iter64\n", | |
" # del $13.5\n", | |
" # $phi30.1 = $13.6 :: range_iter64\n", | |
" # del $13.6\n", | |
" # jump 30\n", | |
" # label 30\n", | |
" # $30.2 = iternext(value=$phi30.1) :: pair<int64, bool>\n", | |
" # $30.3 = pair_first(value=$30.2) :: int64\n", | |
" # $30.4 = pair_second(value=$30.2) :: bool\n", | |
" # del $30.2\n", | |
" # $phi33.1 = $30.3 :: int64\n", | |
" # del $30.3\n", | |
" # branch $30.4, 33, 78\n", | |
" # label 33\n", | |
" # k = $phi33.1 :: int64\n", | |
" # del $phi33.1\n", | |
"\n", | |
" for k in range(n-1):\n", | |
"\n", | |
" # --- LINE 5 --- \n", | |
" # $33.2 = global(print: <built-in function print>) :: print\n", | |
" # $33.3 = global(np: <module 'numpy' from '/Users/oyama/anaconda/envs/quantecon-dev/lib/python2.7/site-packages/numpy/__init__.pyc'>) :: Module(<module 'numpy' from '/Users/oyama/anaconda/envs/quantecon-dev/lib/python2.7/site-packages/numpy/__init__.pyc'>)\n", | |
" # $33.4 = getattr(attr=sum, value=$33.3) :: Function(<unbound method Numpy_reduce_<function sum at 0x104afbed8>.sum>)\n", | |
" # del $33.3\n", | |
" # $const33.8 = const(int, 1) :: int32\n", | |
" # $33.9 = k + $const33.8 :: int64\n", | |
" # del $const33.8\n", | |
" # $33.11 = global(slice: <type 'slice'>) :: slice\n", | |
" # $33.12 = call $33.11($33.9, n, ) :: (int64, int64) -> slice3_type\n", | |
" # del $33.9\n", | |
" # del $33.11\n", | |
" # $33.13 = build_tuple(items=[Var(k, <ipython-input-9-ee604f27fd2b> (4)), Var($33.12, <ipython-input-9-ee604f27fd2b> (5))]) :: (int64, slice3_type)\n", | |
" # del k\n", | |
" # del $33.12\n", | |
" # $33.14 = getitem(index=$33.13, value=A) :: array(float64, 1d, A)\n", | |
" # del $33.13\n", | |
" # $33.15 = call $33.4($33.14, ) :: (array(float64, 1d, A),) -> float64\n", | |
" # del $33.4\n", | |
" # del $33.14\n", | |
" # $33.16 = call $33.2($33.15, ) :: (float64,) -> none\n", | |
" # del $33.2\n", | |
" # del $33.16\n", | |
" # del $33.15\n", | |
" # jump 30\n", | |
" # label 78\n", | |
" # del n\n", | |
" # del A\n", | |
" # del $phi33.1\n", | |
" # del $phi30.1\n", | |
" # del $30.4\n", | |
" # jump 79\n", | |
" # label 79\n", | |
" # $const79.1 = const(NoneType, None) :: none\n", | |
" # $79.2 = cast(value=$const79.1) :: none\n", | |
" # del $const79.1\n", | |
" # return $79.2\n", | |
"\n", | |
" print(np.sum(A[k, k+1:n]))\n", | |
"\n", | |
"\n", | |
"================================================================================\n", | |
"func_jit (array(float64, 2d, C),)\n", | |
"--------------------------------------------------------------------------------\n", | |
"# File: <ipython-input-9-ee604f27fd2b>\n", | |
"# --- LINE 1 --- \n", | |
"\n", | |
"@jit\n", | |
"\n", | |
"# --- LINE 2 --- \n", | |
"\n", | |
"def func_jit(A):\n", | |
"\n", | |
" # --- LINE 3 --- \n", | |
" # label 0\n", | |
" # A = arg(0, name=A) :: array(float64, 2d, C)\n", | |
" # $0.2 = getattr(attr=shape, value=A) :: (int64 x 2)\n", | |
" # $const0.3 = const(int, 0) :: int32\n", | |
" # $0.4 = getitem(index=$const0.3, value=$0.2) :: int64\n", | |
" # del $const0.3\n", | |
" # del $0.2\n", | |
" # n = $0.4 :: int64\n", | |
" # del $0.4\n", | |
"\n", | |
" n = A.shape[0]\n", | |
"\n", | |
" # --- LINE 4 --- \n", | |
" # jump 13\n", | |
" # label 13\n", | |
" # $13.1 = global(range: <built-in function range>) :: range\n", | |
" # $const13.3 = const(int, 1) :: int32\n", | |
" # $13.4 = n - $const13.3 :: int64\n", | |
" # del $const13.3\n", | |
" # $13.5 = call $13.1($13.4, ) :: (int64,) -> range_state64\n", | |
" # del $13.4\n", | |
" # del $13.1\n", | |
" # $13.6 = getiter(value=$13.5) :: range_iter64\n", | |
" # del $13.5\n", | |
" # $phi30.1 = $13.6 :: range_iter64\n", | |
" # del $13.6\n", | |
" # jump 30\n", | |
" # label 30\n", | |
" # $30.2 = iternext(value=$phi30.1) :: pair<int64, bool>\n", | |
" # $30.3 = pair_first(value=$30.2) :: int64\n", | |
" # $30.4 = pair_second(value=$30.2) :: bool\n", | |
" # del $30.2\n", | |
" # $phi33.1 = $30.3 :: int64\n", | |
" # del $30.3\n", | |
" # branch $30.4, 33, 78\n", | |
" # label 33\n", | |
" # k = $phi33.1 :: int64\n", | |
" # del $phi33.1\n", | |
"\n", | |
" for k in range(n-1):\n", | |
"\n", | |
" # --- LINE 5 --- \n", | |
" # $33.2 = global(print: <built-in function print>) :: print\n", | |
" # $33.3 = global(np: <module 'numpy' from '/Users/oyama/anaconda/envs/quantecon-dev/lib/python2.7/site-packages/numpy/__init__.pyc'>) :: Module(<module 'numpy' from '/Users/oyama/anaconda/envs/quantecon-dev/lib/python2.7/site-packages/numpy/__init__.pyc'>)\n", | |
" # $33.4 = getattr(attr=sum, value=$33.3) :: Function(<unbound method Numpy_reduce_<function sum at 0x104afbed8>.sum>)\n", | |
" # del $33.3\n", | |
" # $const33.8 = const(int, 1) :: int32\n", | |
" # $33.9 = k + $const33.8 :: int64\n", | |
" # del $const33.8\n", | |
" # $33.11 = global(slice: <type 'slice'>) :: slice\n", | |
" # $33.12 = call $33.11($33.9, n, ) :: (int64, int64) -> slice3_type\n", | |
" # del $33.9\n", | |
" # del $33.11\n", | |
" # $33.13 = build_tuple(items=[Var(k, <ipython-input-9-ee604f27fd2b> (4)), Var($33.12, <ipython-input-9-ee604f27fd2b> (5))]) :: (int64, slice3_type)\n", | |
" # del k\n", | |
" # del $33.12\n", | |
" # $33.14 = getitem(index=$33.13, value=A) :: array(float64, 1d, A)\n", | |
" # del $33.13\n", | |
" # $33.15 = call $33.4($33.14, ) :: (array(float64, 1d, A),) -> float64\n", | |
" # del $33.4\n", | |
" # del $33.14\n", | |
" # $33.16 = call $33.2($33.15, ) :: (float64,) -> none\n", | |
" # del $33.2\n", | |
" # del $33.16\n", | |
" # del $33.15\n", | |
" # jump 30\n", | |
" # label 78\n", | |
" # del n\n", | |
" # del A\n", | |
" # del $phi33.1\n", | |
" # del $phi30.1\n", | |
" # del $30.4\n", | |
" # jump 79\n", | |
" # label 79\n", | |
" # $const79.1 = const(NoneType, None) :: none\n", | |
" # $79.2 = cast(value=$const79.1) :: none\n", | |
" # del $const79.1\n", | |
" # return $79.2\n", | |
"\n", | |
" print(np.sum(A[k, k+1:n]))\n", | |
"\n", | |
"\n", | |
"================================================================================\n" | |
] | |
} | |
], | |
"source": [ | |
"func_jit.inspect_types()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.9" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment