工作小记 cv-cuda使用

最近要实现RGB相关cuda算子的功能,最终通过自己手写核函数实现。这里记录一下对cv-cuda的调研和使用,因为项目要求gcc-5,而cv-cuda要求gcc11而放弃使用,但是相关的记录,以及使用方法都要记录下来,以便下次项目一旦更新gcc(笑)时再次使用cv-cuda
https://cvcuda.github.io/ 官网连接
https://cvcuda.github.io/installation.html 安装指南

安装相关

在官网下载对应cuda版本的nvcv包
nvcv-dev-0.4.0_beta-cuda12-x86_64-linux.tar.xz 对应 lib doc include
cvcuda-tests-0.4.0_beta-cuda12-x86_64-linux.tar.xz 对应 lib
nvcv-lib-0.4.0_beta-cuda12-x86_64-linux.tar.xz 对应bin share
统一放入/home/softwares/cvcuda_test路径下,tar -xvf 解压后

zyx@host:/home/softwares/cvcuda_test/opt/nvidia/cvcuda0$ ls
bin  doc  etc  include  lib  share

执行对应的测试脚本,检验cvcuda安装是否正确

export LD_LIBRARY_PATH=/home/softwares/cvcuda_test/opt/nvidia/cvcuda0/lib/x86_64-linux-gnu/:$LD_LIBRARY_PATH
zyx@host:/home/softwares/cvcuda_test/opt/nvidia/cvcuda0/bin$ ./run_tests.sh

输出如下,正确
在这里插入图片描述

编译相关

1 这里要对项目的conanfile做改动,提升gcc的版本
在这里插入图片描述
2 库文件和头文件的路径要设定好

if (${TARGET_ARCH} STREQUAL "x86_64")
find_package(ffmpeg-with-qsv-cuda)
if (ffmpeg-with-qsv-cuda_FOUND)
  include_directories(SYSTEM ${ffmpeg-with-qsv-cuda_INCLUDE_DIRS})
  list(APPEND LINK_SEARCH_PATH ${ffmpeg-with-qsv-cuda_LIB_DIRS})
  link_directories(${ffmpeg-with-qsv-cuda_LIB_DIRS})
  message("ffmpeg-with-qsv-cuda_LIB provided")
endif()

find_package(CUDA REQUIRED)
if (CUDA_FOUND)
  include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
endif()


# list(APPEND CMAKE_PREFIX_PATH "/home/softwares/cvcuda_test/opt/nvidia/cvcuda0/lib/x86_64-linux-gnu/cmake")

# find_package(nvcv_types REQUIRED)
# if (nvcv_types_FOUND)
#   include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
# endif()

# find_package(cvcuda REQUIRED)
# if (cvcuda_FOUND)
#   include_directories(SYSTEM ${CUDA_INCLUDE_DIRS})
# endif()

set(CVCUDA_LIBRARY_PATH "/home/softwares/cvcuda_test/opt/nvidia/cvcuda0")
include_directories(${CVCUDA_LIBRARY_PATH}/include)
link_directories(${CVCUDA_LIBRARY_PATH}/lib/x86_64-linux-gnu)
# message(STATUS "######################--------------------------#################################")

endif()


if (${TARGET_ARCH} STREQUAL "x86_64")
  set(TARGET_ARCH_LIBRARIES
  avutil
  avcodec
  datatools
  nvcv_types cvcuda
  ${TensorRT_LIBRARIES}
  ${CUDA_LIBRARIES})
endif()

编译过程中的一些错误:

报错 /home/softwares/cvcuda_test/opt/nvidia/cvcuda0/include/nvcv/detail/ImageBatchImpl.hpp:115:65: error: no matching function for call to ‘nvcv::ImageBatch::ImageBatch()’inline ImageBatchVarShape::ImageBatchVarShape(ImageBatch &&batch)

因为cvcuda是gcc-11的要求,而项目原来的编译器是gcc-5的,所以报这个错误,用gcc-11的编译器后报错解决。但是会报如下的错误,因为gcc太高cuda里的有些东西会有问题

