[PyOV] Update BUILDING.md and minor dev docs fixes (#14357)

This commit is contained in:
Jan Iwaszkiewicz 2022-12-19 16:03:54 +01:00 committed by GitHub
parent 4d44c70c32
commit c8493bd47b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 89 additions and 289 deletions

View File

@ -1,248 +0,0 @@
# Building the OpenVINO™ Python* API
This document provides the instructions for building the OpenVINO™ Python API from source on Linux, macOS and Windows 10 platforms.
For each platform, you can build and install the API as a part of OpenVINO™ Toolkit or as a Python wheel.
A Python wheel is a portable package that allows you to install OpenVINO™ in either your Python distribution or a dedicated virtual environment.
## Linux* and macOS*
### Prerequisites
To build the OpenVINO™ Python API, you need to install a few additional packages.
On Ubuntu* 20.04 LTS you can use the following instructions to install the required packages, including Python and Cython.
```bash
apt install git wget build-essential cmake
apt install python3 python3-dev python3-pip python3-virtualenv python-is-python3
```
On macOS, you can use [Homebrew](https://brew.sh) to install required packages:
```bash
brew install cmake
brew install python3
```
Install Cython in the Python installation, or virtualenv that you are planning to use:
```bash
pip3 install cython
```
### Configure and Build as a part of OpenVINO™ Toolkit on Linux and macOS
The following section illustrates how to build and install OpenVINO™ in a workspace directory using CMake.
The workspace directory is specified by the `${OV_WORKSPACE}` variable. Set this variable to a directory of your choice:
```bash
export OV_WORKSPACE=/path/to/my/workspace
```
Now you can clone the OpenVINO™ repository, configure it using `cmake` and build using `make`.
In order to build the OpenVINO™ Python APIs set the `ENABLE_PYTHON` flag to `ON`.
Note the `CMAKE_INSTALL_PREFIX`, which defaults to `/usr/local/` if not set.
```bash
cd ${OV_WORKSPACE}
git clone --recursive https://github.com/openvinotoolkit/openvino.git
cd openvino
git submodule update --init
### You may also want to install OpenVINO™ dependencies with:
# ./install_build_dependencies.sh
mkdir build && cd build
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_PYTHON=ON \
-DCMAKE_INSTALL_PREFIX="${OV_WORKSPACE}/openvino_dist"
make -j 4 install
```
The Python module is installed in the folder:
${OV_WORKSPACE}/openvino_dist/python/python<version>/
You may also find it in:
${OV_WORKSPACE}/openvino/bin/intel64/[BUILD_TYPE]/python_api/python<version>/
If you would like to use a specific version of Python, or use a virtual environment, you can add the `PYTHON_EXECUTABLE` variable to your CMake command line. For example:
```bash
-DPYTHON_EXECUTABLE=/path/to/venv/bin/python
# or while in virtual environment
-DPYTHON_EXECUTABLE=`which python`
```
Set up the OpenVINO™ environment in order to add the module path to `PYTHONPATH`:
```bash
source ${OV_WORKSPACE}/openvino_dist/setupvars.sh
```
If you want more control over enviroment variables, to simply enable OpenVINO™ Python API, export these variables:
```bash
export LD_LIBRARY_PATH=${OV_WORKSPACE}/openvino_dist/runtime/lib/intel64/
export PYTHONPATH=${OV_WORKSPACE}/openvino_dist/python/python<version>/
```
### Rebuild OpenVINO™ project
To rebuild project, simply navigate to build folder and re-run `make` command:
```bash
cd ${OV_WORKSPACE}/openvino/build
make -j 4 install
```
*Note: If changes are adding new compilation units, files or change CMake scripts, there is a need to remove the exisiting build and rebuild it from scratch!*
### Build an OpenVINO™ Python Wheel on Linux and macOS
#### First method - using CMake command
You can build the Python wheel by adding `ENABLE_WHEEL` flag to `cmake` command:
```bash
cmake .. \
-DCMAKE_BUILD_TYPE=Release \
-DENABLE_PYTHON=ON \
-DENABLE_WHEEL=ON \
-DCMAKE_INSTALL_PREFIX="${OV_WORKSPACE}/openvino_dist"
```
Once completed, the wheel package should be located under the following path:
```bash
$ ls ${OV_WORKSPACE}/openvino/src/bindings/python/dist
openvino-0.0.0-cp<version>-cp<version>-linux_x86_64.whl
```
You can now install the wheel in your Python environment:
```bash
cd ${OV_WORKSPACE}/openvino/src/bindings/python/dist
pip3 install openvino-0.0.0-cp<version>-cp<version>-linux_x86_64.whl
```
#### Second method - using setup.py file
You can build the Python wheel running the following command:
```bash
cd ${OV_WORKSPACE}/openvino/src/bindings/python/wheel
python3 setup.py bdist_wheel
```
Once completed, the wheel package should be located under the following path:
```bash
$ ls ${OV_WORKSPACE}/openvino/src/bindings/python/wheel/dist
openvino-0.0.0-cp<version>-cp<version>-linux_x86_64.whl
```
You can now install the wheel in your Python environment:
```bash
cd ${OV_WORKSPACE}/openvino/src/bindings/python/wheel/dist
pip3 install openvino-0.0.0-cp<version>-cp<version>-linux_x86_64.whl
```
## Windows* 10
### Prerequisites
In order to build OpenVINO™ and its Python wheel on Windows, you need to install Microsoft Visual Studio* and Python.
Once Python is installed, you also need to install Cython using `pip install cython`.
### Configure and Build as a Part of OpenVINO™ Toolkit on Windows
The following section illustrates how to build and install OpenVINO™ in a workspace directory using CMake.
The workspace directory is specified by the `OPENVINO_BASEDIR` variable. Set this variable to a directory of your choice:
set OPENVINO_BASEDIR=/path/to/my/workspace
Configure the build with a `cmake` invocation similar to the following. Note that need to set `-G` and
`-DCMAKE_CXX_COMPILER` to match the version and location of your Microsoft Visual Studio installation.
```
cmake .. ^
-G"Visual Studio 16 2019" ^
-DCMAKE_BUILD_TYPE=Release ^
-DCMAKE_INSTALL_PREFIX="%OPENVINO_BASEDIR%/openvino_dist" ^
-DENABLE_INTEL_GPU=OFF ^
-DENABLE_INTEL_MYRIAD_COMMON=OFF ^
-DENABLE_OV_ONNX_FRONTEND=ON ^
-DENABLE_PYTHON=ON ^
-DCMAKE_CXX_COMPILER="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.27.29110\bin\Hostx64\x64"
```
There are a couple of things to notice here. One is that the full path to the x64 version of
MSVC compiler has to be specified. This is because DNNL requires a 64-bit version and `cmake` may
fail to detect it correctly.
If you want to specify an exact Python version, use the following options:
```
-DPYTHON_EXECUTABLE="C:\Program Files\Python37\python.exe" ^
-DPYTHON_LIBRARY="C:\Program Files\Python37\libs\python37.lib" ^
-DPYTHON_INCLUDE_DIR="C:\Program Files\Python37\include" ^
```
In order to build and install OpenVINO™, build the `install` target:
cmake --build . --target install --config Release -j 8
In this step, OpenVINO™ is built and installed to the directory specified above. You can
adjust the number of threads used in the building process to your machine's capabilities.
Set up the OpenVINO™ environment in order to add a module path to `PYTHONPATH`:
%OPENVINO_BASEDIR%\openvino_dist\setupvars.bat
### Build a Python Wheel on Windows
Build the Python wheel package:
cd "%OPENVINO_BASEDIR%/openvino/src/bindings/python"
python setup.py bdist_wheel
The final wheel should be located in the `bindings\python\dist` directory.
dir openvino/src/bindings/python/dist/
10/09/2020 04:06 PM 4,010,943 openvino-0.0.0.dev0-cp<version>-cp<version>-win_amd64.whl
## Run Tests
### Use a virtualenv (Optional)
You may wish to use a virutualenv for your installation.
$ virtualenv -p $(which python3) venv
$ source venv/bin/activate
(venv) $
### Install the Wheel and Other Requirements
(venv) $ cd "${OPENVINO_BASEDIR}/openvino/src/bindings/python"
(venv) $ pip3 install -r requirements.txt
(venv) $ pip3 install -r requirements_test.txt
(venv) $ pip3 install dist/openvino-0.0.0.dev0-cp38-cp38-linux_x86_64.whl
### Run Tests
You should now be able to run tests.
You may need to run the `setupvars` script from the OpenVINO™ Toolkit to set paths to OpenVINO™ components.
source ${OPENVINO_BASEDIR}/openvino_dist/setupvars.sh
Now you can run tests using `pytest`:
pytest tests

View File

@ -0,0 +1,65 @@
# Building the OpenVINO™ Python API
**Refer to ["How to build OpenVINO" in OpenVINO™ developer documentation](../../../../docs/dev/build.md) for general building instructions.**
For each platform, you can build and install the API as a part of OpenVINO™ Toolkit or as a Python wheel.
A Python wheel is a portable package that allows you to install OpenVINO™ in either your Python distribution or a dedicated virtual environment.
## Virtual environments
OpenVINO can be built based on specific virtual environments such as [venv](https://docs.python.org/3/tutorial/venv.html), [virtualenv](https://virtualenv.pypa.io/en/latest/) or [pyenv](https://github.com/pyenv/pyenv). It is highly recommended to use virtual environments during development. They improve development process and allow better management of Python versions and packages.
*Note: Supported Python versions can be found in ["System Requirements" section](../../../../docs/install_guides/pypi-openvino-dev.md#system-requirements).*
### Example: using pyenv with OpenVINO™ on Linux based system
1. First, set up the `pyenv` project. Please follow [official instructions of the pyenv project](https://github.com/pyenv/pyenv#installation) for any additional information.
2. Install a desired Python version. Following example will use Python in version 3.10.7. To correctly link libraries, an installed Python version must match OpenVINO™:
* Python with a shared library for a dynamically linked OpenVINO™:
```shell
env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install --verbose 3.10.7
```
* Python with a static library version for a static build of OpenVINO™:
```shell
pyenv install --verbose 3.10.7
```
3. Create a virtual environment based on the installed Python version:
```
pyenv virtualenv 3.10.7 ov-py310
```
4. Activate the environment:
```bash
pyenv activate ov-py310
```
5. Install developer requirements for OpenVINO™ Python API while inside virtual environment:
```shell
cd <openvino_repo>
pip install -r src/bindings/python/requirements.txt
pip install -r src/bindings/python/requirements_test.txt
pip install -r src/bindings/python/src/compatibility/openvino/requirements-dev.txt
```
If `-DENABLE_WHEEL=ON` flag is present in `cmake` command, additionally install wheel requirements:
```
pip install -r src/bindings/python/wheel/requirements-dev.txt
```
6. Add following flags to the main `cmake` command to use specific virtual environment:
```shell
-DPYTHON_EXECUTABLE=`which python` \
-DPYTHON_LIBRARY=/home/user/.pyenv/versions/3.10.7/lib/libpython3.10.so \
-DPYTHON_INCLUDE_DIR=/home/user/.pyenv/versions/3.10.7/include/python3.10
```
*Note: In order to use `which python`, specific virtual environment has to be activated in a current shell.*
*Note: `libpython3.10.so` is created with `--enable-shared` flag while installing specific Python version. For static build name of library may differ.*
7. Follow the rest of building and installation steps from ["How to build OpenVINO" developer documentation](../../../../docs/dev/build.md).
## Run tests to verify OpenVINO™ Python API
Follow instructions in [How to test OpenVINO™ Python API?](./test_examples.md#Running_OpenVINO™_Python_API_tests) to verify the build.

View File

@ -1,17 +1,9 @@
# Examples of OpenVINO:tm: Python API code
# Examples of OpenVINO Python API code
#### Prerequisites
*To be added...*
#### Building and environment
Instructions can be found in ["Building the OpenVINO™ Python API"](./build.md).
##### Enviroment
<!-- TODO: Link to enviroment setup -->
*To be added...*
##### Building
<!-- TODO: Link to building instructions -->
*To be added...*
### Different ways of extending OpenVINO:tm: Python API
### Different ways of extending OpenVINO™ Python API
###### Before start: Project's naming conventions
General guide:
@ -24,13 +16,13 @@ General guide:
One of the simplest ways to extend the existing codebase is by writing it in pure Python.
###### Before start: Layout of the project
How does OpenVINO:tm: packaging work? It is strictly connected to the layout of the Python API itself and reused in different supporting packages like tools and extensions. The main namespace of `openvino` provides a unified place that connects all packages together during import, **which is the required part**. However, it is up to the developer how to organize the rest of the package. There are also other common namespaces which follow the same rules:
How does OpenVINO packaging work? It is strictly connected to the layout of the Python API itself and reused in different supporting packages like tools and extensions. The main namespace of `openvino` provides a unified place that connects all packages together during import, **which is the required part**. However, it is up to the developer how to organize the rest of the package. There are also other common namespaces which follow the same rules:
* `openvino.tools`
* ...
For further reading, please refer to: https://packaging.python.org/en/latest/guides/packaging-namespace-packages/
##### Creating new package that extends OpenVINO:tm: project namespace
##### Creating new package that extends OpenVINO project namespace
Let's go over the example available in `openvino/src/bindings/python/docs/examples/openvino`:
```
@ -42,7 +34,7 @@ openvino/ <-- Main package/namespace
└── myclass.py
```
Now let's add it to your exisiting `PYTHONPATH` (replace `[your_path]` with correct path to the OpenVINO:tm: project):
Now let's add it to your exisiting `PYTHONPATH` (replace `[your_path]` with correct path to the OpenVINO project):
export PYTHONPATH=$PYTHONPATH:[your_path]/openvino/src/bindings/python/docs/examples/
@ -106,7 +98,7 @@ Following this method, developers can add new modules and adjust existing ones,
<!-- Pure pybind11 solution describes C++ based approach -->
#### Pure pybind11 solution
The second approach to extend OpenVINO:tm: codebase is utilizing the *pybind11* library. It allows to write C++ based code, thus creating so-called Python bindings.
The second approach to extend OpenVINO codebase is utilizing the *pybind11* library. It allows to write C++ based code, thus creating so-called Python bindings.
**The example in this section covers the scenario of adding new features to a newly created submodule. Extending existing codebase can be done in a similar fashion by working on already implemented classes and modules.**
@ -127,7 +119,7 @@ Add a new submodule by writing:
```cpp
py::module mymodule = m.def_submodule("mymodule", "My first feature - openvino.runtime.mymodule");
```
This is a shorthand way of adding new submodules which can later be used to extend the package. The mysterious `m` is actaully the main OpenVINO:tm: module called `pyopenvino` -- it is registered with `PYBIND11_MODULE(pyopenvino, m)` at the top of the "registering-point" file. Later imports from it are done by calling upon the `openvino._pyopenvino` package.
This is a shorthand way of adding new submodules which can later be used to extend the package. The mysterious `m` is actaully the main OpenVINO module called `pyopenvino` -- it is registered with `PYBIND11_MODULE(pyopenvino, m)` at the top of the "registering-point" file. Later imports from it are done by calling upon the `openvino._pyopenvino` package.
Keep in mind that in most real-life scenarios, modules and classes are registered in different files. The general idea is to create a helper function that will hold all of the registered modules, classes, and functions. This function needs to be exposed within a separate header file and included in "registering-point". The project's common guideline suggests to use names in the following convention: `regmodule_[domain]_[name_of_the_module]` or `regclass_[domain]_[name_of_the_class]`. Where optional `[domain]` generally points to parts of the API such as graph or frontend, or stay empty in the case of core runtime. Examples can be found in the "registering-point" file, `openvino/src/bindings/python/src/pyopenvino/pyopenvino.cpp`.
@ -167,7 +159,7 @@ py::class_<MyTensor, std::shared_ptr<MyTensor>> cls(mymodule, "MyTensor");
cls.doc() = "These are my first class bindings!"
```
Create `__init__` and functions for the class. `py::arg` stand for actual arguments of the given function. Remember, these should match their C++ equivalents both in order and number. However, argument names are not required to be exact copies of the C++ ones, as different restricted keywords or shortnames could appear. Pick them tastefully :) A very unusual construct of `R"(...)"` adds a documentation string to the function. The OpenVINO:tm: project follows the *reST (reStructuredText)* format of docstrings.
Create `__init__` and functions for the class. `py::arg` stand for actual arguments of the given function. Remember, these should match their C++ equivalents both in order and number. However, argument names are not required to be exact copies of the C++ ones, as different restricted keywords or shortnames could appear. Pick them tastefully :) A very unusual construct of `R"(...)"` adds a documentation string to the function. The OpenVINO project follows the *reST (reStructuredText)* format of docstrings.
```cpp
// This initialize use already implemented C++ constructor
cls.def(py::init<ov::Tensor&>(),
@ -253,7 +245,7 @@ Note: **bindings** that are created for classes are sometimes called **wrappers*
MyTensor wraps (around) Tensor class.
However, in OpenVINO:tm: there is an unwritten distinction between "everyday" wrappers and more complex ones (with this article published... it is now a written one ;) ). An example may be found in `openvino/src/bindings/python/src/pyopenvino/core/infer_request.hpp`, where `InferRequest` is actually wrapped inside `InferRequestWrapper`, similarly to the `Tensor` and `MyTensor` scenario. It helps to extend original object capabilities with members and functions that do not necessarily belong to the C++ API. Thus, explicitly calling something a **wrapper** in the project indicates that binding is probably inheriting or using the composition technique to include the original class, later extending it in some way.
However, in OpenVINO there is an unwritten distinction between "everyday" wrappers and more complex ones (with this article published... it is now a written one ;) ). An example may be found in `openvino/src/bindings/python/src/pyopenvino/core/infer_request.hpp`, where `InferRequest` is actually wrapped inside `InferRequestWrapper`, similarly to the `Tensor` and `MyTensor` scenario. It helps to extend original object capabilities with members and functions that do not necessarily belong to the C++ API. Thus, explicitly calling something a **wrapper** in the project indicates that binding is probably inheriting or using the composition technique to include the original class, later extending it in some way.
##### Overloads of functions
One of the main advantages of *pybind11* is the ability to resolve overloaded functions. Let's assume that a previously created function is extended to print any message passed by the user.
@ -310,7 +302,7 @@ Notice that only functions with correct arguments are **not** throwing exception
#### Mix between Python and pybind11
Although *pybind11* is a powerful tool, it is sometimes required (or simply easier and more efficent) to combine both approaches and utilize both languages to achive best results.
##### Making pybind11-based module/class visible in OpenVINO:tm: package
##### Making pybind11-based module/class visible in OpenVINO package
Let's move a new class from `openvino._pyopenvino.mymodule` to the actual package. Simply introduce a new import statement in the desired file. Let it be `openvino/src/bindings/python/src/openvino/runtime/__init__.py`:
```python
from openvino._pyopenvino.mymodule import MyTensor
@ -408,7 +400,7 @@ a.say_hello([1,2,3])
Great! Now the class has reached its destination, from C++, to Python, to Python once more. Such aliasing is a common technique in the project and gives a lot of power to the developer. With easy-to-understand code, the `say_hello` function is now able to dispatch arguments based on their type and apply necessary preprocessing to feed data into the function. However, you might say that this could be done with "a few more lines of C++" as well. Where is the tricky part? The answer is, the difficult feat of returning different types based on the same argument type is achieved here (look at the dispatching of integer arguments).
This concludes developer work on OpenVINO:tm: Python API. Don't forget to recompile your builds and have a good time while writing your code!:)
This concludes developer work on OpenVINO Python API. Don't forget to recompile your builds and have a good time while writing your code!:)
#### Testing out new code
All of the code is now written. Let's move on to testing.

View File

@ -1,4 +1,4 @@
# Contributing to OpenVINO:tm: Python API
# Contributing to OpenVINO Python API
#### Prerequisites
*To be added...*
@ -9,13 +9,12 @@ In case the Python version you have is not supported by OpenVINO, you can refer
*To be added...*
##### Building
<!-- TODO: Link to building instructions -->
*To be added...*
Building instructions can be found in [BUILDING.md](../BUILDING.md)
## Contribution guidelines and best practices
#### How to contribute to Python API?
It is nothing special... :) First, make sure that all prerequisites are met and focus on writing the code itself. A good starting point is to have some knowledge of the Python language. C++ is also a vital language for OpenVINO:tm:, so it is not a surprise that it is used in this part of the project as well.
It is nothing special... :) First, make sure that all prerequisites are met and focus on writing the code itself. A good starting point is to have some knowledge of the Python language. C++ is also a vital language for OpenVINO, so it is not a surprise that it is used in this part of the project as well.
Code snippets and detailed explanations can be found here:
<!-- Link to EXAMPLES -->
@ -27,7 +26,7 @@ Please refer to Test Guide available here:
openvino/src/bindings/python/docs/test_examples.md
Moreover, the project utilizes *flake8* and *mypy* packages to run codestyle checks. Additionally OpenVINO:tm: uses the custom configuration file to exclude some strict rules. To run codestyle checks, navigate to the main Python API folder first and use following commands:
Moreover, the project utilizes *flake8* and *mypy* packages to run codestyle checks. Additionally OpenVINO uses the custom configuration file to exclude some strict rules. To run codestyle checks, navigate to the main Python API folder first and use following commands:
```shell
cd .../openvino/src/bindings/python/

View File

@ -1,17 +1,9 @@
# How to test OpenVINO:tm: Python API?
# How to test OpenVINO Python API?
#### Prerequisites
*To be added...*
#### Building and environment
Instructions can be found in ["Building the OpenVINO™ Python API"](./build.md).
##### Enviroment
<!-- TODO: Link to enviroment setup -->
*To be added...*
##### Building
<!-- TODO: Link to building instructions -->
*To be added...*
### Running OpenVINO:tm: Python API tests
### Running OpenVINO™ Python API tests
*For simplicity, all of these commands require to navigate to the main Python API folder first:*
```shell
cd .../openvino/src/bindings/python/
@ -43,12 +35,12 @@ To run full test suite one can utilize `tox` command:
tox
```
### Writing OpenVINO:tm: Python API tests
### Writing OpenVINO Python API tests
###### Before start
Follow and complete `openvino/src/bindings/python/docs/code_examples.md`.
##### Adding new test-case in the correct place
Let's add a new test for OpenVINO:tm: Python API.
Let's add a new test for OpenVINO Python API.
First, the test should confirm that the new pybind11-based class of `MyTensor` is behaving correctly. Navigate to tests folder and create a new file that describes tests within it. It should be along the lines of:
@ -112,4 +104,4 @@ Notice that the test name is shared between cases. In a real-life pull request,
###### Difference between *tests* and *tests_compatibility* directories
<!-- TO-DELETE when compatibility layer is no longer supported in the project -->
Someone could notice two similar folders `tests` and `tests_compatibility`. First one is the desired place for all upcoming features and tests. Compatibility layer is only supported in specific cases and any updates to it should be explicitly approved by OpenVINO:tm: reviewers. Please do not duplicate tests in both directories if not necessary.
Someone could notice two similar folders `tests` and `tests_compatibility`. First one is the desired place for all upcoming features and tests. Compatibility layer is only supported in specific cases and any updates to it should be explicitly approved by OpenVINO reviewers. Please do not duplicate tests in both directories if not necessary.