#include "base_model.h" namespace trt_vehicle{ std::mutex mtx; CudaPredictor::~CudaPredictor(){ if (m_stream) cudaStreamDestroy(m_stream); mtx.lock(); if (m_context) m_context->destroy(); if (m_engine) m_engine->destroy(); if (m_runtime) m_runtime->destroy(); mtx.unlock(); } int CudaPredictor::loadModel(const string &path){ ifstream file(path, ios::in | ios::binary); if (!file) { return -3; } std::vector trtModelStream; size_t size{0}; if (file.good()) { file.seekg(0, file.end); size = file.tellg(); file.seekg(0, file.beg); trtModelStream.resize(size); file.read(trtModelStream.data(), size); file.close(); } try { m_engine = m_runtime->deserializeCudaEngine(trtModelStream.data(), size, nullptr); if(m_engine == nullptr){ return -5; } } catch(...){ return -6; } return 0; } int CudaPredictor::prepare() { m_context = m_engine->createExecutionContext(); if (!m_context) { return -7; } cudaError_t ret = cudaStreamCreate(&m_stream); if(ret != cudaSuccess){ return -8; } return 0; } int CudaPredictor::init(const std::string path,int deviceID , bool verbose) { int countGpus=0; cudaGetDeviceCount(&countGpus); if(deviceID > countGpus -1){ return -1; } mtx.lock(); cudaSetDevice(deviceID); static sample::Logger gLogger{sample::Logger::Severity::kINFO}; m_runtime = createInferRuntime(gLogger); if(m_runtime == nullptr){ mtx.unlock(); return -2; } int ret = loadModel(path); if(ret != 0){ mtx.unlock(); return ret; } ret = prepare(); mtx.unlock(); return ret; } int CudaPredictor::getSizeYolo(int& batch,int& inputSizeC,int& inputSizeH,int& inputSizeW,int& outputNum,int& classNum,int& boxNum){ auto dims0 = m_engine->getBindingDimensions(0); batch = dims0.d[0]; inputSizeH = dims0.d[1]; inputSizeW = dims0.d[2]; inputSizeC = dims0.d[3]; auto dims1 = m_engine->getBindingDimensions(1); auto dims2 = m_engine->getBindingDimensions(2); outputNum = dims1.d[1]; classNum = dims1.d[2]; boxNum = dims2.d[3]; return 0; } int CudaPredictor::getSize(int& batch,int& inputSizeC,int& inputSizeH,int& inputSizeW,int& outputDim1,int& outputDim2,int& outputDim3, NetworkInputType networkInputType){ auto dims0 = m_engine->getBindingDimensions(0); batch = dims0.d[0]; if (networkInputType == NetworkInputType::CHW) { inputSizeC = dims0.d[1]; inputSizeH = dims0.d[2]; inputSizeW = dims0.d[3]; } else { inputSizeH = dims0.d[1]; inputSizeW = dims0.d[2]; inputSizeC = dims0.d[3]; } auto dims1 = m_engine->getBindingDimensions(1); outputDim1 = dims1.d[1]; outputDim2 = dims1.d[2]; outputDim3 = dims1.d[3]; if(outputDim2 < 1){ outputDim2 = 1; } if(outputDim3 < 1){ outputDim3 = 1; } return 0; } int CudaPredictor::getSizeVehicle(int& batch, int& inputSizeC, int& inputSizeH, int& inputSizeW, int& outputDim1, int& outputDim2, int& outputDim3) { auto dims0 = m_engine->getBindingDimensions(0); batch = 1; // dims0.d[0]; //TODO inputSizeH = dims0.d[1]; inputSizeW = dims0.d[2]; inputSizeC = dims0.d[0]; auto dims1 = m_engine->getBindingDimensions(1); outputDim1 = dims1.d[0]; outputDim2 = dims1.d[1]; outputDim3 = dims1.d[2]; if (outputDim2 < 1) { outputDim2 = 1; } if (outputDim3 < 1) { outputDim3 = 1; } return 0; } int CudaPredictor::infer(vector &buffers, int batch){ bool ok = m_context->execute(batch, buffers.data()); if(ok == false){ return -1; } cudaError_t ret = cudaStreamSynchronize(m_stream); if(ret != cudaSuccess){ return -2; } return 0; } int BaseModel::getInputSize(int& inputW,int& inputH){ inputH = m_inputSizeH; inputW = m_inputSizeW; return 0; } void BaseModel::imageResize(const cv::Mat &src, cv::Size size,std::vector& data) { cv::Mat dst; cv::resize(src, dst, size, (0.0), (0.0), cv::INTER_LINEAR); int h = size.height; int w = size.width; if (m_inputType == NetworkInputType::CHW) { this->readMeanImageFile(); data.resize(w * h * 3); std::vector dataTmp = (std::vector)(dst.reshape(1, 1)); for (int row=0; row < h; row++) { for (int col = 0; col < w; col++) { for (int k = 0; k < 3; k++) { int dstIndex = w * h * k + row * w + col; int srcIndex = row * w * 3 + col * 3 + k; data[dstIndex] = (float)dataTmp[srcIndex]; if(m_meanFileData) data[dstIndex] -= m_meanFileData[srcIndex]; } } } } else { data = (std::vector)(dst.reshape(1, 1)); } } bool BaseModel::readMeanImageFile() { if (m_meanFileData != nullptr || m_MeanFile.empty()) return false; std::ifstream infile(m_MeanFile, std::ifstream::binary); size_t size = m_inputSizeH * m_inputSizeW * m_inputSizeC; uint8_t tempMeanDataChar[size]; if (!infile.good()) { return false; } std::string magic, max; unsigned int h, w; infile >> magic >> w >> h >> max; if (magic != "P3" && magic != "P6") { return false; } if (w != m_inputSizeW || h != m_inputSizeH) { std:; cerr << "Mismatch between ppm mean image resolution and network resolution " << std::endl; return false; } infile.get(); infile.read((char*)tempMeanDataChar, size); if (infile.gcount() != (int)size || infile.fail()) { return false; } m_meanFileData = new float[size]; for (size_t i = 0; i < size; i++) { m_meanFileData[i] = (float)tempMeanDataChar[i]; } return true; } int BaseModel::imagePreprocess(cv::Mat& img,vector& imageData) { cv::Mat src; if(img.channels() == 1){ cv::cvtColor(img,src,cv::COLOR_GRAY2RGB); } else{ //src = img.clone(); src = img; } cv::Mat input; src.convertTo(input, CV_32FC3); vector data; imageResize(input, cv::Size(m_inputSizeW, m_inputSizeH),data); imageData.insert(imageData.end(), data.begin(), data.end()); return 0; } BaseModel::~BaseModel(){ if (m_meanFileData != nullptr) delete[] m_meanFileData; } }