edgefirst-validator 4.2.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- deepview/modelpack/utils/argmax.py +16 -0
- edgefirst/validator/__init__.py +1 -0
- edgefirst/validator/__main__.py +375 -0
- edgefirst/validator/datasets/__init__.py +118 -0
- edgefirst/validator/datasets/cache.py +296 -0
- edgefirst/validator/datasets/core.py +250 -0
- edgefirst/validator/datasets/darknet.py +446 -0
- edgefirst/validator/datasets/database.py +1067 -0
- edgefirst/validator/datasets/instance/__init__.py +4 -0
- edgefirst/validator/datasets/instance/core.py +222 -0
- edgefirst/validator/datasets/instance/detection.py +145 -0
- edgefirst/validator/datasets/instance/multitask.py +80 -0
- edgefirst/validator/datasets/instance/segmentation.py +120 -0
- edgefirst/validator/datasets/utils/fetch.py +682 -0
- edgefirst/validator/datasets/utils/readers.py +425 -0
- edgefirst/validator/datasets/utils/transformations.py +1695 -0
- edgefirst/validator/evaluators/__init__.py +17 -0
- edgefirst/validator/evaluators/callbacks/__init__.py +3 -0
- edgefirst/validator/evaluators/callbacks/core.py +192 -0
- edgefirst/validator/evaluators/callbacks/plots.py +900 -0
- edgefirst/validator/evaluators/callbacks/studio.py +234 -0
- edgefirst/validator/evaluators/core.py +257 -0
- edgefirst/validator/evaluators/detection.py +749 -0
- edgefirst/validator/evaluators/multitask.py +270 -0
- edgefirst/validator/evaluators/parameters/__init__.py +53 -0
- edgefirst/validator/evaluators/parameters/core.py +554 -0
- edgefirst/validator/evaluators/parameters/dataset.py +239 -0
- edgefirst/validator/evaluators/parameters/model.py +338 -0
- edgefirst/validator/evaluators/parameters/validation.py +528 -0
- edgefirst/validator/evaluators/segmentation.py +729 -0
- edgefirst/validator/evaluators/utils/__init__.py +3 -0
- edgefirst/validator/evaluators/utils/classify.py +292 -0
- edgefirst/validator/evaluators/utils/match.py +262 -0
- edgefirst/validator/evaluators/utils/timer.py +132 -0
- edgefirst/validator/metrics/__init__.py +9 -0
- edgefirst/validator/metrics/data/__init__.py +7 -0
- edgefirst/validator/metrics/data/label.py +668 -0
- edgefirst/validator/metrics/data/metrics.py +759 -0
- edgefirst/validator/metrics/data/plots.py +476 -0
- edgefirst/validator/metrics/data/stats.py +507 -0
- edgefirst/validator/metrics/detection.py +595 -0
- edgefirst/validator/metrics/segmentation.py +173 -0
- edgefirst/validator/metrics/utils/math.py +717 -0
- edgefirst/validator/publishers/__init__.py +3 -0
- edgefirst/validator/publishers/console.py +147 -0
- edgefirst/validator/publishers/studio.py +128 -0
- edgefirst/validator/publishers/tensorboard.py +119 -0
- edgefirst/validator/publishers/utils/logger.py +111 -0
- edgefirst/validator/publishers/utils/table.py +403 -0
- edgefirst/validator/runners/__init__.py +8 -0
- edgefirst/validator/runners/core.py +727 -0
- edgefirst/validator/runners/deepviewrt.py +177 -0
- edgefirst/validator/runners/hailo.py +263 -0
- edgefirst/validator/runners/keras.py +150 -0
- edgefirst/validator/runners/kinara.py +265 -0
- edgefirst/validator/runners/offline.py +228 -0
- edgefirst/validator/runners/onnx.py +241 -0
- edgefirst/validator/runners/processing/decode.py +320 -0
- edgefirst/validator/runners/processing/dvapi.py +4192 -0
- edgefirst/validator/runners/processing/nms.py +637 -0
- edgefirst/validator/runners/processing/outputs.py +507 -0
- edgefirst/validator/runners/tensorrt.py +321 -0
- edgefirst/validator/runners/tflite.py +221 -0
- edgefirst/validator/validate.py +843 -0
- edgefirst/validator/visualize/__init__.py +3 -0
- edgefirst/validator/visualize/detection.py +623 -0
- edgefirst/validator/visualize/segmentation.py +281 -0
- edgefirst/validator/visualize/utils/plots.py +635 -0
- edgefirst_validator-4.2.1.dist-info/METADATA +111 -0
- edgefirst_validator-4.2.1.dist-info/RECORD +73 -0
- edgefirst_validator-4.2.1.dist-info/WHEEL +5 -0
- edgefirst_validator-4.2.1.dist-info/entry_points.txt +2 -0
- edgefirst_validator-4.2.1.dist-info/top_level.txt +2 -0
|
@@ -0,0 +1,4192 @@
|
|
|
1
|
+
# Copyright (c) 2018-25, Kinara, Inc. All rights reserved.
|
|
2
|
+
# Kinara Proprietary. This software is owned or controlled by Kinara and
|
|
3
|
+
# may only be used strictly in accordance with the applicable license
|
|
4
|
+
# terms.
|
|
5
|
+
"""
|
|
6
|
+
DV inference proxy python APIS
|
|
7
|
+
|
|
8
|
+
Examples
|
|
9
|
+
--------
|
|
10
|
+
>>> import numpy as np
|
|
11
|
+
>>> from dvapi import *
|
|
12
|
+
>>> ret, connection = DVSession.create_via_unix_socket("/var/run/ara2.sock")
|
|
13
|
+
>>> with connection as conn:
|
|
14
|
+
... ret, connected_endpoints = conn.get_endpoint_list()
|
|
15
|
+
... ret, loaded_model = conn.load_model_from_file("./my_model.dvm")
|
|
16
|
+
... input_param = loaded_model.input_param[0]
|
|
17
|
+
... my_image_data = np.fromfile("./my_preprocessed_image", dtype=np.int8)
|
|
18
|
+
... input_tensor = DVTensor(my_input, input_param)
|
|
19
|
+
... ret, response = loaded_model.infer_sync(
|
|
20
|
+
... [input_tensor],
|
|
21
|
+
... timeout=50000,
|
|
22
|
+
... endpoint=connected_endpoints.get(0))
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from ctypes import *
|
|
26
|
+
from enum import IntEnum
|
|
27
|
+
from typing import Callable
|
|
28
|
+
import logging
|
|
29
|
+
import os
|
|
30
|
+
import errno
|
|
31
|
+
import sys
|
|
32
|
+
import functools
|
|
33
|
+
import numpy as np
|
|
34
|
+
import platform
|
|
35
|
+
import mmap
|
|
36
|
+
import typing
|
|
37
|
+
|
|
38
|
+
logging.getLogger().setLevel(logging.INFO)
|
|
39
|
+
logger = logging.getLogger('dvapi')
|
|
40
|
+
logger.setLevel(logging.INFO)
|
|
41
|
+
|
|
42
|
+
dvapi_handler = logging.StreamHandler()
|
|
43
|
+
dvapi_formatter = logging.Formatter('[%(levelname)s] - DVAPI: %(message)s')
|
|
44
|
+
dvapi_handler.setFormatter(dvapi_formatter)
|
|
45
|
+
|
|
46
|
+
logger.addHandler(dvapi_handler)
|
|
47
|
+
logger.propagate = False
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def dv_is_null(pv):
|
|
51
|
+
return (cast(pv, c_void_p).value is None)
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
class DVClientLibNotFoundError(FileNotFoundError):
|
|
55
|
+
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
@functools.lru_cache(maxsize=10)
|
|
59
|
+
def _dvApiObj():
|
|
60
|
+
DV_API_OBJ = None
|
|
61
|
+
|
|
62
|
+
def load_dvinfclient_lib(libpath):
|
|
63
|
+
nonlocal DV_API_OBJ
|
|
64
|
+
try:
|
|
65
|
+
if os.path.exists(libpath):
|
|
66
|
+
DV_API_OBJ = CDLL(libpath)
|
|
67
|
+
logger.info("loaded dvinfclient lib: %s", libpath)
|
|
68
|
+
return True
|
|
69
|
+
else:
|
|
70
|
+
logger.info("failed to load dvinfclient lib: %s", libpath)
|
|
71
|
+
return False
|
|
72
|
+
except BaseException:
|
|
73
|
+
logger.info("failed to load dvinfclient lib: %s", libpath)
|
|
74
|
+
return False
|
|
75
|
+
|
|
76
|
+
lib_loaded = False
|
|
77
|
+
cwd = os.path.dirname(os.path.abspath(__file__))
|
|
78
|
+
curr_platform = platform.system()
|
|
79
|
+
env = os.environ.get('DV_TGT_ROOT')
|
|
80
|
+
if curr_platform == "Windows":
|
|
81
|
+
if 'DV_TGT_ROOT' in os.environ:
|
|
82
|
+
if os.path.exists(os.path.join(
|
|
83
|
+
env, "art/windows/x86/client/md_release/araclient.dll")):
|
|
84
|
+
lib_loaded = load_dvinfclient_lib(os.path.join(
|
|
85
|
+
env, "art/windows/x86/client/md_release/araclient.dll"))
|
|
86
|
+
else:
|
|
87
|
+
lib_loaded = load_dvinfclient_lib(os.path.abspath(
|
|
88
|
+
os.path.join(cwd, "../client/md_release/araclient.dll")))
|
|
89
|
+
if curr_platform == "Linux":
|
|
90
|
+
lib_loaded = load_dvinfclient_lib("/usr/lib/libaraclient.so.1")
|
|
91
|
+
|
|
92
|
+
if not lib_loaded:
|
|
93
|
+
raise DVClientLibNotFoundError(errno.ENOENT, os.strerror(
|
|
94
|
+
errno.ENOENT), "unable to load dvinfclient library")
|
|
95
|
+
return DV_API_OBJ
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
###############################################################################
|
|
99
|
+
# dvapi enum wrappers based on ctypes
|
|
100
|
+
###############################################################################
|
|
101
|
+
class dv_DV_ERROR_CATEGORY(IntEnum):
|
|
102
|
+
DV_ERROR_CATEGORY_SUCCESS = 0,
|
|
103
|
+
DV_ERROR_CATEGORY_RETRY = 100,
|
|
104
|
+
DV_ERROR_CATEGORY_INVALID = 200,
|
|
105
|
+
DV_ERROR_CATEGORY_SW_CLIENT_FATAL = 300,
|
|
106
|
+
DV_ERROR_CATEGORY_SW_SERVER_FATAL = 400,
|
|
107
|
+
DV_ERROR_CATEGORY_HW_FATAL = 500,
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
class dv_status_code(IntEnum):
|
|
111
|
+
# DV_ERROR_CATEGORY_SUCCESS
|
|
112
|
+
DV_ERROR_CATEGORY_SUCCESS_START = 0,
|
|
113
|
+
DV_SUCCESS = 0,
|
|
114
|
+
DV_ERROR_CATEGORY_SUCCESS_END = 0,
|
|
115
|
+
# TODO KARTHIK only change name to DV_STATUS_UNKNOWN
|
|
116
|
+
DV_FAILURE_UNKOWN = 1,
|
|
117
|
+
|
|
118
|
+
# DV_ERROR_CATEGORY_RETRY
|
|
119
|
+
DV_ERROR_CATEGORY_RETRY_START = 100,
|
|
120
|
+
# Not enough DDR memory available on endpoint; use
|
|
121
|
+
DV_ENDPOINT_OUT_OF_MEMORY = 100,
|
|
122
|
+
# dv_endpoint_get_dram_statistics to get available memory
|
|
123
|
+
# inference queue (Internal to Kinara)
|
|
124
|
+
DV_ERROR_CATEGORY_RETRY_END = 199,
|
|
125
|
+
|
|
126
|
+
# DV_ERROR_CATEGORY_INVALID
|
|
127
|
+
DV_ERROR_CATEGORY_INVALID_START = 200,
|
|
128
|
+
DV_RESOURCE_NOT_FOUND = 200, # Model file given as input not accessible
|
|
129
|
+
# Invalid pointer value encountered in proxy (Internal to Kinara)
|
|
130
|
+
DV_INVALID_VALUE = 201,
|
|
131
|
+
DV_INVALID_HOST_PTR = 202, # Invalid pointer value encountered in clientlib
|
|
132
|
+
DV_INVALID_OPERATION = 203, # One of the below invalid requests sent
|
|
133
|
+
# 1. SHM/SFD request over TCP/IP socket
|
|
134
|
+
# 2. Snapshot dump recieved invalid endpoint ID
|
|
135
|
+
# 3. Proxy received invalid request ID (Internal to Kinara)
|
|
136
|
+
|
|
137
|
+
DV_OPERATION_NOT_PERMITTED = 204, # Reserved (unused currently)
|
|
138
|
+
DV_OPERATION_NOT_SUPPORTED = 205, # Reserved (unused currently)
|
|
139
|
+
DV_SESSION_UNIX_SOCKET_FILE_TOO_LONG = 220,
|
|
140
|
+
# Unix socket file exceeded 108 bytes
|
|
141
|
+
DV_SESSION_INVALID_TCP_IPV4_ADDR = 221, # Invalid TCP Address
|
|
142
|
+
DV_SESSION_INVALID_TCP_IPV4_PORT = 222, # Invalid TCP port value
|
|
143
|
+
# Request sent over session that does not exist
|
|
144
|
+
DV_SESSION_INVALID_HANDLE = 223,
|
|
145
|
+
# Request sent for endpoint list with no active endpoints
|
|
146
|
+
DV_ENDPOINT_INVALID_HANDLE = 230,
|
|
147
|
+
# Invalid endpoint param sent for stats collection/fault recovery
|
|
148
|
+
DV_ENDPOINT_INVALID_PARAMS = 231,
|
|
149
|
+
DV_ENDPOINT_NOT_FOUND = 232, # Reserved (currently unused)
|
|
150
|
+
# No valid endpoints received in dv_endpoint_get_list
|
|
151
|
+
DV_ENDPOINT_NOT_AVAILABLE = 233,
|
|
152
|
+
DV_ENDPOINT_GROUP_INVALID = 234, # Reserved (unused currently)
|
|
153
|
+
DV_ENDPOINT_POWER_SWITCH_FAILURE = 235, # Endpoint power switch failed
|
|
154
|
+
# Endpoint cannot run inferences since it is in power gated mode
|
|
155
|
+
DV_ENDPOINT_POWER_GATED = 236,
|
|
156
|
+
# Invalid power state switch requested
|
|
157
|
+
DV_ENDPOINT_INVALID_POWER_STATE = 237,
|
|
158
|
+
# Generic error if get endpoint list fails.
|
|
159
|
+
DV_ENDPOINT_GET_LIST_FAILED = 238,
|
|
160
|
+
DV_ENDPOINT_GET_STATS_FAILED = 239,
|
|
161
|
+
DV_MODEL_INVALID_PARAMS = 240, # One of the below errors occurred
|
|
162
|
+
# 1. Model context not found/ invalid on device (Internal to
|
|
163
|
+
# Kinara)
|
|
164
|
+
# 2. Inference request sent on a device with no model loaded
|
|
165
|
+
# 3. Invalid input size sent for model
|
|
166
|
+
DV_MODEL_INVALID_HANDLE = 241, # One of the below errors occurred
|
|
167
|
+
# 1. Null/invalid model handle passed for inference
|
|
168
|
+
# 2. Invalid model handle passed to dv_model_unload
|
|
169
|
+
DV_MODEL_INVALID_MODEL_FILE = 242, # Model of size 0 passed
|
|
170
|
+
DV_MODEL_PARSE_FAILURE = 243, # Invalid file format of model.dvm
|
|
171
|
+
DV_MODEL_UNSUPPORTED_VERSION = 244, # Deprecated model.dvm file provided
|
|
172
|
+
DV_MODEL_CACHING_FAILURE = 245, # One of the below errors occurred
|
|
173
|
+
# 1. Model cache path inaccessible for model write
|
|
174
|
+
# 2. Model cache path not writable
|
|
175
|
+
DV_MODEL_CACHE_FETCH_FAILURE = 246, # One of the below errors occurred
|
|
176
|
+
# 1. Model cache path inaccessible for model read
|
|
177
|
+
# 2. Model not readable from cache
|
|
178
|
+
# 3. Checksum comparison failed after model read from cache
|
|
179
|
+
# (Internal to Kinara)
|
|
180
|
+
DV_INFER_INVALID_SHM_BUFFERS = 250, # Unable to read/write SHM buffers
|
|
181
|
+
# dv_wait_for_completion called on invalid inference request object
|
|
182
|
+
DV_INFER_REQUEST_INVALID_HANDLE = 251,
|
|
183
|
+
# (or) error in clientlib while processing inference
|
|
184
|
+
# invalid firmware version for firmware binaries
|
|
185
|
+
DV_FIRMWARE_VERSION_INVALID = 252,
|
|
186
|
+
DV_MODEL_LOAD_SUBMITTED = 253,
|
|
187
|
+
DV_MODEL_ALREADY_LOADED = 254,
|
|
188
|
+
DV_MODEL_UNLOAD_SUBMITTED = 255,
|
|
189
|
+
DV_MODEL_LOAD_SUBMIT_FAILED = 256,
|
|
190
|
+
DV_MODEL_LOAD_ABORTED = 257,
|
|
191
|
+
DV_MODEL_UNLOAD_SUBMIT_FAILED = 258,
|
|
192
|
+
DV_ERROR_CATEGORY_INVALID_END = 299,
|
|
193
|
+
|
|
194
|
+
# DV_ERROR_CATEGORY_SW_CLIENT_FATAL
|
|
195
|
+
DV_ERROR_CATEGORY_SW_CLIENT_FATAL_START = 300,
|
|
196
|
+
DV_CLIENT_VERSION_MISMATCH = 300, # Incorrect version of clientlib used; to
|
|
197
|
+
# be matched with Proxy version
|
|
198
|
+
DV_CONNECTION_ERROR = 301, # Connection is faulty/closed
|
|
199
|
+
DV_HIF_PUSH_FAILED = 302,
|
|
200
|
+
DV_HIF_ERROR = 303,
|
|
201
|
+
DV_HIF_TIMEOUT = 304,
|
|
202
|
+
DV_HIF_POP_FAILED = 305,
|
|
203
|
+
DV_ERROR_CATEGORY_SW_CLIENT_FATAL_END = 399,
|
|
204
|
+
|
|
205
|
+
# DV_ERROR_CATEGORY_SW_SERVER_FATAL
|
|
206
|
+
DV_ERROR_CATEGORY_SW_SERVER_FATAL_START = 400,
|
|
207
|
+
# Host is out of memory (calloc/malloc call fails)
|
|
208
|
+
DV_HOST_OUT_OF_MEMORY = 400,
|
|
209
|
+
# One of the below errors occurred (Internal to Kinara)
|
|
210
|
+
DV_INTERNAL_ERROR = 401,
|
|
211
|
+
# 1. Mismatch in expected payload sizes
|
|
212
|
+
# 2. Failed to add request to host list
|
|
213
|
+
DV_REQUEST_TIMEDOUT = 402, # Request timed out; default values of timeouts
|
|
214
|
+
# are API specific and mentioned in dvapi.h
|
|
215
|
+
DV_SHMBUF_NOT_PERMITTED = 403, # One of the below errors occurred
|
|
216
|
+
# 1. Mmap of shm file failed
|
|
217
|
+
# 2. Invalid fd sent in sfd request
|
|
218
|
+
# 3. No more free shm buffers present
|
|
219
|
+
DV_REQUEST_SEND_FAILED = 404, # failed to send the request
|
|
220
|
+
DV_REQUEST_PROCESSING_FAILED = 405, # failed to processing incoming request
|
|
221
|
+
# 1. happens at on_request()
|
|
222
|
+
|
|
223
|
+
DV_ERROR_CATEGORY_SW_SERVER_FATAL_END = 499,
|
|
224
|
+
|
|
225
|
+
# DV_ERROR_CATEGORY_HW_FATAL (Endpoint to be reset)
|
|
226
|
+
DV_ERROR_CATEGORY_HW_FATAL_START = 500,
|
|
227
|
+
# DMA from endpoint to host failed in case of PCIe
|
|
228
|
+
DV_ENDPOINT_DMA_FAILED = 500,
|
|
229
|
+
DV_ENDPOINT_FIRMWARE_LOAD_FAILURE = 501, # Failed to load firmware
|
|
230
|
+
DV_ENDPOINT_FIRMWARE_BOOT_FAILURE = 502, # Failed to boot firmware
|
|
231
|
+
DV_ENDPOINT_NO_FIRMWARE = 503, # Reserved (unused currently)
|
|
232
|
+
# Interface gone bad or device exception occurred (Refer Fault
|
|
233
|
+
DV_ENDPOINT_NOT_REACHABLE = 504,
|
|
234
|
+
# Handling document for further details)
|
|
235
|
+
# Model binding not present in the device.
|
|
236
|
+
DV_ENDPOINT_MODEL_BINDING_FAILURE = 505,
|
|
237
|
+
DV_TENSOR_FREE_ERROR = 506, # Failed to free the allocated tensors
|
|
238
|
+
|
|
239
|
+
# Model load request failed on all endpoints in list due to one of
|
|
240
|
+
DV_MODEL_LOAD_FAILURE = 520,
|
|
241
|
+
# the following
|
|
242
|
+
# 1. Model write to endpoints failed
|
|
243
|
+
# 2. Model context write to endpoints failed
|
|
244
|
+
# 3. Unable to perform model integrity check after model write
|
|
245
|
+
# (Internal to Kinara)
|
|
246
|
+
# 4. Model checksum compare failure (Internal to Kinara)
|
|
247
|
+
# 5. Invalid model object received in request
|
|
248
|
+
# 6. No endpoints active in endpoint list to load model
|
|
249
|
+
# Device in faulty state on trying to reload model from cache
|
|
250
|
+
DV_MODEL_RELOAD_FAILURE = 521,
|
|
251
|
+
DV_MODEL_UNLOAD_FAILURE = 522,
|
|
252
|
+
# failed to load/unload model on some of the given devices
|
|
253
|
+
DV_PARTIAL_SUCCESS = 523,
|
|
254
|
+
# Failed to write buffer to endpoint (Internal to Kinara)
|
|
255
|
+
DV_TENSOR_WRITE_FAILURE = 541,
|
|
256
|
+
# Failed to read buffer from endpoint (Internal to Kinara)
|
|
257
|
+
DV_TENSOR_READ_FAILURE = 542,
|
|
258
|
+
DV_TENSOR_CREATE_FAILURE = 543, # Failed to create tensor
|
|
259
|
+
# Failed to allocate device memory for a tensor.
|
|
260
|
+
DV_TENSOR_ALLOCTAION_FAILURE = 545,
|
|
261
|
+
DV_TENSOR_INTEGRITY_CHECK_FAILURE = 546, # Integrity check failed.
|
|
262
|
+
|
|
263
|
+
# Proxy not able to initialize device
|
|
264
|
+
DV_PROXY_DEVICE_INIT_FAILURE = 551,
|
|
265
|
+
|
|
266
|
+
# Inference request failed to complete within the timeout limit
|
|
267
|
+
DV_INFER_TIME_OUT = 560,
|
|
268
|
+
DV_INFER_FAILURE = 561, # inference failure
|
|
269
|
+
DV_INFER_INVALID_INPUT = 562, # inference request received with invalid input
|
|
270
|
+
# Inference queue on host side is full; current inferences in queue
|
|
271
|
+
DV_INFER_QUEUE_FULL = 563,
|
|
272
|
+
# to be processed to accept more requests
|
|
273
|
+
DV_INFER_QUEUE_EMPTY = 564, # No inferences scheduled on endpoint host
|
|
274
|
+
DV_INFER_MODEL_NOT_FOUND = 565, # Model not loaded on for inference request
|
|
275
|
+
DV_INFER_ABORTED = 566, # Inference aborted before submitting to device
|
|
276
|
+
DV_INFER_SUBMIT_FAILURE = 567, # Infer request submission to device failed
|
|
277
|
+
# Inference request failed due to increase in temperature
|
|
278
|
+
DV_INFER_TIME_OUT_THERMAL_RUNAWAY = 568,
|
|
279
|
+
|
|
280
|
+
DV_ERROR_CATEGORY_HW_FATAL_END = 599,
|
|
281
|
+
|
|
282
|
+
DV_CLIENT_TXRX_WRITE_FAILURE = 600, # UV write failue
|
|
283
|
+
DV_CLIENT_TXRX_READ_FAILURE = 601, # UV read failure
|
|
284
|
+
DV_CLIENT_TXRX_ASYNC_SEND_FAILURE = 602, # UV read failure
|
|
285
|
+
DV_CLIENT_TXRX_FD_COUNT_MISMATCH = 603, # fd count mismatch at proxy client
|
|
286
|
+
DV_CLIENT_TXRX_DISCONNECT_ERROR = 604, # client disconnected from server
|
|
287
|
+
DV_CLIENT_RECEIVED_UNKNOWN_RESPONSE = 605,
|
|
288
|
+
# proxy client received unknown response
|
|
289
|
+
# client not connnected to transreceiver
|
|
290
|
+
DV_CLIENT_TO_TXRX_CONNECTION_ERROR = 606,
|
|
291
|
+
|
|
292
|
+
DV_FLOW_CREATE_FAILED = 700, # Failed to submit the control flow
|
|
293
|
+
DV_FLOW_SUBMIT_FAILED = 701, # Failed to submit the control flow
|
|
294
|
+
DV_FLOW_ABORTED = 702, # Flow is aborted explicitly
|
|
295
|
+
|
|
296
|
+
DV_CP_INDEX_ALLOC_FAILURE = 800, # Failed to get the CP index.
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
class dv_session_socket_type(IntEnum):
|
|
300
|
+
DV_SESSION_SOCKET_TYPE_UNIX = 0, # unix domain socket
|
|
301
|
+
DV_SESSION_SOCKET_TYPE_TCPIPv4 = 1 # tcp ipv4 socket
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
class dv_endpoint_host_interface(IntEnum):
|
|
305
|
+
# host and dv connected via pcie interface
|
|
306
|
+
DV_ENDPOINT_HOST_INTERFACE_PCIE = 1,
|
|
307
|
+
DV_ENDPOINT_HOST_INTERFACE_USB = 2 # host and dv connected via usb interface
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
class dv_endpoint_default_group(IntEnum):
|
|
311
|
+
# default group for all the endpoint(s) connected to inference proxy server
|
|
312
|
+
DV_ENDPOINT_DEFAULT_GROUP_ALL = 0,
|
|
313
|
+
# default group for all the pcie endpoint(s) connected to inference proxy
|
|
314
|
+
# server
|
|
315
|
+
DV_ENDPOINT_DEFAULT_GROUP_PCIE = 1,
|
|
316
|
+
# default group for all the usb endpoint(s) connected to inference proxy
|
|
317
|
+
# server
|
|
318
|
+
DV_ENDPOINT_DEFAULT_GROUP_USB = 2,
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
class dv_endpoint_state(IntEnum):
|
|
322
|
+
# endpoint reset done but firmware not loaded yet(this is a transient
|
|
323
|
+
# state)
|
|
324
|
+
DV_ENDPOINT_STATE_INIT = 0,
|
|
325
|
+
# firmware loaded and endpoint is ready for inference execution
|
|
326
|
+
DV_ENDPOINT_STATE_IDLE = 1,
|
|
327
|
+
DV_ENDPOINT_STATE_ACTIVE = 2, # inference execution ongoing
|
|
328
|
+
# endpoint is operating at reduced frequency
|
|
329
|
+
DV_ENDPOINT_STATE_ACTIVE_SLOW = 3,
|
|
330
|
+
# endpoint is operating at reduced frequency
|
|
331
|
+
DV_ENDPOINT_STATE_ACTIVE_BOOSTED = 4,
|
|
332
|
+
# endpoint is in thermal Inactive state
|
|
333
|
+
DV_ENDPOINT_STATE_THERMAL_INACTIVE = 5,
|
|
334
|
+
DV_ENDPOINT_STATE_THERMAL_UNKNOWN = 6, # endpoint is in unown thermal state
|
|
335
|
+
DV_ENDPOINT_STATE_INACTIVE = 7, # endpoint is in Inactive state
|
|
336
|
+
DV_ENDPOINT_STATE_FAULT = 8, # endpoint is in faulty state
|
|
337
|
+
DV_ENDPOINT_STATE_BAD_INTERFACE = 1001, # [unsupported]
|
|
338
|
+
DV_ENDPOINT_STATE_RECOVERY = 1003, # [unsupported]
|
|
339
|
+
DV_ENDPOINT_STATE_DEAD = 1004, # [unsupported]
|
|
340
|
+
DV_ENDPOINT_STATE_DRAIN = 1005, # [unsupported]
|
|
341
|
+
DV_ENDPOINT_STATE_POWER_GATED = 1006, # [unsupported]
|
|
342
|
+
DV_ENDPOINT_STATE_CLOSED = 1007, # [unsupported]
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
class dv_endpoint_power_state(IntEnum):
|
|
346
|
+
# state with maximum power and performance (default state when endpoint is
|
|
347
|
+
# initialized)
|
|
348
|
+
DV_POWER_STATE_L0 = 0,
|
|
349
|
+
DV_POWER_STATE_L1 = 1, # endpoint operating at a sys clock of 300 MHz
|
|
350
|
+
DV_POWER_STATE_L1A = 2, # endpoint operating at a sys clock of 150 MHz
|
|
351
|
+
# endpoint set to a sys clock of 150 MHz and all subsystems are power gated
|
|
352
|
+
DV_POWER_STATE_L2 = 3
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class dv_endpoint_group_type(IntEnum):
|
|
356
|
+
DV_ENDPOINT_GROUP_TYPE_NONE = 0, # endpoint group type none
|
|
357
|
+
DV_ENDPOINT_GROUP_TYPE_ALL = 1, # endpoint group type all
|
|
358
|
+
DV_ENDPOINT_GROUP_TYPE_PCIE = 2, # endpoint group type pcie
|
|
359
|
+
DV_ENDPOINT_GROUP_TYPE_USB = 3, # endpoint group type usb
|
|
360
|
+
DV_ENDPOINT_GROUP_TYPE_CUSTOM = 4, # endpoint group type custom
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
# Model Network type
|
|
364
|
+
class dv_layer_output_type(IntEnum):
|
|
365
|
+
# represent classification type of network
|
|
366
|
+
DV_LAYER_OUTPUT_TYPE_CLASSIFICATION = 0,
|
|
367
|
+
DV_LAYER_OUTPUT_TYPE_DETECTION = 1, # represent detection type of network
|
|
368
|
+
# represent semantic segmentation type of network
|
|
369
|
+
DV_LAYER_OUTPUT_TYPE_SEMANTIC_SEGMENTATION = 2,
|
|
370
|
+
# represents all other network types which can't be determined
|
|
371
|
+
DV_LAYER_OUTPUT_TYPE_RAW = 3
|
|
372
|
+
|
|
373
|
+
|
|
374
|
+
class dv_model_priority_level(IntEnum):
|
|
375
|
+
DV_MODEL_PRIORITY_LEVEL_LOW = 0, # model priority low
|
|
376
|
+
DV_MODEL_PRIORITY_LEVEL_MEDIUM = 1, # model priority medium
|
|
377
|
+
DV_MODEL_PRIORITY_LEVEL_DEFAULT = 1, # model priority default
|
|
378
|
+
DV_MODEL_PRIORITY_LEVEL_HIGH = 2 # model priority high
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
class dv_inference_status(IntEnum):
|
|
382
|
+
DV_INFERENCE_STATUS_QUEUED = 0, # Inference is in queued state
|
|
383
|
+
DV_INFERENCE_STATUS_RUNNING = 1, # Inference is in running/executing state
|
|
384
|
+
DV_INFERENCE_STATUS_COMPLETED = 2, # Inference is in completed state
|
|
385
|
+
DV_INFERENCE_STATUS_FAILED = 4, # Inference is in failed state
|
|
386
|
+
DV_INFERENCE_STATUS_UNKNOWN = 5 # Inference information is not available
|
|
387
|
+
|
|
388
|
+
|
|
389
|
+
class dv_blob_type(IntEnum):
|
|
390
|
+
DV_BLOB_TYPE_RAW_POINTER = 0, # represents blob backed by raw pointer
|
|
391
|
+
# represents blob backed by registered shared memory descriptor
|
|
392
|
+
DV_BLOB_TYPE_SHM_DESCRIPTOR = 1,
|
|
393
|
+
DV_BLOB_TYPE_FD = 2 # represents blob backed by non-registered file descriptor
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
###############################################################################
|
|
397
|
+
# dvapi_private enum wrappers based on ctypes
|
|
398
|
+
###############################################################################
|
|
399
|
+
|
|
400
|
+
class dv_client_log_level(IntEnum):
|
|
401
|
+
DV_CLIENT_LOG_LEVEL_OFF = 0, # turn of client logs
|
|
402
|
+
DV_CLIENT_LOG_LEVEL_ERROR = 1, # dump only error logs
|
|
403
|
+
DV_CLIENT_LOG_LEVEL_WARN = 2, # dump error and warning logs
|
|
404
|
+
DV_CLIENT_LOG_LEVEL_INFO = 3 # dump error, warning and info logs
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
# ************** dvapi structs **************
|
|
408
|
+
|
|
409
|
+
|
|
410
|
+
class dv_blob(Structure):
|
|
411
|
+
_fields_ = [("handle", c_void_p), # blob handle (raw pointer or shared file id returned by server)
|
|
412
|
+
("offset", c_uint64), # blob offset
|
|
413
|
+
("size", c_uint64), # blob size
|
|
414
|
+
("blob_type", c_int)] # blob type as represented in enum DV_BLOB_TYPE
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
class dv_session_options(Structure):
|
|
418
|
+
_fields_ = [("timeout_ms", c_int)] # global default timeout
|
|
419
|
+
|
|
420
|
+
|
|
421
|
+
class dv_session(Structure):
|
|
422
|
+
_fields_ = [("handle", c_void_p), # session private handle, managed by client library
|
|
423
|
+
# NULL terminated socket connection string
|
|
424
|
+
("socket_str", c_char_p),
|
|
425
|
+
("socket_type", c_int)] # socket types: Unix domain socket/TCPIPv4
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
class dv_endpoint_chip_info(Structure):
|
|
429
|
+
_fields_ = [("id", c_char_p), # dv chip id
|
|
430
|
+
("rev", c_char_p), # dv chip revision
|
|
431
|
+
# dv chip control processor count
|
|
432
|
+
("control_processor_count", c_int),
|
|
433
|
+
# dv chip neural processor count
|
|
434
|
+
("neural_processor_count", c_int),
|
|
435
|
+
("l2_memory_size", c_uint)] # dv chip internal L2 memory size in bytes
|
|
436
|
+
|
|
437
|
+
|
|
438
|
+
class dv_endpoint_dram_info(Structure):
|
|
439
|
+
_fields_ = [("vendor_id", c_uint), # dv dram vendor id
|
|
440
|
+
("vendor_name", c_char_p), # dv dram vendor name
|
|
441
|
+
("size", c_uint), # dv dram memory size in bytes
|
|
442
|
+
("rev_id1", c_ubyte), # dv dram revision id 1
|
|
443
|
+
("rev_id2", c_ubyte), # dv dram revision id 2
|
|
444
|
+
("density", c_ubyte), # dv dram density
|
|
445
|
+
("io_width", c_ubyte)] # dv dram io width
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
class dv_endpoint_iface_info(Structure):
|
|
449
|
+
class dv_endpoint_iface_info_sysfs_path(Union):
|
|
450
|
+
_fields_ = [("pcie_dir", c_char_p)]
|
|
451
|
+
|
|
452
|
+
_fields_ = [("type", c_int), # dv module physical interface (pcie, usb) with host
|
|
453
|
+
# host interface bus number on which dv device is connected
|
|
454
|
+
("bus_num", c_int),
|
|
455
|
+
# host interface device number on which dv device is connected
|
|
456
|
+
("device_num", c_int),
|
|
457
|
+
("sysfs_path", dv_endpoint_iface_info_sysfs_path),
|
|
458
|
+
("port_num", c_int)] # port number for on which USB device is connected
|
|
459
|
+
|
|
460
|
+
|
|
461
|
+
class dv_endpoint_info(Structure):
|
|
462
|
+
_fields_ = [("device_id", c_uint), # dv endpoint device id
|
|
463
|
+
# dv endpoint vendor id
|
|
464
|
+
("vendor_id", c_uint),
|
|
465
|
+
# dv endpoint chip informantion
|
|
466
|
+
("chip", POINTER(dv_endpoint_chip_info)),
|
|
467
|
+
# dv endpoint external dram information
|
|
468
|
+
("dram", POINTER(dv_endpoint_dram_info)),
|
|
469
|
+
# dv endpoint interface information
|
|
470
|
+
("iface", POINTER(dv_endpoint_iface_info)),
|
|
471
|
+
# dv physical module name connected to server
|
|
472
|
+
("module_name", c_char_p),
|
|
473
|
+
# dv endpoint GPIO value0
|
|
474
|
+
("gpio0", c_uint),
|
|
475
|
+
# dv endpoint GPIO value1
|
|
476
|
+
("gpio1", c_uint),
|
|
477
|
+
("device_uid", c_uint)] # dv endpoint GPIO id
|
|
478
|
+
|
|
479
|
+
|
|
480
|
+
class dv_endpoint(Structure):
|
|
481
|
+
_fields_ = [("handle", c_void_p), # endpoint private handle, managed by client library
|
|
482
|
+
# session object
|
|
483
|
+
("session", POINTER(dv_session)),
|
|
484
|
+
# number of endpoints in the group
|
|
485
|
+
("num_ep", c_int),
|
|
486
|
+
# endpoint group type
|
|
487
|
+
("grp_type", c_int),
|
|
488
|
+
("ep_info_list", POINTER(POINTER(dv_endpoint_info)))] # list of configuration for all the endpoint(s) in the group
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
class dv_endpoint_dram_statistics(Structure):
|
|
492
|
+
_fields_ = [("ep", POINTER(dv_endpoint)), # endpoint handle
|
|
493
|
+
# endpoint dram size in bytes
|
|
494
|
+
("ep_total_dram_size", c_uint32),
|
|
495
|
+
# endpoint dram memory occupied in bytes
|
|
496
|
+
("ep_total_dram_occupancy_size", c_uint32),
|
|
497
|
+
# endpoint dram memory free in bytes
|
|
498
|
+
("ep_total_free_size", c_uint32),
|
|
499
|
+
# endpoint dram reserved memory in bytes for firmware
|
|
500
|
+
("ep_total_reserved_occupancy_size", c_uint32),
|
|
501
|
+
# endpoint dram memory occupied by all the active model
|
|
502
|
+
# artefacts in bytes
|
|
503
|
+
("ep_total_model_occupancy_size", c_uint32),
|
|
504
|
+
("ep_total_tensor_occupancy_size", c_uint32)] # endpoint dram memory occupied by all the active model tensors in bytes
|
|
505
|
+
|
|
506
|
+
|
|
507
|
+
class dv_inference_queue_statistics(Structure):
|
|
508
|
+
_fields_ = [("occupancy_count", c_int), # Number of inference queue slots occupied with inference request for the endpoint
|
|
509
|
+
# length of the inference queue for the endpoint
|
|
510
|
+
("length", c_int),
|
|
511
|
+
("wait_time", c_float)] # waiting time in mili secs for the new inference request to get picked up by endpoint
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
class dv_model_statistics(Structure):
|
|
515
|
+
_fields_ = [("model", c_uint32), # model handle
|
|
516
|
+
# number for active model input tensor(s) present in an
|
|
517
|
+
# endpoint
|
|
518
|
+
("active_input_tensors_count", c_uint32),
|
|
519
|
+
# number for active model output tensor(s) present in an
|
|
520
|
+
# endpoint
|
|
521
|
+
("active_output_tensors_count", c_uint32),
|
|
522
|
+
# number for active model inference request queued in an
|
|
523
|
+
# endpoint
|
|
524
|
+
("active_inferences_count", c_uint32),
|
|
525
|
+
# total endpoint dram occupancy in bytes by model artefacts
|
|
526
|
+
("model_total_dram_occupancy_size", c_uint32),
|
|
527
|
+
# total endpoint dram occupancy in bytes by model input tensors
|
|
528
|
+
("model_total_input_tensor_occupancy_size", c_uint32),
|
|
529
|
+
# total endpoint dram occupancy in bytes by model output
|
|
530
|
+
# tensors
|
|
531
|
+
("model_total_output_tensor_occupancy_size", c_uint32),
|
|
532
|
+
("model_handle", c_void_p)] # since r5.3 void* handle which can be compared to `handle` member of dv_model_t
|
|
533
|
+
|
|
534
|
+
|
|
535
|
+
class dv_endpoint_stats(Structure):
|
|
536
|
+
_fields_ = [("ep", POINTER(dv_endpoint)), # endpoint handle
|
|
537
|
+
# endpoint state
|
|
538
|
+
("state", c_int),
|
|
539
|
+
# endpoint system core clock in MHz
|
|
540
|
+
("ep_sys_clk", c_int),
|
|
541
|
+
# endpoint dram clock in MHz
|
|
542
|
+
("ep_dram_clk", c_int),
|
|
543
|
+
# average of endpoint core voltage across all measurement point
|
|
544
|
+
# in hardware in volts
|
|
545
|
+
("ep_core_voltage", c_float),
|
|
546
|
+
# average of endpoint temperature across all measurement point
|
|
547
|
+
# in hardware in degree celsius
|
|
548
|
+
("ep_temp", c_float),
|
|
549
|
+
# number of inference queues available for the endpoint
|
|
550
|
+
("num_inference_queues", c_int),
|
|
551
|
+
# inference queue statistics for the endpoint
|
|
552
|
+
("ep_infq_stats", POINTER(dv_inference_queue_statistics)),
|
|
553
|
+
# number of active models present in endpoint
|
|
554
|
+
("num_active_models", c_int),
|
|
555
|
+
# statistics for all models active on the endpoint
|
|
556
|
+
("model_stats", POINTER(dv_model_statistics)),
|
|
557
|
+
# endpoint dram statistics
|
|
558
|
+
("ep_dram_stats", dv_endpoint_dram_statistics),
|
|
559
|
+
# endpoint power state
|
|
560
|
+
("ep_power_state", c_int),
|
|
561
|
+
("ep_soft_reset_count", c_uint32)] # endpoint soft reset count, non zero for usb devices
|
|
562
|
+
|
|
563
|
+
|
|
564
|
+
class dv_model_input_preprocess_param(Structure):
|
|
565
|
+
_fields_ = [("qn", c_float), # input quantization
|
|
566
|
+
("scale", POINTER(c_float)), # per channel scale
|
|
567
|
+
("mean", POINTER(c_float)), # per channel mean
|
|
568
|
+
# aspect ratio based resize
|
|
569
|
+
("aspect_resize", c_bool),
|
|
570
|
+
("mirror", c_bool), # mirror effect
|
|
571
|
+
("center_crop", c_bool), # center crop
|
|
572
|
+
("bgr_to_rgb", c_bool), # convert BGR to RGB
|
|
573
|
+
# interpolation method supported by OpenCV
|
|
574
|
+
("interpolation", c_int),
|
|
575
|
+
# input range ((-128) - 128)/(0 - 255)
|
|
576
|
+
("is_signed", c_bool),
|
|
577
|
+
("bpp", c_int), # bytes per pixel
|
|
578
|
+
# outputscale for asymmetric
|
|
579
|
+
("output_scale", c_float),
|
|
580
|
+
# aspect resize scaling factor
|
|
581
|
+
("aspect_resize_scale", c_float),
|
|
582
|
+
("offset", c_int), # output offset
|
|
583
|
+
("qmode", c_int)]
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
class dv_model_input_param(Structure):
|
|
587
|
+
_fields_ = [("preprocess_param", POINTER(dv_model_input_preprocess_param)),
|
|
588
|
+
("layer_id", c_int), # input layer id
|
|
589
|
+
("blob_id", c_int), # input blob id
|
|
590
|
+
("layer_name", c_char_p), # input layer name
|
|
591
|
+
("blob_name", c_char_p), # input blob name
|
|
592
|
+
("layer_type", c_char_p), # input layer type
|
|
593
|
+
("layout", c_char_p), # input layer type
|
|
594
|
+
("size", c_int), # tensor size in bytes
|
|
595
|
+
("width", c_int), # tensor width
|
|
596
|
+
("height", c_int), # tensor height
|
|
597
|
+
("depth", c_int), # depth dimension
|
|
598
|
+
("nch", c_int), # number of channels
|
|
599
|
+
("bpp", c_int), # bytes per pixel
|
|
600
|
+
("batch_size", c_int), # batch size
|
|
601
|
+
("num", c_int), # num
|
|
602
|
+
("src_graph_layer_name", c_char_p)] # src_graph_layer_name
|
|
603
|
+
|
|
604
|
+
|
|
605
|
+
class dv_model_output_postprocess_param(Structure):
|
|
606
|
+
_fields_ = [("qn", c_float), # output quantization parameter
|
|
607
|
+
# output is structured or not
|
|
608
|
+
("is_struct_format", c_bool),
|
|
609
|
+
("is_float", c_bool), # output is float type
|
|
610
|
+
("is_signed", c_bool), # output is signed ot not
|
|
611
|
+
("output_scale", c_float), # outputscale for asymmetric
|
|
612
|
+
("offset", c_int)] # offset for asymmetric
|
|
613
|
+
|
|
614
|
+
|
|
615
|
+
class dv_model_output_param(Structure):
|
|
616
|
+
_fields_ = [("postprocess_param", POINTER(dv_model_output_postprocess_param)),
|
|
617
|
+
("layer_id", c_int), # layer id
|
|
618
|
+
("blob_id", c_int), # blob id
|
|
619
|
+
("fused_parent_id", c_int), # layer fused parent id
|
|
620
|
+
("layer_name", c_char_p), # layer name
|
|
621
|
+
("blob_name", c_char_p), # blob name
|
|
622
|
+
# layer fused parent name
|
|
623
|
+
("layer_fused_parent_name", c_char_p),
|
|
624
|
+
("layer_type", c_char_p), # layer type
|
|
625
|
+
("layout", c_char_p), # layout
|
|
626
|
+
("size", c_int), # layer size in bytes
|
|
627
|
+
("width", c_int), # layer width in pixels
|
|
628
|
+
("height", c_int), # layer height in pixels
|
|
629
|
+
("depth", c_int), # layer depth in pixels
|
|
630
|
+
("nch", c_int), # number of channels
|
|
631
|
+
("bpp", c_int), # bytes per pixel
|
|
632
|
+
# number of classes for which model is trained on
|
|
633
|
+
("num_classes", c_int),
|
|
634
|
+
("layer_output_type", c_int), # output type of layer
|
|
635
|
+
("num", c_int), # num
|
|
636
|
+
("max_dynamic_id", c_int), # max batch id
|
|
637
|
+
("src_graph_layer_name", c_char_p)] # src_graph_layer_name
|
|
638
|
+
|
|
639
|
+
|
|
640
|
+
class dv_compiler_statistics(Structure):
|
|
641
|
+
_fields_ = [("config_name", c_char_p), # DV1 config name, governed on ep system core clock
|
|
642
|
+
# total cycles estimated by compiler
|
|
643
|
+
("cycles", c_float),
|
|
644
|
+
# inference per seconds estimated by compiler
|
|
645
|
+
("ips", c_float),
|
|
646
|
+
("ddr_bandwidth", c_float)] # ep dram estimated by compiler
|
|
647
|
+
|
|
648
|
+
|
|
649
|
+
class dv_model_type(IntEnum):
|
|
650
|
+
DV_MODEL_TYPE_ARA1_CNN = 0, # for ara1 cnn models
|
|
651
|
+
DV_MODEL_TYPE_ARA2_CNN = 1, # for ara2 cnn models
|
|
652
|
+
DV_MODEL_TYPE_ARA2_LLM = 2, # for ara2 dyn quant v1 llm models
|
|
653
|
+
DV_MODEL_TYPE_ARA2_LLM_DYN_V2 = 3 # for ara2 v2 llm models
|
|
654
|
+
|
|
655
|
+
|
|
656
|
+
class dv_model_options(Structure):
|
|
657
|
+
_fields_ = [("model_name", c_char_p), # model name (unused)
|
|
658
|
+
("priority", c_int), # priority of the model
|
|
659
|
+
# if true, the model is cached on disk
|
|
660
|
+
("cache", c_bool),
|
|
661
|
+
# if true, the model load API immediately return \see
|
|
662
|
+
# dv_model_load_wait_for_completion
|
|
663
|
+
("async", c_bool),
|
|
664
|
+
("model_type", c_int)]
|
|
665
|
+
|
|
666
|
+
|
|
667
|
+
class dv_infer_type(IntEnum):
|
|
668
|
+
DV_INFER_TYPE_ARA1_CNN = 0,
|
|
669
|
+
DV_INFER_TYPE_ARA2_CNN = 1,
|
|
670
|
+
DV_INFER_TYPE_LLM_PROMPT_PROCESSING = 2,
|
|
671
|
+
DV_INFER_TYPE_LLM_FOLLOWUP_PROMPT_PROCESSING = 3,
|
|
672
|
+
DV_INFER_TYPE_LLM_TOKEN_GENERATION = 4,
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
class dv_infer_options(Structure):
|
|
676
|
+
_fields_ = [("enable_stats", c_bool),
|
|
677
|
+
("infer_type", c_int),
|
|
678
|
+
("active_tokens", c_uint64),
|
|
679
|
+
("valid_tokens", c_uint32),
|
|
680
|
+
("tokens_to_skip", c_uint32)]
|
|
681
|
+
|
|
682
|
+
|
|
683
|
+
class dv_model_llm_params(Structure):
|
|
684
|
+
_fields_ = [("vocab_size", c_uint32),
|
|
685
|
+
("embedding_size", c_uint32),
|
|
686
|
+
("input_precision", c_uint32),
|
|
687
|
+
("output_precision", c_uint32),
|
|
688
|
+
("max_num_tokens", c_uint32),
|
|
689
|
+
("is_dynamic", c_uint32),
|
|
690
|
+
("num_inputs", c_uint32),
|
|
691
|
+
("pad_token_id", c_uint32),
|
|
692
|
+
("eos_token_id", c_uint32),
|
|
693
|
+
("bos_token_id", c_uint32)]
|
|
694
|
+
|
|
695
|
+
def __str__(self):
|
|
696
|
+
return 'dv_model_llm_params <vocab_size={}, embedding_size={}, input_precision={}, output_precision={}, max_num_tokens={}, is_dynamic={}, num_inputs={}, pad_token_id={}, eos_token_id={}, bos_token_id={}>'.format(
|
|
697
|
+
self.vocab_size, self.embedding_size, self.input_precision, self.output_precision, self.max_num_tokens, self.is_dynamic, self.num_inputs, self.pad_token_id, self.eos_token_id, self.bos_token_id)
|
|
698
|
+
|
|
699
|
+
|
|
700
|
+
class dv_llm_cfg_upd_req(Structure):
|
|
701
|
+
_fields_ = [("top_k", c_uint32),
|
|
702
|
+
("top_p", c_float),
|
|
703
|
+
("temperature", c_float),
|
|
704
|
+
("repetition_penalty", c_float),
|
|
705
|
+
("target_token_post_mcp", c_uint32),
|
|
706
|
+
("target_token_pre_mcp", c_uint32),
|
|
707
|
+
("target_prompt_post_mcp", c_uint32),
|
|
708
|
+
("target_prompt_pre_mcp", c_uint32),
|
|
709
|
+
("draft_token_post_mcp", c_uint32),
|
|
710
|
+
("draft_token_pre_mcp", c_uint32),
|
|
711
|
+
("draft_prompt_post_mcp", c_uint32),
|
|
712
|
+
("draft_prompt_pre_mcp", c_uint32)]
|
|
713
|
+
|
|
714
|
+
|
|
715
|
+
def __str__(self):
|
|
716
|
+
return 'dv_model_llm_params <top_k={}, top_p={:.3f}, temperature={:.3f}, repetition_penalty={}, target_token_post_mcp={}, target_token_pre_mcp={}, target_prompt_post_mcp={}, target_prompt_pre_mcp={}, draft_token_post_mcp={}, draft_token_pre_mcp={}, draft_prompt_post_mcp={}, draft_prompt_pre_mcp={}, >'.format(
|
|
717
|
+
self.top_k, self.top_p, self.temperature, self.repetition_penalty, self.target_token_post_mcp, self.target_token_pre_mcp, self.target_prompt_post_mcp, self.target_prompt_pre_mcp, self.draft_token_post_mcp, self.draft_token_pre_mcp, self.draft_prompt_post_mcp, self.draft_prompt_pre_mcp)
|
|
718
|
+
|
|
719
|
+
|
|
720
|
+
class dv_model(Structure):
|
|
721
|
+
_fields_ = [("handle", c_void_p), # private handle, managed by client library
|
|
722
|
+
# session object
|
|
723
|
+
("session", POINTER(dv_session)),
|
|
724
|
+
# endpoint object
|
|
725
|
+
("endpoint", POINTER(dv_endpoint)),
|
|
726
|
+
# model version as generated by compiler
|
|
727
|
+
("version", c_uint),
|
|
728
|
+
# internal model name as generated by compiler
|
|
729
|
+
("name", c_char_p),
|
|
730
|
+
("model_type", c_int),
|
|
731
|
+
# internal model name as generated by compiler
|
|
732
|
+
("internal_name", c_char_p),
|
|
733
|
+
# number of inputs needed by model
|
|
734
|
+
("num_inputs", c_int),
|
|
735
|
+
# number of output produced by model
|
|
736
|
+
("num_outputs", c_int),
|
|
737
|
+
# model priority as set by user
|
|
738
|
+
("priority", c_int),
|
|
739
|
+
("input_param",
|
|
740
|
+
POINTER(dv_model_input_param)),
|
|
741
|
+
# list of input params
|
|
742
|
+
("output_param",
|
|
743
|
+
POINTER(dv_model_output_param)),
|
|
744
|
+
# list of output params
|
|
745
|
+
("llm_params",
|
|
746
|
+
POINTER(dv_model_llm_params)),
|
|
747
|
+
# list of llm params
|
|
748
|
+
# number of compiler stats config
|
|
749
|
+
("num_compiler_config", c_int),
|
|
750
|
+
("compiler_stats",
|
|
751
|
+
POINTER(dv_compiler_statistics)),
|
|
752
|
+
# list of compiler stats
|
|
753
|
+
# @since r6.0 options used when loading the model
|
|
754
|
+
("model_load_options", POINTER(dv_model_options)),
|
|
755
|
+
("cp_layer", c_bool)]
|
|
756
|
+
|
|
757
|
+
|
|
758
|
+
class c_timespec(Structure):
|
|
759
|
+
_fields_ = [("tv_sec", c_long),
|
|
760
|
+
("tv_nsec", c_long)]
|
|
761
|
+
|
|
762
|
+
|
|
763
|
+
class dv_infer_statistics(Structure):
|
|
764
|
+
_fields_ = [("ep_hw_sys_clk", c_int), # ep hardware system core clock in MHz
|
|
765
|
+
# ep hardware external nnp clock in MHz
|
|
766
|
+
("ep_hw_nnp_clk", c_int),
|
|
767
|
+
# ep hardware external sbp clock in MHz
|
|
768
|
+
("ep_hw_sbp_clk", c_int),
|
|
769
|
+
# ep hardware external dram clock in MHz
|
|
770
|
+
("ep_hw_dram_clk", c_int),
|
|
771
|
+
# total cycles taken to compute inference in hardware,
|
|
772
|
+
# including floating point computation
|
|
773
|
+
("ep_hw_total_inference_cycles", c_uint),
|
|
774
|
+
# cycles taken to compute floating point operation in hardware
|
|
775
|
+
("ep_hw_fp_cycles", c_uint),
|
|
776
|
+
# time taken in mili-seconds to transfer input(s) from host
|
|
777
|
+
# dram to ep hardware dram
|
|
778
|
+
("input_transfer_time", c_float),
|
|
779
|
+
# time taken in mili-seconds to transfer output(s) from ep
|
|
780
|
+
# hardware dram to host dram
|
|
781
|
+
("output_transfer_time", c_float),
|
|
782
|
+
# time taken in mili-seconds to submit inference request to ep
|
|
783
|
+
# hardw
|
|
784
|
+
("ep_queue_submission_time", c_float),
|
|
785
|
+
("cum_replay_cnt", c_uint32),
|
|
786
|
+
("cur_replay_cnt", c_uint32),
|
|
787
|
+
# time stamp when input transfer started
|
|
788
|
+
("input_transfer_start_time_stamp", c_timespec),
|
|
789
|
+
# time stamp when output transfer started
|
|
790
|
+
("output_transfer_start_time_stamp", c_timespec),
|
|
791
|
+
# time stamp when inference went into NNP queue
|
|
792
|
+
("inference_start_time_stamp", c_timespec),
|
|
793
|
+
# time taken for inference execution in microseconds
|
|
794
|
+
("inference_execution_time", c_float),
|
|
795
|
+
("input_ddr_address", c_int32), # input ddr address
|
|
796
|
+
("output_ddr_address", c_int32)] # output ddr address
|
|
797
|
+
|
|
798
|
+
|
|
799
|
+
class dv_infer_llm_info(Structure):
|
|
800
|
+
_fields_ = [("llm_infer_resp_num_valid_tokens", c_uint32)]
|
|
801
|
+
|
|
802
|
+
|
|
803
|
+
class dv_infer_request(Structure):
|
|
804
|
+
_fields_ = [("handle", c_void_p), # private handle, managed by client library
|
|
805
|
+
# session for which inference is submitted
|
|
806
|
+
("session", POINTER(dv_session)),
|
|
807
|
+
# endpoint for which inference is queued.
|
|
808
|
+
("ep_queued", POINTER(dv_endpoint)),
|
|
809
|
+
# when inference request is queued on group of endpoints, this
|
|
810
|
+
# provide endpoint info on which inference is submitted.
|
|
811
|
+
("ep_submitted", POINTER(dv_endpoint)),
|
|
812
|
+
# model handle for inference request
|
|
813
|
+
("model", POINTER(dv_model)),
|
|
814
|
+
# input blob list
|
|
815
|
+
("ip_blob_list", POINTER(dv_blob)),
|
|
816
|
+
# output blob list
|
|
817
|
+
("op_blob_list", POINTER(dv_blob)),
|
|
818
|
+
# inference run status
|
|
819
|
+
("status", c_int),
|
|
820
|
+
("stats", POINTER(dv_infer_statistics)), # inference stats
|
|
821
|
+
("llm_infer_info", POINTER(dv_infer_llm_info))]
|
|
822
|
+
|
|
823
|
+
# ************** dvapi private structs **************
|
|
824
|
+
|
|
825
|
+
|
|
826
|
+
class dv_endpoint_hw_statistics(Structure):
|
|
827
|
+
_fields_ = [("ep", POINTER(dv_endpoint)), # endpoint handle
|
|
828
|
+
# endpoint system core clock in MHz
|
|
829
|
+
("ep_sys_clk", c_int),
|
|
830
|
+
# endpoint dram clock in MHz
|
|
831
|
+
("ep_dram_clk", c_int),
|
|
832
|
+
# endpoint total dram size in bytes
|
|
833
|
+
("ep_dram_size", c_uint),
|
|
834
|
+
# number of voltage measurement points available in hardware
|
|
835
|
+
("num_volt", c_int),
|
|
836
|
+
# list of endpoint voltage readings for all measurement points
|
|
837
|
+
# in volts
|
|
838
|
+
("ep_core_volt", POINTER(c_float)),
|
|
839
|
+
# number of temperature measurement points available in
|
|
840
|
+
# hardware
|
|
841
|
+
("num_temp", c_int),
|
|
842
|
+
("ep_temp", POINTER(c_float))] # list of endpoint temperature readings for all measurement points in degree celsius
|
|
843
|
+
|
|
844
|
+
|
|
845
|
+
class dv_request_options(Structure):
|
|
846
|
+
# timeout in milliseconds for synchronous request
|
|
847
|
+
_fields_ = [("timeout_ms", c_int)]
|
|
848
|
+
|
|
849
|
+
|
|
850
|
+
class dv_endpoint_takedown_options(Structure):
|
|
851
|
+
# proxy API request options
|
|
852
|
+
_fields_ = [("request_options", dv_request_options)]
|
|
853
|
+
|
|
854
|
+
|
|
855
|
+
###############################################################################
|
|
856
|
+
# dvapi function wrappers based on ctypes
|
|
857
|
+
###############################################################################
|
|
858
|
+
def dv_stringify_status_code(status_code):
|
|
859
|
+
"""
|
|
860
|
+
Parameters
|
|
861
|
+
----------
|
|
862
|
+
dv_status_code
|
|
863
|
+
|
|
864
|
+
Returns
|
|
865
|
+
-------
|
|
866
|
+
string
|
|
867
|
+
stringified status code
|
|
868
|
+
"""
|
|
869
|
+
fun = _dvApiObj().dv_stringify_status_code
|
|
870
|
+
fun.argtypes = [c_int]
|
|
871
|
+
fun.restype = c_char_p
|
|
872
|
+
s = fun(status_code)
|
|
873
|
+
return s.decode("utf8")
|
|
874
|
+
|
|
875
|
+
|
|
876
|
+
def _glibc_free(ctypes_ptr):
|
|
877
|
+
fun = _dvApiObj().free
|
|
878
|
+
fun.argtypes = [c_void_p]
|
|
879
|
+
fun.restype = None
|
|
880
|
+
fun(ctypes_ptr)
|
|
881
|
+
|
|
882
|
+
|
|
883
|
+
def dv_model_set_llm_cfg_params(session: dv_session, endpoint: dv_endpoint,
|
|
884
|
+
model: dv_model, llm_cfg_update: dv_llm_cfg_upd_req) -> dv_status_code:
|
|
885
|
+
fun = _dvApiObj().dv_model_set_llm_cfg_params
|
|
886
|
+
fun.argtypes = [
|
|
887
|
+
POINTER(dv_session),
|
|
888
|
+
POINTER(dv_endpoint),
|
|
889
|
+
POINTER(dv_model),
|
|
890
|
+
POINTER(dv_llm_cfg_upd_req)]
|
|
891
|
+
fun.restype = dv_status_code
|
|
892
|
+
ret = fun(session, endpoint, model, llm_cfg_update)
|
|
893
|
+
return ret
|
|
894
|
+
|
|
895
|
+
|
|
896
|
+
def dv_session_create_via_unix_socket(socket_path):
|
|
897
|
+
""" connects to the proxy via unix socket
|
|
898
|
+
|
|
899
|
+
Parameters
|
|
900
|
+
----------
|
|
901
|
+
socket_path : str
|
|
902
|
+
path to the unix socket
|
|
903
|
+
|
|
904
|
+
Returns
|
|
905
|
+
-------
|
|
906
|
+
(dv_status_code, dv_session)
|
|
907
|
+
DV_SUCCESS, dv_session if the connection was successfully established
|
|
908
|
+
if the status is not DV_SUCCESS, dv_session is invalid
|
|
909
|
+
"""
|
|
910
|
+
fun = _dvApiObj().dv_session_create_via_unix_socket
|
|
911
|
+
fun.argtypes = [c_char_p, POINTER(POINTER(dv_session))]
|
|
912
|
+
fun.restype = dv_status_code
|
|
913
|
+
session = POINTER(dv_session)()
|
|
914
|
+
ret = fun(socket_path.encode('utf-8'), byref(session))
|
|
915
|
+
return ret, session
|
|
916
|
+
|
|
917
|
+
|
|
918
|
+
def dv_session_create_via_tcp_ipv4_socket(ipv4_addr, port):
|
|
919
|
+
""" connects to the proxy over the network
|
|
920
|
+
|
|
921
|
+
Parameters
|
|
922
|
+
----------
|
|
923
|
+
ip_addr : str
|
|
924
|
+
IPv4 address to connect to
|
|
925
|
+
|
|
926
|
+
port : int
|
|
927
|
+
Port number proxy is listening on
|
|
928
|
+
|
|
929
|
+
Returns
|
|
930
|
+
-------
|
|
931
|
+
(dv_status_code, dv_session)
|
|
932
|
+
DV_SUCCESS, dv_session if the connection was successfully established
|
|
933
|
+
if the status is not DV_SUCCESS, dv_session is invalid
|
|
934
|
+
"""
|
|
935
|
+
fun = _dvApiObj().dv_session_create_via_tcp_ipv4_socket
|
|
936
|
+
fun.argtypes = [c_char_p, c_uint, POINTER(POINTER(dv_session))]
|
|
937
|
+
fun.restype = dv_status_code
|
|
938
|
+
session = POINTER(dv_session)()
|
|
939
|
+
ret = fun(ipv4_addr.encode('utf-8'), c_uint(port), byref(session))
|
|
940
|
+
return ret, session
|
|
941
|
+
|
|
942
|
+
|
|
943
|
+
def dv_session_close(session):
|
|
944
|
+
""" closes connection `dv_session` to the proxy
|
|
945
|
+
|
|
946
|
+
Parameters
|
|
947
|
+
----------
|
|
948
|
+
|
|
949
|
+
session : dv_session
|
|
950
|
+
dv_session object returned by initial dv_session_create_* call
|
|
951
|
+
|
|
952
|
+
Returns
|
|
953
|
+
-------
|
|
954
|
+
dv_status_code
|
|
955
|
+
dv_status_code.DV_SUCCESS if successful
|
|
956
|
+
"""
|
|
957
|
+
fun = _dvApiObj().dv_session_close
|
|
958
|
+
fun.argtypes = [POINTER(dv_session)]
|
|
959
|
+
fun.restype = dv_status_code
|
|
960
|
+
return fun(session)
|
|
961
|
+
|
|
962
|
+
|
|
963
|
+
def dv_endpoint_get_list(session):
|
|
964
|
+
""" returns a list of endpoints that are enumerated by the connected proxy
|
|
965
|
+
|
|
966
|
+
Parameters
|
|
967
|
+
----------
|
|
968
|
+
session : dv_session
|
|
969
|
+
client session
|
|
970
|
+
|
|
971
|
+
Returns
|
|
972
|
+
-------
|
|
973
|
+
(dv_status_code, dv_endpoint, count)
|
|
974
|
+
error status, list of endpoints connected, num connected endpoints
|
|
975
|
+
if error status is not DV_SUCCESS, the list will be None
|
|
976
|
+
"""
|
|
977
|
+
fun = _dvApiObj().dv_endpoint_get_list
|
|
978
|
+
fun.argtypes = [
|
|
979
|
+
POINTER(dv_session),
|
|
980
|
+
POINTER(
|
|
981
|
+
POINTER(dv_endpoint)),
|
|
982
|
+
POINTER(c_int)]
|
|
983
|
+
fun.restype = dv_status_code
|
|
984
|
+
|
|
985
|
+
count = c_int()
|
|
986
|
+
eplist = POINTER(dv_endpoint)()
|
|
987
|
+
ret = fun(session, byref(eplist), byref(count))
|
|
988
|
+
|
|
989
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
990
|
+
return ret, None, 0
|
|
991
|
+
|
|
992
|
+
return ret, eplist, count
|
|
993
|
+
|
|
994
|
+
|
|
995
|
+
def dv_endpoint_get_default_group(session, ep_default_grp):
|
|
996
|
+
""" get default endpoint group created by client
|
|
997
|
+
|
|
998
|
+
Parameters
|
|
999
|
+
----------
|
|
1000
|
+
session : dv_session
|
|
1001
|
+
session
|
|
1002
|
+
|
|
1003
|
+
ep_default_grp : dv_endpoint
|
|
1004
|
+
|
|
1005
|
+
Returns
|
|
1006
|
+
-------
|
|
1007
|
+
(dv_status_code, dv_endpoint)
|
|
1008
|
+
status code and endpoint handle of the created default endpoint group
|
|
1009
|
+
"""
|
|
1010
|
+
|
|
1011
|
+
fun = _dvApiObj().dv_endpoint_get_default_group
|
|
1012
|
+
fun.argtypes = [POINTER(dv_session), c_int, POINTER(POINTER(dv_endpoint))]
|
|
1013
|
+
fun.restype = dv_status_code
|
|
1014
|
+
|
|
1015
|
+
ep_grp = POINTER(dv_endpoint)()
|
|
1016
|
+
ret = fun(session, ep_default_grp, byref(ep_grp))
|
|
1017
|
+
|
|
1018
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1019
|
+
return ret, None
|
|
1020
|
+
|
|
1021
|
+
return ret, ep_grp
|
|
1022
|
+
|
|
1023
|
+
|
|
1024
|
+
def dv_endpoint_create_group(session, ep_list, ep_count):
|
|
1025
|
+
""" create a custom group from the endpoint list
|
|
1026
|
+
|
|
1027
|
+
Parameters
|
|
1028
|
+
----------
|
|
1029
|
+
session : dv_session
|
|
1030
|
+
session
|
|
1031
|
+
ep_list : dv_endpoint
|
|
1032
|
+
list of endpoints
|
|
1033
|
+
ep_count : dv_endpoint
|
|
1034
|
+
number of endpoints in the list
|
|
1035
|
+
|
|
1036
|
+
Returns
|
|
1037
|
+
-------
|
|
1038
|
+
(dv_status_code, dv_endpoint)
|
|
1039
|
+
status code and endpoint handle of the created custom endpoint group
|
|
1040
|
+
"""
|
|
1041
|
+
|
|
1042
|
+
fun = _dvApiObj().dv_endpoint_create_group
|
|
1043
|
+
fun.argtypes = [
|
|
1044
|
+
POINTER(dv_session), POINTER(
|
|
1045
|
+
POINTER(dv_endpoint)), c_int, POINTER(
|
|
1046
|
+
POINTER(dv_endpoint))]
|
|
1047
|
+
fun.restype = dv_status_code
|
|
1048
|
+
ep_grp = POINTER(dv_endpoint)()
|
|
1049
|
+
ep_list_array = (POINTER(dv_endpoint) * ep_count)(*
|
|
1050
|
+
[pointer(s) for s in ep_list])
|
|
1051
|
+
ret = fun(session, ep_list_array, c_int(ep_count), byref(ep_grp))
|
|
1052
|
+
|
|
1053
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1054
|
+
return ret, None
|
|
1055
|
+
|
|
1056
|
+
return ret, ep_grp
|
|
1057
|
+
|
|
1058
|
+
|
|
1059
|
+
def dv_endpoint_free_group(ep_grp):
|
|
1060
|
+
""" free the endpoint group created from dv_endpoint_create_group
|
|
1061
|
+
|
|
1062
|
+
Parameters
|
|
1063
|
+
----------
|
|
1064
|
+
ep_grp : dv_endpoint
|
|
1065
|
+
endpoint group
|
|
1066
|
+
|
|
1067
|
+
Returns
|
|
1068
|
+
-------
|
|
1069
|
+
dv_status_code
|
|
1070
|
+
status == DV_SUCCESS on pass
|
|
1071
|
+
"""
|
|
1072
|
+
fun = _dvApiObj().dv_endpoint_free_group
|
|
1073
|
+
fun.argtypes = [POINTER(dv_endpoint)]
|
|
1074
|
+
fun.restype = dv_status_code
|
|
1075
|
+
|
|
1076
|
+
return fun(ep_grp)
|
|
1077
|
+
|
|
1078
|
+
|
|
1079
|
+
def dv_model_load_from_file(session, ep, model_path, model_name, priority):
|
|
1080
|
+
""" loads a model onto the device from the provided file path
|
|
1081
|
+
|
|
1082
|
+
Parameters
|
|
1083
|
+
----------
|
|
1084
|
+
|
|
1085
|
+
session : dv_session
|
|
1086
|
+
connected client session
|
|
1087
|
+
|
|
1088
|
+
ep : dv_endpoint
|
|
1089
|
+
endpoint on which to load the model
|
|
1090
|
+
|
|
1091
|
+
model_path : str
|
|
1092
|
+
path to the model on filesystem
|
|
1093
|
+
|
|
1094
|
+
model_name : str
|
|
1095
|
+
a reference name to be assigned to the model
|
|
1096
|
+
|
|
1097
|
+
priority : int
|
|
1098
|
+
priority of the model
|
|
1099
|
+
|
|
1100
|
+
Returns
|
|
1101
|
+
-------
|
|
1102
|
+
(dv_status_code, dv_model)
|
|
1103
|
+
an error status and the model handle. if the error status is not
|
|
1104
|
+
DV_SUCCESS, dv_model_handle is invalid
|
|
1105
|
+
"""
|
|
1106
|
+
fun = _dvApiObj().dv_model_load_from_file
|
|
1107
|
+
fun.argtypes = [
|
|
1108
|
+
POINTER(dv_session),
|
|
1109
|
+
POINTER(dv_endpoint),
|
|
1110
|
+
c_char_p,
|
|
1111
|
+
c_char_p,
|
|
1112
|
+
c_int,
|
|
1113
|
+
POINTER(POINTER(dv_model))]
|
|
1114
|
+
|
|
1115
|
+
fun.restype = dv_status_code
|
|
1116
|
+
|
|
1117
|
+
model = POINTER(dv_model)()
|
|
1118
|
+
|
|
1119
|
+
ret = fun(session,
|
|
1120
|
+
ep,
|
|
1121
|
+
model_path.encode('utf-8'),
|
|
1122
|
+
model_name.encode('utf-8'),
|
|
1123
|
+
priority,
|
|
1124
|
+
byref(model))
|
|
1125
|
+
|
|
1126
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1127
|
+
return ret, None
|
|
1128
|
+
|
|
1129
|
+
return ret, model
|
|
1130
|
+
|
|
1131
|
+
|
|
1132
|
+
def dv_model_load_from_blob(session, ep, model_blob, model_name, priority):
|
|
1133
|
+
""" loads a model onto the device from the provided file path
|
|
1134
|
+
|
|
1135
|
+
Parameters
|
|
1136
|
+
----------
|
|
1137
|
+
|
|
1138
|
+
session : dv_session
|
|
1139
|
+
connected client session
|
|
1140
|
+
|
|
1141
|
+
ep : dv_endpoint
|
|
1142
|
+
endpoint on which to load the model
|
|
1143
|
+
|
|
1144
|
+
model_blob : dv_blob
|
|
1145
|
+
model blob
|
|
1146
|
+
|
|
1147
|
+
model_name : str
|
|
1148
|
+
a reference name to be assigned to the model
|
|
1149
|
+
|
|
1150
|
+
priority : int
|
|
1151
|
+
priority of the model
|
|
1152
|
+
|
|
1153
|
+
enable_caching : bool
|
|
1154
|
+
indicaes if the model should be cached by the server.
|
|
1155
|
+
API call fails if the model could not be cached by the server
|
|
1156
|
+
|
|
1157
|
+
Returns
|
|
1158
|
+
-------
|
|
1159
|
+
(dv_status_code, dv_model_handle)
|
|
1160
|
+
an error status and the model handle. if the error status is not
|
|
1161
|
+
DV_SUCCESS, dv_model_handle is invalid
|
|
1162
|
+
"""
|
|
1163
|
+
|
|
1164
|
+
fun = _dvApiObj().dv_model_load_from_blob
|
|
1165
|
+
fun.argtypes = [
|
|
1166
|
+
POINTER(dv_session),
|
|
1167
|
+
POINTER(dv_endpoint),
|
|
1168
|
+
POINTER(dv_blob),
|
|
1169
|
+
c_char_p,
|
|
1170
|
+
c_int,
|
|
1171
|
+
POINTER(POINTER(dv_model))]
|
|
1172
|
+
|
|
1173
|
+
fun.restype = dv_status_code
|
|
1174
|
+
|
|
1175
|
+
model = POINTER(dv_model)()
|
|
1176
|
+
|
|
1177
|
+
ret = fun(session,
|
|
1178
|
+
ep,
|
|
1179
|
+
model_blob,
|
|
1180
|
+
model_name.encode('utf-8'),
|
|
1181
|
+
priority,
|
|
1182
|
+
byref(model))
|
|
1183
|
+
|
|
1184
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1185
|
+
return ret, None
|
|
1186
|
+
|
|
1187
|
+
return ret, model
|
|
1188
|
+
|
|
1189
|
+
|
|
1190
|
+
def dv_model_unload(model):
|
|
1191
|
+
""" unloads model from the dvinfproxy
|
|
1192
|
+
|
|
1193
|
+
Parameters
|
|
1194
|
+
----------
|
|
1195
|
+
model : dv_model
|
|
1196
|
+
model handle returned by dv_model_load*
|
|
1197
|
+
|
|
1198
|
+
Returns
|
|
1199
|
+
-------
|
|
1200
|
+
dv_status_code
|
|
1201
|
+
DV_SUCCESS if the unload was successful
|
|
1202
|
+
"""
|
|
1203
|
+
fun = _dvApiObj().dv_model_unload
|
|
1204
|
+
fun.argtypes = [POINTER(dv_model)]
|
|
1205
|
+
fun.restype = dv_status_code
|
|
1206
|
+
return fun(model)
|
|
1207
|
+
|
|
1208
|
+
|
|
1209
|
+
class dvBoxOutput(Structure):
|
|
1210
|
+
""" ctypes mapping to `struct BoxOutput` defined in `dvoutstruct.h` """
|
|
1211
|
+
_fields_ = [("xmin", c_float),
|
|
1212
|
+
("ymin", c_float),
|
|
1213
|
+
("xmax", c_float),
|
|
1214
|
+
("ymax", c_float),
|
|
1215
|
+
("imageId", c_uint),
|
|
1216
|
+
("label", c_uint),
|
|
1217
|
+
("score", c_float)]
|
|
1218
|
+
|
|
1219
|
+
def __str__(self):
|
|
1220
|
+
return 'dvBoxOutput<xmin={:.3f}, ymin={:.3f}, xmax={:.3f}, ymax={:.3f}, imageId={}, label={}, score={:.3f}>'.format(
|
|
1221
|
+
self.xmin, self.ymin, self.xmax, self.ymax, self.imageId, self.label, self.score)
|
|
1222
|
+
|
|
1223
|
+
|
|
1224
|
+
class dvDetectionOutput(Structure):
|
|
1225
|
+
""" ctypes mapping to `struct DetectionOutput` defined in `dvoutstruct.h` """
|
|
1226
|
+
|
|
1227
|
+
_fields_ = [("numBoxesDetected", c_uint),
|
|
1228
|
+
("detectedBoxes", dvBoxOutput * 200)]
|
|
1229
|
+
|
|
1230
|
+
|
|
1231
|
+
class dvClassificationItem(Structure):
|
|
1232
|
+
""" ctypes mapping to `struct ClassificationItem` defined in `dvoutstruct.h` """
|
|
1233
|
+
|
|
1234
|
+
_fields_ = [("label", c_uint),
|
|
1235
|
+
("score", c_float)]
|
|
1236
|
+
|
|
1237
|
+
def __str__(self):
|
|
1238
|
+
return 'dvClassificationItem<label={}, score={:.3f}>'.format(
|
|
1239
|
+
self.label, self.score)
|
|
1240
|
+
|
|
1241
|
+
|
|
1242
|
+
class dvClassificationOutput(Structure):
|
|
1243
|
+
""" ctypes mapping to `struct ClassificationOutput` defined in `dvoutstruct.h` """
|
|
1244
|
+
|
|
1245
|
+
_fields_ = [("numOutputs", c_uint),
|
|
1246
|
+
("rows", dvClassificationItem * 10)]
|
|
1247
|
+
|
|
1248
|
+
|
|
1249
|
+
"""
|
|
1250
|
+
Deprecated since, 7.2.
|
|
1251
|
+
Instead use DVModel level API i.e., infer_sync.
|
|
1252
|
+
"""
|
|
1253
|
+
|
|
1254
|
+
|
|
1255
|
+
def dv_infer_sync(session, endpoint, model, inputs,
|
|
1256
|
+
outputs, timeout, enable_stats=True):
|
|
1257
|
+
""" submits a synchronous inference request with timeout
|
|
1258
|
+
|
|
1259
|
+
Parameters
|
|
1260
|
+
----------
|
|
1261
|
+
session : dv_session
|
|
1262
|
+
|
|
1263
|
+
endpoint : dv_endpoint
|
|
1264
|
+
|
|
1265
|
+
model : dv_model
|
|
1266
|
+
|
|
1267
|
+
inputs : contiguous dvIoTensorBlob
|
|
1268
|
+
pointers buffers that contain the inputs, this must contain pointers
|
|
1269
|
+
to each input in order, pointer at index 0 will be used to read data
|
|
1270
|
+
for the 1st input etc...
|
|
1271
|
+
|
|
1272
|
+
outputs : contiguous dvIoTensorBlob
|
|
1273
|
+
ptrs to where outputs of the inference are written, this list must be
|
|
1274
|
+
in order, ie 1st output is written to the pointer at index 0, 2nd output
|
|
1275
|
+
is written to the pointer at index 1 etc..
|
|
1276
|
+
|
|
1277
|
+
timeout : int
|
|
1278
|
+
timeout in ms
|
|
1279
|
+
|
|
1280
|
+
Warnings
|
|
1281
|
+
--------
|
|
1282
|
+
Please ensure that the object backing the ctypes.c_void_p are not allowed to
|
|
1283
|
+
be refcounted or garbage collected - if the pointer becomes invalid during
|
|
1284
|
+
operation, the runtime will segfault
|
|
1285
|
+
|
|
1286
|
+
Returns
|
|
1287
|
+
-------
|
|
1288
|
+
(dv_status_code, inf_request_id)
|
|
1289
|
+
DV_SUCCESS, inf_request_id if the inference was completed successfully
|
|
1290
|
+
else, inf_request_id is invalid
|
|
1291
|
+
"""
|
|
1292
|
+
fun = _dvApiObj().dv_infer_sync
|
|
1293
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1294
|
+
POINTER(dv_endpoint),
|
|
1295
|
+
POINTER(dv_model),
|
|
1296
|
+
POINTER(dv_blob),
|
|
1297
|
+
POINTER(dv_blob),
|
|
1298
|
+
c_int,
|
|
1299
|
+
c_bool,
|
|
1300
|
+
POINTER(POINTER(dv_infer_request))]
|
|
1301
|
+
|
|
1302
|
+
fun.restype = dv_status_code
|
|
1303
|
+
|
|
1304
|
+
inf_request = POINTER(dv_infer_request)()
|
|
1305
|
+
|
|
1306
|
+
ret = fun(session,
|
|
1307
|
+
endpoint,
|
|
1308
|
+
model,
|
|
1309
|
+
cast(inputs, POINTER(dv_blob)),
|
|
1310
|
+
cast(outputs, POINTER(dv_blob)),
|
|
1311
|
+
c_int(timeout),
|
|
1312
|
+
c_bool(enable_stats),
|
|
1313
|
+
byref(inf_request))
|
|
1314
|
+
|
|
1315
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1316
|
+
return ret, None
|
|
1317
|
+
|
|
1318
|
+
return ret, inf_request
|
|
1319
|
+
|
|
1320
|
+
|
|
1321
|
+
def dv_infer_async(session, endpoint, model, inputs,
|
|
1322
|
+
outputs, enable_stats=True):
|
|
1323
|
+
""" submits an asynchronous inference request with timeout
|
|
1324
|
+
|
|
1325
|
+
Parameters
|
|
1326
|
+
----------
|
|
1327
|
+
session : dv_session
|
|
1328
|
+
|
|
1329
|
+
endpoint : dv_endpoint
|
|
1330
|
+
|
|
1331
|
+
model : dv_model
|
|
1332
|
+
|
|
1333
|
+
inputs : list of ctypes.c_void_p
|
|
1334
|
+
pointers buffers that contain the inputs, this must contain pointers
|
|
1335
|
+
to each input in order, pointer at index 0 will be used to read data
|
|
1336
|
+
for the 1st input etc...
|
|
1337
|
+
|
|
1338
|
+
outputs : list of ctypes.c_void_p
|
|
1339
|
+
ptrs to where outputs of the inference are written, this list must be
|
|
1340
|
+
in order, ie 1st output is written to the pointer at index 0, 2nd output
|
|
1341
|
+
is written to the pointer at index 1 etc..
|
|
1342
|
+
|
|
1343
|
+
Warnings
|
|
1344
|
+
--------
|
|
1345
|
+
Please ensure that the object backing the ctypes.c_void_p are not allowed to
|
|
1346
|
+
be refcounted and freed or garbage collected - if the pointer becomes invalid
|
|
1347
|
+
while a response is being written to the ptr the runtime will segfault
|
|
1348
|
+
|
|
1349
|
+
Returns
|
|
1350
|
+
-------
|
|
1351
|
+
(dv_status_code, inf_request_id)
|
|
1352
|
+
DV_SUCCESS, inf_request_id if the inference was submitted successfully
|
|
1353
|
+
to the inference proxy else, inf_request_id is invalid
|
|
1354
|
+
"""
|
|
1355
|
+
fun = _dvApiObj().dv_infer_async
|
|
1356
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1357
|
+
POINTER(dv_endpoint),
|
|
1358
|
+
POINTER(dv_model),
|
|
1359
|
+
POINTER(dv_blob),
|
|
1360
|
+
POINTER(dv_blob),
|
|
1361
|
+
c_bool,
|
|
1362
|
+
POINTER(POINTER(dv_infer_request))]
|
|
1363
|
+
fun.restype = dv_status_code
|
|
1364
|
+
inf_request = POINTER(dv_infer_request)()
|
|
1365
|
+
ret = fun(session,
|
|
1366
|
+
endpoint,
|
|
1367
|
+
model,
|
|
1368
|
+
cast(inputs, POINTER(dv_blob)),
|
|
1369
|
+
cast(outputs, POINTER(dv_blob)),
|
|
1370
|
+
c_bool(enable_stats),
|
|
1371
|
+
byref(inf_request))
|
|
1372
|
+
|
|
1373
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1374
|
+
return ret, None
|
|
1375
|
+
|
|
1376
|
+
return ret, inf_request
|
|
1377
|
+
|
|
1378
|
+
|
|
1379
|
+
def dv_infer_sync_with_flags(
|
|
1380
|
+
session, endpoint, model, inputs, outputs, timeout, options, enable_stats=True):
|
|
1381
|
+
fun = _dvApiObj().dv_infer_sync_with_flags
|
|
1382
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1383
|
+
POINTER(dv_endpoint),
|
|
1384
|
+
POINTER(dv_model),
|
|
1385
|
+
POINTER(dv_blob),
|
|
1386
|
+
POINTER(dv_blob),
|
|
1387
|
+
c_int,
|
|
1388
|
+
c_bool,
|
|
1389
|
+
POINTER(POINTER(dv_infer_request)),
|
|
1390
|
+
c_uint16]
|
|
1391
|
+
|
|
1392
|
+
fun.restype = dv_status_code
|
|
1393
|
+
inf_request = POINTER(dv_infer_request)()
|
|
1394
|
+
ret = fun(session,
|
|
1395
|
+
endpoint,
|
|
1396
|
+
model,
|
|
1397
|
+
cast(inputs, POINTER(dv_blob)),
|
|
1398
|
+
cast(outputs, POINTER(dv_blob)),
|
|
1399
|
+
c_int(timeout),
|
|
1400
|
+
c_bool(enable_stats),
|
|
1401
|
+
byref(inf_request),
|
|
1402
|
+
c_uint16(options))
|
|
1403
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1404
|
+
return ret, None
|
|
1405
|
+
return ret, inf_request
|
|
1406
|
+
|
|
1407
|
+
# def dv_infer_wait_for_completion(session, inf_list, timeout) ->
|
|
1408
|
+
# tuple[dv_status_code ,dv_infer_request] : # fixme::typing hint giving
|
|
1409
|
+
# error
|
|
1410
|
+
|
|
1411
|
+
|
|
1412
|
+
def dv_infer_wait_for_completion(session, inf_list, timeout):
|
|
1413
|
+
""" blocking call that waits for inference to reach a final state
|
|
1414
|
+
|
|
1415
|
+
Parameters
|
|
1416
|
+
----------
|
|
1417
|
+
session : dv_session
|
|
1418
|
+
|
|
1419
|
+
inf_id : dv_infer_request
|
|
1420
|
+
|
|
1421
|
+
timeout : int
|
|
1422
|
+
timeout in milliseconds
|
|
1423
|
+
|
|
1424
|
+
Returns
|
|
1425
|
+
-------
|
|
1426
|
+
dv_status_code
|
|
1427
|
+
|
|
1428
|
+
"""
|
|
1429
|
+
fun = _dvApiObj().dv_infer_wait_for_completion
|
|
1430
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1431
|
+
POINTER(POINTER(dv_infer_request)),
|
|
1432
|
+
c_int,
|
|
1433
|
+
c_int,
|
|
1434
|
+
POINTER(POINTER(dv_infer_request))]
|
|
1435
|
+
fun.restype = dv_status_code
|
|
1436
|
+
|
|
1437
|
+
completed_req = POINTER(dv_infer_request)()
|
|
1438
|
+
|
|
1439
|
+
status = fun(
|
|
1440
|
+
session,
|
|
1441
|
+
byref(inf_list),
|
|
1442
|
+
c_int(1),
|
|
1443
|
+
c_int(timeout),
|
|
1444
|
+
byref(completed_req))
|
|
1445
|
+
|
|
1446
|
+
return status, completed_req
|
|
1447
|
+
|
|
1448
|
+
|
|
1449
|
+
def dv_infer_get_req_id(infer_req):
|
|
1450
|
+
"""
|
|
1451
|
+
Returns the status code and request id of an inference
|
|
1452
|
+
|
|
1453
|
+
If return value is DV_SUCCESS req_id will contain the request id of the
|
|
1454
|
+
inference request sent to kinara inference proxy
|
|
1455
|
+
|
|
1456
|
+
Returns
|
|
1457
|
+
-------
|
|
1458
|
+
dv_status_code : SUCCESS or FAILURE code
|
|
1459
|
+
int : req_id
|
|
1460
|
+
"""
|
|
1461
|
+
fun = _dvApiObj().dv_infer_get_req_id
|
|
1462
|
+
fun.argtypes = [POINTER(dv_infer_request), POINTER(c_uint)]
|
|
1463
|
+
fun.restype = dv_status_code
|
|
1464
|
+
req_id = c_uint()
|
|
1465
|
+
status = fun(infer_req, byref(req_id))
|
|
1466
|
+
return status, req_id
|
|
1467
|
+
|
|
1468
|
+
|
|
1469
|
+
def dv_infer_free(inf_req_obj):
|
|
1470
|
+
fun = _dvApiObj().dv_infer_free
|
|
1471
|
+
fun.argtypes = [POINTER(dv_infer_request)]
|
|
1472
|
+
fun.restype = dv_status_code
|
|
1473
|
+
|
|
1474
|
+
return fun(inf_req_obj)
|
|
1475
|
+
|
|
1476
|
+
|
|
1477
|
+
def dv_infer_get_inflight_count(session):
|
|
1478
|
+
""" Returns the number of inflight inference requests for the session
|
|
1479
|
+
object for which the client library has not recieved a response from
|
|
1480
|
+
the proxy server
|
|
1481
|
+
|
|
1482
|
+
Parameters
|
|
1483
|
+
----------
|
|
1484
|
+
session : dv_session
|
|
1485
|
+
|
|
1486
|
+
Returns
|
|
1487
|
+
-------
|
|
1488
|
+
dv_status_code
|
|
1489
|
+
|
|
1490
|
+
count: c_int
|
|
1491
|
+
number of inference requests in flight
|
|
1492
|
+
|
|
1493
|
+
"""
|
|
1494
|
+
fun = _dvApiObj().dv_infer_get_inflight_count
|
|
1495
|
+
fun.argtypes = [POINTER(dv_session), POINTER(c_int)]
|
|
1496
|
+
fun.restype = dv_status_code
|
|
1497
|
+
count = c_int()
|
|
1498
|
+
status = fun(session, byref(count))
|
|
1499
|
+
return status, count
|
|
1500
|
+
|
|
1501
|
+
|
|
1502
|
+
def dv_infer_sync_with_options(session: dv_session, endpoint: dv_endpoint, model: dv_model,
|
|
1503
|
+
inputs, outputs, timeout_ms: int, infer_options: dv_infer_options):
|
|
1504
|
+
""" submits an asynchronous inference request with timeout
|
|
1505
|
+
|
|
1506
|
+
Parameters
|
|
1507
|
+
----------
|
|
1508
|
+
session : dv_session
|
|
1509
|
+
|
|
1510
|
+
endpoint : dv_endpoint
|
|
1511
|
+
|
|
1512
|
+
model : dv_model
|
|
1513
|
+
inputs : list of DVBlob
|
|
1514
|
+
pointers buffers that contain the inputs, this must contain pointers
|
|
1515
|
+
to each input in order, pointer at index 0 will be used to read data
|
|
1516
|
+
for the 1st input etc...
|
|
1517
|
+
|
|
1518
|
+
outputs : list of DVBlob
|
|
1519
|
+
ptrs to where outputs of the inference are written, this list must be
|
|
1520
|
+
in order, ie 1st output is written to the pointer at index 0, 2nd output
|
|
1521
|
+
is written to the pointer at index 1 etc..
|
|
1522
|
+
|
|
1523
|
+
Warnings
|
|
1524
|
+
--------
|
|
1525
|
+
Please ensure that the object backing the ctypes.c_void_p are not allowed to
|
|
1526
|
+
be refcounted and freed or garbage collected - if the pointer becomes invalid
|
|
1527
|
+
while a response is being written to the ptr the runtime will segfault
|
|
1528
|
+
|
|
1529
|
+
Returns
|
|
1530
|
+
-------
|
|
1531
|
+
(dv_status_code, inf_request_id)
|
|
1532
|
+
DV_SUCCESS, inf_request_id if the inference was submitted successfully
|
|
1533
|
+
to the inference proxy else, inf_request_id is invalid
|
|
1534
|
+
"""
|
|
1535
|
+
|
|
1536
|
+
fun = _dvApiObj().dv_infer_sync_with_options
|
|
1537
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1538
|
+
POINTER(dv_endpoint),
|
|
1539
|
+
POINTER(dv_model),
|
|
1540
|
+
POINTER(dv_blob),
|
|
1541
|
+
POINTER(dv_blob),
|
|
1542
|
+
c_int,
|
|
1543
|
+
POINTER(POINTER(dv_infer_request)),
|
|
1544
|
+
POINTER(dv_infer_options)]
|
|
1545
|
+
|
|
1546
|
+
fun.restype = dv_status_code
|
|
1547
|
+
inf_request = POINTER(dv_infer_request)()
|
|
1548
|
+
ret = fun(session,
|
|
1549
|
+
endpoint,
|
|
1550
|
+
model,
|
|
1551
|
+
cast(inputs, POINTER(dv_blob)),
|
|
1552
|
+
cast(outputs, POINTER(dv_blob)),
|
|
1553
|
+
timeout_ms,
|
|
1554
|
+
byref(inf_request),
|
|
1555
|
+
infer_options)
|
|
1556
|
+
|
|
1557
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
1558
|
+
return ret, None
|
|
1559
|
+
|
|
1560
|
+
return ret, inf_request
|
|
1561
|
+
|
|
1562
|
+
###############################################################################
|
|
1563
|
+
# dvapi_private function wrappers based on ctypes
|
|
1564
|
+
###############################################################################
|
|
1565
|
+
|
|
1566
|
+
|
|
1567
|
+
def dv_client_set_logger(logger: Callable[[str], None]):
|
|
1568
|
+
"""
|
|
1569
|
+
Register a logger plugin with client
|
|
1570
|
+
|
|
1571
|
+
Parameters
|
|
1572
|
+
----------
|
|
1573
|
+
logger : Callable[[str], None]
|
|
1574
|
+
|
|
1575
|
+
Returns
|
|
1576
|
+
-------
|
|
1577
|
+
None
|
|
1578
|
+
"""
|
|
1579
|
+
pfn_logger = CFUNCTYPE(None, c_char_p)
|
|
1580
|
+
|
|
1581
|
+
fun = _dvApiObj().dv_client_set_logger
|
|
1582
|
+
fun.argtypes = [pfn_logger]
|
|
1583
|
+
fun.restype = None
|
|
1584
|
+
|
|
1585
|
+
global logger_ptr
|
|
1586
|
+
logger_ptr = pfn_logger(logger)
|
|
1587
|
+
fun(logger_ptr)
|
|
1588
|
+
|
|
1589
|
+
|
|
1590
|
+
def dv_client_set_log_level(log_level):
|
|
1591
|
+
"""
|
|
1592
|
+
Set log level for the client to dump desired logs
|
|
1593
|
+
|
|
1594
|
+
Parameters
|
|
1595
|
+
----------
|
|
1596
|
+
log_level
|
|
1597
|
+
|
|
1598
|
+
Returns
|
|
1599
|
+
-------
|
|
1600
|
+
dv_status_code
|
|
1601
|
+
"""
|
|
1602
|
+
fun = _dvApiObj().dv_client_set_log_level
|
|
1603
|
+
fun.argtype = [dv_client_log_level]
|
|
1604
|
+
fun.restype = dv_status_code
|
|
1605
|
+
|
|
1606
|
+
return fun(log_level)
|
|
1607
|
+
|
|
1608
|
+
|
|
1609
|
+
def dv_session_create_via_unix_socket_with_options(socket_path, timeout):
|
|
1610
|
+
""" connects to the proxy via unix socket
|
|
1611
|
+
|
|
1612
|
+
Parameters
|
|
1613
|
+
----------
|
|
1614
|
+
socket_path : str
|
|
1615
|
+
path to the unix socket
|
|
1616
|
+
|
|
1617
|
+
timeout : int
|
|
1618
|
+
timeout value in msec
|
|
1619
|
+
|
|
1620
|
+
Returns
|
|
1621
|
+
-------
|
|
1622
|
+
(dv_status_code, dv_session)
|
|
1623
|
+
DV_SUCCESS, dv_session if the connection was successfully established
|
|
1624
|
+
if the status is not DV_SUCCESS, dv_session is invalid
|
|
1625
|
+
"""
|
|
1626
|
+
fun = _dvApiObj().dv_session_create_via_unix_socket_with_options
|
|
1627
|
+
fun.argtypes = [
|
|
1628
|
+
c_char_p,
|
|
1629
|
+
POINTER(
|
|
1630
|
+
POINTER(dv_session)),
|
|
1631
|
+
POINTER(dv_session_options)]
|
|
1632
|
+
fun.restype = dv_status_code
|
|
1633
|
+
session = POINTER(dv_session)()
|
|
1634
|
+
options = dv_session_options()
|
|
1635
|
+
options.timeout_ms = c_int(timeout)
|
|
1636
|
+
ret = fun(socket_path.encode('utf-8'), byref(session), byref(options))
|
|
1637
|
+
return ret, session
|
|
1638
|
+
|
|
1639
|
+
|
|
1640
|
+
def dv_session_create_via_tcp_ipv4_socket_with_options(
|
|
1641
|
+
ipv4_addr, port, timeout):
|
|
1642
|
+
""" connects to the proxy over the network
|
|
1643
|
+
|
|
1644
|
+
Parameters
|
|
1645
|
+
----------
|
|
1646
|
+
ip_addr : str
|
|
1647
|
+
IPv4 address to connect to
|
|
1648
|
+
|
|
1649
|
+
port : int
|
|
1650
|
+
Port number proxy is listening on
|
|
1651
|
+
|
|
1652
|
+
timeout : int
|
|
1653
|
+
timeout value in msec
|
|
1654
|
+
|
|
1655
|
+
Returns
|
|
1656
|
+
-------
|
|
1657
|
+
(dv_status_code, dv_session)
|
|
1658
|
+
DV_SUCCESS, dv_session if the connection was successfully established
|
|
1659
|
+
if the status is not DV_SUCCESS, dv_session is invalid
|
|
1660
|
+
"""
|
|
1661
|
+
fun = _dvApiObj().dv_session_create_via_tcp_ipv4_socket_with_options
|
|
1662
|
+
fun.argtypes = [
|
|
1663
|
+
c_char_p,
|
|
1664
|
+
c_uint,
|
|
1665
|
+
POINTER(
|
|
1666
|
+
POINTER(dv_session)),
|
|
1667
|
+
POINTER(dv_session_options)]
|
|
1668
|
+
fun.restype = dv_status_code
|
|
1669
|
+
session = POINTER(dv_session)()
|
|
1670
|
+
options = dv_session_options()
|
|
1671
|
+
options.timeout_ms = c_int(timeout)
|
|
1672
|
+
ret = fun(
|
|
1673
|
+
ipv4_addr.encode('utf-8'),
|
|
1674
|
+
c_uint(port),
|
|
1675
|
+
byref(session),
|
|
1676
|
+
byref(options))
|
|
1677
|
+
return ret, session
|
|
1678
|
+
|
|
1679
|
+
|
|
1680
|
+
def dv_endpoint_get_hw_statistics(session, ep):
|
|
1681
|
+
"""
|
|
1682
|
+
Parameters
|
|
1683
|
+
----------
|
|
1684
|
+
session : dv_session
|
|
1685
|
+
|
|
1686
|
+
ep : dv_endpoint
|
|
1687
|
+
endpoint/endpoint_group
|
|
1688
|
+
|
|
1689
|
+
Returns
|
|
1690
|
+
-------
|
|
1691
|
+
(dv_status_code, endpoint_hw_stats, dv_endpoint)
|
|
1692
|
+
|
|
1693
|
+
endpoint/endpoint_group count
|
|
1694
|
+
|
|
1695
|
+
"""
|
|
1696
|
+
fun = _dvApiObj().dv_endpoint_get_hw_statistics
|
|
1697
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1698
|
+
POINTER(dv_endpoint),
|
|
1699
|
+
POINTER(POINTER(dv_endpoint_hw_statistics)),
|
|
1700
|
+
POINTER(c_int)]
|
|
1701
|
+
fun.restype = dv_status_code
|
|
1702
|
+
endpoint_hw_stats = POINTER(dv_endpoint_hw_statistics)()
|
|
1703
|
+
ep_count = c_int()
|
|
1704
|
+
status = fun(session, ep, byref(endpoint_hw_stats), byref(ep_count))
|
|
1705
|
+
return status, endpoint_hw_stats, ep_count
|
|
1706
|
+
|
|
1707
|
+
|
|
1708
|
+
def dv_endpoint_free_hw_statistics(ep_hw_stats, count):
|
|
1709
|
+
"""
|
|
1710
|
+
Parameters
|
|
1711
|
+
----------
|
|
1712
|
+
ep_hw_stats : dv_endpoint_hw_statistics
|
|
1713
|
+
calloc pointer created by dv_endpoint_get_hw_statistics for endpoint_hw_stats
|
|
1714
|
+
|
|
1715
|
+
count : c_int
|
|
1716
|
+
number of endpoints in endpoint/endpoint_group
|
|
1717
|
+
|
|
1718
|
+
Returns
|
|
1719
|
+
-------
|
|
1720
|
+
dv_status_code
|
|
1721
|
+
|
|
1722
|
+
"""
|
|
1723
|
+
fun = _dvApiObj().dv_endpoint_free_hw_statistics
|
|
1724
|
+
fun.argtypes = [POINTER(dv_endpoint_hw_statistics),
|
|
1725
|
+
c_int]
|
|
1726
|
+
fun.restype = dv_status_code
|
|
1727
|
+
return fun(ep_hw_stats, count)
|
|
1728
|
+
|
|
1729
|
+
|
|
1730
|
+
def dv_endpoint_get_dram_statistics(session, ep):
|
|
1731
|
+
"""
|
|
1732
|
+
Parameters
|
|
1733
|
+
----------
|
|
1734
|
+
session : dv_session
|
|
1735
|
+
|
|
1736
|
+
ep : dv_endpoint
|
|
1737
|
+
endpoint/endpoint_group handle for particular endpoint or endpoint group
|
|
1738
|
+
or NULL for all endpoints
|
|
1739
|
+
|
|
1740
|
+
Returns
|
|
1741
|
+
-------
|
|
1742
|
+
(dv_status_code, endpoint_dram_statistics, endpoint/endpoint_group count)
|
|
1743
|
+
status code, list of endpoint_dram_statistics for the endpoint/endpoint group
|
|
1744
|
+
"""
|
|
1745
|
+
fun = _dvApiObj().dv_endpoint_get_dram_statistics
|
|
1746
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1747
|
+
POINTER(dv_endpoint),
|
|
1748
|
+
POINTER(POINTER(dv_endpoint_dram_statistics)),
|
|
1749
|
+
POINTER(c_int)]
|
|
1750
|
+
fun.restype = dv_status_code
|
|
1751
|
+
ep_count = c_int()
|
|
1752
|
+
endpoint_dram_statistics = POINTER(dv_endpoint_dram_statistics)()
|
|
1753
|
+
status = fun(session, ep, byref(endpoint_dram_statistics), byref(ep_count))
|
|
1754
|
+
return status, endpoint_dram_statistics, ep_count
|
|
1755
|
+
|
|
1756
|
+
|
|
1757
|
+
def dv_endpoint_free_dram_statistics(ep_dram_stats, count):
|
|
1758
|
+
"""
|
|
1759
|
+
Parameters
|
|
1760
|
+
----------
|
|
1761
|
+
ep_dram_stats : dv_endpoint_dram_statistics
|
|
1762
|
+
calloc pointer created by dv_endpoint_get_dram_statistics for endpoint_dram_statistics
|
|
1763
|
+
|
|
1764
|
+
count : c_int
|
|
1765
|
+
number of endpoints in endpoint/endpoint_group
|
|
1766
|
+
|
|
1767
|
+
Returns
|
|
1768
|
+
-------
|
|
1769
|
+
dv_status_code
|
|
1770
|
+
|
|
1771
|
+
"""
|
|
1772
|
+
fun = _dvApiObj().dv_endpoint_free_dram_statistics
|
|
1773
|
+
fun.argtypes = [POINTER(dv_endpoint_dram_statistics),
|
|
1774
|
+
c_int]
|
|
1775
|
+
fun.restype = dv_status_code
|
|
1776
|
+
return fun(ep_dram_stats, count)
|
|
1777
|
+
|
|
1778
|
+
|
|
1779
|
+
def dv_endpoint_get_statistics(session, ep):
|
|
1780
|
+
"""
|
|
1781
|
+
Parameters
|
|
1782
|
+
----------
|
|
1783
|
+
session : dv_session
|
|
1784
|
+
|
|
1785
|
+
ep : dv_endpoint
|
|
1786
|
+
endpoint/endpoint_group
|
|
1787
|
+
|
|
1788
|
+
Returns
|
|
1789
|
+
-------
|
|
1790
|
+
(dv_status_code, endpoint_statistics, endpoint/endpoint_group count)
|
|
1791
|
+
|
|
1792
|
+
"""
|
|
1793
|
+
fun = _dvApiObj().dv_endpoint_get_statistics
|
|
1794
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1795
|
+
POINTER(dv_endpoint),
|
|
1796
|
+
POINTER(POINTER(dv_endpoint_stats)),
|
|
1797
|
+
POINTER(c_int)]
|
|
1798
|
+
fun.restype = dv_status_code
|
|
1799
|
+
ep_stats = POINTER(dv_endpoint_stats)()
|
|
1800
|
+
ep_count = c_int()
|
|
1801
|
+
status = fun(session, ep, byref(ep_stats), byref(ep_count))
|
|
1802
|
+
return status, ep_stats, ep_count
|
|
1803
|
+
|
|
1804
|
+
|
|
1805
|
+
def dv_endpoint_free_statistics(ep_stats, count):
|
|
1806
|
+
"""
|
|
1807
|
+
Parameters
|
|
1808
|
+
----------
|
|
1809
|
+
ep_stats : dv_endpoint_stats
|
|
1810
|
+
calloc pointer created by dv_endpoint_get_statistics for ep_stats
|
|
1811
|
+
|
|
1812
|
+
count : c_int
|
|
1813
|
+
number of endpoints in endpoint/endpoint_group
|
|
1814
|
+
|
|
1815
|
+
Returns
|
|
1816
|
+
-------
|
|
1817
|
+
dv_status_code
|
|
1818
|
+
|
|
1819
|
+
"""
|
|
1820
|
+
fun = _dvApiObj().dv_endpoint_free_statistics
|
|
1821
|
+
fun.argtypes = [POINTER(dv_endpoint_stats),
|
|
1822
|
+
c_int]
|
|
1823
|
+
fun.restype = dv_status_code
|
|
1824
|
+
return fun(ep_stats, count)
|
|
1825
|
+
|
|
1826
|
+
|
|
1827
|
+
def dv_register_fault_callback(session, fault_handler, user_data=None):
|
|
1828
|
+
""" Subscribe to notification event in case of a fault
|
|
1829
|
+
Returns DV_SUCCESS on success, else error
|
|
1830
|
+
Endpoint handle dv_endpoint_t received as input to the callback function
|
|
1831
|
+
denotes the endpoint that has gone faulty Only one client per proxy needs to
|
|
1832
|
+
register to this callback to avoid multiple resets of the same endpoint
|
|
1833
|
+
|
|
1834
|
+
Parameters
|
|
1835
|
+
----------
|
|
1836
|
+
session : dv_session handle
|
|
1837
|
+
fault_handler : pointer to function that does platform-specific hard reset of device
|
|
1838
|
+
user_data : pointer to custom user data which will be passed as an argument to the fault handler, default is NULL
|
|
1839
|
+
"""
|
|
1840
|
+
dv_endpoint_fault_callback_fun = CFUNCTYPE(
|
|
1841
|
+
None, POINTER(dv_endpoint_stats), c_void_p)
|
|
1842
|
+
fun = _dvApiObj().dv_register_fault_callback
|
|
1843
|
+
fun.argtypes = [
|
|
1844
|
+
POINTER(dv_session),
|
|
1845
|
+
dv_endpoint_fault_callback_fun,
|
|
1846
|
+
c_void_p]
|
|
1847
|
+
fun.restype = dv_status_code
|
|
1848
|
+
fault_handler_ptr = dv_endpoint_fault_callback_fun(fault_handler)
|
|
1849
|
+
return fun(session, fault_handler_ptr, user_data)
|
|
1850
|
+
|
|
1851
|
+
|
|
1852
|
+
def dv_endpoint_bringup(session, ep):
|
|
1853
|
+
""" Proxy will attempt to reload all models which were cached earlier.
|
|
1854
|
+
If this API returns `DV_MODEL_CACHE_FETCH_FAILURE`, loading of cached
|
|
1855
|
+
models have failed, but device can be assumed to be in good state and
|
|
1856
|
+
`dv_model_load*` APIs can be used to load the same again.
|
|
1857
|
+
|
|
1858
|
+
Parameters
|
|
1859
|
+
----------
|
|
1860
|
+
session : dv_session
|
|
1861
|
+
ep : dv_endpoint
|
|
1862
|
+
endpoint/endpoint_group
|
|
1863
|
+
Returns
|
|
1864
|
+
-------
|
|
1865
|
+
dv_status_code
|
|
1866
|
+
"""
|
|
1867
|
+
fun = _dvApiObj().dv_endpoint_bringup
|
|
1868
|
+
fun.argtypes = [POINTER(dv_session), POINTER(dv_endpoint)]
|
|
1869
|
+
fun.restype = dv_status_code
|
|
1870
|
+
return fun(session, ep)
|
|
1871
|
+
|
|
1872
|
+
|
|
1873
|
+
def dv_endpoint_takedown(session, ep):
|
|
1874
|
+
""" Takes down ANY active endpoint. If the endpoint is part of an
|
|
1875
|
+
active endpoint group, requests will be scheduled by Proxy to other
|
|
1876
|
+
active endpoints in the group
|
|
1877
|
+
|
|
1878
|
+
Parameters
|
|
1879
|
+
----------
|
|
1880
|
+
session : dv_session
|
|
1881
|
+
|
|
1882
|
+
ep : dv_endpoint
|
|
1883
|
+
endpoint/endpoint_group
|
|
1884
|
+
|
|
1885
|
+
Returns
|
|
1886
|
+
-------
|
|
1887
|
+
dv_status_code
|
|
1888
|
+
|
|
1889
|
+
"""
|
|
1890
|
+
fun = _dvApiObj().dv_endpoint_takedown
|
|
1891
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1892
|
+
POINTER(dv_endpoint)]
|
|
1893
|
+
fun.restype = dv_status_code
|
|
1894
|
+
return fun(session, ep)
|
|
1895
|
+
|
|
1896
|
+
|
|
1897
|
+
def dv_endpoint_takedown_with_options(session, ep, options):
|
|
1898
|
+
"""
|
|
1899
|
+
Takes down ANY active endpoint. If the endpoint is part of an active endpoint group,
|
|
1900
|
+
requests will be scheduled by Proxy to other active endpoints in the group.
|
|
1901
|
+
|
|
1902
|
+
Parameters
|
|
1903
|
+
----------
|
|
1904
|
+
session : dv_session
|
|
1905
|
+
|
|
1906
|
+
ep : dv_endpoint
|
|
1907
|
+
endpoint/endpoint_group
|
|
1908
|
+
|
|
1909
|
+
options: dv_endpoint_takedown_options
|
|
1910
|
+
|
|
1911
|
+
Returns
|
|
1912
|
+
-------
|
|
1913
|
+
dv_status_code
|
|
1914
|
+
"""
|
|
1915
|
+
|
|
1916
|
+
fun = _dvApiObj().dv_endpoint_takedown_with_options
|
|
1917
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1918
|
+
POINTER(dv_endpoint),
|
|
1919
|
+
POINTER(dv_endpoint_takedown_options)]
|
|
1920
|
+
fun.restype = dv_status_code
|
|
1921
|
+
return fun(session, ep, options)
|
|
1922
|
+
|
|
1923
|
+
|
|
1924
|
+
def dv_endpoint_check_status(session, ep):
|
|
1925
|
+
"""checks the state of the endpoint
|
|
1926
|
+
|
|
1927
|
+
Parameters
|
|
1928
|
+
----------
|
|
1929
|
+
session : dv_session
|
|
1930
|
+
|
|
1931
|
+
ep : dv_endpoint
|
|
1932
|
+
endpoint/endpoint_group
|
|
1933
|
+
|
|
1934
|
+
Returns
|
|
1935
|
+
-------
|
|
1936
|
+
(dv_status_code, state)
|
|
1937
|
+
Endpoint/endpoint_group current state
|
|
1938
|
+
|
|
1939
|
+
"""
|
|
1940
|
+
fun = _dvApiObj().dv_endpoint_check_status
|
|
1941
|
+
fun.argtypes = [POINTER(dv_session),
|
|
1942
|
+
POINTER(dv_endpoint),
|
|
1943
|
+
POINTER(c_int)]
|
|
1944
|
+
fun.restype = dv_status_code
|
|
1945
|
+
state = c_int()
|
|
1946
|
+
ret = fun(session, ep, byref(state))
|
|
1947
|
+
return ret, state
|
|
1948
|
+
|
|
1949
|
+
|
|
1950
|
+
def dv_endpoint_enter_power_state(session, ep, power_state):
|
|
1951
|
+
"""Switches endpoint to a different supported power state.
|
|
1952
|
+
Returns DV_SUCCESS when endpoint is moved to same state as current state; does not perform any action on the endpoint.
|
|
1953
|
+
|
|
1954
|
+
Parameters
|
|
1955
|
+
----------
|
|
1956
|
+
session : dv_session
|
|
1957
|
+
|
|
1958
|
+
ep : dv_endpoint
|
|
1959
|
+
endpoint/endpoint_group
|
|
1960
|
+
|
|
1961
|
+
power_state : c_int
|
|
1962
|
+
state to switch endpoint to
|
|
1963
|
+
"""
|
|
1964
|
+
fun = _dvApiObj().dv_endpoint_enter_power_state
|
|
1965
|
+
fun.argtypes = [POINTER(dv_session), POINTER(dv_endpoint), POINTER(c_int)]
|
|
1966
|
+
fun.restype = dv_status_code
|
|
1967
|
+
p_state = c_int(power_state)
|
|
1968
|
+
return fun(session, ep, byref(p_state))
|
|
1969
|
+
|
|
1970
|
+
|
|
1971
|
+
def dv_register_endpoint_power_state_callback(
|
|
1972
|
+
session, power_state_handler, user_data=None):
|
|
1973
|
+
"""
|
|
1974
|
+
Registers a callback function to be called when an endpoint changes power state
|
|
1975
|
+
Endpoint handle dv_endpoint_t received as input to the callback function denotes
|
|
1976
|
+
the endpoint which has switched states
|
|
1977
|
+
|
|
1978
|
+
Parameters
|
|
1979
|
+
----------
|
|
1980
|
+
session : dv_session
|
|
1981
|
+
|
|
1982
|
+
power_state_handler : Callable[[POINTER(dv_endpoint_t), dv_endpoint_power_state, dv_endpoint_power_state, c_void_p], None]
|
|
1983
|
+
callback function to be called when an endpoint changes power state
|
|
1984
|
+
|
|
1985
|
+
user_data : c_void_p
|
|
1986
|
+
user data pointer to be passed to the callback function
|
|
1987
|
+
|
|
1988
|
+
Returns
|
|
1989
|
+
-------
|
|
1990
|
+
dv_status_code
|
|
1991
|
+
"""
|
|
1992
|
+
dv_endpoint_power_state_callback = CFUNCTYPE(
|
|
1993
|
+
None, POINTER(dv_endpoint), c_int, c_int, c_void_p)
|
|
1994
|
+
fun = _dvApiObj().dv_register_endpoint_power_state_callback
|
|
1995
|
+
fun.argtypes = [
|
|
1996
|
+
POINTER(dv_session),
|
|
1997
|
+
dv_endpoint_power_state_callback,
|
|
1998
|
+
c_void_p]
|
|
1999
|
+
fun.restype = dv_status_code
|
|
2000
|
+
power_state_callback_ptr = dv_endpoint_power_state_callback(
|
|
2001
|
+
power_state_handler)
|
|
2002
|
+
return fun(session, power_state_callback_ptr, user_data)
|
|
2003
|
+
|
|
2004
|
+
|
|
2005
|
+
def dv_model_load_from_file_cache(
|
|
2006
|
+
session, ep, model_path, model_name, priority):
|
|
2007
|
+
""" loads a model onto the device from the provided file path and caches the model onto disk
|
|
2008
|
+
|
|
2009
|
+
Parameters
|
|
2010
|
+
----------
|
|
2011
|
+
|
|
2012
|
+
session : dv_session
|
|
2013
|
+
connected client session
|
|
2014
|
+
|
|
2015
|
+
ep : dv_endpoint
|
|
2016
|
+
endpoint on which to load the model
|
|
2017
|
+
|
|
2018
|
+
model_path : str
|
|
2019
|
+
path to the model on filesystem
|
|
2020
|
+
|
|
2021
|
+
model_name : str
|
|
2022
|
+
a reference name to be assigned to the model
|
|
2023
|
+
|
|
2024
|
+
priority : int
|
|
2025
|
+
priority of the model
|
|
2026
|
+
|
|
2027
|
+
Returns
|
|
2028
|
+
-------
|
|
2029
|
+
(dv_status_code, dv_model)
|
|
2030
|
+
an error status and the model handle. if the error status is not
|
|
2031
|
+
DV_SUCCESS, dv_model_handle is invalid
|
|
2032
|
+
"""
|
|
2033
|
+
fun = _dvApiObj().dv_model_load_from_file_cache
|
|
2034
|
+
fun.argtypes = [
|
|
2035
|
+
POINTER(dv_session),
|
|
2036
|
+
POINTER(dv_endpoint),
|
|
2037
|
+
c_char_p,
|
|
2038
|
+
c_char_p,
|
|
2039
|
+
c_int,
|
|
2040
|
+
POINTER(POINTER(dv_model))]
|
|
2041
|
+
|
|
2042
|
+
fun.restype = dv_status_code
|
|
2043
|
+
|
|
2044
|
+
model = POINTER(dv_model)()
|
|
2045
|
+
|
|
2046
|
+
ret = fun(session,
|
|
2047
|
+
ep,
|
|
2048
|
+
model_path.encode('utf-8'),
|
|
2049
|
+
model_name.encode('utf-8'),
|
|
2050
|
+
priority,
|
|
2051
|
+
byref(model))
|
|
2052
|
+
|
|
2053
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2054
|
+
return ret, None
|
|
2055
|
+
|
|
2056
|
+
return ret, model
|
|
2057
|
+
|
|
2058
|
+
|
|
2059
|
+
def dv_model_load_from_blob_cache(
|
|
2060
|
+
session, ep, model_blob, model_name, priority):
|
|
2061
|
+
""" loads a model onto the device from the provided file path and caches model onto disk
|
|
2062
|
+
|
|
2063
|
+
Parameters
|
|
2064
|
+
----------
|
|
2065
|
+
session : dv_session
|
|
2066
|
+
connected client session
|
|
2067
|
+
|
|
2068
|
+
ep : dv_endpoint
|
|
2069
|
+
endpoint on which to load the model
|
|
2070
|
+
|
|
2071
|
+
model_blob : dv_blob
|
|
2072
|
+
model blob
|
|
2073
|
+
|
|
2074
|
+
model_name : str
|
|
2075
|
+
a reference name to be assigned to the model
|
|
2076
|
+
|
|
2077
|
+
priority : int
|
|
2078
|
+
priority of the model
|
|
2079
|
+
|
|
2080
|
+
enable_caching : bool
|
|
2081
|
+
indicaes if the model should be cached by the server.
|
|
2082
|
+
API call fails if the model could not be cached by the server
|
|
2083
|
+
|
|
2084
|
+
Returns
|
|
2085
|
+
-------
|
|
2086
|
+
(dv_status_code, dv_model_handle)
|
|
2087
|
+
an error status and the model handle. if the error status is not
|
|
2088
|
+
DV_SUCCESS, dv_model_handle is invalid
|
|
2089
|
+
"""
|
|
2090
|
+
|
|
2091
|
+
fun = _dvApiObj().dv_model_load_from_blob_cache
|
|
2092
|
+
fun.argtypes = [
|
|
2093
|
+
POINTER(dv_session),
|
|
2094
|
+
POINTER(dv_endpoint),
|
|
2095
|
+
POINTER(dv_blob),
|
|
2096
|
+
c_char_p,
|
|
2097
|
+
c_int,
|
|
2098
|
+
POINTER(POINTER(dv_model))]
|
|
2099
|
+
|
|
2100
|
+
fun.restype = dv_status_code
|
|
2101
|
+
|
|
2102
|
+
model = POINTER(dv_model)()
|
|
2103
|
+
|
|
2104
|
+
ret = fun(session,
|
|
2105
|
+
ep,
|
|
2106
|
+
model_blob,
|
|
2107
|
+
model_name.encode('utf-8'),
|
|
2108
|
+
priority,
|
|
2109
|
+
byref(model))
|
|
2110
|
+
|
|
2111
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2112
|
+
return ret, None
|
|
2113
|
+
|
|
2114
|
+
return ret, model
|
|
2115
|
+
|
|
2116
|
+
|
|
2117
|
+
def dv_model_load_from_file_with_options(
|
|
2118
|
+
session: dv_session, ep: dv_endpoint, model_file_path: str, options: dv_model_options):
|
|
2119
|
+
"""Creates a model object and load model contents from blob and transfer it to endpoint
|
|
2120
|
+
|
|
2121
|
+
Notes
|
|
2122
|
+
-----
|
|
2123
|
+
Model object contains the model handle and model parameters.
|
|
2124
|
+
`dv_model_get_loaded_endpoint_list` returns the list of endpoints (individual device dv_endpoint_t handles)
|
|
2125
|
+
on which the model was successfully loaded.
|
|
2126
|
+
If model load fails on all individual devices representing `endpt`, the API call will error out
|
|
2127
|
+
|
|
2128
|
+
Parameters
|
|
2129
|
+
----------
|
|
2130
|
+
session : dv_session
|
|
2131
|
+
session handle
|
|
2132
|
+
ep : dv_endpoint
|
|
2133
|
+
endpoint handle
|
|
2134
|
+
model_file_path : str
|
|
2135
|
+
path to model file
|
|
2136
|
+
options : dv_model_options
|
|
2137
|
+
model load option
|
|
2138
|
+
|
|
2139
|
+
Returns
|
|
2140
|
+
-------
|
|
2141
|
+
(dv_status_code, dv_model)
|
|
2142
|
+
an error status and the model handle.
|
|
2143
|
+
"""
|
|
2144
|
+
|
|
2145
|
+
fun = _dvApiObj().dv_model_load_from_file_with_options
|
|
2146
|
+
fun.argtypes = [
|
|
2147
|
+
POINTER(dv_session),
|
|
2148
|
+
POINTER(dv_endpoint),
|
|
2149
|
+
c_char_p,
|
|
2150
|
+
POINTER(POINTER(dv_model)),
|
|
2151
|
+
POINTER(dv_model_options)]
|
|
2152
|
+
|
|
2153
|
+
fun.restype = dv_status_code
|
|
2154
|
+
|
|
2155
|
+
model = POINTER(dv_model)()
|
|
2156
|
+
|
|
2157
|
+
ret = fun(session,
|
|
2158
|
+
ep,
|
|
2159
|
+
model_file_path.encode('utf-8'),
|
|
2160
|
+
byref(model),
|
|
2161
|
+
options)
|
|
2162
|
+
|
|
2163
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2164
|
+
return ret, None
|
|
2165
|
+
|
|
2166
|
+
return ret, model
|
|
2167
|
+
|
|
2168
|
+
|
|
2169
|
+
def dv_model_load_from_file_with_flags(session: dv_session, ep: dv_endpoint, model_file_path: str,
|
|
2170
|
+
flags: int, model_name: str, priority: dv_model_priority_level, cache: bool, async_flag: bool):
|
|
2171
|
+
fun = _dvApiObj().dv_model_load_from_file_with_flags
|
|
2172
|
+
fun.argtypes = [
|
|
2173
|
+
POINTER(dv_session),
|
|
2174
|
+
POINTER(dv_endpoint),
|
|
2175
|
+
c_char_p,
|
|
2176
|
+
c_char_p,
|
|
2177
|
+
c_int,
|
|
2178
|
+
c_bool,
|
|
2179
|
+
c_bool,
|
|
2180
|
+
POINTER(POINTER(dv_model)),
|
|
2181
|
+
c_uint16]
|
|
2182
|
+
fun.restype = dv_status_code
|
|
2183
|
+
model = POINTER(dv_model)()
|
|
2184
|
+
ret = fun(session,
|
|
2185
|
+
ep,
|
|
2186
|
+
model_file_path.encode('utf-8'),
|
|
2187
|
+
model_name.encode('utf-8'),
|
|
2188
|
+
priority,
|
|
2189
|
+
cache,
|
|
2190
|
+
async_flag,
|
|
2191
|
+
byref(model),
|
|
2192
|
+
flags)
|
|
2193
|
+
|
|
2194
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2195
|
+
return ret, None
|
|
2196
|
+
|
|
2197
|
+
return ret, model
|
|
2198
|
+
|
|
2199
|
+
|
|
2200
|
+
def dv_model_load_from_blob_with_options(session, ep, blob, options):
|
|
2201
|
+
"""Creates a model object and load model contents from blob and transfer it to endpoint
|
|
2202
|
+
|
|
2203
|
+
Notes
|
|
2204
|
+
-----
|
|
2205
|
+
Model object contains the model handle and model parameters.
|
|
2206
|
+
`dv_model_get_loaded_endpoint_list` returns the list of endpoints (individual device dv_endpoint_t handles)
|
|
2207
|
+
on which the model was successfully loaded.
|
|
2208
|
+
If model load fails on all individual devices representing `endpt`, the API call will error out
|
|
2209
|
+
|
|
2210
|
+
Parameters
|
|
2211
|
+
----------
|
|
2212
|
+
session : dv_session
|
|
2213
|
+
session handle
|
|
2214
|
+
ep : dv_endpoint
|
|
2215
|
+
endpoint handle
|
|
2216
|
+
blob : dv_blob_t
|
|
2217
|
+
blob of the model
|
|
2218
|
+
options : dv_model_options
|
|
2219
|
+
model load option
|
|
2220
|
+
|
|
2221
|
+
Returns
|
|
2222
|
+
-------
|
|
2223
|
+
(dv_status_code, dv_model)
|
|
2224
|
+
an error status and the model handle.
|
|
2225
|
+
"""
|
|
2226
|
+
|
|
2227
|
+
fun = _dvApiObj().dv_model_load_from_blob_with_options
|
|
2228
|
+
fun.argtypes = [
|
|
2229
|
+
POINTER(dv_session),
|
|
2230
|
+
POINTER(dv_endpoint),
|
|
2231
|
+
POINTER(dv_blob),
|
|
2232
|
+
POINTER(POINTER(dv_model)),
|
|
2233
|
+
POINTER(dv_model_options)]
|
|
2234
|
+
|
|
2235
|
+
fun.restype = dv_status_code
|
|
2236
|
+
|
|
2237
|
+
model = POINTER(dv_model)()
|
|
2238
|
+
|
|
2239
|
+
ret = fun(session,
|
|
2240
|
+
ep,
|
|
2241
|
+
blob,
|
|
2242
|
+
byref(model),
|
|
2243
|
+
options)
|
|
2244
|
+
|
|
2245
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2246
|
+
return ret, None
|
|
2247
|
+
|
|
2248
|
+
return ret, model
|
|
2249
|
+
|
|
2250
|
+
|
|
2251
|
+
def dv_model_load_wait_for_completion(model, timeout):
|
|
2252
|
+
"""Wait for asynchronous model load API call to complete. If the model was loaded specifying
|
|
2253
|
+
`async = true`, this API will wait for the model load result to become availalbe. If the model is
|
|
2254
|
+
already done loading, the API will return immediately.
|
|
2255
|
+
"""
|
|
2256
|
+
fun = _dvApiObj().dv_model_load_wait_for_completion
|
|
2257
|
+
fun.argtypes = [POINTER(dv_model),
|
|
2258
|
+
c_int]
|
|
2259
|
+
|
|
2260
|
+
fun.restype = dv_status_code
|
|
2261
|
+
|
|
2262
|
+
ret = fun(model, timeout)
|
|
2263
|
+
|
|
2264
|
+
return ret
|
|
2265
|
+
|
|
2266
|
+
|
|
2267
|
+
def dv_model_get_parameters_from_file(model_path):
|
|
2268
|
+
""" get model parameters without loading into device
|
|
2269
|
+
|
|
2270
|
+
Parameters
|
|
2271
|
+
----------
|
|
2272
|
+
model_path : str
|
|
2273
|
+
path to the model on filesystem
|
|
2274
|
+
|
|
2275
|
+
Returns
|
|
2276
|
+
-------
|
|
2277
|
+
(dv_status_code, dv_model)
|
|
2278
|
+
DV_SUCCESS if the model was successful
|
|
2279
|
+
unloaded model object with the parameters
|
|
2280
|
+
"""
|
|
2281
|
+
|
|
2282
|
+
fun = _dvApiObj().dv_model_get_parameters_from_file
|
|
2283
|
+
fun.argtypes = [c_char_p, POINTER(POINTER(dv_model))]
|
|
2284
|
+
fun.restype = dv_status_code
|
|
2285
|
+
|
|
2286
|
+
model = POINTER(dv_model)()
|
|
2287
|
+
|
|
2288
|
+
ret = fun(model_path.encode('utf-8'), byref(model))
|
|
2289
|
+
|
|
2290
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2291
|
+
return ret, None
|
|
2292
|
+
return ret, model
|
|
2293
|
+
|
|
2294
|
+
|
|
2295
|
+
def dv_model_get_parameters_from_blob(model_blob):
|
|
2296
|
+
""" get model parameters without loading into device
|
|
2297
|
+
|
|
2298
|
+
Parameters
|
|
2299
|
+
----------
|
|
2300
|
+
model_blob : dv_blob
|
|
2301
|
+
model blob
|
|
2302
|
+
|
|
2303
|
+
Returns
|
|
2304
|
+
-------
|
|
2305
|
+
(dv_status_code, dv_model)
|
|
2306
|
+
DV_SUCCESS if the unload was successful
|
|
2307
|
+
unloaded model object with the parameters
|
|
2308
|
+
"""
|
|
2309
|
+
|
|
2310
|
+
fun = _dvApiObj().dv_model_get_parameters_from_blob
|
|
2311
|
+
fun.argtypes = [POINTER(dv_blob), POINTER(POINTER(dv_model))]
|
|
2312
|
+
fun.restype = dv_status_code
|
|
2313
|
+
|
|
2314
|
+
model = POINTER(dv_model)()
|
|
2315
|
+
|
|
2316
|
+
ret = fun(model_blob, byref(model))
|
|
2317
|
+
|
|
2318
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2319
|
+
return ret, None
|
|
2320
|
+
|
|
2321
|
+
return ret, model
|
|
2322
|
+
|
|
2323
|
+
|
|
2324
|
+
def dv_model_free_parameters(model):
|
|
2325
|
+
""" free model parameters
|
|
2326
|
+
|
|
2327
|
+
Parameters
|
|
2328
|
+
----------
|
|
2329
|
+
model : dv_model
|
|
2330
|
+
model object
|
|
2331
|
+
|
|
2332
|
+
Returns
|
|
2333
|
+
-------
|
|
2334
|
+
dv_status_code
|
|
2335
|
+
DV_SUCCESS if the unload was successful
|
|
2336
|
+
"""
|
|
2337
|
+
|
|
2338
|
+
fun = _dvApiObj().dv_model_free_parameters
|
|
2339
|
+
fun.argtypes = [POINTER(dv_model)]
|
|
2340
|
+
fun.restype = dv_status_code
|
|
2341
|
+
return fun(model)
|
|
2342
|
+
|
|
2343
|
+
|
|
2344
|
+
def dv_model_get_loaded_endpoint_list(session, model):
|
|
2345
|
+
"""Returns a list of all connected endpoints + list of indexes in the aforementioned list on which the specified model is loaded.
|
|
2346
|
+
|
|
2347
|
+
Notes
|
|
2348
|
+
-----
|
|
2349
|
+
`endpt_list` and `endpt_list_size` is populated with the same output as `dv_endpoint_get_list`
|
|
2350
|
+
and is managed by the client library - `endpt_list` is not to be freed / deallocated by the caller.
|
|
2351
|
+
`loaded_endpt_idxes` is not managed by the client library and must be freed by the caller.
|
|
2352
|
+
|
|
2353
|
+
Parameters
|
|
2354
|
+
----------
|
|
2355
|
+
session : dv_session
|
|
2356
|
+
connected client session
|
|
2357
|
+
model : dv_model
|
|
2358
|
+
model object
|
|
2359
|
+
|
|
2360
|
+
Returns
|
|
2361
|
+
-------
|
|
2362
|
+
(dv_status_code,list(dv_endpoint),endpt_list_size,list(loaded_endpt_idxes),loaded_endpt_list_size)
|
|
2363
|
+
dv_status_code : status code
|
|
2364
|
+
|
|
2365
|
+
endpt_list : list of all endpoints as returned by dv_endpoint_get_list
|
|
2366
|
+
|
|
2367
|
+
endpt_list_size : length of endpt_list as returned by dv_endpoint_get_list
|
|
2368
|
+
|
|
2369
|
+
loaded_endpt_idxes : list of indexes of items in endpt_list which have model loaded
|
|
2370
|
+
|
|
2371
|
+
loaded_endpt_list_size : length of loaded_endpt_idxes
|
|
2372
|
+
|
|
2373
|
+
"""
|
|
2374
|
+
|
|
2375
|
+
fun = _dvApiObj().dv_model_get_loaded_endpoint_list
|
|
2376
|
+
fun.argtypes = [POINTER(dv_session),
|
|
2377
|
+
POINTER(dv_model),
|
|
2378
|
+
POINTER(POINTER(dv_endpoint)),
|
|
2379
|
+
POINTER(c_int),
|
|
2380
|
+
POINTER(POINTER(c_int)),
|
|
2381
|
+
POINTER(c_int)]
|
|
2382
|
+
fun.restype = dv_status_code
|
|
2383
|
+
|
|
2384
|
+
endpt_list = POINTER(dv_endpoint)()
|
|
2385
|
+
endpt_list_size = c_int()
|
|
2386
|
+
loaded_endpt_idxes = POINTER(c_int)()
|
|
2387
|
+
loaded_endpt_list_size = c_int()
|
|
2388
|
+
|
|
2389
|
+
ret = fun(
|
|
2390
|
+
session,
|
|
2391
|
+
model,
|
|
2392
|
+
byref(endpt_list),
|
|
2393
|
+
byref(endpt_list_size),
|
|
2394
|
+
byref(loaded_endpt_idxes),
|
|
2395
|
+
byref(loaded_endpt_list_size))
|
|
2396
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
2397
|
+
return ret, None, None, None, None
|
|
2398
|
+
|
|
2399
|
+
return ret, endpt_list, endpt_list_size, loaded_endpt_idxes, loaded_endpt_list_size
|
|
2400
|
+
|
|
2401
|
+
|
|
2402
|
+
def dv_model_compare_handles(model1, model2):
|
|
2403
|
+
""" Compare model handles
|
|
2404
|
+
Used to compare if model objects returned by different APIs point to the same model file
|
|
2405
|
+
Ex: model handle returned by dv_endpoint_get_statistics and dv_model_load* APIs can be compared
|
|
2406
|
+
Returns "true" if they're the same, else false
|
|
2407
|
+
|
|
2408
|
+
Parameters
|
|
2409
|
+
----------
|
|
2410
|
+
model1: dv_model_handle_t handle of model to be compared
|
|
2411
|
+
model2: dv_model_handle_t handle of model to be compared
|
|
2412
|
+
"""
|
|
2413
|
+
fun = _dvApiObj().dv_model_compare_handles
|
|
2414
|
+
fun.argtype = [c_void_p, c_void_p]
|
|
2415
|
+
fun.restype = c_bool
|
|
2416
|
+
return fun(model1, model1)
|
|
2417
|
+
|
|
2418
|
+
|
|
2419
|
+
def dv_get_dynamic_op_size(model, op_blob_list, op_index):
|
|
2420
|
+
""" returns the index and size of a valid output for networks that produce a dynamic output
|
|
2421
|
+
|
|
2422
|
+
Parameters
|
|
2423
|
+
----------
|
|
2424
|
+
model: model for which outputs are generated
|
|
2425
|
+
|
|
2426
|
+
op_blob_list: list of outputs for the given model
|
|
2427
|
+
|
|
2428
|
+
op_index: index for which output size is to be returned
|
|
2429
|
+
|
|
2430
|
+
Returns
|
|
2431
|
+
-------
|
|
2432
|
+
dv_status_code
|
|
2433
|
+
|
|
2434
|
+
op_index: c_int
|
|
2435
|
+
size of op chunk to be read
|
|
2436
|
+
|
|
2437
|
+
size_index: c_int
|
|
2438
|
+
index at which data is to read
|
|
2439
|
+
"""
|
|
2440
|
+
fun = _dvApiObj().dv_get_dynamic_op_size
|
|
2441
|
+
fun.argtypes = [
|
|
2442
|
+
POINTER(dv_model),
|
|
2443
|
+
POINTER(dv_blob),
|
|
2444
|
+
c_int,
|
|
2445
|
+
POINTER(c_int),
|
|
2446
|
+
POINTER(c_int)]
|
|
2447
|
+
fun.restype = dv_status_code
|
|
2448
|
+
|
|
2449
|
+
op_size = c_int()
|
|
2450
|
+
size_index = c_int()
|
|
2451
|
+
|
|
2452
|
+
status = fun(
|
|
2453
|
+
model,
|
|
2454
|
+
cast(
|
|
2455
|
+
op_blob_list,
|
|
2456
|
+
POINTER(dv_blob)),
|
|
2457
|
+
op_index,
|
|
2458
|
+
byref(op_size),
|
|
2459
|
+
byref(size_index))
|
|
2460
|
+
|
|
2461
|
+
return status, op_size, size_index
|
|
2462
|
+
|
|
2463
|
+
|
|
2464
|
+
def dv_session_create_via_named_pipe(named_pipe, session):
|
|
2465
|
+
""" Create a session to the server using windows named pipe.
|
|
2466
|
+
Returns DV_SUCCESS on success, else error
|
|
2467
|
+
|
|
2468
|
+
Parameters
|
|
2469
|
+
----------
|
|
2470
|
+
named_pipe: server pipe
|
|
2471
|
+
|
|
2472
|
+
session : dv_session
|
|
2473
|
+
session handle
|
|
2474
|
+
|
|
2475
|
+
Returns
|
|
2476
|
+
-------
|
|
2477
|
+
dv_status_code
|
|
2478
|
+
|
|
2479
|
+
"""
|
|
2480
|
+
fun = _dvApiObj().dv_session_create_via_named_pipe
|
|
2481
|
+
fun.argtypes = [c_char_p, POINTER(POINTER(dv_session))]
|
|
2482
|
+
fun.restype = dv_status_code
|
|
2483
|
+
session = POINTER(dv_session)()
|
|
2484
|
+
return fun(named_pipe.encode('utf-8'), byref(session))
|
|
2485
|
+
|
|
2486
|
+
|
|
2487
|
+
def dv_infer_wait_for_all_completion(session, inf_list, timeout):
|
|
2488
|
+
""" Monitor multiple inference request object and wait until, all of the
|
|
2489
|
+
request updates/changes run status If the list is empty it waits until,
|
|
2490
|
+
atleast one inference request submitted in the session changes run status and
|
|
2491
|
+
API keeps track of status change for a inference request and run status is
|
|
2492
|
+
reported only once.
|
|
2493
|
+
|
|
2494
|
+
For non-empty request list, application needs to remove the completed
|
|
2495
|
+
inference object from the list. Request completion status can be reported
|
|
2496
|
+
multiple times.
|
|
2497
|
+
|
|
2498
|
+
Parameters
|
|
2499
|
+
----------
|
|
2500
|
+
session : dv_session
|
|
2501
|
+
session handle
|
|
2502
|
+
|
|
2503
|
+
inf_list : dv_infer_request
|
|
2504
|
+
inference request object list
|
|
2505
|
+
|
|
2506
|
+
timeout : int
|
|
2507
|
+
maximum time in mili seconds to wait for inference request to change status
|
|
2508
|
+
(defaults to 60 seconds in case timeout is passed as -1)
|
|
2509
|
+
|
|
2510
|
+
Returns
|
|
2511
|
+
-------
|
|
2512
|
+
dv_status_code
|
|
2513
|
+
|
|
2514
|
+
completed_inf_list : list of completed inferences
|
|
2515
|
+
|
|
2516
|
+
completed_inf_count : count of completed inferences
|
|
2517
|
+
|
|
2518
|
+
"""
|
|
2519
|
+
fun = _dvApiObj().dv_infer_wait_for_all_completion
|
|
2520
|
+
fun.argtypes = [POINTER(dv_session),
|
|
2521
|
+
POINTER(POINTER(dv_infer_request)),
|
|
2522
|
+
c_int,
|
|
2523
|
+
c_int,
|
|
2524
|
+
POINTER(POINTER(dv_infer_request)),
|
|
2525
|
+
POINTER(c_int)]
|
|
2526
|
+
fun.restype = dv_status_code
|
|
2527
|
+
completed_inf_list = POINTER(dv_infer_request)()
|
|
2528
|
+
completed_inf_count = c_int()
|
|
2529
|
+
status = fun(
|
|
2530
|
+
session,
|
|
2531
|
+
byref(inf_list),
|
|
2532
|
+
c_int(1),
|
|
2533
|
+
c_int(timeout),
|
|
2534
|
+
byref(completed_inf_list),
|
|
2535
|
+
byref(completed_inf_count))
|
|
2536
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
2537
|
+
return status, None, None
|
|
2538
|
+
return status, completed_inf_list, completed_inf_count
|
|
2539
|
+
|
|
2540
|
+
|
|
2541
|
+
def dv_get_endpoint_busyness(session, endpoint):
|
|
2542
|
+
""" Get the busyness for the endpoint.
|
|
2543
|
+
Server provides busyness of any one endpoint at the time of request
|
|
2544
|
+
Memory for is_busy bool variable should be provided by client app
|
|
2545
|
+
Returns DV_SUCCESS on success, else error
|
|
2546
|
+
|
|
2547
|
+
Parameters
|
|
2548
|
+
----------
|
|
2549
|
+
session : dv_session
|
|
2550
|
+
session handle
|
|
2551
|
+
endpoint : dv_endpoint
|
|
2552
|
+
endpoint handle for particular endpoint
|
|
2553
|
+
|
|
2554
|
+
Returns
|
|
2555
|
+
-------
|
|
2556
|
+
dv_status_code
|
|
2557
|
+
|
|
2558
|
+
is_busy : bool
|
|
2559
|
+
"""
|
|
2560
|
+
fun = _dvApiObj().dv_get_endpoint_busyness
|
|
2561
|
+
fun.argtypes = [POINTER(dv_session),
|
|
2562
|
+
POINTER(c_bool)]
|
|
2563
|
+
fun.restype = dv_status_code
|
|
2564
|
+
is_busy = c_bool()
|
|
2565
|
+
status = fun(session, endpoint, byref(is_busy))
|
|
2566
|
+
return status, is_busy
|
|
2567
|
+
|
|
2568
|
+
|
|
2569
|
+
def dv_infer_async_with_options(
|
|
2570
|
+
session, endpoint, model, inputs, outputs, infer_options):
|
|
2571
|
+
"""submits an asynchronous inference request.
|
|
2572
|
+
|
|
2573
|
+
Parameters
|
|
2574
|
+
----------
|
|
2575
|
+
session : dv_session
|
|
2576
|
+
session handle
|
|
2577
|
+
|
|
2578
|
+
endpoint : dv_endpoint
|
|
2579
|
+
endpoint handle for particular endpoint
|
|
2580
|
+
|
|
2581
|
+
model : dv_model
|
|
2582
|
+
|
|
2583
|
+
inputs : list of DVBlob
|
|
2584
|
+
pointers buffers that contain the inputs, this must contain pointers
|
|
2585
|
+
to each input in order, pointer at index 0 will be used to read data
|
|
2586
|
+
for the 1st input etc...
|
|
2587
|
+
|
|
2588
|
+
outputs : list of DVBlob
|
|
2589
|
+
ptrs to where outputs of the inference are written, this list must be
|
|
2590
|
+
in order, ie 1st output is written to the pointer at index 0, 2nd output
|
|
2591
|
+
is written to the pointer at index 1 etc..
|
|
2592
|
+
|
|
2593
|
+
infer_options : dv_infer_options
|
|
2594
|
+
|
|
2595
|
+
Warnings
|
|
2596
|
+
--------
|
|
2597
|
+
Please ensure that the object backing the ctypes.c_void_p are not allowed to
|
|
2598
|
+
be refcounted and freed or garbage collected - if the pointer becomes invalid
|
|
2599
|
+
while a response is being written to the ptr the runtime will segfault
|
|
2600
|
+
|
|
2601
|
+
Returns
|
|
2602
|
+
-------
|
|
2603
|
+
(dv_status_code, dv_infer_request)
|
|
2604
|
+
DV_SUCCESS, inf_request_id if the inference was submitted successfully
|
|
2605
|
+
to the inference proxy else, inf_request_id is invalid
|
|
2606
|
+
"""
|
|
2607
|
+
fun = _dvApiObj().dv_infer_async_with_options
|
|
2608
|
+
fun.argtypes = [POINTER(dv_session),
|
|
2609
|
+
POINTER(dv_endpoint),
|
|
2610
|
+
POINTER(dv_model),
|
|
2611
|
+
POINTER(dv_blob),
|
|
2612
|
+
POINTER(dv_blob),
|
|
2613
|
+
POINTER(POINTER(dv_infer_request)),
|
|
2614
|
+
POINTER(dv_infer_options)]
|
|
2615
|
+
fun.restype = dv_status_code
|
|
2616
|
+
inf_obj = POINTER(dv_infer_request)()
|
|
2617
|
+
status = fun(session,
|
|
2618
|
+
endpoint,
|
|
2619
|
+
model,
|
|
2620
|
+
cast(inputs, POINTER(dv_blob)),
|
|
2621
|
+
cast(outputs, POINTER(dv_blob)),
|
|
2622
|
+
byref(inf_obj),
|
|
2623
|
+
infer_options)
|
|
2624
|
+
|
|
2625
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
2626
|
+
return status, None
|
|
2627
|
+
|
|
2628
|
+
return status, inf_obj
|
|
2629
|
+
|
|
2630
|
+
|
|
2631
|
+
def dv_fetch_outputs_by_layer_name(
|
|
2632
|
+
inf_obj: dv_infer_request, src_op_layer_name: str) -> typing.Tuple[dv_status_code, typing.List[dv_blob]]:
|
|
2633
|
+
op_blobs = POINTER(dv_blob)()
|
|
2634
|
+
num_op = c_int()
|
|
2635
|
+
fun = _dvApiObj().dv_fetch_outputs_by_layer_name
|
|
2636
|
+
fun.argtypes = [
|
|
2637
|
+
POINTER(dv_infer_request),
|
|
2638
|
+
c_char_p,
|
|
2639
|
+
POINTER(
|
|
2640
|
+
POINTER(dv_blob)),
|
|
2641
|
+
POINTER(c_int)]
|
|
2642
|
+
fun.restype = dv_status_code
|
|
2643
|
+
|
|
2644
|
+
ret = fun(inf_obj, src_op_layer_name.encode(
|
|
2645
|
+
'utf-8'), byref(op_blobs), byref(num_op))
|
|
2646
|
+
output_blobs = []
|
|
2647
|
+
if ret == dv_status_code.DV_SUCCESS:
|
|
2648
|
+
for i in range(num_op.value):
|
|
2649
|
+
output_blobs.append(op_blobs[i])
|
|
2650
|
+
return ret, output_blobs
|
|
2651
|
+
|
|
2652
|
+
|
|
2653
|
+
def dv_reg_read(session, endpoint, address, value):
|
|
2654
|
+
""" reads the register at the address and returns the value
|
|
2655
|
+
|
|
2656
|
+
Parameters
|
|
2657
|
+
----------
|
|
2658
|
+
session : dv_session
|
|
2659
|
+
session handle
|
|
2660
|
+
|
|
2661
|
+
endpoint : dv_endpoint
|
|
2662
|
+
endpoint handle for particular endpoint
|
|
2663
|
+
|
|
2664
|
+
address : register address
|
|
2665
|
+
|
|
2666
|
+
value: the value saved at the provided address
|
|
2667
|
+
|
|
2668
|
+
"""
|
|
2669
|
+
fun = _dvApiObj().dv_reg_read
|
|
2670
|
+
fun.argtypes = [
|
|
2671
|
+
POINTER(dv_session),
|
|
2672
|
+
POINTER(dv_endpoint),
|
|
2673
|
+
c_uint32,
|
|
2674
|
+
POINTER(c_uint32)]
|
|
2675
|
+
fun.restype = dv_status_code
|
|
2676
|
+
return fun(session, endpoint, address, value)
|
|
2677
|
+
|
|
2678
|
+
|
|
2679
|
+
def dv_reg_write(session, endpoint, address, value):
|
|
2680
|
+
""" writes the value at the address
|
|
2681
|
+
|
|
2682
|
+
Parameters
|
|
2683
|
+
----------
|
|
2684
|
+
session : dv_session
|
|
2685
|
+
session handle
|
|
2686
|
+
|
|
2687
|
+
endpoint : dv_endpoint
|
|
2688
|
+
endpoint handle for particular endpoint
|
|
2689
|
+
|
|
2690
|
+
address : register address
|
|
2691
|
+
|
|
2692
|
+
value: the value to be written at the provided address
|
|
2693
|
+
|
|
2694
|
+
"""
|
|
2695
|
+
fun = _dvApiObj().dv_reg_write
|
|
2696
|
+
fun.argtypes = [
|
|
2697
|
+
POINTER(dv_session),
|
|
2698
|
+
POINTER(dv_endpoint),
|
|
2699
|
+
c_uint32,
|
|
2700
|
+
c_uint32]
|
|
2701
|
+
fun.restype = dv_status_code
|
|
2702
|
+
return fun(session, endpoint, address, value)
|
|
2703
|
+
|
|
2704
|
+
|
|
2705
|
+
def dv_mem_read(session, endpoint, address, value):
|
|
2706
|
+
""" reads from the memory address and returns the value
|
|
2707
|
+
|
|
2708
|
+
Parameters
|
|
2709
|
+
----------
|
|
2710
|
+
session : dv_session
|
|
2711
|
+
session handle
|
|
2712
|
+
|
|
2713
|
+
endpoint : dv_endpoint
|
|
2714
|
+
endpoint handle for particular endpoint
|
|
2715
|
+
|
|
2716
|
+
address : memory address
|
|
2717
|
+
|
|
2718
|
+
value: the value saved at the provided address
|
|
2719
|
+
|
|
2720
|
+
"""
|
|
2721
|
+
fun = _dvApiObj().dv_mem_read
|
|
2722
|
+
fun.argtypes = [
|
|
2723
|
+
POINTER(dv_session),
|
|
2724
|
+
POINTER(dv_endpoint),
|
|
2725
|
+
c_uint32,
|
|
2726
|
+
POINTER(c_uint32)]
|
|
2727
|
+
fun.restype = dv_status_code
|
|
2728
|
+
return fun(session, endpoint, address, value)
|
|
2729
|
+
|
|
2730
|
+
|
|
2731
|
+
def dv_mem_write(session, endpoint, address, value):
|
|
2732
|
+
""" writes the value at the memory address
|
|
2733
|
+
|
|
2734
|
+
Parameters
|
|
2735
|
+
----------
|
|
2736
|
+
session : dv_session
|
|
2737
|
+
session handle
|
|
2738
|
+
|
|
2739
|
+
endpoint : dv_endpoint
|
|
2740
|
+
endpoint handle for particular endpoint
|
|
2741
|
+
|
|
2742
|
+
address : memory address
|
|
2743
|
+
|
|
2744
|
+
value: the value to be written at the provided address
|
|
2745
|
+
|
|
2746
|
+
"""
|
|
2747
|
+
fun = _dvApiObj().dv_mem_write
|
|
2748
|
+
fun.argtypes = [
|
|
2749
|
+
POINTER(dv_session),
|
|
2750
|
+
POINTER(dv_endpoint),
|
|
2751
|
+
c_uint32,
|
|
2752
|
+
c_uint32]
|
|
2753
|
+
fun.restype = dv_status_code
|
|
2754
|
+
return fun(session, endpoint, address, value)
|
|
2755
|
+
|
|
2756
|
+
|
|
2757
|
+
def dv_bulk_read(session, endpoint, address, size, buffer,
|
|
2758
|
+
perf_mode=False, completion_time=None):
|
|
2759
|
+
""" Read in bulk(size) from the endpoint memory address to the buffer
|
|
2760
|
+
|
|
2761
|
+
Parameters
|
|
2762
|
+
----------
|
|
2763
|
+
session : dv_session
|
|
2764
|
+
session handle
|
|
2765
|
+
|
|
2766
|
+
endpoint : dv_endpoint
|
|
2767
|
+
endpoint handle for particular endpoint
|
|
2768
|
+
|
|
2769
|
+
address : endPoint memory address
|
|
2770
|
+
|
|
2771
|
+
size : size to read
|
|
2772
|
+
|
|
2773
|
+
buffer: buffer to be filled
|
|
2774
|
+
|
|
2775
|
+
perf_mode : enable perf mode in the interface, data will not be copied
|
|
2776
|
+
|
|
2777
|
+
completion_time : time to complete the operation
|
|
2778
|
+
|
|
2779
|
+
"""
|
|
2780
|
+
fun = _dvApiObj().dv_bulk_read
|
|
2781
|
+
fun.argtypes = [
|
|
2782
|
+
POINTER(dv_session),
|
|
2783
|
+
POINTER(dv_endpoint),
|
|
2784
|
+
c_uint32,
|
|
2785
|
+
c_uint32,
|
|
2786
|
+
POINTER(c_uint32),
|
|
2787
|
+
c_bool,
|
|
2788
|
+
POINTER(c_float)]
|
|
2789
|
+
fun.restype = dv_status_code
|
|
2790
|
+
return fun(session, endpoint, address, size,
|
|
2791
|
+
buffer, perf_mode, completion_time)
|
|
2792
|
+
|
|
2793
|
+
|
|
2794
|
+
###############################################################################
|
|
2795
|
+
# Object oriented APIs
|
|
2796
|
+
###############################################################################
|
|
2797
|
+
|
|
2798
|
+
def _one_time_callable_cleanup_function(f):
|
|
2799
|
+
""" a utility decorator that ensures that member function that must be called
|
|
2800
|
+
only once (like connection close, deallocate memory etc..) are called just
|
|
2801
|
+
once, for cases where the function may be called on garbage collection or by
|
|
2802
|
+
the users themselves
|
|
2803
|
+
|
|
2804
|
+
Methods marked with this decorator are definitely not idempotent and calling
|
|
2805
|
+
them repeatedly might cause issues
|
|
2806
|
+
"""
|
|
2807
|
+
@functools.wraps(f)
|
|
2808
|
+
def wrapper(target_self):
|
|
2809
|
+
attr = getattr(target_self, '_dv_is_deleted', None)
|
|
2810
|
+
if attr is None:
|
|
2811
|
+
retval = f(target_self)
|
|
2812
|
+
target_self._dv_is_deleted = retval
|
|
2813
|
+
else:
|
|
2814
|
+
return target_self._dv_is_deleted
|
|
2815
|
+
return wrapper
|
|
2816
|
+
|
|
2817
|
+
|
|
2818
|
+
class DVTensor:
|
|
2819
|
+
""" a convenience wrapper that encapsulates tensor along with its
|
|
2820
|
+
parameters for convenience
|
|
2821
|
+
|
|
2822
|
+
Attributes
|
|
2823
|
+
----------
|
|
2824
|
+
numpy_data : numpy array of type int8
|
|
2825
|
+
actual tensor data
|
|
2826
|
+
|
|
2827
|
+
params : DVIpTensorParam | DVOpTensorParam
|
|
2828
|
+
tensor parameter object, currently this will
|
|
2829
|
+
only contain DVOpTensorParam
|
|
2830
|
+
"""
|
|
2831
|
+
|
|
2832
|
+
def __init__(self, numpy_data, params, mem_desc=None, offset=0):
|
|
2833
|
+
self.numpy_data: np.ndarray = numpy_data
|
|
2834
|
+
self.params = params
|
|
2835
|
+
self.mem_desc = mem_desc
|
|
2836
|
+
self.offset = offset
|
|
2837
|
+
|
|
2838
|
+
def as_classification_output(self):
|
|
2839
|
+
""" treat the underlying int8 data as the output of a classification
|
|
2840
|
+
network. this operation is valid if `params.is_structure_output` and
|
|
2841
|
+
output_type on the DVLoadedModel is `DV_LAYER_OUTPUT_TYPE.DV_MODEL_NW_CLASSIFICATION`
|
|
2842
|
+
|
|
2843
|
+
At most 10 rows will be returned.
|
|
2844
|
+
|
|
2845
|
+
Returns
|
|
2846
|
+
-------
|
|
2847
|
+
dvClassificationOutput
|
|
2848
|
+
"""
|
|
2849
|
+
ptr = self.numpy_data.ctypes.data_as(c_char_p)
|
|
2850
|
+
return cast(ptr, POINTER(dvClassificationOutput)).contents
|
|
2851
|
+
|
|
2852
|
+
def as_fp32softmax_classification(self, n=10):
|
|
2853
|
+
""" treats the underlying data as if it the channels are pure probabilities
|
|
2854
|
+
given by a softmax layer, and return a DVClassificationOutput
|
|
2855
|
+
|
|
2856
|
+
Parameters
|
|
2857
|
+
----------
|
|
2858
|
+
n : int
|
|
2859
|
+
number of rows to return - this must be less than the number
|
|
2860
|
+
of channels in the output layer
|
|
2861
|
+
|
|
2862
|
+
Returns
|
|
2863
|
+
-------
|
|
2864
|
+
dvClassificationOutput
|
|
2865
|
+
"""
|
|
2866
|
+
channels = self.params.nch
|
|
2867
|
+
buf = self.numpy_data.astype(np.float32)
|
|
2868
|
+
items = (dvClassificationItem * n)()
|
|
2869
|
+
|
|
2870
|
+
for c in range(0, channels):
|
|
2871
|
+
for topk in range(0, n):
|
|
2872
|
+
if items[topk].score < buf[c]:
|
|
2873
|
+
for swap in reversed(range(topk, n)):
|
|
2874
|
+
items[swap].score = items[swap - 1].score
|
|
2875
|
+
items[swap].label = items[swap - 1].label
|
|
2876
|
+
items[topk].label = c
|
|
2877
|
+
items[topk].score = buf[c]
|
|
2878
|
+
break
|
|
2879
|
+
|
|
2880
|
+
return dvClassificationOutput(n, items)
|
|
2881
|
+
|
|
2882
|
+
def as_detection_output(self):
|
|
2883
|
+
""" treat the underlying data as structured output of a detection type
|
|
2884
|
+
network. this operation is valid if `params.is_structured_output`
|
|
2885
|
+
and the output_type is `DV_LAYER_OUTPUT_TYPE.DV_MODEL_NW_DETECTION`
|
|
2886
|
+
|
|
2887
|
+
At most 200 detection boxes will be returned
|
|
2888
|
+
|
|
2889
|
+
Returns
|
|
2890
|
+
-------
|
|
2891
|
+
dvDetectionOutput
|
|
2892
|
+
"""
|
|
2893
|
+
ptr = self.numpy_data.ctypes.data_as(c_char_p)
|
|
2894
|
+
return cast(ptr, POINTER(dvDetectionOutput)).contents
|
|
2895
|
+
|
|
2896
|
+
|
|
2897
|
+
class TimeStamp:
|
|
2898
|
+
def __init__(self, timestamp) -> None:
|
|
2899
|
+
self.tv_sec = timestamp.tv_sec
|
|
2900
|
+
self.tv_nsec = timestamp.tv_nsec
|
|
2901
|
+
|
|
2902
|
+
def __str__(self) -> str:
|
|
2903
|
+
return (" {} seconds, {} nanoseconds").format(
|
|
2904
|
+
self.tv_sec, self.tv_nsec)
|
|
2905
|
+
|
|
2906
|
+
|
|
2907
|
+
class DVInferStatistics:
|
|
2908
|
+
""" Inference performance stats
|
|
2909
|
+
|
|
2910
|
+
Attributes
|
|
2911
|
+
----------
|
|
2912
|
+
ep_hw_sys_clk : int
|
|
2913
|
+
|
|
2914
|
+
ep_hw_dram_clk : int
|
|
2915
|
+
DRAM clock at the time of inference
|
|
2916
|
+
|
|
2917
|
+
ep_hw_total_inference_cycles: int
|
|
2918
|
+
total cycles taken to compute inference in hardware, including floating point computation
|
|
2919
|
+
|
|
2920
|
+
ep_hw_fp_cycles: int
|
|
2921
|
+
cycles taken to compute floating point operation in hardware
|
|
2922
|
+
|
|
2923
|
+
tensor_read_time : float
|
|
2924
|
+
time taken in miliseconds to transfer output(s) from ep hardware dram to host dram
|
|
2925
|
+
|
|
2926
|
+
tensor_write_time : float
|
|
2927
|
+
time taken in miliseconds to submit inference request to ep hardware
|
|
2928
|
+
"""
|
|
2929
|
+
|
|
2930
|
+
def __init__(self, inf_stats):
|
|
2931
|
+
self.ep_hw_sys_clk = inf_stats[0].ep_hw_sys_clk
|
|
2932
|
+
self.ep_hw_dram_clk = inf_stats[0].ep_hw_dram_clk
|
|
2933
|
+
self.ep_hw_total_inference_cycles = inf_stats[0].ep_hw_total_inference_cycles
|
|
2934
|
+
self.ep_hw_fp_cycles = inf_stats[0].ep_hw_fp_cycles
|
|
2935
|
+
self.input_transfer_time = inf_stats[0].input_transfer_time
|
|
2936
|
+
self.output_transfer_time = inf_stats[0].output_transfer_time
|
|
2937
|
+
self.ep_queue_submission_time = inf_stats[0].ep_queue_submission_time
|
|
2938
|
+
self.input_transfer_start_time_stamp = TimeStamp(
|
|
2939
|
+
inf_stats[0].input_transfer_start_time_stamp)
|
|
2940
|
+
self.output_transfer_start_time_stamp = TimeStamp(
|
|
2941
|
+
inf_stats[0].output_transfer_start_time_stamp)
|
|
2942
|
+
self.inference_start_time_stamp = TimeStamp(
|
|
2943
|
+
inf_stats[0].inference_start_time_stamp)
|
|
2944
|
+
|
|
2945
|
+
def __str__(self):
|
|
2946
|
+
return ('dvInfStats: HwInfTime={:.2f}ms, HwFpComputationTime={:.2f}ms, HwPerfStats(sclk={} MHz, dclk={} MHz, TotalCycles={}, FPCycles={}), ' +
|
|
2947
|
+
'ipXferTime={:.2f}ms, opXferTime={:.2f}ms, queueSubmissionTime={:.2f}ms, input_transfer_start_time_stamp={}, output_transfer_start_time_stamp={}, inference_start_time_stamp={}').format(
|
|
2948
|
+
self.ep_hw_total_inference_cycles / (self.ep_hw_sys_clk * 1000),
|
|
2949
|
+
self.ep_hw_fp_cycles / (self.ep_hw_sys_clk * 1000),
|
|
2950
|
+
self.ep_hw_sys_clk,
|
|
2951
|
+
self.ep_hw_dram_clk,
|
|
2952
|
+
self.ep_hw_total_inference_cycles,
|
|
2953
|
+
self.ep_hw_fp_cycles,
|
|
2954
|
+
self.input_transfer_time,
|
|
2955
|
+
self.output_transfer_time,
|
|
2956
|
+
self.ep_queue_submission_time,
|
|
2957
|
+
self.input_transfer_start_time_stamp,
|
|
2958
|
+
self.output_transfer_start_time_stamp,
|
|
2959
|
+
self.inference_start_time_stamp
|
|
2960
|
+
)
|
|
2961
|
+
|
|
2962
|
+
|
|
2963
|
+
class DVLLMInferInfo:
|
|
2964
|
+
def __init__(self, llm_info: dv_infer_llm_info):
|
|
2965
|
+
self.llm_infer_resp_num_valid_tokens = llm_info[0].llm_infer_resp_num_valid_tokens
|
|
2966
|
+
|
|
2967
|
+
|
|
2968
|
+
class DVInferRequest:
|
|
2969
|
+
""" response that represents a response that is yet to
|
|
2970
|
+
reach a terminal state
|
|
2971
|
+
|
|
2972
|
+
Attributes
|
|
2973
|
+
----------
|
|
2974
|
+
request_id
|
|
2975
|
+
request_id returned by the proxy for the enqueued
|
|
2976
|
+
inference request
|
|
2977
|
+
|
|
2978
|
+
inputs: [DVTensor]
|
|
2979
|
+
original inputs passed to the sync or async inference APIs
|
|
2980
|
+
|
|
2981
|
+
outputs : [DVTensor]
|
|
2982
|
+
outputs of the inference
|
|
2983
|
+
|
|
2984
|
+
model_obj : DVModel
|
|
2985
|
+
dv_model object
|
|
2986
|
+
|
|
2987
|
+
stats : DVInferStatistics
|
|
2988
|
+
statistics collected for the inference request. this information
|
|
2989
|
+
is available only after `wait_for_completion` is invoked on the inference
|
|
2990
|
+
which ran succesfully
|
|
2991
|
+
|
|
2992
|
+
status: dv_inference_status
|
|
2993
|
+
"""
|
|
2994
|
+
|
|
2995
|
+
def __init__(self, inputs: typing.List[DVTensor],
|
|
2996
|
+
outputs: typing.List[DVTensor], inf_req: dv_infer_request, model_obj):
|
|
2997
|
+
self._inf_req = inf_req
|
|
2998
|
+
self.handle = inf_req[0].handle
|
|
2999
|
+
self.session = inf_req[0].session
|
|
3000
|
+
self._model = inf_req[0].model
|
|
3001
|
+
self.ep_queued = DVEndpoint(inf_req[0].ep_submitted[0])
|
|
3002
|
+
self.ep_submitted = None
|
|
3003
|
+
self.model = model_obj
|
|
3004
|
+
self.inputs = inputs
|
|
3005
|
+
self.outputs = outputs
|
|
3006
|
+
self.status = inf_req[0].status
|
|
3007
|
+
self.stats = None
|
|
3008
|
+
self.llm_infer_info = None
|
|
3009
|
+
|
|
3010
|
+
if self.status == dv_inference_status.DV_INFERENCE_STATUS_COMPLETED or self.status == dv_inference_status.DV_INFERENCE_STATUS_FAILED:
|
|
3011
|
+
self.stats = DVInferStatistics(inf_req[0].stats)
|
|
3012
|
+
try:
|
|
3013
|
+
self.ep_submitted = DVEndpoint(inf_req[0].ep_submitted[0])
|
|
3014
|
+
except BaseException:
|
|
3015
|
+
self.ep_submitted = None
|
|
3016
|
+
|
|
3017
|
+
try:
|
|
3018
|
+
self.llm_infer_info = DVLLMInferInfo(
|
|
3019
|
+
self._inf_req[0].llm_infer_info)
|
|
3020
|
+
except BaseException:
|
|
3021
|
+
self.llm_infer_info = None
|
|
3022
|
+
|
|
3023
|
+
@_one_time_callable_cleanup_function
|
|
3024
|
+
def mark_complete(self):
|
|
3025
|
+
"""DVInferRequest method that finish the life cycle for the inference request.
|
|
3026
|
+
API will free up the associated memory for the inference request and will no longer be accessible.
|
|
3027
|
+
After completion, any operation on the inference request will be invalid.
|
|
3028
|
+
|
|
3029
|
+
Returns
|
|
3030
|
+
-------
|
|
3031
|
+
dv_status_code
|
|
3032
|
+
|
|
3033
|
+
"""
|
|
3034
|
+
return dv_infer_free(self._inf_req)
|
|
3035
|
+
|
|
3036
|
+
def __del__(self):
|
|
3037
|
+
self.mark_complete()
|
|
3038
|
+
|
|
3039
|
+
def wait_for_completion(self, timeout=50000):
|
|
3040
|
+
""" blocks on the current thread till either inference completes
|
|
3041
|
+
or the timeout supplied in the initial inference call is exceeded
|
|
3042
|
+
|
|
3043
|
+
if the request has already reached a terminal state, `DV_SUCCESS` is returned
|
|
3044
|
+
|
|
3045
|
+
Parameters
|
|
3046
|
+
----------
|
|
3047
|
+
timeout : int
|
|
3048
|
+
timeout to wait for inference response
|
|
3049
|
+
|
|
3050
|
+
Returns
|
|
3051
|
+
-------
|
|
3052
|
+
dv_status_code
|
|
3053
|
+
"""
|
|
3054
|
+
|
|
3055
|
+
# return immediately if we already have success
|
|
3056
|
+
if self.status == dv_inference_status.DV_INFERENCE_STATUS_COMPLETED or self.status == dv_inference_status.DV_INFERENCE_STATUS_FAILED:
|
|
3057
|
+
return dv_status_code.DV_SUCCESS
|
|
3058
|
+
|
|
3059
|
+
status, completed_req = dv_infer_wait_for_completion(
|
|
3060
|
+
self.session, self._inf_req, timeout)
|
|
3061
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
3062
|
+
return status
|
|
3063
|
+
|
|
3064
|
+
self.stats = DVInferStatistics(completed_req[0].stats)
|
|
3065
|
+
self.status = completed_req[0].status
|
|
3066
|
+
try:
|
|
3067
|
+
self.ep_submitted = DVEndpoint(completed_req[0].ep_submitted[0])
|
|
3068
|
+
except BaseException:
|
|
3069
|
+
self.ep_submitted = None
|
|
3070
|
+
|
|
3071
|
+
try:
|
|
3072
|
+
self.llm_infer_info = DVLLMInferInfo(
|
|
3073
|
+
self._inf_req[0].llm_infer_info)
|
|
3074
|
+
except BaseException:
|
|
3075
|
+
self.llm_infer_info = None
|
|
3076
|
+
return status
|
|
3077
|
+
|
|
3078
|
+
def get_output_tensors(self):
|
|
3079
|
+
return self.outputs
|
|
3080
|
+
|
|
3081
|
+
def get_infer_req_id(self):
|
|
3082
|
+
"""
|
|
3083
|
+
Returns the status code and request id of an inference
|
|
3084
|
+
|
|
3085
|
+
If return value is DV_SUCCESS req_id will contain the request id of the
|
|
3086
|
+
inference request sent to kinara inference proxy
|
|
3087
|
+
|
|
3088
|
+
Returns
|
|
3089
|
+
-------
|
|
3090
|
+
dv_status_code : SUCCESS or FAILURE code
|
|
3091
|
+
int : req_id
|
|
3092
|
+
"""
|
|
3093
|
+
return dv_infer_get_req_id(self._inf_req)
|
|
3094
|
+
|
|
3095
|
+
def get_performance_statistics(self):
|
|
3096
|
+
"""
|
|
3097
|
+
returns the inference statistics for a completed inference request
|
|
3098
|
+
stats are generated only for inference that complete successfully
|
|
3099
|
+
|
|
3100
|
+
Returns
|
|
3101
|
+
-------
|
|
3102
|
+
(dv_status_code, DVInferStatistics)
|
|
3103
|
+
|
|
3104
|
+
|
|
3105
|
+
Notes
|
|
3106
|
+
-----
|
|
3107
|
+
The perf stats pertaining to an inference are not held by the
|
|
3108
|
+
server for a long duration and will be overwritten when it needs
|
|
3109
|
+
more memory, in such scenario the dv_status_code returned will be
|
|
3110
|
+
DV_INF_REQUEST_INVALID_HANDLE
|
|
3111
|
+
"""
|
|
3112
|
+
return dv_status_code.DV_SUCCESS, self.stats
|
|
3113
|
+
|
|
3114
|
+
def fetch_outputs_for_layer(
|
|
3115
|
+
self, src_op_layer_name: str) -> typing.Tuple[dv_status_code, typing.List[dv_blob]]:
|
|
3116
|
+
return dv_fetch_outputs_by_layer_name(self._inf_req, src_op_layer_name)
|
|
3117
|
+
|
|
3118
|
+
|
|
3119
|
+
class DVModelInputPreProcessParam:
|
|
3120
|
+
""" input image preprocessing as specified by the model
|
|
3121
|
+
|
|
3122
|
+
Attributes
|
|
3123
|
+
----------
|
|
3124
|
+
|
|
3125
|
+
aspect_resize : bool
|
|
3126
|
+
mirror : bool
|
|
3127
|
+
center_crop : bool
|
|
3128
|
+
bgr2rgb : bool
|
|
3129
|
+
mean : float
|
|
3130
|
+
scale : float
|
|
3131
|
+
qn : float
|
|
3132
|
+
aspect_resize_scale : float
|
|
3133
|
+
interpolation : int
|
|
3134
|
+
corresponds to the following enum (check See Also)
|
|
3135
|
+
NN = 0
|
|
3136
|
+
LINEAR = 1
|
|
3137
|
+
CUBIC = 2
|
|
3138
|
+
AREA = 3
|
|
3139
|
+
LANCZOS4 = 4
|
|
3140
|
+
|
|
3141
|
+
See Also
|
|
3142
|
+
--------
|
|
3143
|
+
dutils.preprocessor (preprocessor.py script shipped in debug utils)
|
|
3144
|
+
"""
|
|
3145
|
+
|
|
3146
|
+
def __init__(self, input_preproc_param, nch):
|
|
3147
|
+
self.qn = input_preproc_param.qn
|
|
3148
|
+
self.aspect_resize = input_preproc_param.aspect_resize
|
|
3149
|
+
self.mirror = input_preproc_param.mirror
|
|
3150
|
+
self.center_crop = input_preproc_param.center_crop
|
|
3151
|
+
self.bgr_to_rgb = input_preproc_param.bgr_to_rgb
|
|
3152
|
+
self.interpolation = input_preproc_param.interpolation
|
|
3153
|
+
self.is_signed = input_preproc_param.is_signed
|
|
3154
|
+
self.bpp = input_preproc_param.bpp
|
|
3155
|
+
self.output_scale = input_preproc_param.output_scale
|
|
3156
|
+
self.aspect_resize_scale = input_preproc_param.aspect_resize_scale
|
|
3157
|
+
self.mean = []
|
|
3158
|
+
self.scale = []
|
|
3159
|
+
self.offset = input_preproc_param.offset
|
|
3160
|
+
self.qmode = input_preproc_param.qmode
|
|
3161
|
+
|
|
3162
|
+
if nch <= 3:
|
|
3163
|
+
for i in range(0, nch):
|
|
3164
|
+
self.mean.append(input_preproc_param.mean[i])
|
|
3165
|
+
self.scale.append(input_preproc_param.scale[i])
|
|
3166
|
+
|
|
3167
|
+
def __str__(self):
|
|
3168
|
+
ipp_str = 'qn={}, scale={}, mean={}, aspect_resize={}, mirror={}, center_crop={}, bgr_to_rgb={} interpolation={}, offset:{}, qmode:{},'.format(
|
|
3169
|
+
self.qn, self.scale, self.mean, self.aspect_resize, self.mirror, self.center_crop, self.bgr_to_rgb, self.interpolation, self.offset, self.qmode)
|
|
3170
|
+
return ipp_str
|
|
3171
|
+
|
|
3172
|
+
|
|
3173
|
+
class DVModelInputParam:
|
|
3174
|
+
""" Input tensor params
|
|
3175
|
+
|
|
3176
|
+
Attributes
|
|
3177
|
+
----------
|
|
3178
|
+
id : int
|
|
3179
|
+
layer_id
|
|
3180
|
+
|
|
3181
|
+
size : int
|
|
3182
|
+
size in bytes of the input tensor
|
|
3183
|
+
|
|
3184
|
+
width : int
|
|
3185
|
+
height : int
|
|
3186
|
+
depth : int
|
|
3187
|
+
channels : int
|
|
3188
|
+
num : int
|
|
3189
|
+
input_format : int
|
|
3190
|
+
|
|
3191
|
+
layer_name : str
|
|
3192
|
+
name of the layer as per the generated caffe.prototxt
|
|
3193
|
+
|
|
3194
|
+
layer_type : str
|
|
3195
|
+
type of the neural network layer
|
|
3196
|
+
|
|
3197
|
+
preproc_params : DVIpTensorPreProcParams
|
|
3198
|
+
represents the preprocessing that needs to be done on raw JPEG images
|
|
3199
|
+
before they can be quantized and supplied to the model
|
|
3200
|
+
"""
|
|
3201
|
+
|
|
3202
|
+
def __init__(self, input_param):
|
|
3203
|
+
self.layer_id = input_param.layer_id
|
|
3204
|
+
self.blob_id = input_param.blob_id
|
|
3205
|
+
self.layer_name = input_param.layer_name.decode('utf-8')
|
|
3206
|
+
self.blob_name = input_param.blob_name.decode('utf-8')
|
|
3207
|
+
self.layer_type = input_param.layer_type.decode('utf-8')
|
|
3208
|
+
self.layout = input_param.layout.decode('utf-8')
|
|
3209
|
+
self.size = input_param.size
|
|
3210
|
+
self.width = input_param.width
|
|
3211
|
+
self.height = input_param.height
|
|
3212
|
+
self.depth = input_param.depth
|
|
3213
|
+
self.nch = input_param.nch
|
|
3214
|
+
self.bpp = input_param.bpp
|
|
3215
|
+
self.batch_size = input_param.batch_size
|
|
3216
|
+
self.num = input_param.num
|
|
3217
|
+
self.src_graph_layer_name = input_param.src_graph_layer_name.decode(
|
|
3218
|
+
'utf-8')
|
|
3219
|
+
self.preprocess_param = DVModelInputPreProcessParam(
|
|
3220
|
+
input_param.preprocess_param[0], input_param.nch)
|
|
3221
|
+
|
|
3222
|
+
def __str__(self):
|
|
3223
|
+
ipparam_str = 'layer_id={}, blob_id={}, layer_name={}, blob_name={}, layer_type={}, layout={}, size={}, width={}, height={}, depth={}, nch={}, bpp={}, batch_size={}, num:{}, src_graph_layer_name:{}, \npreprocess_params:{}'.format(
|
|
3224
|
+
self.layer_id, self.blob_id, self.layer_name, self.blob_name, self.layer_type, self.layout,
|
|
3225
|
+
self.size, self.width, self.height, self.depth,
|
|
3226
|
+
self.nch, self.bpp, self.batch_size, self.num, self.src_graph_layer_name, self.preprocess_param)
|
|
3227
|
+
return ipparam_str
|
|
3228
|
+
|
|
3229
|
+
|
|
3230
|
+
class DVModelOutputPostProcessParam:
|
|
3231
|
+
def __init__(self, op_postproc_param):
|
|
3232
|
+
self.qn = op_postproc_param.qn
|
|
3233
|
+
self.is_struct_format = op_postproc_param.is_struct_format
|
|
3234
|
+
self.is_float = op_postproc_param.is_float
|
|
3235
|
+
self.is_signed = op_postproc_param.is_signed
|
|
3236
|
+
self.output_scale = op_postproc_param.output_scale
|
|
3237
|
+
self.offset = op_postproc_param.offset
|
|
3238
|
+
|
|
3239
|
+
def __str__(self):
|
|
3240
|
+
ip_preproc_str = 'qn={}, is_struct_format={}, is_float={}, is_signed={}, output_scale = {}, offset = {}'.format(
|
|
3241
|
+
self.qn, self.is_struct_format, self.is_float, self.is_signed, self.output_scale, self.offset)
|
|
3242
|
+
return ip_preproc_str
|
|
3243
|
+
|
|
3244
|
+
|
|
3245
|
+
class DVModelOutputParam:
|
|
3246
|
+
""" describes an output tensor
|
|
3247
|
+
|
|
3248
|
+
Attributes
|
|
3249
|
+
----------
|
|
3250
|
+
id : str
|
|
3251
|
+
layer_id
|
|
3252
|
+
|
|
3253
|
+
size : int
|
|
3254
|
+
size in bytes of the tensor
|
|
3255
|
+
|
|
3256
|
+
width : int
|
|
3257
|
+
height : int
|
|
3258
|
+
depth : int
|
|
3259
|
+
channels : int
|
|
3260
|
+
num : int
|
|
3261
|
+
ncl : int
|
|
3262
|
+
|
|
3263
|
+
bpp : int
|
|
3264
|
+
bytes per pixel
|
|
3265
|
+
|
|
3266
|
+
is_struct_format : bool
|
|
3267
|
+
specifies if the output must be cast to a C struct type specified
|
|
3268
|
+
in `dvoutstruct.h`
|
|
3269
|
+
|
|
3270
|
+
is_output_signed : bool
|
|
3271
|
+
specifies if the output is signed
|
|
3272
|
+
|
|
3273
|
+
is_output_float : bool
|
|
3274
|
+
specifies if the output is to be treated as 32 bit floating point
|
|
3275
|
+
|
|
3276
|
+
output_qn : float
|
|
3277
|
+
|
|
3278
|
+
fused_layer_name : str
|
|
3279
|
+
|
|
3280
|
+
layer_name : str
|
|
3281
|
+
name of the neural network layer
|
|
3282
|
+
|
|
3283
|
+
layer_type : str
|
|
3284
|
+
type of the neural network layer that produces this output
|
|
3285
|
+
|
|
3286
|
+
Notes
|
|
3287
|
+
-----
|
|
3288
|
+
|
|
3289
|
+
usage of `bpp` and `is_output_signed`
|
|
3290
|
+
|
|
3291
|
+
========= ================ ===========
|
|
3292
|
+
bpp value is_output_signed numpy dtype
|
|
3293
|
+
========= ================ ===========
|
|
3294
|
+
1 False np.uint8
|
|
3295
|
+
1 True np.int8
|
|
3296
|
+
2 False np.uint16
|
|
3297
|
+
2 True np.int16
|
|
3298
|
+
4 False np.uint32
|
|
3299
|
+
4 True np.int32
|
|
3300
|
+
========= ================ ===========
|
|
3301
|
+
|
|
3302
|
+
"""
|
|
3303
|
+
|
|
3304
|
+
def __init__(self, output_param):
|
|
3305
|
+
self.layer_id = output_param.layer_id
|
|
3306
|
+
self.blob_id = output_param.blob_id
|
|
3307
|
+
self.fused_parent_id = output_param.fused_parent_id
|
|
3308
|
+
self.layer_name = output_param.layer_name.decode('utf-8')
|
|
3309
|
+
self.blob_name = output_param.blob_name.decode('utf-8')
|
|
3310
|
+
self.layer_fused_parent_name = output_param.layer_fused_parent_name.decode(
|
|
3311
|
+
'utf-8')
|
|
3312
|
+
self.layer_type = output_param.layer_type.decode('utf-8')
|
|
3313
|
+
self.layout = output_param.layout.decode('utf-8')
|
|
3314
|
+
self.size = output_param.size
|
|
3315
|
+
self.width = output_param.width
|
|
3316
|
+
self.height = output_param.height
|
|
3317
|
+
self.depth = output_param.depth
|
|
3318
|
+
self.nch = output_param.nch
|
|
3319
|
+
self.bpp = output_param.bpp
|
|
3320
|
+
self.num_classes = output_param.num_classes
|
|
3321
|
+
self.layer_output_type = output_param.layer_output_type
|
|
3322
|
+
self.num = output_param.num
|
|
3323
|
+
self.max_dynamic_id = output_param.max_dynamic_id
|
|
3324
|
+
self.src_graph_layer_name = output_param.src_graph_layer_name.decode(
|
|
3325
|
+
'utf-8')
|
|
3326
|
+
self.postprocess_param = DVModelOutputPostProcessParam(
|
|
3327
|
+
output_param.postprocess_param[0])
|
|
3328
|
+
|
|
3329
|
+
def __str__(self):
|
|
3330
|
+
opparam_str = 'layer_id={}, blob_id={}, fused_parent_id={},layer_name={}, blob_name={}, layer_fused_parent_name={}, layer_type={}, layout={}, size={}, width={}, height={}, depth={}, nch={}, bpp={}, num_classes={}, layer_output_type={}, num={}, max_dynamic_id={}, src_graph_layer_name={}, postprocess_param={}'.format(
|
|
3331
|
+
self.layer_id, self.blob_id, self.fused_parent_id, self.layer_name, self.blob_name, self.layer_fused_parent_name, self.layer_type, self.layout,
|
|
3332
|
+
self.size, self.width, self.height, self.depth,
|
|
3333
|
+
self.nch, self.bpp, self.num_classes, self.layer_output_type, self.num, self.max_dynamic_id, self.src_graph_layer_name, self.postprocess_param)
|
|
3334
|
+
|
|
3335
|
+
return opparam_str
|
|
3336
|
+
|
|
3337
|
+
|
|
3338
|
+
class DVModelLoadOptions:
|
|
3339
|
+
def __init__(self, model_load_options):
|
|
3340
|
+
self._model_load_options = model_load_options
|
|
3341
|
+
self.model_name = model_load_options[0].model_name.decode('utf-8')
|
|
3342
|
+
self.priority = model_load_options[0].priority
|
|
3343
|
+
self.cache = model_load_options[0].cache
|
|
3344
|
+
self.model_type = model_load_options[0].model_type
|
|
3345
|
+
self.model_async = getattr(model_load_options[0], "async")
|
|
3346
|
+
|
|
3347
|
+
@classmethod
|
|
3348
|
+
def model_load_option(cls, model_name="model.dvm", priority=1, cache=False,
|
|
3349
|
+
model_async=False, model_type: dv_model_type = dv_model_type.DV_MODEL_TYPE_ARA2_CNN):
|
|
3350
|
+
m_options = dv_model_options(
|
|
3351
|
+
model_name.encode('utf-8'),
|
|
3352
|
+
c_int(priority),
|
|
3353
|
+
c_bool(cache),
|
|
3354
|
+
c_bool(model_async),
|
|
3355
|
+
dv_model_type(model_type))
|
|
3356
|
+
m_options_pointer = pointer(m_options)
|
|
3357
|
+
dv_model_load_options = cls(m_options_pointer)
|
|
3358
|
+
return dv_model_load_options
|
|
3359
|
+
|
|
3360
|
+
def __str__(self):
|
|
3361
|
+
model_load_options = "model_name={}, priority={}, cache={}, async={}, model_type={}".format(
|
|
3362
|
+
self.model_name, self.priority, self.cache, self.model_async, self.model_type)
|
|
3363
|
+
return model_load_options
|
|
3364
|
+
|
|
3365
|
+
|
|
3366
|
+
class DVLLMModelCfgUpdateParams:
|
|
3367
|
+
def __init__(self, llm_config_update_params: dv_llm_cfg_upd_req):
|
|
3368
|
+
self._llm_config_options = llm_config_update_params
|
|
3369
|
+
self.top_k = llm_config_update_params[0].top_k
|
|
3370
|
+
self.top_p = llm_config_update_params[0].top_p
|
|
3371
|
+
self.temperature = llm_config_update_params[0].temperature
|
|
3372
|
+
self.repetition_penalty = llm_config_update_params[0].repetition_penalty
|
|
3373
|
+
self.target_token_post_mcp = llm_config_update_params[0].target_token_post_mcp
|
|
3374
|
+
self.target_token_pre_mcp = llm_config_update_params[0].target_token_pre_mcp
|
|
3375
|
+
self.target_prompt_post_mcp = llm_config_update_params[0].target_prompt_post_mcp
|
|
3376
|
+
self.target_prompt_pre_mcp = llm_config_update_params[0].target_prompt_pre_mcp
|
|
3377
|
+
self.draft_token_post_mcp = llm_config_update_params[0].draft_token_post_mcp
|
|
3378
|
+
self.draft_token_pre_mcp = llm_config_update_params[0].draft_token_pre_mcp
|
|
3379
|
+
self.draft_prompt_post_mcp = llm_config_update_params[0].draft_prompt_post_mcp
|
|
3380
|
+
self.draft_prompt_pre_mcp = llm_config_update_params[0].draft_prompt_pre_mcp
|
|
3381
|
+
|
|
3382
|
+
@classmethod
|
|
3383
|
+
def llm_model_cfg_options(cls, top_k=1, top_p=0.9, temperature=0.7, repetition_penalty=1.12, target_token_post_mcp=0, target_token_pre_mcp=0,
|
|
3384
|
+
target_prompt_post_mcp=0, target_prompt_pre_mcp=0, draft_token_post_mcp=1, draft_token_pre_mcp=1, draft_prompt_post_mcp=1, draft_prompt_pre_mcp=1):
|
|
3385
|
+
cfg_options = dv_llm_cfg_upd_req(
|
|
3386
|
+
c_uint32(top_k),
|
|
3387
|
+
c_float(top_p),
|
|
3388
|
+
c_float(temperature),
|
|
3389
|
+
c_float(repetition_penalty),
|
|
3390
|
+
c_uint32(target_token_post_mcp),
|
|
3391
|
+
c_uint32(target_token_pre_mcp),
|
|
3392
|
+
c_uint32(target_prompt_post_mcp),
|
|
3393
|
+
c_uint32(target_prompt_pre_mcp),
|
|
3394
|
+
c_uint32(draft_token_post_mcp),
|
|
3395
|
+
c_uint32(draft_token_pre_mcp),
|
|
3396
|
+
c_uint32(draft_prompt_post_mcp),
|
|
3397
|
+
c_uint32(draft_prompt_pre_mcp))
|
|
3398
|
+
cfg_options_pointer = pointer(cfg_options)
|
|
3399
|
+
dv_llm_cfg_options = cls(cfg_options_pointer)
|
|
3400
|
+
return dv_llm_cfg_options
|
|
3401
|
+
|
|
3402
|
+
|
|
3403
|
+
class DVInferOptions:
|
|
3404
|
+
def __init__(self, infer_options_handle: dv_infer_options):
|
|
3405
|
+
self._infer_options_handle = infer_options_handle
|
|
3406
|
+
self.enable_stats: bool = infer_options_handle[0].enable_stats
|
|
3407
|
+
self.infer_type: dv_infer_type = infer_options_handle[0].infer_type
|
|
3408
|
+
self.active_tokens: c_int64 = infer_options_handle[0].active_tokens
|
|
3409
|
+
self.valid_tokens: c_int64 = infer_options_handle[0].valid_tokens
|
|
3410
|
+
self.tokens_to_skip: c_int32 = infer_options_handle[0].tokens_to_skip
|
|
3411
|
+
|
|
3412
|
+
@classmethod
|
|
3413
|
+
def dv_infer_options(cls, enable_stats: bool, infer_type: dv_infer_type,
|
|
3414
|
+
active_tokens: int, valid_tokens: int, tokens_to_skip: int):
|
|
3415
|
+
m_infer_options = dv_infer_options(
|
|
3416
|
+
c_bool(enable_stats),
|
|
3417
|
+
c_int(infer_type),
|
|
3418
|
+
c_uint64(active_tokens),
|
|
3419
|
+
c_uint32(valid_tokens),
|
|
3420
|
+
c_uint32(tokens_to_skip))
|
|
3421
|
+
m_infer_options_ptr = pointer(m_infer_options)
|
|
3422
|
+
return cls(m_infer_options_ptr)
|
|
3423
|
+
|
|
3424
|
+
def __str__(self):
|
|
3425
|
+
# todo ::
|
|
3426
|
+
return "DVInferOptions, this need to be filled "
|
|
3427
|
+
|
|
3428
|
+
|
|
3429
|
+
class DVBlob(Structure):
|
|
3430
|
+
""" specification of a tensor
|
|
3431
|
+
|
|
3432
|
+
Attributes
|
|
3433
|
+
----------
|
|
3434
|
+
|
|
3435
|
+
handle : c_void_p
|
|
3436
|
+
void pointer to the underlying buffer or memory mapped file
|
|
3437
|
+
|
|
3438
|
+
offset : int
|
|
3439
|
+
applicable for memory mapped files - offset at which the tensor
|
|
3440
|
+
is located in the file
|
|
3441
|
+
|
|
3442
|
+
size : int
|
|
3443
|
+
size of the tensor in a memory mapped file starting for offset
|
|
3444
|
+
|
|
3445
|
+
blob_type : dv_blob_type
|
|
3446
|
+
type of blob.
|
|
3447
|
+
"""
|
|
3448
|
+
_fields_ = [("handle", c_void_p),
|
|
3449
|
+
("offset", c_uint64),
|
|
3450
|
+
("size", c_uint64),
|
|
3451
|
+
("blob_type", c_int)]
|
|
3452
|
+
|
|
3453
|
+
def for_shm_desc(self, shm_desc, offset, size):
|
|
3454
|
+
""" utility that sets the attribute values for a mmapped file
|
|
3455
|
+
|
|
3456
|
+
Parameters
|
|
3457
|
+
----------
|
|
3458
|
+
shm_desc : dv_shm_descriptor
|
|
3459
|
+
shm_desc as returned by dv_shmfile_register
|
|
3460
|
+
|
|
3461
|
+
offset : int
|
|
3462
|
+
|
|
3463
|
+
size : int
|
|
3464
|
+
"""
|
|
3465
|
+
ptr = cast(shm_desc, c_void_p)
|
|
3466
|
+
self.handle = ptr
|
|
3467
|
+
self.offset = c_uint64(offset)
|
|
3468
|
+
self.size = c_uint64(size)
|
|
3469
|
+
self.blob_type = c_int(dv_blob_type.DV_BLOB_TYPE_SHM_DESCRIPTOR)
|
|
3470
|
+
|
|
3471
|
+
def for_raw_pointer(self, ctypes_void_ptr, size):
|
|
3472
|
+
""" set attribute values for a raw ctypes buffer
|
|
3473
|
+
|
|
3474
|
+
Parameters
|
|
3475
|
+
----------
|
|
3476
|
+
ctypes_void_ptr : c_void_p
|
|
3477
|
+
pointer to a buffer, normally we pass np.array().ctypes.data_as(c_void_p)
|
|
3478
|
+
|
|
3479
|
+
size : int
|
|
3480
|
+
"""
|
|
3481
|
+
self.handle = ctypes_void_ptr
|
|
3482
|
+
self.offset = c_uint64(0)
|
|
3483
|
+
self.size = c_uint64(size)
|
|
3484
|
+
self.blob_type = c_int(dv_blob_type.DV_BLOB_TYPE_RAW_POINTER)
|
|
3485
|
+
|
|
3486
|
+
|
|
3487
|
+
class DVModel:
|
|
3488
|
+
""" a model that has been loaded onto an endpoint
|
|
3489
|
+
|
|
3490
|
+
Attributes
|
|
3491
|
+
----------
|
|
3492
|
+
|
|
3493
|
+
model : DVModel
|
|
3494
|
+
Underlying model buffer that was parsed - this is stateless
|
|
3495
|
+
|
|
3496
|
+
connection : DVConnection
|
|
3497
|
+
The proxy connection which was used to load the model
|
|
3498
|
+
|
|
3499
|
+
"""
|
|
3500
|
+
|
|
3501
|
+
def __init__(self, model):
|
|
3502
|
+
self._model = model
|
|
3503
|
+
self.handle = model.handle
|
|
3504
|
+
self.session = model.session
|
|
3505
|
+
self.endpoint = model.endpoint
|
|
3506
|
+
self.version = model.version
|
|
3507
|
+
self.name = model.name.decode('utf-8')
|
|
3508
|
+
self.internal_name = model.internal_name.decode('utf-8')
|
|
3509
|
+
self.priority = model.priority
|
|
3510
|
+
self.num_inputs = model.num_inputs
|
|
3511
|
+
self.num_outputs = model.num_outputs
|
|
3512
|
+
self.input_param = []
|
|
3513
|
+
self.output_param = []
|
|
3514
|
+
self.num_compiler_config = model.num_compiler_config
|
|
3515
|
+
self.compiler_stats = []
|
|
3516
|
+
self.cp_layer = model.cp_layer
|
|
3517
|
+
self.model_type = dv_model_type(model.model_type)
|
|
3518
|
+
if dv_is_null(model.model_load_options):
|
|
3519
|
+
self.model_load_options = None
|
|
3520
|
+
else:
|
|
3521
|
+
self.model_load_options = DVModelLoadOptions(
|
|
3522
|
+
model.model_load_options)
|
|
3523
|
+
if (self.model_type is not (dv_model_type.DV_MODEL_TYPE_ARA2_LLM_DYN_V2)) and (
|
|
3524
|
+
self.model_type is not (dv_model_type.DV_MODEL_TYPE_ARA2_LLM)):
|
|
3525
|
+
for i in range(0, self.num_compiler_config):
|
|
3526
|
+
self.compiler_stats.append(
|
|
3527
|
+
DVCompilerStats(model.compiler_stats[i]))
|
|
3528
|
+
|
|
3529
|
+
for i in range(0, self.num_inputs):
|
|
3530
|
+
if model.input_param[i] is not None:
|
|
3531
|
+
self.input_param.append(
|
|
3532
|
+
DVModelInputParam(
|
|
3533
|
+
model.input_param[i]))
|
|
3534
|
+
else:
|
|
3535
|
+
print("DVModelInputParam idx:{} is none", i)
|
|
3536
|
+
|
|
3537
|
+
for j in range(0, self.num_outputs):
|
|
3538
|
+
self.output_param.append(
|
|
3539
|
+
DVModelOutputParam(
|
|
3540
|
+
model.output_param[j]))
|
|
3541
|
+
|
|
3542
|
+
def __str__(self):
|
|
3543
|
+
compiler_stats_str = ', '.join(map(str, self.compiler_stats))
|
|
3544
|
+
input_param_str = ', '.join(map(str, self.input_param))
|
|
3545
|
+
output_param_str = ', '.join(map(str, self.output_param))
|
|
3546
|
+
model_str = 'handle={}, version={}, name={}, internal_name={}, priority={}, num_inputs={}, num_outputs={}, num_compiler_config={}, model_load_options={}, cp_layer={}, \ninput_parameters=[{}], \noutput_parameters=[{}], \ncompiler_statistics=[{}]'.format(
|
|
3547
|
+
self.handle, self.version, self.name, self.internal_name, self.priority, self.num_inputs, self.num_outputs, self.num_compiler_config, self.model_load_options, self.cp_layer, input_param_str, output_param_str, compiler_stats_str)
|
|
3548
|
+
return model_str
|
|
3549
|
+
|
|
3550
|
+
@staticmethod
|
|
3551
|
+
def get_parameters_from_file(model_path):
|
|
3552
|
+
"""Takes the (.dvm) model from the specified path and get parameters
|
|
3553
|
+
|
|
3554
|
+
Parameters
|
|
3555
|
+
----------
|
|
3556
|
+
model_path : str
|
|
3557
|
+
|
|
3558
|
+
Returns
|
|
3559
|
+
-------
|
|
3560
|
+
(dv_status_code, DVModel)
|
|
3561
|
+
DV_SUCCESS on successfully getting parameters from the specified path
|
|
3562
|
+
|
|
3563
|
+
"""
|
|
3564
|
+
ret, model = dv_model_get_parameters_from_file(model_path)
|
|
3565
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
3566
|
+
return ret, None
|
|
3567
|
+
|
|
3568
|
+
mdl = DVModel(model[0])
|
|
3569
|
+
mdl.unload = lambda: None
|
|
3570
|
+
dv_model_free_parameters(model)
|
|
3571
|
+
|
|
3572
|
+
return ret, mdl
|
|
3573
|
+
|
|
3574
|
+
@staticmethod
|
|
3575
|
+
def get_parameters_from_blob(model_blob):
|
|
3576
|
+
"""
|
|
3577
|
+
Takes model blob as parameters
|
|
3578
|
+
|
|
3579
|
+
Parameters
|
|
3580
|
+
---------
|
|
3581
|
+
model_blob: dv_blob()
|
|
3582
|
+
|
|
3583
|
+
Returns
|
|
3584
|
+
---------
|
|
3585
|
+
(dv_status_code, DVModel)
|
|
3586
|
+
"""
|
|
3587
|
+
ret, model = dv_model_get_parameters_from_blob(model_blob)
|
|
3588
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
3589
|
+
return ret, None
|
|
3590
|
+
|
|
3591
|
+
mdl = DVModel(model[0])
|
|
3592
|
+
mdl.unload = lambda: None
|
|
3593
|
+
dv_model_free_parameters(model)
|
|
3594
|
+
|
|
3595
|
+
return ret, mdl
|
|
3596
|
+
|
|
3597
|
+
@_one_time_callable_cleanup_function
|
|
3598
|
+
def unload(self):
|
|
3599
|
+
""" unloads this model from the endpoint on which
|
|
3600
|
+
it was loaded. This is a blocking call
|
|
3601
|
+
|
|
3602
|
+
Returns
|
|
3603
|
+
-------
|
|
3604
|
+
dv_status_code
|
|
3605
|
+
DV_SUCCESS if the unload was successful
|
|
3606
|
+
|
|
3607
|
+
Notes
|
|
3608
|
+
-----
|
|
3609
|
+
Call this with caution!
|
|
3610
|
+
This is a blocking call.
|
|
3611
|
+
It is automatically called by class destructor.
|
|
3612
|
+
|
|
3613
|
+
"""
|
|
3614
|
+
return dv_model_unload(self._model)
|
|
3615
|
+
|
|
3616
|
+
def _allocate_output_tensors(self):
|
|
3617
|
+
""" allocates space for all output tensors and returns
|
|
3618
|
+
a map of tensor_name -> tensor
|
|
3619
|
+
"""
|
|
3620
|
+
# fixme:: this api may break for llm models
|
|
3621
|
+
if (self.model_type is dv_model_type.DV_MODEL_TYPE_ARA2_LLM_DYN_V2) or (
|
|
3622
|
+
self.model_type is dv_model_type.DV_MODEL_TYPE_ARA2_LLM):
|
|
3623
|
+
logging.warning(
|
|
3624
|
+
"_allocate_output_tensors may break with llm models")
|
|
3625
|
+
output_size_total = 0
|
|
3626
|
+
offsets = []
|
|
3627
|
+
for param in self.output_param:
|
|
3628
|
+
output_size_total += param.size
|
|
3629
|
+
offsets.append((param.size, param.layer_name))
|
|
3630
|
+
|
|
3631
|
+
output_tensor_contig = np.zeros((output_size_total,), dtype=np.int8)
|
|
3632
|
+
|
|
3633
|
+
slices = dict()
|
|
3634
|
+
|
|
3635
|
+
start_offset = 0
|
|
3636
|
+
|
|
3637
|
+
for idx, (offset, tensor_name) in enumerate(offsets):
|
|
3638
|
+
tensor_slice =\
|
|
3639
|
+
output_tensor_contig[start_offset: offset + start_offset]
|
|
3640
|
+
|
|
3641
|
+
slices[idx] =\
|
|
3642
|
+
DVTensor(tensor_slice, self.output_param[idx])
|
|
3643
|
+
start_offset += offset
|
|
3644
|
+
return slices
|
|
3645
|
+
|
|
3646
|
+
def _output_tensors_to_blobs(self, output_tensors):
|
|
3647
|
+
output_tensor_blobs = (DVBlob * len(output_tensors))()
|
|
3648
|
+
# fixme:: this api may break for llm models
|
|
3649
|
+
if (self.model_type is dv_model_type.DV_MODEL_TYPE_ARA2_LLM_DYN_V2) or (
|
|
3650
|
+
self.model_type is dv_model_type.DV_MODEL_TYPE_ARA2_LLM):
|
|
3651
|
+
logging.warning(
|
|
3652
|
+
"_output_tensors_to_blobs may break with llm models")
|
|
3653
|
+
for idx, param in enumerate(self.output_param):
|
|
3654
|
+
tensor = output_tensors[idx]
|
|
3655
|
+
if tensor.mem_desc is not None:
|
|
3656
|
+
output_tensor_blobs[idx].for_shm_desc(tensor.mem_desc._shm_desc,
|
|
3657
|
+
tensor.offset,
|
|
3658
|
+
param.size)
|
|
3659
|
+
else:
|
|
3660
|
+
ptr = tensor.numpy_data.ctypes.data_as(c_void_p)
|
|
3661
|
+
output_tensor_blobs[idx].for_raw_pointer(ptr, param.size)
|
|
3662
|
+
|
|
3663
|
+
return output_tensor_blobs
|
|
3664
|
+
|
|
3665
|
+
def _input_tensors_to_blobs(self, input_tensors):
|
|
3666
|
+
input_tensor_blobs = (DVBlob * len(input_tensors))()
|
|
3667
|
+
# fixme:: this api may break for llm models
|
|
3668
|
+
if (self.model_type is dv_model_type.DV_MODEL_TYPE_ARA2_LLM_DYN_V2) or (
|
|
3669
|
+
self.model_type is dv_model_type.DV_MODEL_TYPE_ARA2_LLM):
|
|
3670
|
+
logging.warning(
|
|
3671
|
+
"_input_tensors_to_blobs may break with llm models")
|
|
3672
|
+
for idx, param in enumerate(self.input_param):
|
|
3673
|
+
tensor = input_tensors[idx]
|
|
3674
|
+
if tensor.mem_desc is not None:
|
|
3675
|
+
input_tensor_blobs[idx].for_shm_desc(tensor.mem_desc._shm_desc,
|
|
3676
|
+
tensor.offset,
|
|
3677
|
+
param.size)
|
|
3678
|
+
tensor.mem_desc.mmap_buf.flush()
|
|
3679
|
+
else:
|
|
3680
|
+
ptr = tensor.numpy_data.ctypes.data_as(c_void_p)
|
|
3681
|
+
input_tensor_blobs[idx].for_raw_pointer(ptr, param.size)
|
|
3682
|
+
|
|
3683
|
+
return input_tensor_blobs
|
|
3684
|
+
|
|
3685
|
+
def infer_sync(self, input_tensors, output_tensors=None,
|
|
3686
|
+
endpoint=None, timeout=50000):
|
|
3687
|
+
status, async_inf_response = self.infer_async(
|
|
3688
|
+
input_tensors, output_tensors, endpoint)
|
|
3689
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
3690
|
+
return status, None
|
|
3691
|
+
|
|
3692
|
+
status = async_inf_response.wait_for_completion(timeout)
|
|
3693
|
+
return status, async_inf_response
|
|
3694
|
+
|
|
3695
|
+
def infer_sync_with_options(self, input_tensors: typing.List[DVTensor], output_tensors: typing.List[
|
|
3696
|
+
DVTensor], endpoint: dv_endpoint, timeout_ms: int, infer_options: DVInferOptions):
|
|
3697
|
+
def get_blobs_frm_tensors_list(tensors: typing.List[DVTensor]):
|
|
3698
|
+
tensor_blobs = (DVBlob * len(tensors))()
|
|
3699
|
+
for idx, tensor in enumerate(tensors):
|
|
3700
|
+
size = tensor.numpy_data.nbytes
|
|
3701
|
+
ptr = tensor.numpy_data.ctypes.data_as(c_void_p)
|
|
3702
|
+
tensor_blobs[idx].for_raw_pointer(ptr, size)
|
|
3703
|
+
return tensor_blobs
|
|
3704
|
+
input_tensor_blobs = get_blobs_frm_tensors_list(input_tensors)
|
|
3705
|
+
output_tensor_blobs = get_blobs_frm_tensors_list(output_tensors)
|
|
3706
|
+
status, inf_req_obj =\
|
|
3707
|
+
dv_infer_sync_with_options(self.session,
|
|
3708
|
+
self.endpoint,
|
|
3709
|
+
self._model,
|
|
3710
|
+
input_tensor_blobs,
|
|
3711
|
+
output_tensor_blobs,
|
|
3712
|
+
timeout_ms,
|
|
3713
|
+
infer_options._infer_options_handle)
|
|
3714
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
3715
|
+
return status, None
|
|
3716
|
+
# todo:: return DVInferRequest from here
|
|
3717
|
+
return status, inf_req_obj
|
|
3718
|
+
|
|
3719
|
+
def infer_async(self, input_tensors, output_tensors=None,
|
|
3720
|
+
endpoint=None, desc=None):
|
|
3721
|
+
""" send an inference request for the given list of input
|
|
3722
|
+
tensors
|
|
3723
|
+
|
|
3724
|
+
Parameters
|
|
3725
|
+
----------
|
|
3726
|
+
input_tensors : [DVTensor]
|
|
3727
|
+
dict that specifies the tensor to be loaded onto input whose
|
|
3728
|
+
name is indicated by the key
|
|
3729
|
+
|
|
3730
|
+
output_tensors : Optional[DVTensor]
|
|
3731
|
+
optional - specify output tensor where the output should be written, if none
|
|
3732
|
+
is provided, numpy arrays are created automatically to which outputs will
|
|
3733
|
+
be written
|
|
3734
|
+
|
|
3735
|
+
endpoint : int
|
|
3736
|
+
endpoint to run the inference on - by default the inference runs
|
|
3737
|
+
on the default endpoint group created by the proxy connected to.
|
|
3738
|
+
|
|
3739
|
+
Returns
|
|
3740
|
+
-------
|
|
3741
|
+
(dv_status_code, DVInferRequest)
|
|
3742
|
+
DV_SUCCESS, A future like object which can be waited on in a blocking
|
|
3743
|
+
manner pending inference request reaching a final state
|
|
3744
|
+
|
|
3745
|
+
error status, None if the inference could not be initiated
|
|
3746
|
+
"""
|
|
3747
|
+
if output_tensors is None:
|
|
3748
|
+
output_tensors = self._allocate_output_tensors()
|
|
3749
|
+
input_tensor_blobs = self._input_tensors_to_blobs(input_tensors)
|
|
3750
|
+
output_tensor_blobs = self._output_tensors_to_blobs(output_tensors)
|
|
3751
|
+
# form the infernce request and add to map before initiating
|
|
3752
|
+
# the call to prevent any racy behavior
|
|
3753
|
+
|
|
3754
|
+
status, inf_req_obj =\
|
|
3755
|
+
dv_infer_async(self.session,
|
|
3756
|
+
self.endpoint,
|
|
3757
|
+
self._model,
|
|
3758
|
+
input_tensor_blobs,
|
|
3759
|
+
output_tensor_blobs)
|
|
3760
|
+
|
|
3761
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
3762
|
+
return status, None
|
|
3763
|
+
|
|
3764
|
+
inf_req = DVInferRequest(
|
|
3765
|
+
input_tensors,
|
|
3766
|
+
output_tensors,
|
|
3767
|
+
inf_req_obj,
|
|
3768
|
+
self)
|
|
3769
|
+
return status, inf_req
|
|
3770
|
+
|
|
3771
|
+
def infer_sync_with_flags(
|
|
3772
|
+
self, input_tensors: typing.List[DVTensor], output_tensors: typing.List[DVTensor] = None, flags=None, timeout=60000, endpoint=None, desc=None):
|
|
3773
|
+
if output_tensors is None:
|
|
3774
|
+
output_tensors = self._allocate_output_tensors()
|
|
3775
|
+
|
|
3776
|
+
def get_blobs_frm_tensors_list(tensors: typing.List[DVTensor]):
|
|
3777
|
+
tensor_blobs = (DVBlob * len(tensors))()
|
|
3778
|
+
for idx, tensor in enumerate(tensors):
|
|
3779
|
+
size = tensor.numpy_data.nbytes
|
|
3780
|
+
ptr = tensor.numpy_data.ctypes.data_as(c_void_p)
|
|
3781
|
+
tensor_blobs[idx].for_raw_pointer(ptr, size)
|
|
3782
|
+
return tensor_blobs
|
|
3783
|
+
|
|
3784
|
+
input_tensor_blobs = get_blobs_frm_tensors_list(input_tensors)
|
|
3785
|
+
output_tensor_blobs = get_blobs_frm_tensors_list(output_tensors)
|
|
3786
|
+
|
|
3787
|
+
status, inf_req_obj =\
|
|
3788
|
+
dv_infer_sync_with_flags(self.session,
|
|
3789
|
+
self.endpoint,
|
|
3790
|
+
self._model,
|
|
3791
|
+
input_tensor_blobs,
|
|
3792
|
+
output_tensor_blobs,
|
|
3793
|
+
timeout,
|
|
3794
|
+
flags)
|
|
3795
|
+
if status != dv_status_code.DV_SUCCESS:
|
|
3796
|
+
return status, None
|
|
3797
|
+
|
|
3798
|
+
def __del__(self):
|
|
3799
|
+
self.unload()
|
|
3800
|
+
|
|
3801
|
+
|
|
3802
|
+
class DVCompilerStats:
|
|
3803
|
+
def __init__(self, compiler_stats):
|
|
3804
|
+
self.config_name = compiler_stats.config_name.decode('utf-8')
|
|
3805
|
+
self.cycles = compiler_stats.cycles
|
|
3806
|
+
self.ips = compiler_stats.ips
|
|
3807
|
+
self.ddr_bandwidth = compiler_stats.ddr_bandwidth
|
|
3808
|
+
|
|
3809
|
+
def __str__(self):
|
|
3810
|
+
compiler_stats_str = "config_name={}, cycles={}, ips={}, ddr_bandwidth={}".format(
|
|
3811
|
+
self.config_name, self.cycles, self.ips, self.ddr_bandwidth)
|
|
3812
|
+
return compiler_stats_str
|
|
3813
|
+
|
|
3814
|
+
|
|
3815
|
+
class DVEndpointDramInfo:
|
|
3816
|
+
def __init__(self, dram_info):
|
|
3817
|
+
self.vendor_id = dram_info.vendor_id
|
|
3818
|
+
self.vendor_name = dram_info.vendor_name.decode('utf-8')
|
|
3819
|
+
self.size = dram_info.size
|
|
3820
|
+
self.rev_id1 = dram_info.rev_id1
|
|
3821
|
+
self.rev_id2 = dram_info.rev_id2
|
|
3822
|
+
self.density = dram_info.density
|
|
3823
|
+
self.io_widths = dram_info.io_width
|
|
3824
|
+
|
|
3825
|
+
def __str__(self):
|
|
3826
|
+
dram_info = 'vendor_id={}, vendor_name={}, size={}, rev_id1={}, rev_id2={}, density={}, io_widths={}'.format(
|
|
3827
|
+
self.vendor_id, self.vendor_name, self.size, self.rev_id1, self.rev_id2, self.density, self.io_widths)
|
|
3828
|
+
return dram_info
|
|
3829
|
+
|
|
3830
|
+
|
|
3831
|
+
class DVEndpointIfaceInfo:
|
|
3832
|
+
def __init__(self, iface_info):
|
|
3833
|
+
self.type = iface_info.type
|
|
3834
|
+
self.bus_num = iface_info.bus_num
|
|
3835
|
+
self.device_num = iface_info.device_num
|
|
3836
|
+
self.sysfs_path = ""
|
|
3837
|
+
if self.type == dv_endpoint_host_interface.DV_ENDPOINT_HOST_INTERFACE_PCIE:
|
|
3838
|
+
self.sysfs_path = iface_info.sysfs_path.pcie_dir.decode('utf-8')
|
|
3839
|
+
|
|
3840
|
+
def __str__(self):
|
|
3841
|
+
iface_info = 'type={}, bus_num={}, device_num={}, sysfs_path={}'.format(
|
|
3842
|
+
self.type, self.bus_num, self.device_num, self.sysfs_path)
|
|
3843
|
+
return iface_info
|
|
3844
|
+
|
|
3845
|
+
|
|
3846
|
+
class DVEndpointChipInfo:
|
|
3847
|
+
def __init__(self, chip_info):
|
|
3848
|
+
self.id = chip_info.id.decode('utf-8')
|
|
3849
|
+
self.rev = chip_info.rev.decode('utf-8')
|
|
3850
|
+
self.control_processor_count = chip_info.control_processor_count
|
|
3851
|
+
self.neural_processor_count = chip_info.neural_processor_count
|
|
3852
|
+
self.l2_memory_size = chip_info.l2_memory_size
|
|
3853
|
+
|
|
3854
|
+
def __str__(self):
|
|
3855
|
+
chip_info_str = 'id={}, rev={}, control_processor_count={}, neural_processor_count={}, l2_memory_size={}'.format(
|
|
3856
|
+
self.id, self.rev, self.control_processor_count, self.neural_processor_count, self.l2_memory_size)
|
|
3857
|
+
return chip_info_str
|
|
3858
|
+
|
|
3859
|
+
|
|
3860
|
+
class DVEndpointInfo:
|
|
3861
|
+
def __init__(self, endpoint_info):
|
|
3862
|
+
self.gpio0 = endpoint_info.gpio0
|
|
3863
|
+
self.gpio1 = endpoint_info.gpio1
|
|
3864
|
+
self.device_uid = endpoint_info.device_uid
|
|
3865
|
+
self.device_id = endpoint_info.device_id
|
|
3866
|
+
self.vendor_id = endpoint_info.vendor_id
|
|
3867
|
+
self.module_name = ""
|
|
3868
|
+
self.chip = DVEndpointChipInfo(endpoint_info.chip[0])
|
|
3869
|
+
self.dram = DVEndpointDramInfo(endpoint_info.dram[0])
|
|
3870
|
+
self.iface = DVEndpointIfaceInfo(endpoint_info.iface[0])
|
|
3871
|
+
|
|
3872
|
+
def __str__(self):
|
|
3873
|
+
ep_info_str = 'gpio0={}, gpio1={}, device_uid={}, device_id={}, vendor_id={}, module_name={}, chip={}, dram={}, ifaace={}'.format(
|
|
3874
|
+
self.gpio0, self.gpio1, self.device_uid, self.device_id, self.vendor_id, self.module_name,
|
|
3875
|
+
str(self.chip), str(self.dram), str(self.iface))
|
|
3876
|
+
return ep_info_str
|
|
3877
|
+
|
|
3878
|
+
|
|
3879
|
+
class DVEndpoint:
|
|
3880
|
+
""" a wrapper around a C buffer that stores a list of endpoint handles
|
|
3881
|
+
"""
|
|
3882
|
+
|
|
3883
|
+
def __init__(self, endpoint):
|
|
3884
|
+
self._endpoint = endpoint
|
|
3885
|
+
self.handle = endpoint.handle
|
|
3886
|
+
self.session = endpoint.session
|
|
3887
|
+
self.num_ep = endpoint.num_ep
|
|
3888
|
+
self.ep_info = []
|
|
3889
|
+
|
|
3890
|
+
for i in range(0, self.num_ep):
|
|
3891
|
+
self.ep_info.append(DVEndpointInfo(endpoint.ep_info_list[i][0]))
|
|
3892
|
+
|
|
3893
|
+
def __str__(self):
|
|
3894
|
+
ep_info_str = ', '.join(map(str, self.ep_info))
|
|
3895
|
+
ep_str = 'handle={}, num_ep={}, ep_info[]={}'.format(
|
|
3896
|
+
self.handle, self.num_ep, ep_info_str)
|
|
3897
|
+
return ep_str
|
|
3898
|
+
|
|
3899
|
+
|
|
3900
|
+
class DVSession:
|
|
3901
|
+
""" base class for connections. instantiate `DVProxyUnixConnection` or
|
|
3902
|
+
`DVProxyTCPConnection` to communicate with the proxy.
|
|
3903
|
+
"""
|
|
3904
|
+
|
|
3905
|
+
def __init__(self, session):
|
|
3906
|
+
self._session = session
|
|
3907
|
+
self.handle = session[0].handle
|
|
3908
|
+
self.socket_type = session[0].socket_type
|
|
3909
|
+
self.socket_str = session[0].socket_str.decode('utf-8')
|
|
3910
|
+
self.options = None
|
|
3911
|
+
self.fault_callback_ptr = None
|
|
3912
|
+
self.power_state_callback_ptr = None
|
|
3913
|
+
self._ep_list = None
|
|
3914
|
+
self.ep_list = []
|
|
3915
|
+
self.inf_map = {}
|
|
3916
|
+
|
|
3917
|
+
@_one_time_callable_cleanup_function
|
|
3918
|
+
def close(self):
|
|
3919
|
+
"""closes the connection, existing requests that hold a reference
|
|
3920
|
+
to this connection will become invalidated or will never receive their
|
|
3921
|
+
respective responses
|
|
3922
|
+
|
|
3923
|
+
Returns
|
|
3924
|
+
-------
|
|
3925
|
+
dv_status_code
|
|
3926
|
+
DV_SUCCESS if the connection was closed correctly
|
|
3927
|
+
"""
|
|
3928
|
+
return dv_session_close(self._session)
|
|
3929
|
+
|
|
3930
|
+
def __str__(self):
|
|
3931
|
+
session_str = 'handle={}, socket_type={}, socket_str={}, options={}'.format(
|
|
3932
|
+
self.handle, self.socket_type, self.socket_str, self.options)
|
|
3933
|
+
return session_str
|
|
3934
|
+
|
|
3935
|
+
def __enter__(self):
|
|
3936
|
+
return self
|
|
3937
|
+
|
|
3938
|
+
def __exit__(self, exc_type, exc_value, tb):
|
|
3939
|
+
self.close()
|
|
3940
|
+
return False
|
|
3941
|
+
|
|
3942
|
+
def __del__(self):
|
|
3943
|
+
self.close()
|
|
3944
|
+
|
|
3945
|
+
@classmethod
|
|
3946
|
+
def create_via_unix_socket(cls, path):
|
|
3947
|
+
"""DVSession @classmethod that connects to the proxy via unix socket
|
|
3948
|
+
|
|
3949
|
+
Parameters
|
|
3950
|
+
----------
|
|
3951
|
+
path : str
|
|
3952
|
+
path to the unix socket
|
|
3953
|
+
|
|
3954
|
+
Returns
|
|
3955
|
+
-------
|
|
3956
|
+
(dv_status_code, DVSession)
|
|
3957
|
+
DV_SUCCESS, DVSession if the connection was successfully established else returns the Error Code
|
|
3958
|
+
|
|
3959
|
+
"""
|
|
3960
|
+
ret, session = dv_session_create_via_unix_socket(socket_path=path)
|
|
3961
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
3962
|
+
return ret, None
|
|
3963
|
+
|
|
3964
|
+
s = cls(session)
|
|
3965
|
+
return ret, s
|
|
3966
|
+
|
|
3967
|
+
@classmethod
|
|
3968
|
+
def create_via_tcp_ipv4_socket(cls, ip, port):
|
|
3969
|
+
"""DVSession @classmethod that connects to the proxy over the network
|
|
3970
|
+
|
|
3971
|
+
Parameters
|
|
3972
|
+
----------
|
|
3973
|
+
ip : str
|
|
3974
|
+
IPv4 address to connect to
|
|
3975
|
+
|
|
3976
|
+
port : int
|
|
3977
|
+
Port number proxy is listening on
|
|
3978
|
+
|
|
3979
|
+
Returns
|
|
3980
|
+
-------
|
|
3981
|
+
(dv_status_code, DVSession)
|
|
3982
|
+
DV_SUCCESS, DVSession if the connection was successfully established else returns the Error Code
|
|
3983
|
+
|
|
3984
|
+
"""
|
|
3985
|
+
ret, session = dv_session_create_via_tcp_ipv4_socket(
|
|
3986
|
+
ipv4_addr=ip, port=port)
|
|
3987
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
3988
|
+
return ret, None
|
|
3989
|
+
|
|
3990
|
+
s = cls(session)
|
|
3991
|
+
return ret, s
|
|
3992
|
+
|
|
3993
|
+
def get_endpoint_list(self):
|
|
3994
|
+
"""DVSession method that lists all endpoints connected to the inference proxy
|
|
3995
|
+
|
|
3996
|
+
Returns
|
|
3997
|
+
-------
|
|
3998
|
+
(dv_status_code, list(DVEndpoint))
|
|
3999
|
+
DVEndpoints will be None if the dv_status_code != DV_SUCCESS
|
|
4000
|
+
|
|
4001
|
+
"""
|
|
4002
|
+
|
|
4003
|
+
ret, epl, count = dv_endpoint_get_list(self._session)
|
|
4004
|
+
|
|
4005
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4006
|
+
return ret, None
|
|
4007
|
+
|
|
4008
|
+
self._ep_list = epl
|
|
4009
|
+
|
|
4010
|
+
for i in range(0, count.value):
|
|
4011
|
+
self.ep_list.append(DVEndpoint(epl[i]))
|
|
4012
|
+
|
|
4013
|
+
return ret, self.ep_list
|
|
4014
|
+
|
|
4015
|
+
def get_loaded_endpoint_list(self, model):
|
|
4016
|
+
"""DVSession method that returns a list of all connected endpoints + list of indexes in the aforementioned list
|
|
4017
|
+
on which the specified model is loaded.
|
|
4018
|
+
|
|
4019
|
+
Parameters
|
|
4020
|
+
----------
|
|
4021
|
+
model : DVModel
|
|
4022
|
+
|
|
4023
|
+
Returns
|
|
4024
|
+
-------
|
|
4025
|
+
(dv_status_code, list(DVEndpoint), list(loaded_ep_indexs)
|
|
4026
|
+
dv_status_code : DV_SUCCESS in case of success, else the error code
|
|
4027
|
+
ep_list : list of DVEndpoint object
|
|
4028
|
+
loaded_ep_indexs : list of indexes in the aforementioned list on which the specified model is loaded
|
|
4029
|
+
"""
|
|
4030
|
+
ret, endpt_list, endpt_list_size, loaded_endpt_idxes, loaded_endpt_list_size = dv_model_get_loaded_endpoint_list(
|
|
4031
|
+
self._session, model._model)
|
|
4032
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4033
|
+
return ret, None, None, None, None
|
|
4034
|
+
|
|
4035
|
+
ep_list = []
|
|
4036
|
+
for i in range(0, endpt_list_size.value):
|
|
4037
|
+
ep_list.append(DVEndpoint(endpt_list[i]))
|
|
4038
|
+
|
|
4039
|
+
loaded_ep_indexs = []
|
|
4040
|
+
for i in range(0, loaded_endpt_list_size.value):
|
|
4041
|
+
loaded_ep_indexs.append(loaded_endpt_idxes[i])
|
|
4042
|
+
|
|
4043
|
+
return ret, ep_list, loaded_ep_indexs
|
|
4044
|
+
|
|
4045
|
+
def get_endpoint_default_group(self, default_grp_enum):
|
|
4046
|
+
"""DVSession method to get default endpoint group created by client
|
|
4047
|
+
|
|
4048
|
+
Parameters
|
|
4049
|
+
----------
|
|
4050
|
+
default_grp_enum
|
|
4051
|
+
dv_endpoint_default_group
|
|
4052
|
+
|
|
4053
|
+
Returns
|
|
4054
|
+
-------
|
|
4055
|
+
(dv_status_code, DVEndpoint)
|
|
4056
|
+
|
|
4057
|
+
"""
|
|
4058
|
+
ret, ep_grp = dv_endpoint_get_default_group(
|
|
4059
|
+
self._session, default_grp_enum)
|
|
4060
|
+
|
|
4061
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4062
|
+
return ret, None
|
|
4063
|
+
ep_default_grp = DVEndpoint(ep_grp[0])
|
|
4064
|
+
return ret, ep_default_grp
|
|
4065
|
+
|
|
4066
|
+
def infer_inflight_count(self):
|
|
4067
|
+
"""DVSession method that returns the number of inflight inference requests for the session
|
|
4068
|
+
object for which the client library has not recieved a response from
|
|
4069
|
+
the proxy server
|
|
4070
|
+
|
|
4071
|
+
Returns
|
|
4072
|
+
-------
|
|
4073
|
+
dv_status_code
|
|
4074
|
+
|
|
4075
|
+
count : number of inference requests in flight
|
|
4076
|
+
|
|
4077
|
+
"""
|
|
4078
|
+
ret, count = dv_infer_get_inflight_count(self._session)
|
|
4079
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4080
|
+
return ret, None
|
|
4081
|
+
|
|
4082
|
+
return ret, count.value
|
|
4083
|
+
|
|
4084
|
+
def free_endpoint_group(self, ep_group):
|
|
4085
|
+
"""DVSession method free endpoint group
|
|
4086
|
+
|
|
4087
|
+
Parameters
|
|
4088
|
+
----------
|
|
4089
|
+
ep_group : DVEndpoint
|
|
4090
|
+
|
|
4091
|
+
Returns
|
|
4092
|
+
-------
|
|
4093
|
+
(dv_status_code)
|
|
4094
|
+
|
|
4095
|
+
"""
|
|
4096
|
+
return dv_endpoint_free_group(ep_group._endpoint)
|
|
4097
|
+
|
|
4098
|
+
def load_model_from_file(self, endpoint, model_path, model_name="model.dvm",
|
|
4099
|
+
priority=dv_model_priority_level.DV_MODEL_PRIORITY_LEVEL_DEFAULT, cache_model=False):
|
|
4100
|
+
"""DVSession method that loads and parses a `model.dvm` file present at path onto the default
|
|
4101
|
+
endpoint group of the connected proxy.
|
|
4102
|
+
|
|
4103
|
+
Parameters
|
|
4104
|
+
----------
|
|
4105
|
+
endpoint : DVEndpoint
|
|
4106
|
+
endpoint on which we wish to load the model
|
|
4107
|
+
|
|
4108
|
+
path : str
|
|
4109
|
+
path to a compiled model.dvm file
|
|
4110
|
+
|
|
4111
|
+
model_name : str
|
|
4112
|
+
name of the model
|
|
4113
|
+
|
|
4114
|
+
priority : DV_MODEL_PRIORITY_LEVEL
|
|
4115
|
+
priority associated with the model, by default it is
|
|
4116
|
+
DV_MODEL_PRIORITY_LEVEL.DV_MODEL_PRIORITY_LEVEL_DEFAULT
|
|
4117
|
+
|
|
4118
|
+
cache_model : bool
|
|
4119
|
+
indicates if the model should be cached by the server.
|
|
4120
|
+
if the caching of the model fails, the model load API call with fail
|
|
4121
|
+
|
|
4122
|
+
Returns
|
|
4123
|
+
-------
|
|
4124
|
+
(dv_status_code, DVModel)
|
|
4125
|
+
DV_SUCCESS, DVModel object if load call succeeded
|
|
4126
|
+
|
|
4127
|
+
(dv_status_code, None)
|
|
4128
|
+
if the load call could not succeed
|
|
4129
|
+
|
|
4130
|
+
"""
|
|
4131
|
+
if cache_model:
|
|
4132
|
+
pass
|
|
4133
|
+
else:
|
|
4134
|
+
ret, model_handle = dv_model_load_from_file(self._session,
|
|
4135
|
+
endpoint._endpoint,
|
|
4136
|
+
model_path,
|
|
4137
|
+
model_name,
|
|
4138
|
+
priority)
|
|
4139
|
+
|
|
4140
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4141
|
+
return ret, None
|
|
4142
|
+
|
|
4143
|
+
model = DVModel(model_handle[0])
|
|
4144
|
+
return ret, model
|
|
4145
|
+
|
|
4146
|
+
def load_model_from_file_with_flags(self, endpoint, model_path, flags, model_name="model.dvm",
|
|
4147
|
+
priority=dv_model_priority_level.DV_MODEL_PRIORITY_LEVEL_DEFAULT, cache_model=False, load_async=True):
|
|
4148
|
+
ret, model_handle = dv_model_load_from_file_with_flags(self._session,
|
|
4149
|
+
endpoint._endpoint,
|
|
4150
|
+
model_path,
|
|
4151
|
+
flags,
|
|
4152
|
+
model_name,
|
|
4153
|
+
priority,
|
|
4154
|
+
cache_model,
|
|
4155
|
+
load_async)
|
|
4156
|
+
|
|
4157
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4158
|
+
return ret, None
|
|
4159
|
+
|
|
4160
|
+
model = DVModel(model_handle[0])
|
|
4161
|
+
return ret, model
|
|
4162
|
+
|
|
4163
|
+
def load_model_from_file_with_options(
|
|
4164
|
+
self, endpoint: dv_endpoint, model_path: str, options: DVModelLoadOptions):
|
|
4165
|
+
"""DVSession method that creates a model object and load model contents from blob and transfer it to endpoint
|
|
4166
|
+
|
|
4167
|
+
Notes
|
|
4168
|
+
-----
|
|
4169
|
+
If model load fails on all individual devices representing `endpt`, the API call will error out
|
|
4170
|
+
|
|
4171
|
+
Parameters
|
|
4172
|
+
----------
|
|
4173
|
+
endpoint : DVEndpoint
|
|
4174
|
+
endpoint on which we wish to load the model
|
|
4175
|
+
|
|
4176
|
+
model_path
|
|
4177
|
+
path to model file
|
|
4178
|
+
|
|
4179
|
+
options : DVModelLoadOptions
|
|
4180
|
+
model load option
|
|
4181
|
+
|
|
4182
|
+
"""
|
|
4183
|
+
ret, model_handle = dv_model_load_from_file_with_options(self._session,
|
|
4184
|
+
endpoint._endpoint,
|
|
4185
|
+
model_path,
|
|
4186
|
+
options._model_load_options)
|
|
4187
|
+
|
|
4188
|
+
if ret != dv_status_code.DV_SUCCESS:
|
|
4189
|
+
return ret, None
|
|
4190
|
+
|
|
4191
|
+
model = DVModel(model_handle[0])
|
|
4192
|
+
return ret, model
|