From efb809c04384b24bc075c8141d3d63fb7d4f5f17 Mon Sep 17 00:00:00 2001 From: wang-xinyu Date: Sun, 6 Sep 2020 17:13:21 +0800 Subject: [PATCH] optimize gpu buffer --- yolov5/common.hpp | 2 +- yolov5/yololayer.cu | 5 +++++ yolov5/yolov5.cpp | 51 +++++++++++++++++++-------------------------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/yolov5/common.hpp b/yolov5/common.hpp index 17d0471..cb502a1 100644 --- a/yolov5/common.hpp +++ b/yolov5/common.hpp @@ -40,7 +40,7 @@ cv::Mat preprocess_img(cv::Mat& img) { y = 0; } cv::Mat re(h, w, CV_8UC3); - cv::resize(img, re, re.size(), 0, 0, cv::INTER_CUBIC); + cv::resize(img, re, re.size(), 0, 0, cv::INTER_LINEAR); cv::Mat out(Yolo::INPUT_H, Yolo::INPUT_W, CV_8UC3, cv::Scalar(128, 128, 128)); re.copyTo(out(cv::Rect(x, y, re.cols, re.rows))); return out; diff --git a/yolov5/yololayer.cu b/yolov5/yololayer.cu index 86a67d6..e14ee18 100644 --- a/yolov5/yololayer.cu +++ b/yolov5/yololayer.cu @@ -28,6 +28,11 @@ namespace nvinfer1 YoloLayerPlugin::~YoloLayerPlugin() { + for(int ii = 0; ii < mKernelCount; ii ++) + { + CUDA_CHECK(cudaFree(mAnchor[ii])); + } + CUDA_CHECK(cudaFreeHost(mAnchor)); } // create the plugin at runtime from a byte stream diff --git a/yolov5/yolov5.cpp b/yolov5/yolov5.cpp index 6dbcbfa..c0503b0 100644 --- a/yolov5/yolov5.cpp +++ b/yolov5/yolov5.cpp @@ -447,37 +447,12 @@ void APIToModel(unsigned int maxBatchSize, IHostMemory** modelStream) { builder->destroy(); } -void doInference(IExecutionContext& context, float* input, float* output, int batchSize) { - const ICudaEngine& engine = context.getEngine(); - - // Pointers to input and output device buffers to pass to engine. - // Engine requires exactly IEngine::getNbBindings() number of buffers. - assert(engine.getNbBindings() == 2); - void* buffers[2]; - - // In order to bind the buffers, we need to know the names of the input and output tensors. - // Note that indices are guaranteed to be less than IEngine::getNbBindings() - const int inputIndex = engine.getBindingIndex(INPUT_BLOB_NAME); - const int outputIndex = engine.getBindingIndex(OUTPUT_BLOB_NAME); - - // Create GPU buffers on device - CHECK(cudaMalloc(&buffers[inputIndex], batchSize * 3 * INPUT_H * INPUT_W * sizeof(float))); - CHECK(cudaMalloc(&buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float))); - - // Create stream - cudaStream_t stream; - CHECK(cudaStreamCreate(&stream)); - +void doInference(IExecutionContext& context, cudaStream_t& stream, void **buffers, float* input, float* output, int batchSize) { // DMA input batch data to device, infer on the batch asynchronously, and DMA output back to host - CHECK(cudaMemcpyAsync(buffers[inputIndex], input, batchSize * 3 * INPUT_H * INPUT_W * sizeof(float), cudaMemcpyHostToDevice, stream)); + CHECK(cudaMemcpyAsync(buffers[0], input, batchSize * 3 * INPUT_H * INPUT_W * sizeof(float), cudaMemcpyHostToDevice, stream)); context.enqueue(batchSize, buffers, stream, nullptr); - CHECK(cudaMemcpyAsync(output, buffers[outputIndex], batchSize * OUTPUT_SIZE * sizeof(float), cudaMemcpyDeviceToHost, stream)); + CHECK(cudaMemcpyAsync(output, buffers[1], batchSize * OUTPUT_SIZE * sizeof(float), cudaMemcpyDeviceToHost, stream)); cudaStreamSynchronize(stream); - - // Release stream and buffers - cudaStreamDestroy(stream); - CHECK(cudaFree(buffers[inputIndex])); - CHECK(cudaFree(buffers[outputIndex])); } int main(int argc, char** argv) { @@ -535,6 +510,20 @@ int main(int argc, char** argv) { IExecutionContext* context = engine->createExecutionContext(); assert(context != nullptr); delete[] trtModelStream; + assert(engine->getNbBindings() == 2); + void* buffers[2]; + // In order to bind the buffers, we need to know the names of the input and output tensors. + // Note that indices are guaranteed to be less than IEngine::getNbBindings() + const int inputIndex = engine->getBindingIndex(INPUT_BLOB_NAME); + const int outputIndex = engine->getBindingIndex(OUTPUT_BLOB_NAME); + assert(inputIndex == 0); + assert(outputIndex == 1); + // Create GPU buffers on device + CHECK(cudaMalloc(&buffers[inputIndex], BATCH_SIZE * 3 * INPUT_H * INPUT_W * sizeof(float))); + CHECK(cudaMalloc(&buffers[outputIndex], BATCH_SIZE * OUTPUT_SIZE * sizeof(float))); + // Create stream + cudaStream_t stream; + CHECK(cudaStreamCreate(&stream)); int fcount = 0; for (int f = 0; f < (int)file_names.size(); f++) { @@ -559,7 +548,7 @@ int main(int argc, char** argv) { // Run inference auto start = std::chrono::system_clock::now(); - doInference(*context, data, prob, BATCH_SIZE); + doInference(*context, stream, buffers, data, prob, BATCH_SIZE); auto end = std::chrono::system_clock::now(); std::cout << std::chrono::duration_cast(end - start).count() << "ms" << std::endl; std::vector> batch_res(fcount); @@ -581,6 +570,10 @@ int main(int argc, char** argv) { fcount = 0; } + // Release stream and buffers + cudaStreamDestroy(stream); + CHECK(cudaFree(buffers[inputIndex])); + CHECK(cudaFree(buffers[outputIndex])); // Destroy the engine context->destroy(); engine->destroy();