Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit b19669b1 authored by paugier's avatar paugier
Browse files

Work on second week presentations

parent 6b5e018e
......@@ -10,44 +10,62 @@
"source": [
"# Processing time evaluation\n",
"\n",
"Pierre Augier (LEGI), Raphaël Bacher (Gipsa), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre),Loïc Huder (ISTerre)\n"
"Pierre Augier (LEGI), Raphaël Bacher (Gipsa), Cyrille Bonamy (LEGI), Eric Maldonado (Irstea), Franck Thollard (ISTerre), Loïc Huder (ISTerre)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Given a problem (*e.g* finding which element is missing in a listof elements), we want to code a solution that solves the problem. The classical workflow is: \n",
"\n",
" * **design** an algorithm that solves the problem.\n",
" - study the input of the algorithm (it is special in one sens -- *e.g* the list we are given is almost sorted)\n",
" - design an algorithms comes (given the specificity of your data)\n",
" - choose the adequate data structure, *i.e.* the data structure that will optimize the relevant operations, a.k.a the operations that takes time or that are repeated a large number of time. \n",
" - check the adequation of\n",
" * **evaluate** the complexity of the algorithm (theoretical point of view)\n",
" * **take care** of the special cases (can my list be empty, in such a case what is my strategy ?)\n",
" * **write your specs**: *e.g.* if the list is empty, we raise an exception.\n",
" * **write some tests** to check your implementation is correct\n",
" * **code** *i.e.* do the implementation of both code and test\n",
" * **profile**: check where are the bottleneck \n",
" * **code** the implementation,\n",
" * **profile**\n",
" * ...."
"### Measure ⏱, don't guess! Profile to find the bottlenecks.\n",
"\n",
"\n",
"### Do not optimize everything!\n",
"\n",
"- *\"Premature optimization is the root of all evil\"* (Donald Knuth)\n",
"\n",
"- 80 / 20 rule, efficiency important for expensive things and NOT for small things"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Context: some notes on developing efficient software\n",
"\n",
"Given a problem (e.g. finding which element is missing in a list of elements), we want to code a solution that solves the problem. The classical workflow is: \n",
"\n",
"* **design** an algorithm that solves the problem.\n",
" - study the input of the algorithm (is it special in one sens?)\n",
" - design an algorithms comes (given the specificity of your data)\n",
" - choose the adequate data structure, i.e. the data structure that will optimize the relevant operations, a.k.a the operations that takes time or that are repeated a large number of time. \n",
"\n",
"* **evaluate** the complexity of the algorithm (theoretical point of view)\n",
"* **take care** of the special cases (can my list be empty, in such a case what is my strategy ?)\n",
"* **write your specs**: for example if the list is empty, we raise an exception.\n",
"* **write some tests** to check your implementation is correct\n",
"* **code**\n",
"* **profile**: find where are the bottlenecks\n",
"* **code**\n",
"* **profile**\n",
"* ..."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note 1:\n",
"----------\n",
"## Note 1\n",
" \n",
" If your data is large enough, a basic implementation of an algorithm with low complexity will run faster than a fined tuned implementation of a algorithm with high complexity\n",
"If your data is large enough, a basic implementation of an algorithm with low complexity will run faster than a fined tuned implementation of a algorithm with high complexity\n",
" \n",
"Example:\n",
"--------------\n",
"### Example\n",
"\n",
"Looking for the missing element problem: we know that all the element for 0 to N should be present. We can compute the sum and calculate the difference between the computed sum and the mathematical sum. This algorithm acces only once each element. It thus has an $O(N)$ complexity, where N is the number of elements. \n",
"Looking for the missing element problem: we know that all the element for 0 to N should be present. We can compute the sum and calculate the difference between the computed sum and the mathematical sum. This algorithm access only once each element. It thus has an $O(N)$ complexity, where N is the number of elements. \n",
"\n",
"An algorithm that checks if element e belongs to the list, for each e will has an $O(N^2)$ complexity and will be slower that the previous one for **sufficient large value of N**. \n"
]
......@@ -56,50 +74,31 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"Note 2:\n",
"----------\n",
"## Note 2\n",
" \n",
" If your data has some specificity, take advantage of it. \n",
"If your data has some specificity, take advantage of it. \n",
" \n",
" \n",
"Example:\n",
"--------------\n",
"### Example\n",
"\n",
" - if your list is sorted, solving the above problem can be done by checking that two consecutive elements in the list are consective numbers. The complexity is thus $O(N)$\n",
" - sorting N elements can be done in $O(N)$ in the special case where the $N$ items belongs to a range of size N."
"- if your list is sorted, solving the above problem can be done by checking that two consecutive elements in the list are consective numbers. The complexity is thus $O(N)$\n",
"- sorting N elements can be done in $O(N)$ in the special case where the $N$ items belongs to a range of size N."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Note 3:\n",
"----------\n",
"## Note 3\n",
" \n",
" Complexity analysis is done over the **worst case**, what is the worst input for our algorithm\n",
"Complexity analysis is done over the **worst case**, what is the worst input for our algorithm\n",
" \n",
"Example:\n",
"--------------\n",
"\n",
" - sorting elements\n",
" - worst case: elements are already sorted but in reverse order\n",
" \n",
" - counting\n",
" - all counts are 1 .... "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Measure ⏱, don't guess! Profile to find the bottlenecks.\n",
"\n",
"\n",
"### Do not optimize everything!\n",
"### Example\n",
"\n",
"- *\"Premature optimization is the root of all evil\"* (Donald Knuth)\n",
"Sorting elements: \n",
"\n",
"- 80 / 20 rule, efficiency important for expensive things and NOT for small things"
"worst case = elements are already sorted but in reverse order\n",
" "
]
},
{
......@@ -145,9 +144,20 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"18.7 µs ± 700 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n",
"13.5 µs ± 566 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n",
"7.27 µs ± 38.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n",
"3.74 µs ± 18.4 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)\n"
]
}
],
"source": [
"import math\n",
"l = [] \n",
......@@ -161,6 +171,19 @@
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- [`pyperf`](https://pypi.org/project/pyperf/) is a more powerful tool but we can also do the same as with the module `timeit`:\n",
"\n",
"`python3 -m pyperf timeit -s \"import math; l=[]\" \"for x in range(100): l.append(math.pow(x,2))\"`"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"## Do not guess (the return of word counting problem)\n",
"\n"
......@@ -168,9 +191,23 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"len(s) = 7160000, nbkeys 33 base, count, count_count, except, colection.counter\n",
"517 ms ± 2.26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
"478 ms ± 3.98 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
"196 ms ± 680 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
"464 ms ± 12.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
"247 ms ± 843 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
"414 ms ± 3.04 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
"source": [
"def build_count_base(t): \n",
" d = {} \n",
......@@ -220,8 +257,30 @@
"%timeit build_count_count(s)\n",
"%timeit build_count_excpt(s)\n",
"%timeit build_count_counter(s)\n",
"%timeit build_count_defaultdict(s)\n",
"\n",
"%timeit build_count_defaultdict(s)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"with split\n",
"len(s) = 1100000, nbkeys 90 base, count, count_count, except, colection.counter\n",
"113 ms ± 4.27 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
"104 ms ± 2.48 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
"982 ms ± 2.85 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n",
"93.2 ms ± 347 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
"59.9 ms ± 1.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n",
"410 ms ± 2.74 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
]
}
],
"source": [
"print(\"with split\")\n",
"s2 = s.split()\n",
"print(f\"len(s) = {len(s2)}, nbkeys {len(set(s2))} base, count, count_count, except, colection.counter\")\n",
......@@ -237,25 +296,16 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Conclusion\n",
"### Conclusion of these measurements\n",
"\n",
"The best performing algorithm depends upon the feature of the input.\n",
"The best performing algorithm depends on the feature of the input.\n",
"\n",
"In our case: how many different words do we have in our vocabulary: \n",
"In our case: how many different words do we have in our vocabulary?\n",
" - 4 for ADN, \n",
" - 26 for letters, \n",
" - 60 Millions for natural texts"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"- [`pyperf`](https://pypi.org/project/pyperf/) is a more powerful tool but we can also do the same as with the module `timeit`:\n",
"\n",
"`python3 -m pyperf timeit -s \"import math; l=[]\" \"for x in range(100): l.append(math.pow(x,2))\"`"
]
},
{
"cell_type": "markdown",
"metadata": {
......@@ -284,9 +334,17 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 4,
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"elapsed time: 9.47e-05 s\n"
]
}
],
"source": [
"from time import time\n",
"\n",
......@@ -422,7 +480,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
"version": "3.7.2"
}
},
"nbformat": 4,
......
......@@ -15,11 +15,11 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"We consider here wrapping two static languages: C and Fortran.\n",
"We mainly consider here wrapping codes in C and Fortran.\n",
"\n",
"We classically wrap already existing code to access them via Python. \n",
"We classically wrap already existing codes to access them via Python. \n",
"\n",
"Depending on the language to wrap the tool to use are different. \n"
"Depending on the language to wrap, the tools are different. \n"
]
},
{
......
......@@ -785,6 +785,23 @@
"\n",
"https://pytorch.org/"
]
},
{
"cell_type": "markdown",
"metadata": {
"slideshow": {
"slide_type": "slide"
}
},
"source": [
"# Conclusions\n",
"\n",
"- Many good accelerators and compilers for Python-Numpy code\n",
"\n",
"- Very good results for \"standard types\" (arrays of numbers on CPU and GPU)\n",
"\n",
"- Limitation: high performance with user-defined numerical types"
]
}
],
"metadata": {
......@@ -803,7 +820,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
"version": "3.7.2"
}
},
"nbformat": 4,
......
......@@ -79,7 +79,9 @@
"\n",
" - *Terrible* 🐌 for CPU bounded *if the Python interpreter is used a lot* !\n",
"\n",
" - *No problem* for IO bounded !"
" - *No problem* for IO bounded !\n",
" \n",
" - *No problem* for extensions when the interpreter is not used !"
]
},
{
......@@ -113,8 +115,9 @@
}
},
"source": [
"## 2 other packages for parallel computing with Python\n",
"## Other packages for parallel computing with Python\n",
"\n",
"- IPython\n",
"- dask\n",
"- joblib"
]
......@@ -161,7 +164,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.7.3"
"version": "3.7.2"
}
},
"nbformat": 4,
......
......@@ -3,4 +3,4 @@ all:
python3 -m numpy.f2py -c "dtw_cort.f90" -m distances_fort
clean:
rm -f distances_fort.*.so
rm -f distances_fort.*.so *.mod
......@@ -14,7 +14,7 @@ matplotlib
pandas
h5py
#vizu
# pyviz # (not available in conda!)
# pyviz # (not available in conda-forge)
# wrapper
cffi
# accelerators
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment