Python Wrapper Usage - DigitalMediaProfessionals/dv-sdk GitHub Wiki
This sections describes usage of Python wrapper module for a network using example of MobileNet.
In the example, .ini file given to the DMP tool is assumed to contain python_module = gnet_wrap entry.
PreRequisite
- Boost.Python(libboost-python-dev), Boost.Numpy(libboost-numpy-dev)
- libpython3.6-dev (according to your python version)
- jinja2
How to Build
To create the Python wrapper module, please follow the below steps. (The example code is assumed to be executed in AI FPGA module (referred to as MODULE).)
- Generate Python wrapper c++ source by the DMP tool with python_module option.
- Compile the network class sources with position independent code(PIC) option. See Build an Application for how to build.
- Compile the Python wrapper source with PIC option. Take care that appropriate Python include directory have to be passed to the compiler because the source file depends on python library.
# on MODULE
$ g++ -std=c++11 -O3 -fPIC -c -I/usr/include/python3.6 -o gnet_wrap.o gnet_wrap.cpp
- Link the compiled object files to build the dynamic shared library with the
-ldmpdv -lboost_python3 -lboost_numpy3option. The name of .so file must be gnet_wrap.so. For other network, you replace gnet_wrap with the value of python_module in the input file for the tool.
# on MODULE
$ g++ -std=c++11 -shared -fPIC gnet_wrap.o CaffeMobileNet_gen.o dmp_network.o -o gnet_wrap.so -L/path/to/dv-user-driver -ldmpdv -lboost_python3 -lboost_numpy3
This shared library is used as a python module.
Simple Sample
After building the shared library, we introduce how to use a network in Python code. Here is a sample code (without error check for simplicity).
NOTE: A Python code can import the shared library by its name like a normal Python module.
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2
import numpy as np
import gnet_wrap as gnw
net = gnw.create()
try:
# initialize
gnw.initialize(net)
gnw.load_weights(net, "path/to/network_weight.bin/")
gnw.commit(net)
# get image
img = cv2.imread("path/to/image_file")
## Manipulate image according to the network rule
...
## Be sure to call np.ascontiguousarray() before put_input()
img = np.ascontiguousarray(img)
# run network
gnw.put_input(net, img)
gnw.run_network(net)
output = gnw.get_final_output(net)
# after processing
...
finally:
gnw.destroy(net)
API Reference
Here is API reference of gnet_wrap Python module (and other Python wrapper module for a network).
create()
def create() -> int:
Creates a new network object for the class.
Returns the ID number of the object.
destroy()
def destroy(id: int) -> None:
Destroys the network.
idID number of a network object
initialize()
def initialize(id: int) -> bool:
Initializes the network.
idID number of a network object
Returns True if this function successed, otherwize False.
load_weights()
def load_weights(id: int, weight_file: str) -> bool:
Loads weight of the network.
idID number of a network objectweight_filePath to weight file
Returns True if this function successed, otherwize False.
commit()
def commit(id: int) -> bool:
Commits the network.
idID number of a network object
Returns True if this function successed, otherwize False.
run_network()
def run_network(id: int) -> bool:
Runs the network.
idID number of a network object
Returns True if this function successed, otherwize False.
put_input()
def put_input(id: int, input: numpy.ndarray) -> None:
Feeds an input to the network.
idID number of a network objectinputInput to the network.input.dtypemust benumpy.float16. Please be sure to callnp.ascontiguousarray(input)just before calling this function.
get_final_output()
def put_input(id: int, index: int) -> numpy.ndarray:
idID number of a network objectindexindex of the output of the network
Returns an output from the network.
get_conv_usec()
def get_conv_usec(id: int) -> int:
idID number of a network object
Returns last time spent for executing convolutional layers in microseconds.
get_fc_usec()
def get_fc_usec(id: int) -> int:
idID number of a network object
Returns last time spent for fully connected layers in microseconds.
get_cpu_usec()
def get_cpu_usec(id: int) -> int:
idID number of a network object
Returns last time spent for CPU layers in microseconds.