Numba python как использовать
Перейти к содержимому

Numba python как использовать

  • автор:

A ~5 minute guide to Numba¶

Numba is a just-in-time compiler for Python that works best on code that uses NumPy arrays and functions, and loops. The most common way to use Numba is through its collection of decorators that can be applied to your functions to instruct Numba to compile them. When a call is made to a Numba decorated function it is compiled to machine code “just-in-time” for execution and all or part of your code can subsequently run at native machine code speed!

Out of the box Numba works with the following:

  • OS: Windows (32 and 64 bit), OSX and Linux (32 and 64 bit)
  • Architecture: x86, x86_64, ppc64le. Experimental on armv7l, armv8l (aarch64).
  • GPUs: Nvidia CUDA. Experimental on AMD ROC.
  • CPython
  • NumPy 1.15 — latest

How do I get it?¶

Numba is available as a conda package for the Anaconda Python distribution:

$ conda install numba

Numba also has wheels available:

$ pip install numba

Numba can also be compiled from source , although we do not recommend it for first-time Numba users.

Numba is often used as a core package so its dependencies are kept to an absolute minimum, however, extra packages can be installed as follows to provide additional functionality:

  • scipy — enables support for compiling numpy.linalg functions.
  • colorama — enables support for color highlighting in backtraces/error messages.
  • pyyaml — enables configuration of Numba via a YAML config file.
  • icc_rt — allows the use of the Intel SVML (high performance short vector math library, x86_64 only). Installation instructions are in the performance tips .

Will Numba work for my code?¶

This depends on what your code looks like, if your code is numerically orientated (does a lot of math), uses NumPy a lot and/or has a lot of loops, then Numba is often a good choice. In these examples we’ll apply the most fundamental of Numba’s JIT decorators, @jit , to try and speed up some functions to demonstrate what works well and what does not.

Numba works well on code that looks like this:

from numba import jit import numpy as np x = np.arange(100).reshape(10, 10) @jit(nopython=True) # Set "nopython" mode for best performance, equivalent to @njit def go_fast(a): # Function is compiled to machine code when called the first time trace = 0.0 for i in range(a.shape[0]): # Numba likes loops trace += np.tanh(a[i, i]) # Numba likes NumPy functions return a + trace # Numba likes NumPy broadcasting print(go_fast(x)) 

It won’t work very well, if at all, on code that looks like this:

from numba import jit import pandas as pd x = 'a': [1, 2, 3], 'b': [20, 30, 40]> @jit def use_pandas(a): # Function will not benefit from Numba jit df = pd.DataFrame.from_dict(a) # Numba doesn't know about pd.DataFrame df += 1 # Numba doesn't understand what this is return df.cov() # or this! print(use_pandas(x)) 

Note that Pandas is not understood by Numba and as a result Numba would simply run this code via the interpreter but with the added cost of the Numba internal overheads!

What is nopython mode?¶

The Numba @jit decorator fundamentally operates in two compilation modes, nopython mode and object mode. In the go_fast example above, nopython=True is set in the @jit decorator, this is instructing Numba to operate in nopython mode. The behaviour of the nopython compilation mode is to essentially compile the decorated function so that it will run entirely without the involvement of the Python interpreter. This is the recommended and best-practice way to use the Numba jit decorator as it leads to the best performance.

Should the compilation in nopython mode fail, Numba can compile using object mode , this is a fall back mode for the @jit decorator if nopython=True is not set (as seen in the use_pandas example above). In this mode Numba will identify loops that it can compile and compile those into functions that run in machine code, and it will run the rest of the code in the interpreter. For best performance avoid using this mode!

How to measure the performance of Numba?¶

First, recall that Numba has to compile your function for the argument types given before it executes the machine code version of your function, this takes time. However, once the compilation has taken place Numba caches the machine code version of your function for the particular types of arguments presented. If it is called again the with same types, it can reuse the cached version instead of having to compile again.

A really common mistake when measuring performance is to not account for the above behaviour and to time code once with a simple timer that includes the time taken to compile your function in the execution time.

from numba import jit import numpy as np import time x = np.arange(100).reshape(10, 10) @jit(nopython=True) def go_fast(a): # Function is compiled and runs in machine code trace = 0.0 for i in range(a.shape[0]): trace += np.tanh(a[i, i]) return a + trace # DO NOT REPORT THIS. COMPILATION TIME IS INCLUDED IN THE EXECUTION TIME! start = time.time() go_fast(x) end = time.time() print("Elapsed (with compilation) = %s" % (end - start)) # NOW THE FUNCTION IS COMPILED, RE-TIME IT EXECUTING FROM CACHE start = time.time() go_fast(x) end = time.time() print("Elapsed (after compilation) = %s" % (end - start)) 

