Я использую tensorRT для выполнения логического вывода с помощью CUDA. Я хотел бы использовать CuPy для предварительной обработки некоторых изображений, которые я передам движку tensorRT. Функция предварительной обработки, называемая my_function
, работает нормально, пока tensorRT не запускается между различными вызовами метода my_function
(см. код ниже). В частности, проблема не связана строго с tensorRT, а связана с тем фактом, что вывод tensorRT требует обертывания операциями push
и pop
контекста pycuda.
Что касается следующего кода, последнее выполнение my_function
вызовет следующую ошибку:
File "/home/ubuntu/myfile.py", line 188, in _pre_process_cuda
img = ndimage.zoom(img, scaling_factor)
File "/home/ubuntu/.local/lib/python3.6/site-packages/cupyx/scipy/ndimage/interpolation.py", line 482, in zoom
kern(input, zoom, output)
File "cupy/core/_kernel.pyx", line 822, in cupy.core._kernel.ElementwiseKernel.__call__
File "cupy/cuda/function.pyx", line 196, in cupy.cuda.function.Function.linear_launch
File "cupy/cuda/function.pyx", line 164, in cupy.cuda.function._launch
File "cupy_backends/cuda/api/driver.pyx", line 299, in cupy_backends.cuda.api.driver.launchKernel
File "cupy_backends/cuda/api/driver.pyx", line 124, in cupy_backends.cuda.api.driver.check_status
cupy_backends.cuda.api.driver.CUDADriverError: CUDA_ERROR_INVALID_HANDLE: invalid resource handle
Примечание: в следующем коде я не сообщил весь код вывода tensorRT. На самом деле, простое нажатие и выталкивание контекста pycuda генерирует ошибку
Код:
import numpy as np
import cv2
import time
from PIL import Image
import requests
from io import BytesIO
from matplotlib import pyplot as plt
import cupy as cp
from cupyx.scipy import ndimage
import tensorrt as trt
import pycuda.driver as cuda
import pycuda.autoinit
def my_function(numpy_frame):
dtype = 'float32'
img = cp.array(numpy_frame, dtype='float32')
# print(img)
img = ndimage.zoom(img, (0.5, 0.5, 3))
img = (cp.array(2, dtype=dtype) / cp.array(255, dtype=dtype)) * img - cp.array(1, dtype=dtype)
img = img.transpose((2, 0, 1))
img = img.ravel()
return img
# load image
url = "https://www.pexels.com/photo/109919/download/?search_query=&tracking_id=411xe21veam"
response = requests.get(url)
img = Image.open(BytesIO(response.content))
img = np.array(img)
# initialize tensorrt
TRT_LOGGER = trt.Logger(trt.Logger.WARNING)
trt_runtime = trt.Runtime(TRT_LOGGER)
cfx = cuda.Device(0).make_context()
my_function(img) # ok
my_function(img) # ok
# ----- TENSORRT ---------
cfx.push()
# .... tensorrt inference....
cfx.pop()
# ----- TENSORRT ---------
my_function(img) # <---- error
Я даже пытался сделать это другими способами, но, к сожалению, с тем же результатом:
cfx.push()
my_function(img) # ok
cfx.pop()
cfx.push()
my_function(img) # error
cfx.pop()
@admin: если вы можете придумать лучшее название для этого вопроса, не стесняйтесь его редактировать :)
Было открыто несколько контекстов. Например, кажется, что все следующее открывает контекст:
import pycuda.autoinit
cfx.cuda.Device(0).make_context()
cfx.push()
Итак, если вы запустите три команды выше, то просто запустить одну cfx.pop()
будет недостаточно. Вам нужно будет запустить cfx.pop()
три раза, чтобы открыть все контексты.