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).)

  1. Generate Python wrapper c++ source by the DMP tool with python_module option.
  2. Compile the network class sources with position independent code(PIC) option. See Build an Application for how to build.
  3. 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
  1. Link the compiled object files to build the dynamic shared library with the -ldmpdv -lboost_python3 -lboost_numpy3 option. 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.

  • id ID number of a network object

initialize()

def initialize(id: int) -> bool:

Initializes the network.

  • id ID 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.

  • id ID number of a network object
  • weight_file Path to weight file

Returns True if this function successed, otherwize False.

commit()

def commit(id: int) -> bool:

Commits the network.

  • id ID number of a network object

Returns True if this function successed, otherwize False.

run_network()

def run_network(id: int) -> bool:

Runs the network.

  • id ID 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.

  • id ID number of a network object
  • input Input to the network. input.dtype must be numpy.float16. Please be sure to call np.ascontiguousarray(input) just before calling this function.

get_final_output()

def put_input(id: int, index: int) -> numpy.ndarray:
  • id ID number of a network object
  • index index of the output of the network

Returns an output from the network.

get_conv_usec()

def get_conv_usec(id: int) -> int:
  • id ID 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:
  • id ID 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:
  • id ID number of a network object

Returns last time spent for CPU layers in microseconds.