{"id":4368,"date":"2021-04-19T15:00:53","date_gmt":"2021-04-19T13:00:53","guid":{"rendered":"https:\/\/immune.institute\/?p=4368"},"modified":"2021-04-19T15:00:53","modified_gmt":"2021-04-19T13:00:53","slug":"python-con-numba","status":"publish","type":"post","link":"https:\/\/immune.institute\/en\/blog\/python-con-numba\/","title":{"rendered":"Optimising your code with Numba"},"content":{"rendered":"<p><span style=\"font-weight: 400;\">Optimise your <\/span><b>Python code<\/b><span style=\"font-weight: 400;\"> with Numba<\/span><\/p>\n<p><span style=\"font-weight: 400;\">Discover all the Python acceleration features with Numba. Learn how to <\/span><b>optimise Python code<\/b><span style=\"font-weight: 400;\"> and optimise your resources, with this powerful tool.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">What will we see in this article?<\/span><\/p>\n<h2><b>Topics:<\/b><\/h2>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">What is Numba?\u00a0<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">How does Numba work?<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">First steps: Compiling for the CPU<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Use Numba to compile and accelerate functions using the CPU.<\/span><\/li>\n<\/ul>\n<h2><b>What is Numba?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Numba is a <\/span><b>compiler for<\/b><a href=\"https:\/\/immune.institute\/en\/programas\/diploma-programacion-en-python\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">Python<\/span><\/a><span style=\"font-weight: 400;\">the name of the module specially designed to speed up your numerical functions, generating <\/span><b>machine code<\/b><span style=\"font-weight: 400;\"> optimised from Python code, using LLVM. With this tool you can optimise your code and get performance similar to C, and C++, without having to switch programming languages. Import an optimisation module for your Python development environment.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">You can see the code in my<\/span><a href=\"https:\/\/github.com\/alejandrods\/Numba\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">GitHub<\/span><\/a><span style=\"font-weight: 400;\">! \ud83d\ude42<\/span><\/p>\n<h2><b>How does Numba work?<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Numba allows you to accelerate Python code (the numerical functions) using the CPU (Central Processing Unit) and the GPU (Graphics Processing Unit):<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i><span style=\"font-weight: 400;\">Compiled Functions: <\/span><\/i><span style=\"font-weight: 400;\">Numba compiles only Python functions, not entire applications. Basically, Numba is one of the <\/span><b>Python modules<\/b><span style=\"font-weight: 400;\"> which improves the performance of our functions.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i><span style=\"font-weight: 400;\">Just-in-time: @jit<\/span><\/i><span style=\"font-weight: 400;\"> (Dynamic translation): Numba transforms the \"bytecode\" (intermediate, more abstract code) to <\/span><b>machine code<\/b><span style=\"font-weight: 400;\"> immediately prior to its execution.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><i><span style=\"font-weight: 400;\">Focus on numerical functions:<\/span><\/i><span style=\"font-weight: 400;\"> Numba is focused on numeric data, such as int, float and complex. Today, there are limitations to using it with string data.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Numba is not the only way of programming in<\/span><a href=\"https:\/\/developer.nvidia.com\/cuda-zone\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">CUDA<\/span><\/a><span style=\"font-weight: 400;\">which is normally programmed directly in C, C++. However, Numba allows you to program directly in Python and optimise your code for both CPU and GPU by simply changing a couple of lines of your code. In relation to Python, there are other alternatives such as pyCUDA, here is an overview:<\/span><\/p>\n<p><span style=\"font-weight: 400;\">CUDA C\/C++:<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It is the most common and flexible way of programming in CUDA.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Accelerates C and C++ applications.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">pyCUDA<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It is the most efficient way to program in CUDA in Python.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Requires inserting C code into Python.<\/span><\/li>\n<\/ol>\n<p><span style=\"font-weight: 400;\">Numba<\/span><\/p>\n<ol>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Less efficient than pyCUDA.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Allows you to write your code in Python.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">It also optimises the code for CPU.<\/span><\/li>\n<\/ol>\n<p><img decoding=\"async\" class=\"size-full wp-image-8140 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen2.png\" alt=\"\" width=\"454\" height=\"339\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen2.png 454w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen2-256x191.png 256w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen2-16x12.png 16w\" sizes=\"(max-width: 454px) 100vw, 454px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8141 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen6.png\" alt=\"\" width=\"445\" height=\"264\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen6.png 445w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen6-256x152.png 256w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen6-18x12.png 18w\" sizes=\"(max-width: 445px) 100vw, 445px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8144 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen7.png\" alt=\"\" width=\"392\" height=\"437\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen7.png 392w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen7-230x256.png 230w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen7-11x12.png 11w\" sizes=\"(max-width: 392px) 100vw, 392px\" \/><\/p>\n<h2><b>First steps: Compiling CPU functions\u00a0<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Numba, apart from speeding up your functions by using the <\/span><b>GPU<\/b><span style=\"font-weight: 400;\">can be used to optimise functions in the <\/span><b>CPU<\/b><span style=\"font-weight: 400;\">. To do this, you simply use a <\/span><b>python decorator <\/b><span style=\"font-weight: 400;\">with what is called <\/span><i><span style=\"font-weight: 400;\">decorated functions<\/span><\/i><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">First of all, let's evaluate the hiplot function to see how Numba works. We must use the <\/span><b>compiler<\/b><a href=\"https:\/\/stackoverflow.com\/questions\/95635\/what-does-a-just-in-time-jit-compiler-do\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <b>@jit<\/b><\/a><span style=\"font-weight: 400;\">. The result is the same as the pure Python function, but Numba keeps the original Python implementation in the argument<\/span><a href=\"https:\/\/www.tensorflow.org\/api_docs\/python\/tf\/py_function\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">.py_func<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h3><strong>GPU Benchmark\u00a0<\/strong><\/h3>\n<p><span style=\"font-weight: 400;\">It is important to measure the performance of our code, and to check if Numba really works. There is a difference between the Python implementation and the Numba implementation.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">The result is astonishing: The function<\/span><a href=\"https:\/\/docs.python.org\/3\/library\/math.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <b>math.hypot<\/b><\/a><b> of Python<\/b><span style=\"font-weight: 400;\"> is faster than Numba! This is because Numba introduces certain steps when calling a function, so if the function is very simple, Numba can make it take longer than the pure Python implementation.<\/span><\/p>\n<h3><b>Operation<\/b><span style=\"font-weight: 400;\">\u00a0<\/span><\/h3>\n<p><span style=\"font-weight: 400;\">When we have initialised the hypot:<\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">IR: Intermediate representations<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">Bytecode Analysis: Intermediate code, more abstract than machine code.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">LLVM: Low Level Virtual Machine, infrastructure for developing compilers.<\/span><\/li>\n<li style=\"font-weight: 400;\" aria-level=\"1\"><span style=\"font-weight: 400;\">NVVM: An IR compiler based on LLVM, it is designed to render kernels on GPUs.<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\">Each line of Python is preceded by several lines of <\/span><b>IR code<\/b><span style=\"font-weight: 400;\">. It is most useful to look at the types of annotations Numba displays when operating on variables, for example in<\/span><a href=\"https:\/\/docs.python.org\/3\/c-api\/structures.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <b>pyobjectv<\/b><\/a><span style=\"font-weight: 400;\">Numba is indicating that it does not know the function<\/span><a href=\"https:\/\/numpy.org\/doc\/stable\/reference\/generated\/numpy.sin.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">np.sin<\/span><\/a><span style=\"font-weight: 400;\"> from <\/span><b>Python<\/b><span style=\"font-weight: 400;\"> and import it directly from the source code. We can inspect processes for hypot using<\/span><a href=\"http:\/\/numba.pydata.org\/numba-doc\/0.12.1\/debugging.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">.inspect_types()<\/span><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<h3><b>A Concrete Example: How a fractal is generated<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">We are going to measure the performance of a code that is in charge of <\/span><b>creating fractals<\/b><span style=\"font-weight: 400;\"> using the<\/span><a href=\"https:\/\/es.wikipedia.org\/wiki\/Conjunto_de_Mandelbrot\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">Mandelbrot ensemble<\/span><\/a><span style=\"font-weight: 400;\"> and see if Numba helps us to optimise it.\u00a0<\/span><\/p>\n<p><span style=\"font-weight: 400;\">It takes about 4.64 seconds to <\/span><b>generate a fractal<\/b><span style=\"font-weight: 400;\"> using the Mandelbrot Set, now let's see if Numba improves performance by using the @jit decorator.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">We can see how we have reduced the time from 4.62 seconds to 52.4 ms... and this has been done just by adding a decorator.<\/span><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8145 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen8.png\" alt=\"\" width=\"349\" height=\"552\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen8.png 349w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen8-162x256.png 162w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen8-324x512.png 324w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen8-8x12.png 8w\" sizes=\"(max-width: 349px) 100vw, 349px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8146 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen9.png\" alt=\"\" width=\"344\" height=\"232\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen9.png 344w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen9-256x173.png 256w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen9-18x12.png 18w\" sizes=\"(max-width: 344px) 100vw, 344px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8147 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen12.png\" alt=\"\" width=\"387\" height=\"728\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen12.png 387w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen12-136x256.png 136w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen12-272x512.png 272w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen12-6x12.png 6w\" sizes=\"(max-width: 387px) 100vw, 387px\" \/><\/p>\n<h3><b>A common mistake<\/b><\/h3>\n<p><span style=\"font-weight: 400;\">We have said that Numba only works with numeric functions, and although it compiles and executes Python code, there are some data types that it cannot compile yet (such as dictionaries).<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In the example above we can see however how it did not fail!!! We have said that Numba does not compile dictionaries... The point here is that Numba creates 2 functions, one for Python and one for Numba. So, here we are looking at the Python solution, we can check it by adding<\/span><a href=\"https:\/\/numba.pydata.org\/numba-doc\/latest\/user\/jit.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <b>nopython = True<\/b><\/a><span style=\"font-weight: 400;\">.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">jit(nopython = True)<\/span><i><span style=\"font-weight: 400;\"> is equivalent to<\/span><\/i><a href=\"https:\/\/numba.pydata.org\/numba-doc\/latest\/user\/performance-tips.html\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <i><span style=\"font-weight: 400;\">njit<\/span><\/i><\/a><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8148 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen13.png\" alt=\"\" width=\"624\" height=\"96\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen13.png 624w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen13-256x39.png 256w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen13-512x79.png 512w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen13-18x3.png 18w\" sizes=\"(max-width: 624px) 100vw, 624px\" \/><\/p>\n<p><img decoding=\"async\" class=\"size-full wp-image-8149 aligncenter\" src=\"https:\/\/principal.immune.institute\/wp-content\/uploads\/2021\/04\/Imagen14.png\" alt=\"\" width=\"431\" height=\"344\" srcset=\"https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen14.png 431w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen14-256x204.png 256w, https:\/\/immune.institute\/wp-content\/uploads\/2021\/04\/Imagen14-15x12.png 15w\" sizes=\"(max-width: 431px) 100vw, 431px\" \/><\/p>\n<h2><b>IMMUNE Technology Institute<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">If you want to<\/span><a href=\"https:\/\/immune.institute\/en\/programas\/diploma-programacion-en-python\/\" target=\"_blank\" rel=\"noopener noreferrer\"><span style=\"font-weight: 400;\"> learn Python<\/span><\/a><span style=\"font-weight: 400;\">The development of applications for the world of the 21st century, the handling of large amounts of data and different operating systems, our<\/span><a href=\"https:\/\/immune.institute\/en\/programas\/master-en-data-science-online\/\" target=\"_blank\" rel=\"noopener noreferrer\"> <span style=\"font-weight: 400;\">Master in Data Science<\/span><\/a><span style=\"font-weight: 400;\"> is designed for you. Not only will you acquire all the technical knowledge you need to build your future as a Data Scientist, in the<\/span><a href=\"https:\/\/immune.institute\/en\/campus\/\"> <span style=\"font-weight: 400;\">campus<\/span><\/a><span style=\"font-weight: 400;\"> most comprehensive and innovative<\/span><a href=\"https:\/\/www.madrid.es\/portal\/site\/munimadrid\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">Madrid<\/span><\/a><span style=\"font-weight: 400;\">You will also enjoy discovering the human dimension of the data. For more information,<\/span><a href=\"https:\/\/immune.institute\/en\/programas\/master-en-data-science-online\/\" target=\"_blank\" rel=\"noopener noreferrer\"> <span style=\"font-weight: 400;\">click here.<\/span><\/a><\/p>\n<p>In addition to this, our institution offers many other courses, among which we highlight the <a href=\"https:\/\/immune.institute\/en\/programas\/grado-en-ingenieria-de-desarrollo-de-software\/\" target=\"_blank\" rel=\"noopener noreferrer\">degree in software engineering<\/a>where you will get all the basics to start working with Python and Numba.<\/p>\n<p><span style=\"font-weight: 400;\">This article was written by:<\/span><a href=\"https:\/\/medium.com\/u\/3b43171da13b?source=post_page-----da0503717a62----------------------\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">Alejandro D\u00edaz Santos<\/span><\/a><span style=\"font-weight: 400;\">- (<\/span><a href=\"https:\/\/github.com\/alejandrods\" target=\"_blank\" rel=\"nofollow noopener noreferrer\"> <span style=\"font-weight: 400;\">GitHub<\/span><\/a><span style=\"font-weight: 400;\">) for IMMUNE Technology Institute.<\/span><\/p>","protected":false},"excerpt":{"rendered":"<p>Optimiza tu C\u00f3digo Python con Numba Descubre todas las funcionalidades de aceleraci\u00f3n de Python con Numba. Aprende c\u00f3mo optimizar c\u00f3digo Python y optimizar tus recursos, con esta potente herramienta. \u00bfQu\u00e9 vamos a ver en este art\u00edculo? Temas: \u00bfQu\u00e9 es Numba?\u00a0 \u00bfC\u00f3mo funciona Numba? Primeros pasos: Compilando para la CPU Usar Numba para compilar y acelerar [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":8150,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_crdt_document":"","footnotes":""},"categories":[1],"tags":[],"class_list":["post-4368","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-blog"],"acf":[],"_links":{"self":[{"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/posts\/4368","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/comments?post=4368"}],"version-history":[{"count":0,"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/posts\/4368\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/media\/8150"}],"wp:attachment":[{"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/media?parent=4368"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/categories?post=4368"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/immune.institute\/en\/wp-json\/wp\/v2\/tags?post=4368"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}