Кеннет Рейтц – Автостопом по Python (страница 57)
В чем же разница? В версии Cython вы можете увидеть объявление типов переменных и массива целых чисел, которые выглядят так же, как и в обычном С. Например, дополнительное объявление типа (целочисленного) в выражении cdef int n,k,i позволяет компилятору Cython генерировать более эффективный код С. Поскольку синтаксис несовместим со стандартным Python, он сохраняется в файлах с расширением *.pyx, а не с расширением *.py.
Каковы различия в скорости? Давайте проверим!
Cython time: 0.0054 seconds
Python time: 0.0566 seconds
А здесь результат работы встроенной машины ARM BeagleBone (http://beagleboard.org/Products/BeagleBone):
Cython time: 0.0196 seconds
Python time: 0.3302 seconds
Numba
Numba (http://numba.pydata.org/) — это компилятор для Python, поддерживающий NumPy (он является динамическим — just-in-time (JIT)). Компилирует аннотированный код Python (и NumPy) для LLVM (Low-Level Virtual Machine) (http://llvm.org/) с помощью особых декораторов. Вкратце, Numba использует LLVM для компилирования кода Python в машинный код, который может быть нативно выполнен во время работы программы.
Если вы используете Anaconda, установите Numba с помощью команды conda install numba. Если нет, установите его вручную. Вы должны заранее установить NumPy и LLVM (перед Numba).
Проверьте, какая версия LLVM вам нужна (на странице PyPI для llvmlite по адресу https://pypi.python.org/pypi/llvmlite), и загрузите ее для вашей ОС:
• сборки LLVM для Windows (http://llvm.org/builds/);
• сборки LLVM для Debian/Ubuntu (http://llvm.org/apt/);
• сборки LLVM для Fedora (https://apps.fedoraproject.org/packages/llvm);
• вы можете найти информацию о том, как устанавливать LLVM на основе исходного кода для других систем Unix, в разделе «Сборка компиляторов Clang + LLVM» (http://ftp.math.utah.edu/pub/llvm/);
• для OS X используйте команду brew install homebrew/versions/llvm37 (или выберите текущую версию).
Как только вы установите LLVM и NumPy, инсталлируйте Numba с помощью pip. Вам может понадобиться помочь установщику найти файл llvm-config, предоставив переменной среды LLVM_CONFIG соответствующий путь, например:
$ LLVM_CONFIG=/path/to/llvm-config-3.7 pip install numba
Чтобы использовать его в своем коде, декорируйте свои функции:
Флаг nogil позволит коду игнорировать глобальную блокировку интерпретатора, а модуль numba.pycc можно использовать для компилирования кода заранее. Для получения более подробной информации обратитесь к руководству пользователя для Numba (http://numba.pydata.org/numba-doc/latest/user).
Библиотеки для работы с GPU
Numba опционально может быть создан с той производительностью, которая позволит ему работать на графическом процессоре (graphics processing unit, GPU), оптимизированном для выполнения быстрых параллельных вычислений в современных видеоиграх. Вам понадобится NVIDIA GPU, также нужно установить тулкит CUDA Toolkit от NVIDIA (https://developer.nvidia.com/cuda-downloads). Далее следуйте инструкциям документации по использованию Numba’s CUDA JIT для GPU (http://numba.pydata.org/numba-doc/0.13/CUDAJit.html).
Помимо Numba, еще одной популярной библиотекой, которая может работать с GPU, является TensorFlow (https://www.tensorflow.org/). Выпущена компанией Google под лицензией Apache v2.0. Предоставляет возможность использовать тензоры (многомерные матрицы), а также способ объединить в цепочку операции над ними для более быстрого выполнения операций над матрицами.
На данный момент она может использовать GPU только в операционных системах Linux. Для получения более подробных инструкций обратитесь к следующим страницам:
• установка TensorFlow с поддержкой GPU — http://bit.ly/tensorflow-gpu-support;
• установка TensorFlow без поддержки GPU — http://bit.ly/tensorflow-no-gpu.
Среди тех, кто не пользуется Linux, до того как компания Google опубликовала TensorFlow (http://deeplearning.net/software/theano/), привычным вариантом работы с матричной математикой с помощью GPU была библиотека Theano, активно разрабатываемая в Монреальском университете. Для нее создана страница, посвященная использованию GPU (http://deeplearning.net/software/theano/tutorial/using_gpu.html). Theano поддерживает операционные системы Windows, OS X и Linux. Доступна по команде pip:
$ pip install Theano
Для низкоуровневого взаимодействия с GPU вы можете использовать PyCUDA (https://developer.nvidia.com/pycuda).
Наконец, те, у кого нет NVIDIA GPU, могут использовать PyOpenCL (https://pypi.python.org/pypi/pyopencl), обертку для библиотеки OpenCL от Intel (https://software.intel.com/en-us/intel-opencl), которая совместима с несколькими разными аппаратными наборами (https://software.intel.com/en-us/articles/opencl-drivers).
Взаимодействие с библиотеками, написанными на C/C++/FORTRAN
Все библиотеки, описанные в следующих разделах, отличаются друг от друга. CFFI и ctypes написаны на Python, F2PY нужна для FORTRAN, SWIG позволяет использовать объекты языка C во многих языках (не только Python), а Boost.Python (библиотека C++) — объекты языка C++ в коде Python и наоборот. В табл. 8.2 приводится более подробная информация.
C Foreign Function Interface
Пакет CFFI (https://cffi.readthedocs.org/en/latest/) предоставляет простой механизм для взаимодействия с кодом, написанным на C, из Python и PyPy. CFFI рекомендуется использовать с PyPy (http://doc.pypy.org/en/latest/extending.html) для наилучшей совместимости между CPython и PyPy. Он поддерживает два режима: встроенный режим совместимости для бинарных интерфейсов приложения (application binary interface, ABI) (смотрите следующий пример кода) позволяет динамически загружать и запускать функции из исполняемых модулей (по сути, предоставляет такую же функциональность, как LoadLibrary или dlopen), а также режим API, который позволяет выполнять сборку модулей расширения C[103].
Установите его с помощью pip:
$ pip install cffi
Рассмотрим пример взаимодействия ABI:
ctypes
ctypes (https://docs.python.org/3/library/ctypes.html) — это выбор де-факто для взаимодействия с кодом на C/C++ и CPython; находится в стандартной библиотеке. Предоставляет полный доступ к нативному интерфейсу на С для большей части операционных систем (например, kernel32 для Windows, или libc для *nix), а также поддерживает загрузку и взаимодействие с динамическими библиотеками — разделяемыми объектами (*.so) или DLL — во время выполнения программы. Вместе с ctypes поставляется множество типов для взаимодействия с API системы, что позволяет вам легко определить собственные сложные типы вроде структур и объединений, а также модифицировать элементы вроде внутренних полей и выравнивания, если это нужно. Она может быть несколько неудобна в использовании (поскольку вам нужно вводить много дополнительных символов), но вместе с модулем стандартной библиотеки struct (https://docs.python.org/3.5/library/struct.html) у вас, по сути, будет полный контроль над тем, как ваши типы данных преобразуются в типы, которые могут применять методы, написанные на чистом C/C++.
Например, структура C, определенная следующим образом в файле my_struct.h:
struct my_struct {
····int a;
····int b;
};
может быть реализована так, как показано в файле с именем my_struct.py:
import ctypes
class my_struct(ctypes.Structure):
····_fields_ = [("a", c_int),
················("b", c_int)]
F2PY
Генератор интерфейса Fortran-к-Python (F2PY) (http://docs.scipy.org/doc/numpy/f2py/) является частью NumPy. Чтобы его получить, установите NumPy с помощью команды pip:
$ pip install numpy
Предоставляет гибкую функцию командной строки, f2py, которая может быть использована тремя разными способами (все они задокументированы в руководстве к F2PY по адресу http://docs.scipy.org/doc/numpy/f2py/getting-started.html). Если вы имеете доступ к управлению исходным кодом, то можете добавить особые комментарии с инструкциями для F2PY, которые показывают предназначение каждого аргумента (какие элементы являются входными, а какие — возвращаемыми), а затем запустить F2PY: