Skip to content

Commit

Permalink
#2 add lecture 2
Browse files Browse the repository at this point in the history
  • Loading branch information
martinjrobins committed Oct 1, 2019
1 parent 063eac7 commit 481facc
Showing 1 changed file with 193 additions and 0 deletions.
193 changes: 193 additions & 0 deletions 12_optimisation_1/lectures/lectures_01_cython.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Optimisation - Cython\n",
"## Martin Robinson\n",
"## Oct 2019"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Using lower-level languages\n",
"\n",
"- Interpreted languages are fundamentially speed-limited when they only consider *type* at run-time.\n",
"- e.g. consider what happens with the types of the variables in the following function\n",
"```python\n",
"def norm(arg_list, p):\n",
" sum = 0 # sum is an int here\n",
" for x in arg_list: # type of x depends on input container\n",
" sum += abs(x)**p # type of rhs depends on both x and p, sum could *change* type here\n",
" return sum**(1.0/p) # return value is probably float due to 1.0\n",
"```\n",
"- how much memory to allocate for sum? does this memory need to be re-allocated during the loop? are conversion routines between types required during the loop?"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"- compare to equivilant C++ code\n",
"```cpp\n",
"float norm(std::vector<float>& arg_list, float p) {\n",
" float sum = 0.0f;\n",
" for (size_t i = 0; i < arg_list.size(); ++i) {\n",
" sum += std::pow(std::abs(arg_list), p);\n",
" }\n",
" return std::pow(sum, 1.0f/p);\n",
"}\n",
"```\n",
"- compiler can pre-allocate the stack size because the sizes of local variables known, no type conversions neccessary\n",
"- compiler can generate efficient machine code because the programmer has provided more information (i.e. types)\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# \"Compiling\" Python code\n",
"\n",
"- All python implementations (CPython, PyPy, IronPython) compile to *bytecode*, which is then either interpreted at run-time, or perhaps further compiled to native machine code\n",
"- Implementations that compile to native machine code usually implement something close to normal python, but with restrictions or additions that alter the nature of the language. These include:\n",
" - Cython (Python-to-C)\n",
" - Nuitka (Python-to-C++)\n",
" - Numba (Python-to-LLVM IR)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# \"Wrapping\" C and C++ for use in Python\n",
"\n",
"- the compilers in the previous slide implement an altered version of python, yet another language to learn!\n",
"- If your already comfortable with C, C++ or Fortran, why not use this directly and write a *wrapper* to call from Python?\n",
"- "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Cython"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Your first Cython program"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"```python\n",
"def norm(a, p):\n",
" s = 0\n",
" x_max = a.shape[0]\n",
" y_max = a.shape[1]\n",
" for i in range(x_max):\n",
" for j in range(y_max):\n",
" s += abs(a[i, j])**p\n",
" return s**(1.0/p)\n",
"\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Manual compilation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Examining the generated code"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Adding types"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# memoryviews"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tuning indexing further"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"```python\n",
"from libc.math cimport abs\n",
"cimport cython\n",
"\n",
"@cython.boundscheck(False) # Deactivate bounds checking\n",
"@cython.wraparound(False) # Deactivate negative indexing.\n",
"@cython.cdivision(True) # Deactivate normal python division checking\n",
"cdef double norm(double [:, :] a, int p):\n",
" cdef double s = 0\n",
" cdef Py_ssize_t x_max = a.shape[0]\n",
" cdef Py_ssize_t y_max = a.shape[1]\n",
" for i in range(x_max):\n",
" for j in range(y_max):\n",
" s += abs(a[i, j])**p\n",
" return s**(1.0/p)\n",
"```"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Packaging Cython programs"
]
}
],
"metadata": {
"language_info": {
"name": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}

0 comments on commit 481facc

Please sign in to comment.