mirror of
https://github.com/fverdugo/XM_40017.git
synced 2025-11-09 22:44:23 +01:00
693 lines
36 KiB
Plaintext
693 lines
36 KiB
Plaintext
{
|
|
"cells": [
|
|
{
|
|
"attachments": {},
|
|
"cell_type": "markdown",
|
|
"id": "acfe5cc9",
|
|
"metadata": {},
|
|
"source": [
|
|
"\n",
|
|
"<div>\n",
|
|
"<img src=\"data:image/png;base64,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\" align=\"left\" width=\"300\"/>\n",
|
|
"</div>\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ae2a0512",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Seminars Computational Science\n",
|
|
"### Julia tutorial\n",
|
|
"\n",
|
|
"# Why is Julia fast?\n",
|
|
"\n",
|
|
"by Francesc Verdugo (VU Amsterdam)\n",
|
|
"\n",
|
|
"2022-11-24"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e040636a",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Contents\n",
|
|
"\n",
|
|
"We will learn\n",
|
|
"\n",
|
|
"- Basic julia concepts:\n",
|
|
" - type-inference\n",
|
|
" - JIT compilation\n",
|
|
"- Some Julia syntax\n",
|
|
"- Some useful Julia packages"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "bc1d9ce2",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Using Jupyter notebooks in Julia"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "ff199820",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Running a cell\n",
|
|
"\n",
|
|
"Click on a cell and press `Shift` + `Enter`"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a8e4fba2",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"1+3\n",
|
|
"4*5"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0e035ee9",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Cell order is important"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "187db91d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"foo() = \"Well done!\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a29023dc",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"foo()"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0b788d3b",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Package and help modes"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "23e1803d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"] add BenchmarkTools DataFrames PyCall Conda Test"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "4353e6ec",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"? print"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "44c03fde",
|
|
"metadata": {},
|
|
"source": [
|
|
"## How fast is Julia code?"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "6c088d9e",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Example\n",
|
|
"\n",
|
|
"Sum entries of a given array $a = [a_1,a_2,...,a_n]$\n",
|
|
"\n",
|
|
" $$s = \\sum_{i=1}^n a_i$$\n",
|
|
"\n",
|
|
"### "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "34e3c7dd",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Hand-written sum function\n",
|
|
"\n",
|
|
"### Exercise\n",
|
|
"Write a function that computes the sum of all elements in array `a`. You can view the solution at the bottom of the notebook."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "a672edac",
|
|
"metadata": {
|
|
"code_folding": []
|
|
},
|
|
"outputs": [],
|
|
"source": [
|
|
"# ✍️ Exercise 1\n",
|
|
"function sum_hand(a)\n",
|
|
" # TODO\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "0494a1b3",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Test-driven development\n",
|
|
"Next, you can test your solution. You can use the Julia macro `@test` which is provided in the `Test` package."
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ebac7b9e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using Test"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "aa5505d4",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"a = rand(5)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fc11923c",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@test sum_hand(a) ≈ sum(a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "e23f3ddf",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Benchmarking\n",
|
|
"In order to track the performance of your code, it is useful to time the execution of single functions. In Julia, the most conventional way of measuring the computation time is the macro `@time`. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "caff0307",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"a = rand(10^7);"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "6d073236",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@time sum_hand(a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c664522e",
|
|
"metadata": {},
|
|
"source": [
|
|
"Note that `@time` also measures the compile time of a function if it's the first call to that function. So make sure to run `@time` twice on a freshly compiled function in order to get a more meaningful result. \n",
|
|
"\n",
|
|
"\n",
|
|
"Now in order to benchmark our code, we need to run it several times. To do this we can call our code in a for-loop and gather the runtimes using the Julia macro `@elapsed`. This measures the runtime of an expression in seconds, just as the `@time` macro, only `@elapsed` discards the result of the computation and returns the elapsed time instead. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "bba864c1",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@elapsed sum_hand(a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "70317d33",
|
|
"metadata": {},
|
|
"source": [
|
|
"## BenchmarkTools\n",
|
|
"\n",
|
|
"The `BenchmarkTools` extension package provides useful macros for sampling runtimes automatically. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "424ffe03",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using BenchmarkTools"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "079ef7d0",
|
|
"metadata": {},
|
|
"source": [
|
|
"First of all, the `@benchmark` macro runs the code multiple times and gives out a lot of details: the minimum and maximum time, mean time, median time, number of samples taken, memory allocations, etc. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "b5bb9a12",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"bch_sum_hand = @benchmark sum_hand($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "c77d454b",
|
|
"metadata": {},
|
|
"source": [
|
|
"For quick sanity checks, one can use the `@btime` macro, which is a convenience wrapper around `@benchmark`. It returns only the minimum execution time and memory allocations. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fee5493d",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@btime sum_hand($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "3a1a774c",
|
|
"metadata": {},
|
|
"source": [
|
|
"Similar to the `@elapsed` macro, `BenchmarkTool`'s `@belapsed` discards the return value of the function and instead returns the minimum runtime in seconds. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8e0cdb8c",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@belapsed sum_hand($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "fb530b87",
|
|
"metadata": {},
|
|
"source": [
|
|
"As opposed to `@time` and `@elapsed`, `@btime` and `@belapsed` run the code several times and return the minimum runtime, thus eliminating possible compilation times from the measurement. "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "782be14f",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Built-in sum function"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "07df4939",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"bch_sum = @benchmark sum($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "18972fa7",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Hand-written sum in Python\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "038702c0",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using PyCall"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8e1dcbfa",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"py\"\"\"\n",
|
|
"def sum_py_hand(A):\n",
|
|
" s = 0.0\n",
|
|
" for a in A:\n",
|
|
" s += a\n",
|
|
" return s\n",
|
|
"\"\"\"\n",
|
|
"sum_py_hand = py\"sum_py_hand\""
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "60ca4517",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@test sum(a) ≈ sum_py_hand(a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "2f009076",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"bch_sum_py_hand = @benchmark sum_py_hand($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "22d29afa",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Numpy sum "
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0f7ffb8e",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using Conda"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e667fc80",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"numpy = pyimport(\"numpy\")\n",
|
|
"sum_numpy = numpy[\"sum\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "ee0361df",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@test sum_numpy(a) ≈ sum(a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "d2f4e9ea",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"bch_sum_numpy = @benchmark sum_numpy($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d7c3cbd6",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Sumary of the results\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "5ce4c97a",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"timings = [bch_sum_hand,bch_sum,bch_sum_py_hand,bch_sum_numpy]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "9d5caabd",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"methods = [\"sum_hand\",\"sum\",\"sum_py_hand\",\"sum_numpy\"]"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "8b7a3661",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using DataFrames"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "82b11610",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"df = DataFrame(method=methods,time=timings)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f03c4281",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Improving the hand-written sum in Julia\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "7696719c",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# ✍️ Exercise 3\n",
|
|
"function sum_hand_fast(a)\n",
|
|
" s = 0.0\n",
|
|
" @simd for ai in a\n",
|
|
" s += ai\n",
|
|
" end\n",
|
|
" s\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "0b461036",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@test sum_hand_fast(a) ≈ sum(a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "fc228cba",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"@benchmark sum_hand_fast($a)"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "328f9128",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Conlcusions so far\n",
|
|
"\n",
|
|
"- Julia code (for loops) are much faster than in Python\n",
|
|
"- Julia code can be as fast as optimized C code"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "f9ce5464",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Why Julia is fast?\n",
|
|
"\n",
|
|
"- Julia is a compiled language (like C, C++, Fortran)\n",
|
|
"- Julia is JIT compiled (C, C++, Fortran are AOT compiled)\n",
|
|
"- Type declarations are optional in Julia\n",
|
|
"\n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "aa5254e4",
|
|
"metadata": {},
|
|
"source": [
|
|
"# Conclusion: Why we use Julia in this course\n",
|
|
"\n",
|
|
"- Julia code is fast (it can be as fast as C)\n",
|
|
"- Julia is a high-level language with simpler syntax than C \n",
|
|
"- Julia supports different parallel programming models\n",
|
|
"\n",
|
|
"We will look into the third point in a later section of this course. \n"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d4efafe2",
|
|
"metadata": {},
|
|
"source": [
|
|
"## Solution to the exercises\n",
|
|
"\n",
|
|
"### Solution to Exercise 1"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "17f73c0f",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"function sum_hand(a)\n",
|
|
" s = 0.0\n",
|
|
" for ai in a\n",
|
|
" s += ai\n",
|
|
" end\n",
|
|
" s\n",
|
|
"end"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "markdown",
|
|
"id": "d12d6400",
|
|
"metadata": {},
|
|
"source": [
|
|
"### Solution to Exercise 2"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "e39094da",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"using Statistics\n",
|
|
"\n",
|
|
"a = rand(10^7)\n",
|
|
"num_it = 15\n",
|
|
"runtimes = zeros(num_it)\n",
|
|
"for i in 1:num_it\n",
|
|
" runtimes[i] = @elapsed sum_hand(a)\n",
|
|
"end\n",
|
|
"@show mean(runtimes) \n",
|
|
"@show std(runtimes)\n",
|
|
"@show minimum(runtimes)\n",
|
|
"@show maximum(runtimes);"
|
|
]
|
|
},
|
|
{
|
|
"cell_type": "code",
|
|
"execution_count": null,
|
|
"id": "7943f1cc",
|
|
"metadata": {},
|
|
"outputs": [],
|
|
"source": [
|
|
"# ✍️ Exercise 3\n",
|
|
"function sum_hand_fast(a)\n",
|
|
" s = 0.0\n",
|
|
" @simd for ai in a\n",
|
|
" s += ai\n",
|
|
" end\n",
|
|
" s\n",
|
|
"end"
|
|
]
|
|
}
|
|
],
|
|
"metadata": {
|
|
"kernelspec": {
|
|
"display_name": "Julia 1.8.5",
|
|
"language": "julia",
|
|
"name": "julia-1.8"
|
|
},
|
|
"language_info": {
|
|
"file_extension": ".jl",
|
|
"mimetype": "application/julia",
|
|
"name": "julia",
|
|
"version": "1.8.5"
|
|
}
|
|
},
|
|
"nbformat": 4,
|
|
"nbformat_minor": 5
|
|
}
|