报错 /usr/include/c++/11/bits/std_function.h:435:145: note:`_ArgTypes’

/usr/include/c++/11/bits/std_function.h:435:145: error: parameter packs not expanded with ‘...:
  435 |         function(_Functor&& __f)
      |                                                                                                                                                 ^
/usr/include/c++/11/bits/std_function.h:435:145: note:         ‘_ArgTypes’
/usr/include/c++/11/bits/std_function.h:530:146: error: parameter packs not expanded with ‘...:
  530 |         operator=(_Functor&& __f)
      |                                                                                                                                                  ^
/usr/include/c++/11/bits/std_function.h:530:146: note:         ‘_ArgTypes’

https://github.com/NVlabs/instant-ngp/issues/119
原因是cv-cuda和cuda两个库对gcc11的适配不是很好,这里的解决办法是用gcc-10(更低版本的gcc)放入/usr/local/cuda/bin 即cuda就默认使用gcc-10的编译器

sudo apt install gcc-10 g++-10
export CC=/usr/bin/gcc-10
export CXX=/usr/bin/g++-10
export CUDA_ROOT=/usr/local/cuda
ln -s /usr/bin/gcc-10 $CUDA_ROOT/bin/gcc
ln -s /usr/bin/g++-10 $CUDA_ROOT/bin/g++
(Build Instant-NGP as described)

仍然运行报错,因为一些中间件communication的基础库都是 gcc-5开发的,对于11,会有问题。

使用相关

cv-cuda的开发文档不是很全,这里参照源码中的example学习使用
其对数据结构进行了部分封装。但万变不离其宗,和自己实现的算子流程是很一致的。
1 分配内存
这里分配内存时用了 TensorDataStridedCuda::Buffer 这个数据结构,实际是指定NCHW每一层的size,同样的调用cudaMalloc分配内存
2 内存的属性
拿到分配的一块内存后,如何解析这块内存,使用了 Tensor::Requirements这个结构记录内存的属性,同时传入TensorDataStridedCuda这个数据结构中,该结构最终用于生成我们的Tensor继续后续的算子操作
3 算子操作
老一套的crop,resize CustomCropResize,已经为我们实现好了对应算子操作的类,需要做的就是,指定好传入和传处的tensor的shape,非常的面向过程,和自己实现算子的过程完全一致。拿到处理好的tensor,再怎么操作就和cv-cuda无关了,cv-cuda更多解决的是需要手写算子相关的东西。

int main(int argc, char *argv[])
{
    // Default parameters
    std::string imagePath = "./samples/assets/tabby_tiger_cat.jpg";
    uint32_t    batchSize = 1;

    // Parse the command line paramaters to override the default parameters
    int retval = ParseArgs(argc, argv, imagePath, batchSize);
    if (retval != 0)
    {
        return retval;
    }

    // NvJpeg is used to decode the images to the color format required.
    // Since we need a contiguous buffer for batched input, a buffer is
    // preallocated based on the  maximum image dimensions and  batch size
    // for NvJpeg to write into.

    // Note : The maximum input image dimensions needs to be updated in case
    // of testing with different test images

    int maxImageWidth  = 720;
    int maxImageHeight = 720;
    int maxChannels    = 3;

    // tag: Create the cuda stream
    cudaStream_t stream;
    CHECK_CUDA_ERROR(cudaStreamCreate(&stream));

    // tag: Allocate input tensor
    // Allocating memory for RGBI input image batch of uint8_t data type
    // without padding since NvDecode utility currently doesnt support
    // Padded buffers.

    nvcv::TensorDataStridedCuda::Buffer inBuf;
    inBuf.strides[3] = sizeof(uint8_t);
    inBuf.strides[2] = maxChannels * inBuf.strides[3];
    inBuf.strides[1] = maxImageWidth * inBuf.strides[2];
    inBuf.strides[0] = maxImageHeight * inBuf.strides[1];
    CHECK_CUDA_ERROR(cudaMallocAsync(&inBuf.basePtr, batchSize * inBuf.strides[0], stream));

    // tag: Tensor Requirements
    // Calculate the requirements for the RGBI uint8_t Tensor which include
    // pitch bytes, alignment, shape  and tensor layout
    nvcv::Tensor::Requirements inReqs
        = nvcv::Tensor::CalcRequirements(batchSize, {maxImageWidth, maxImageHeight}, nvcv::FMT_RGB8);

    // Create a tensor buffer to store the data pointer and pitch bytes for each plane
    nvcv::TensorDataStridedCuda inData(nvcv::TensorShape{inReqs.shape, inReqs.rank, inReqs.layout},
                                       nvcv::DataType{inReqs.dtype}, inBuf);

    // TensorWrapData allows for interoperation of external tensor representations with CVCUDA Tensor.
    nvcv::Tensor inTensor = nvcv::TensorWrapData(inData);

    // tag: Image Loading
    // NvJpeg is used to load the images to create a batched input device buffer.
    uint8_t             *gpuInput = reinterpret_cast<uint8_t *>(inBuf.basePtr);
    // The total images is set to the same value as batch size for testing
    uint32_t             totalImages = batchSize;
    // Format in which the decoded output will be saved
    nvjpegOutputFormat_t outputFormat = NVJPEG_OUTPUT_RGBI;

    NvDecode(imagePath, batchSize, totalImages, outputFormat, gpuInput);

    // tag: The input buffer is now ready to be used by the operators

    // Set parameters for Crop and Resize
    // ROI dimensions to crop in the input image
    int cropX      = 150;
    int cropY      = 50;
    int cropWidth  = 400;
    int cropHeight = 300;

    // Set the resize dimensions
    int resizeWidth  = 320;
    int resizeHeight = 240;

    //  Initialize the CVCUDA ROI struct
    NVCVRectI crpRect = {cropX, cropY, cropWidth, cropHeight};

    // tag: Allocate Tensors for Crop and Resize
    // Create a CVCUDA Tensor based on the crop window size.
    nvcv::Tensor cropTensor(batchSize, {cropWidth, cropHeight}, nvcv::FMT_RGB8);
    // Create a CVCUDA Tensor based on resize dimensions
    nvcv::Tensor resizedTensor(batchSize, {resizeWidth, resizeHeight}, nvcv::FMT_RGB8);

#ifdef PROFILE_SAMPLE
    cudaEvent_t start, stop;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);
    cudaEventRecord(start);
#endif
    // tag: Initialize operators for Crop and Resize
    cvcuda::CustomCrop cropOp;
    cvcuda::Resize     resizeOp;

    // tag: Executes the CustomCrop operation on the given cuda stream
    cropOp(stream, inTensor, cropTensor, crpRect);

    // Resize operator can now be enqueued into the same stream
    resizeOp(stream, cropTensor, resizedTensor, NVCV_INTERP_LINEAR);

    // tag: Profile section
#ifdef PROFILE_SAMPLE
    cudaEventRecord(stop);
    cudaEventSynchronize(stop);
    float operatorms = 0;
    cudaEventElapsedTime(&operatorms, start, stop);
    std::cout << "Time for Crop and Resize : " << operatorms << " ms" << std::endl;
#endif

    // tag: Copy the buffer to CPU and write resized image into .bmp file
    WriteRGBITensor(resizedTensor, stream);

    // tag: Clean up
    CHECK_CUDA_ERROR(cudaStreamDestroy(stream));

    // tag: End of Sample
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/338572.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在MD编辑器里插入20次方问题

前言 看了很多文章里面没写怎么插入20次方&#xff0c;最后在官网的一篇文章上看到了很详细的数学公式的插入。 问题 大家肯定以为这样就可以了 效果 明显是不行的 解决 使用{}把数字括起来就可以了。 1 20 1^{20} 120 小知识 在行内显示(就是与文字在一起) $ $另起…

《A++ 敏捷开发》- 5 量化管理从个人开始

我&#xff1a;你们管理层和客户都比较关心项目的进度&#xff0c;项目是否能按时完成&#xff1f;请问你们过去的项目如何&#xff1f; 开发&#xff1a;我们现在就是走敏捷开发&#xff0c;两周一个迭代。每次迭代前&#xff0c;我们聚一起开会&#xff0c;把所有用户故事按优…

互联网加竞赛 基于机器视觉的手势检测和识别算法

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &#x1f9ff; 更多资料, 项目分享&#xff1a; https://gitee.com/dancheng…

(超详细)9-YOLOV5改进-添加EffectiveSEModule注意力机制

1、在yolov5/models下面新建一个EffectiveSEModule.py文件&#xff0c;在里面放入下面的代码 代码如下&#xff1a; import torch from torch import nn as nn from timm.models.layers.create_act import create_act_layerclass EffectiveSEModule(nn.Module):def __init__…

【Leetcode】277.搜寻名人

一、题目 1、题目描述 假设你是一个专业的狗仔,参加了一个 n 人派对,其中每个人被从 0 到 n - 1 标号。在这个派对人群当中可能存在一位 “名人”。所谓 “名人” 的定义是:其他所有 n - 1 个人都认识他/她,而他/她并不认识其他任何人。 现在你想要确认这个 “名人” 是…

【Linux】基本指令收尾

文章目录 日期查找打包压缩系统信息Linux和Windows互传文件 日期 这篇是基本指令的收尾了&#xff0c;还有几个基本指令我们需要说一下 首先是Date&#xff0c;它是用来显示时间和日期 直接输入date的话显示是有点不好看的&#xff0c;所以我们可以根据自己的喜欢加上分隔符&…

java垃圾回收GC过程

GC&#xff08;Gabage Collection&#xff09; 用于回收堆中的垃圾数据 清理方法 1.标记-清理 对数据标记&#xff0c;然后清理 缺点&#xff1a;容易产生内存碎片 2.标记-整理 对标记后的数据清理&#xff0c;剩下数据前移 缺点&#xff1a;每次清理后数据都要迁移&#xff0…

二叉树(一)

&#x1f4d1;前言 本文主要是【数据结构】——二叉树使用的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是听风与他&#x1f947; ☁️博客首页&#xff1a;CSDN主页听风与他 &#x1f304;每日一句&am…

第13节-简历中的开放性问题

(点击即可收听) 不少公司的开放式题目每年不会有太大的变化&#xff0c;所以在答题前可先去相关求职论坛看看这些公司往年的问题&#xff0c;分析和思考自己应当怎么回答 开放式问题回答技巧 开放式问题主要考察的是求职者的求职动机、解决问题的能力、创造力等软实力&#xff…

已解决java.lang.ClassNotFoundException——java连接mysql8/mysql5

1.准备工作 1.mysql8下载安装 这里大家没必要去mysql官网安装&#xff0c;可以直接安装phpStudy_pro,毕竟小皮面板的宣言是让天下没有难配的服务器环境&#xff0c;如下是小皮面板的界面&#xff08;同样的&#xff0c;此次用到的所有资料文末公众号可免费领取&#xff09;&a…

MSPM0L1306例程学习-UART部分(3)

MSPM0L1306例程学习系列 1.背景介绍 写在前边的话&#xff1a; 这个系列比较简单&#xff0c;主要是围绕TI官网给出的SDK例程进行讲解和注释。并没有针对模块的具体使用方法进行描述。所有的例程均来自MSPM0 SDK的安装包&#xff0c;具体可到官网下载并安装: https://www.ti…

快速傅立叶变换FFT学习笔记

什么是FFT&#xff1f; FFT&#xff08;Fast Fourier Transformation&#xff09; 是离散傅氏变换&#xff08;DFT&#xff09;的快速算法&#xff0c;即快速傅氏变换。FFT使计算机计算离散傅里叶变换所需要的乘法次数大为减少&#xff0c;特别是被变换的抽样点数N越多&#x…

使用STM32的UART实现蓝牙通信

✅作者简介&#xff1a;热爱科研的嵌入式开发者&#xff0c;修心和技术同步精进 代码获取、问题探讨及文章转载可私信。 ☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。 &#x1f34e;获取更多嵌入式资料可点击链接进群领取&#xff0c;谢谢支持&#xff01;&#x1f447…

算法优化:LeetCode第122场双周赛解题策略与技巧

接下来会以刷常规题为主 &#xff0c;周赛的难题想要独立做出来还是有一定难度的&#xff0c;需要消耗大量时间 比赛地址 3011. 判断一个数组是否可以变为有序 public class Solution {public int minimumCost(int[] nums) {if (nums.length < 3) {// 数组长度小于3时&a…

Python实现单因素方差分析

Python实现单因素方差分析 1.背景 正念越来越受到人们关注&#xff0c;正念是一种有意的、不加评判的对当下的注意觉察。可以通过可以通过观呼吸、身体扫描、正念饮食等多种方式培养。 为了验证正念对记忆力的影响&#xff0c;选取三组被试分别进行正念训练&#xff0c;运动训…

基于springboot+vue仓库管理系统

摘要 本文介绍了一种基于Spring Boot和Vue的现代化仓库管理系统的设计与实现。仓库管理是企业运营中至关重要的一环&#xff0c;它涉及到货物的进出、库存的管理以及订单的处理等方面。为了提高仓库管理的效率和精确度&#xff0c;我们设计了这个集成了前后端技术的系统。在系统…

37-WEB漏洞-反序列化之PHPJAVA全解(上)

WEB漏洞-反序列化之PHP&JAVA全解&#xff08;上&#xff09; 一、PHP 反序列化原理二、案例演示2.1、无类测试2.1.1、本地2.1.2、CTF 反序列化小真题2.1.3、CTF 反序列化类似题 2.2、有类魔术方法触发2.2.1、本地2.2.2、网鼎杯 2020 青龙大真题 三、参考资料 一、PHP 反序列…

16.云原生之kubesphere组件安装卸载

云原生专栏大纲 文章目录 KubeSphere组件介绍KubeSphere组件安装卸载配置内容参考安装组件步骤卸载组件步骤 KubeSphere组件介绍 KubeSphere 的全部可插拔组件如下&#xff1a; 配置项功能组件描述alertingKubeSphere 告警系统可以为工作负载和节点自定义告警策略。告警策略…

多级缓存

一、多级缓存 传统的缓存策略一般是请求到达Tomcat后&#xff0c;先查询Redis&#xff0c;如果未命中则查询数据库&#xff0c;如图&#xff1a; 存在下面的问题&#xff1a; •请求要经过Tomcat处理&#xff0c;Tomcat的性能成为整个系统的瓶颈 •Redis缓存失效时&#xff…

FPGA时序分析与时序约束(五)——使用Timing Analyzer进行时序分析与约束

Quartus的安装路径下会自带有例程&#xff0c;通过fir_filter进行学习如何使用Timing Analyzer进行时序分析与约束。 1.1 创建时序网表 打开fir_filter并进行综合后可通过菜单栏Tool->Timing Analyzer或工具栏按钮运行Timing Analyzer。 根据前面提到的&#xff0c;时序分析…