This, for example prints:

Elapsed (with compilation) = 0.33030009269714355 Elapsed (after compilation) = 6.67572021484375e-06 

A good way to measure the impact Numba JIT has on your code is to time execution using the timeit module functions, these measure multiple iterations of execution and, as a result, can be made to accommodate for the compilation time in the first execution.

As a side note, if compilation time is an issue, Numba JIT supports on-disk caching of compiled functions and also has an Ahead-Of-Time compilation mode.

How fast is it?¶

Assuming Numba can operate in nopython mode, or at least compile some loops, it will target compilation to your specific CPU. Speed up varies depending on application but can be one to two orders of magnitude. Numba has a performance guide that covers common options for gaining extra performance.

How does Numba work?¶

Numba reads the Python bytecode for a decorated function and combines this with information about the types of the input arguments to the function. It analyzes and optimizes your code, and finally uses the LLVM compiler library to generate a machine code version of your function, tailored to your CPU capabilities. This compiled version is then used every time your function is called.

Other things of interest:¶

Numba has quite a few decorators, we’ve seen @jit , but there’s also:

  • @njit — this is an alias for @jit(nopython=True) as it is so commonly used!
  • @vectorize — produces NumPy ufunc s (with all the ufunc methods supported). Docs are here .
  • @guvectorize — produces NumPy generalized ufunc s. Docs are here .
  • @stencil — declare a function as a kernel for a stencil like operation. Docs are here .
  • @jitclass — for jit aware classes. Docs are here .
  • @cfunc — declare a function for use as a native call back (to be called from C/C++ etc). Docs are here .
  • @overload — register your own implementation of a function for use in nopython mode, e.g. @overload(scipy.special.j0) . Docs are here .

Extra options available in some decorators:

  • parallel = True — enable the automatic parallelization of the function.
  • fastmath = True — enable fast-math behaviour for the function.
  • cffi — The calling of CFFI functions is supported in nopython mode.
  • ctypes — The calling of ctypes wrapped functions is supported in nopython mode. .
  • Cython exported functions are callable .

GPU targets:¶

Numba can target Nvidia CUDA and (experimentally) AMD ROC GPUs. You can write a kernel in pure Python and have Numba handle the computation and data movement (or do this explicitly). Click for Numba documentation on CUDA or ROC .

© Copyright 2012-2020, Anaconda, Inc. and others

Увеличиваем скорость работы Python до уровня C++ с Numba

Повышаем скорость работы Python с использованием библиотеки Numba и сравниваем с «плюсами» на примере простенького алгоритма.

В этой статье автор разобрался, как увеличить скорость работы Python, и продемонстрировал реализацию на реальном примере.

Прим. ред. Это перевод. Мнение редакции может не совпадать с мнением автора оригинала.

Тест базовой скорости

Для сравнения базовой скорости Python и C++ я буду использовать алгоритм генерации случайных простых чисел.

На данный момент этот блок не поддерживается, но мы не забыли о нём! Наша команда уже занята его разработкой, он будет доступен в ближайшее время.

Реализация на Python

import math from time import per_counter def is_prime(num): if num == 2: return True; if num 

Реализация на C++

#include #include #include using namespace std; bool isPrime(int num) < if (num == 2) return true; if (num return true; > int main() < int N = 10000000; clock_t start,end; start = clock(); for (int i; i < N; i++) isPrime(i); end = clock(); cout  

Результат

  • Python: скорость выполнения 80,137 секунд;
  • C++: скорость выполнения 3,174 секунды.

Комментарий

Как и ожидалось, программа на C++ выполняется в 25 раз быстрее, чем на Python. Ожидания подтвердились, потому что:

  • Python — это динамически типизированный язык;
  • GIL(Global Interpreter Lock) — не поддерживает параллельное программирование.

Благодаря тому, что Python это гибкий универсальный язык, наш результат можно улучшить. Один из лучших способов увеличить скорость Python — Numba.

Numba

Чтобы начать использовать Numba, просто установите её через консоль:

pip install numba 

Реализация на Python с использованием Numba

import math from time import per_counter from numba import njit, prange @njit(fastmath=True, cache=True) def is_prime(num): if num == 2: return True; if num 

Как вы могли заметить, в коде добавились декораторы njit:

  • parallel=True — включает параллельное выполнение программы на процессоре;
  • fastmath=True — разрешает использование небезопасных преобразований с плавающей точкой;
  • cache=True — позволяет сократить время компиляции функции, если она уже была скомпилирована.

Итоговая скорость Python

  • Python: скорость выполнения 1,401 секунды;
  • C++: скорость выполнения 3,174 секунды.

