# -*- coding: utf-8 -*-
# ============================
# Python Interface
# ============================
from __future__ import absolute_import, division, print_function
import logging
from os.path import join, realpath, dirname
import numpy as np
import ctypes as C
import sys
from pydarknet import ctypes_interface
logger = logging.getLogger('pydarknet')
[docs]def ensure_bytes_strings(str_list):
# converts python3 strings into bytes
if sys.hexversion > 0x03000000:
return [
str_ if not isinstance(str_, str) else bytes(str_, 'utf-8')
for str_ in str_list
]
else:
return str_list
def _cast_list_to_c(py_list, dtype):
"""
Converts a python list of strings into a c array of strings
adapted from "http://stackoverflow.com/questions/3494598/passing-a-list-of
-strings-to-from-python-ctypes-to-c-function-expecting-char"
Avi's code
"""
c_arr = (dtype * len(py_list))()
c_arr[:] = py_list
return c_arr
def _arrptr_to_np(c_arrptr, shape, arr_t, dtype):
"""
Casts an array pointer from C to numpy
Input:
c_arrpt - an array pointer returned from C
shape - shape of that array pointer
arr_t - the ctypes datatype of c_arrptr
Avi's code
"""
arr_t_size = C.POINTER(C.c_char * dtype().itemsize) # size of each item
c_arr = C.cast(c_arrptr.astype(int), arr_t_size) # cast to ctypes
np_arr = np.ctypeslib.as_array(c_arr, shape) # cast to numpy
np_arr.dtype = dtype # fix numpy dtype
np_arr = np.require(np_arr, dtype=dtype, requirements=['O']) # prevent memory leaks
return np_arr
def _extract_np_array(size_list, ptr_list, arr_t, arr_dtype, arr_dim):
"""
size_list - contains the size of each output 2d array
ptr_list - an array of pointers to the head of each output 2d
array (which was allocated in C)
arr_t - the C pointer type
arr_dtype - the numpy array type
arr_dim - the number of columns in each output 2d array
"""
arr_list = [
_arrptr_to_np(arr_ptr, (size, arr_dim), arr_t, arr_dtype)
for (arr_ptr, size) in zip(ptr_list, size_list)
]
return arr_list
def _find_c_shared_library_by_device(device='cpu'):
root_dir = realpath(join(dirname(__file__), 'lib'))
if device in ['cpu']:
libname = 'pydarknet'
elif device in ['gpu']:
libname = 'pydarknet_cuda'
else:
raise ValueError('device %r not recognized' % (device,))
try:
darknet_clib, def_cfunc = ctypes_interface.load_clib(libname, root_dir)
except ImportError:
if device not in ['cpu']:
logging.info('CPU fallback for: %s' % (libname,))
darknet_clib, def_cfunc = _find_c_shared_library_by_device()
else:
import warnings
warnings.warn('Unable to load C library for darknet')
darknet_clib, def_cfunc = None, None
return darknet_clib, def_cfunc
def _load_c_shared_library(METHODS, device='cpu'):
"""Loads the pydarknet dynamic library and defines its functions"""
darknet_clib, def_cfunc = _find_c_shared_library_by_device(device=device)
if None in [darknet_clib, def_cfunc]:
return None, None
# Load and expose methods from lib
for method in METHODS.keys():
def_cfunc(METHODS[method][1], method, METHODS[method][0])
return darknet_clib, def_cfunc