Déboguer avec VS Code en utilisant Boost Python Numpy

Je pense qu'il est nécessaire d'étendre Python avec c ++ et de convertir le ndarray de Numpy en vecteur c ++. Boost :: python et boost :: python :: numpy sont utiles dans de tels cas. (Il semble que pybind11 soit également populaire ces jours-ci. Je voulais savoir tôt ...)

De plus, boost python peut en fait être construit en tant que fichier exécutable, vous pouvez donc le déboguer avec VSCode, par exemple.

Je vais expliquer à partir de 1 des packages nécessaires.

environnement

Remarques
OS ubuntu 20.04 Lancer sur docker
python 3.8.2
boost 1.73.0
cmake 3.16.3

Préparation

Tout d'abord, installez les packages requis.

Les packages requis pour cet article étaient wget, build-essential, cmake, python3-dev et python3-pip. Veuillez installer selon votre environnement.

$ apt install wget build-essential cmake python3-dev python3-pip 

Vérifiez également l'emplacement d'installation et la version de Python avec la commande suivante.

$ which python3
/usr/bin/python3
$ python3 --version
Python 3.8.2

Si vous souhaitez utiliser boost :: python :: numpy, vous devez installer numpy. (J'ai eu du mal à oublier cela.)

$ pip3 install numpy

Ensuite, téléchargez et installez boost. Installez en vous référant au chapitre 5 du document officiel suivant.

Comment démarrer Boost dans un environnement Unix page de téléchargement boost

Téléchargez boost, décompressez-le et allez dans le dossier décompressé.

$ wget (télécharger l'URL pour booster)
$ tar --bzip2 -xf boost_1_73_0.tar.bz2
$ cd boost_1_73_0

Préparez l'installation avec . / Bootstrap.sh dans le dossier décompressé, puis compilez et installez avec. / B2.

$ ./bootstrap.sh --with-libraries=python --with-python=python3 --with-python-version=3.8
$ ./b2 install -j8

En spécifiant --with-bibliothèques = python, seul boost :: python sera construit et installé, ce qui vous fera gagner du temps. Spécifiez également la version de python confirmée précédemment avec --with-python-version.

(Dans le cas d'un autre environnement tel qu'Anaconda ou pyenv, il semble que des paramètres supplémentaires soient nécessaires. Puisque cet article est construit dans un conteneur, je le fais avec la position que je peux polluer l'environnement autant que je veux.)

Par défaut, boost est installé sous / usr /. Vous pouvez trouver le répertoire d'inclusion et le chemin de la bibliothèque boost en utilisant la commande find.

$ find /usr/ -name "*boost*" | grep include
/usr/include/c++/9/bits/boost_concept_check.h
/usr/local/include/boost
/usr/local/include/boost/chrono/typeof/boost
...
$ find /usr/ -name "*boost*" | grep lib
...
/usr/local/lib/cmake/boost_numpy-1.73.0/libboost_numpy-variant-static-py3.8.cmake
/usr/local/lib/cmake/boost_numpy-1.73.0/boost_numpy-config-version.cmake
/usr/local/lib/cmake/boost_numpy-1.73.0/libboost_numpy-variant-shared-py3.8.cmake
/usr/local/lib/libboost_numpy38.a
/usr/local/lib/libboost_python38.so.1.73
/usr/local/lib/libboost_numpy38.so.1.73
...

Créons un module qui utilise réellement ndarray

Créons un exemple de module qui a en fait une fonction qui renvoie la taille de la première dimension de ndarray.

sample.cpp


#define BOOST_BIND_GLOBAL_PLACEHOLDERS
//Pour éviter les conflits d'espace réservé(Enquête requise)
#include <boost/python/numpy.hpp>
namespace py = boost::python;
namespace np = boost::python::numpy;

auto size(np::ndarray &a)
{
  auto N = a.shape(0);
  return N;
}

BOOST_PYTHON_MODULE(sample)
{
  Py_Initialize();
  np::initialize();
  py::def("size", size);
}

Pour le compiler avec g ++, exécutez la commande suivante:

g++ --shared -fPIC \
	-I$BOOST_INCLUDE_DIR -I/usr/include/python3.8/ \
	sample.cpp -Xlinker -rpath -Xlinker $BOOST_LIB_DIR \
	-lboost_python38 -lboost_numpy38 -o sample.so

$ BOOST_INCLUDE_DIR est le chemin d'inclusion de boost, $ BOOST_LIB_DIR est le chemin de bibliothèque de boost, et je pense que cela dépend de l'environnement. Dans mon environnement, il s'agissait de / usr / local / include / boost / et / usr / local / lib /, respectivement, comme je l'ai confirmé en utilisant la commande find plus tôt.

J'utilise CMake car je dois changer la commande en fonction de l'environnement et il est difficile de taper cette commande à chaque fois.

CMakeLists.txt


cmake_minimum_required(VERSION 3.12)
project(boost-python-test)

find_package(Python3 COMPONENTS Development)
find_package(Boost COMPONENTS python38 numpy38 REQUIRED)

#Pour le débogage: afficher le chemin résolu
message("## Boost_LIBRARIES:  ${Boost_LIBRARIES}")  
message("## Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message("## Python3_INCLUDE_DIRS: ${Python3_INCLUDE_DIRS}") 
message("## Python3_LIBRARIES :${Python3_LIBRARIES}")

add_library(sample SHARED sample.cpp)
target_include_directories(sample PRIVATE ${Python3_INCLUDE_DIRS})
target_link_libraries(sample PRIVATE ${Boost_LIBRARIES} ${Python3_LIBRARIES})
# target_link_libraries(sample PRIVATE ${Boost_LIBRARIES})Cela fonctionne tout seul. La raison est inconnue.
set_target_properties(sample PROPERTIES PREFIX "") #préfixe'lib'Omettre

(Pour savoir comment utiliser g ++ et comment utiliser cmake

Etc. sont détaillés. Si vous regardez cela, vous pouvez tout voir, du mécanisme de compilation au mécanisme find_package utilisé ci-dessus. Merci! )

Ensuite, placez ces «sample.cpp» et «CMakeLists.txt» dans la structure de répertoires suivante.

.
|-- CMakeLists.txt
|-- build
`-- sample.cpp

Construire dans construire.

$ cd build
$ cmake ..
$ cmake --build .

Il existe un fichier (bibliothèque partagée) appelé «sample.so» dans la construction qui le fait. Et si vous écrivez et exécutez le script python suivant dans la construction, il «importera» cette bibliothèque partagée et vous verrez que cela fonctionne bien.

test.py


import sample
import numpy as np

a = np.array([1,2,3,4], dtype=np.float32)
print(a)
size=sample.size(a)
print(size)
$ python3 test.py 
[1. 2. 3. 4.]
4

Déboguer avec VS Code

Tant qu'il est appelé en tant que module python, il est difficile à déboguer et à utiliser, Si vous pouvez le construire en tant que fichier exécutable, vous pouvez utiliser CMake-Tools etc. de VS Code pour accélérer le débogage.

Création d'un environnement de développement C ++ avec des conteneurs distants de Visual Studio Code Préparez l'environnement de débogage distant VS Code en vous référant à. (Il existe également un Référentiel dont j'ai amélioré le référentiel de l'environnement dans l'article ci-dessus.)

Commencez par créer la structure de répertoires suivante sur cet environnement.

.
|-- CMakeLists.txt
|-- build
`-- main.cpp

CMakeLists.txt


cmake_minimum_required(VERSION 3.12)
project(boost-python-test)

find_package(Python3 COMPONENTS Development)
find_package(Boost COMPONENTS python38 numpy38 REQUIRED)

add_executable(main_app main.cpp)
target_include_directories(main_app PRIVATE ${Python3_INCLUDE_DIRS})
target_link_libraries(main_app PRIVATE ${Boost_LIBRARIES} ${Python3_LIBRARIES})

Si vous appelez Py_Initialize () et np :: initialize () au début de la fonction principale comme indiqué ci-dessous dans main.cpp, vous pouvez le construire comme un fichier exécutable.

main.cpp


#include <iostream>
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
//Pour éviter les conflits d'espace réservé(Enquête requise)
#include <boost/python/numpy.hpp>
namespace py = boost::python;
namespace np = boost::python::numpy;

int main()
{
  Py_Initialize();
  np::initialize();
  double v[] = {1.3 , 2.4 , -5.3};
  int v_size = 3;
  py::tuple shape = py::make_tuple(v_size);
  py::tuple stride = py::make_tuple(sizeof(double));
  np::dtype dt = np::dtype::get_builtin<double>();
  np::ndarray output = np::from_data(&v[0], dt, shape, stride, py::object());
  np::ndarray output_array = output.copy();
  
  std::cout << "c++ array address::" << std::endl
          << std::hex << &v[0] << std::endl;
  
  auto *p = reinterpret_cast<double*>(output.get_data());
  std::cout << "ndarray address ::" << std::endl
          << std::hex << p << std::endl;
  return 0;
}

Dans cet état, vous pouvez utiliser la fonction de débogage CMake-Tools de VSCode pour définir des points d'arrêt et examiner les variables. Si vous utilisez la CONSOLE DEBUG de VS Code comme indiqué dans l'image ci-dessous, vous pouvez gérer C ++ comme s'il s'agissait d'un langage d'interprétation, et le débogage sera plus rapide. Pratique!

image.png

Supplément: Articles précédents et sites de référence

Il y a des articles sur Qiita et des articles sur Boost :: python sur des sites externes, Il n'y avait pas d'article qui expliquait ce avec quoi j'étais coincé, ou comment utiliser le soi-disant cmake moderne comme mentionné dans cet article. J'ai donc fait cet article.

Tutoriel Boost.NumPy pour l'extension de Python en C ++ (pratique) Cet article utilise boost-numpy, mais boost-numpy a été intégré dans boost :: python et est désormais obsolète.

Créer une bibliothèque pour Python en C ++ Passer des tableaux numpy entre Python et C ++ Ces articles ont également été très utiles.

Recommended Posts

Déboguer avec VS Code en utilisant Boost Python Numpy
Déboguer Python avec VS Code
Python avec VSCode (Windows 10)
Installez python avec mac vs code
Paramètres de débogage dans un environnement virtuel lors de l'utilisation de Pipenv avec VSCode
Environnement virtuel / package Python (Windows10) avec VSCode
Utiliser Python dans un environnement Anaconda avec VS Code
Code de bourdonnement avec numpy
Créer un environnement d'exécution python avec VS Code
[Python] J'ai immédiatement essayé d'utiliser l'extension VS Code de Pylance.
Paramètres VS Code pour le développement en Python avec achèvement
Relancer la recherche de symboles dans l'espace de travail Python avec VS Code
Comment créer un package Python à l'aide de VS Code
Déboguer à distance l'environnement Django créé avec docker-compose avec VS Code
Obtenez le code du pays avec python
Utilisation de Quaternion avec Python ~ numpy-quaternion ~
[Python] Méthode de calcul avec numpy
[Python] Utilisation d'OpenCV avec Python (basique)
Implémentation de SMO avec Python + NumPy
Déboguer avec l'interpréteur PEPPER python
Utiliser OpenCV avec Python @Mac
Documenter le code Python avec Doxygen
Envoyer en utilisant Python avec Gmail
Paramètres lors du développement d'applications App Engine / Python avec VS Code
Exécutons jupyter nativement pris en charge par VS Code avec python3.8
Essayez Fortran avec VS Code pour déboguer les paramètres. [Win10]
Paramètres pour entrer et déboguer le contenu de la bibliothèque avec VS Code
Histoire que Python a cessé de travailler avec VS Code (Windows 10)
Utilisation de jupyter notobook avec VS Code (mac OS) (mémo personnel)
Créer un environnement Python avec WSL + Pyenv + Jupyter + VSCode
Compléter python avec emacs en utilisant company-jedi
Moyenne harmonique par Python (en utilisant SciPy)
Utilisation de Rstan de Python avec PypeR
[Python] Utilisation d'OpenCV avec Python (transformation d'image)
[Python] Utilisation d'OpenCV avec Python (détection des bords)
Essayez d'exécuter Jupyter avec VS Code
Vérifiez le style de code python à l'aide de pep8
Notes sur l'utilisation de rstrip avec python.
Je veux déboguer avec Python
Lors de l'utilisation de MeCab avec python dans virtualenv
Précautions lors de l'utilisation de six avec Python 2.5
Comment créer un environnement d'exécution Python et Jupyter avec VSCode
[AWS] Utilisation de fichiers ini avec Lambda [Python]
Préparez un environnement virtuel Python pour votre projet avec venv avec VS Code
Comment déboguer un programme Python en se connectant à distance à un conteneur Docker dans un environnement WSL2 avec VS Code
Essayez une formule utilisant Σ avec python
Derrière le flyer: utiliser Docker avec Python
Écrivez du code FizzBuzz piloté par les tests à l'aide de Python doctest.
Utilisation de Python et MeCab avec Azure Databricks
J'étais accro à la création d'un environnement Python venv avec VS Code
Obtenez des métriques de code source Python à l'aide de radon
Essayez d'utiliser Python avec Google Cloud Functions
Procédure de création d'un environnement virtuel Python avec VS Code sous Windows
Créer un environnement de développement à l'aide de Jupyter et Flask avec Python dans Docker (prend en charge à la fois VS Code / code-server)