Теперь вы знаете что Python способен обогнать C++. О других способах увеличения скорости работы Python читайте в статьях про пять проектов, которые помогают ускорить код на Python и про количество памяти, которое занимают разные типы данных в Python.

Следите за новыми постами по любимым темам

Подпишитесь на интересующие вас теги, чтобы следить за новыми постами и быть в курсе событий.

numba jit внутри класса, либо с обращением к атрибутам экземпляра

Есть написанная программа, в которой описана функция с достаточно массивным вычислением, реализованная без использования ООП. Мне удалось очень сильно ускорить выполнение этих вычислений с простым использованием декоратора @njit.

Так как в дальнейшем эта функция должна стать модулем программы с PyQt5 интерфейсом, то мне порекомендовали научиться работать с ООП. Мне удалось создать свой класс, в который эта функция вписалась в качестве метода.

Но проблема в том, что @njit не работает внутри класса. Даже вынося функцию вне класса и просто обращаясь из неё к атрибутам экземпляров @njit не работает. Я попытался явно указать типы данных - не помогло.

Конечно попытался использовать @jitclass, но получаю ошибку:

"TypeError: wrap() takes 1 positional argument but 7 were given"

7 аргументов у меня передается при инициализации экземпляра класса в метод __init__. Без декоратора @jitclass работает.

Может кто-то может помочь выбрать правильное направление дальнейших действий и избавить меня от многих часов метаний в поисках корректного подхода?

Буду очень благодарен, спасибо!

Лучшие ответы ( 1 )
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Закрытие доступа к атрибутам внутри класса
Как известно, есть обходные пути для получения значений, закрытых через 2 нижних подчеркивания.

Создание экземпляра класса внутри другого класса
Добрый вечер. Стоит задача сделать поле ввода с валидацией данных. Нужно чтобы пользователь не.

Видимость экземпляра класса внутри класса
Здравствуйте! Пытаюсь вывести openCV видео в QT виджете. На данный момент в слоте обновления.

Удаление экземпляра класса внутри класса
Ситуация: У меня есть класс Т34, в этом классе есть метод destroy, который должен удалять экземпляр.

Имя экземпляра объекта внутри класса на С++
Добрый день. Подскажите, пожалуйста, как узнать имя экземпляра объекта внутри класса на С++ ? В.

Просто Лис

Эксперт Python

5318 / 3332 / 1021
Регистрация: 17.05.2012
Сообщений: 9,765
Записей в блоге: 9

Лучший ответ

Сообщение было отмечено 9FiZiK как решение

Решение

ЦитатаСообщение от 9FiZiK Посмотреть сообщение

Даже вынося функцию вне класса и просто обращаясь из неё к атрибутам экземпляров

Что-то вы делаете не так.

Попробуйте тупо оставить функцию. Как-то так:

1 2 3 4 5 6 7 8 9 10 11 12
class Fox: def __init__(self, . ): self.attr1 = [1,2,34] def run(self): data = list(self.attr1) result = func(data) self.attr1 = result @njit def func(data): return data + [13]

То есть сделайте чистую функцию, которая принимает на вход простые примитивные данные и возвращает результаты расчётов. Да, придётся написать обёртку над функцией, чтобы правильно подготовить данные для неё и от неё.

Introduction to Numba

Numba provides the ability to speed up applications with high performance functions written directly in Python, rather than using language extensions such as Cython.

Numba allows the compilation of selected portions of pure Python code to native code, and generates optimized machine code using the LLVM compiler infrastructure.

With a few simple annotations, array-oriented and math-heavy Python code can be just-in-time (JIT) optimized to achieve performance similar to C, C++ and Fortran, without having to switch languages or Python interpreters.

Numba works at the function level. From a function, Numba can generate native code for that function as well as the wrapper code needed to call it directly from Python. This compilation is done on-the-fly and in-memory.

Numba’s main features are:

  • On-the-fly code generation (at import time or runtime, at the user’s preference)
  • Native code generation for the CPU (default) and GPU hardware
  • Integration with the Python scientific software stack (thanks to NumPy)

Prerequisites

The examples in this lesson can be run directly using the Python interpreter, using IPython interactively, or using Jupyter notebooks. Anaconda users will already have Numba installed. See Setup for information on installing Numba.

Schedule

00:00 Just-in-time Compiling How does Numba just-in-time compiling work?
00:20 Function Signatures Is it possible to use function type information to improve performance with Numba?
00:40 Compilation Modes Is it possible to ensure Numba will generate high performance code?
01:00 Numba Functions Are there restrictions on calling Numba functions?
Can Numba be used to simplify the creation of ufuncs?
01:20 CUDA Programming How does CUDA programming with Numba work?
What CUDA features are available in Numba?
02:30 Finish

The actual schedule may vary slightly depending on the topics and exercises chosen by the instructor.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *