CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1)

这篇具有很好参考价值的文章主要介绍了CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

cuda小白
原文链接 NPP

GPU架构近些年也有不少的变化,具体的可以参考别的博主的介绍,都比较详细。还有一些cuda中的专有名词的含义,可以参考《详解CUDA的Context、Stream、Warp、SM、SP、Kernel、Block、Grid》

常见的NppStatus,可以看这里。

如有问题,请指出,谢谢

Arithmetic Operations

当前模块主要是加减乘除,abs,平方,矩阵相乘,开根,ln,exp等。不同相同功能,以其中一个为例进行介绍。

AddC

针对图像中每一个像素添加一个常量值。与之类似的还有MulC,SubC,DivC,AbsDiffC,MulScale
大概接口样式:

// 两个结果的区别在于,有I的结果可以就原始的图像地址进行操作,无需进行拷贝
// Sfs的含义 表示可以对图像的数值范围进行约束操作。
NppStatus nppiAddC_[数据类型]_C[通道数]RSfs_[是否使用流]
NppStatus nppiAddC_[数据类型]_C[通道数]IRSfs_[是否使用流]

以为三通道的uint8_t的图像数据为例子:

NppStatus nppiAddC_8u_C3RSfs(const Npp8u * pSrc1,
							 int nSrc1Step,
							 const Npp8u aConstants[3],
							 Npp8u *pDst,
							 int nDstStep,
							 NppiSize oSizeROI,
							 int nScaleFactor);
NppStatus nppiAddC_8u_C3RSfs(const Npp8u aConstants[3],
							 Npp8u *pDst,
							 int nDstStep,
							 NppiSize oSizeROI,
							 int nScaleFactor);	
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }

int main() {
  std::string directory = "../";
  // =============== load image ===============
  cv::Mat image = cv::imread(directory + "dog.png");
  if (image.empty()) {
    std::cout << "Load image error!" << std::endl;
    return -1;
  }

  int image_width = image.cols;
  int image_height = image.rows;
  int image_size = image_width * image_height * 3 * sizeof(uint8_t);
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  // =============== malloc && cpy ===============
  uint8_t *in_ptr, *in_ptr2, *out_ptr, *roi_out_ptr;
  cudaMalloc((void**)&in_ptr, image_size);
  cudaMalloc((void**)&in_ptr2, image_size);
  cudaMalloc((void**)&out_ptr, image_size);
  cudaMalloc((void**)&roi_out_ptr, image_size);
  cudaMemcpy(in_ptr, image.data, image_size, cudaMemcpyHostToDevice);
  cudaMemcpy(in_ptr2, image.data, image_size, cudaMemcpyHostToDevice);

  uint8_t host_constant[3] = { (uint8_t)0, (uint8_t)20, (uint8_t)0 };

  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;
  
  // nppiAddC_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  NppStatus status;
  status = nppiAddC_8u_C3RSfs(in_ptr, image_width * 3, host_constant, out_ptr, 
                              image_width * 3, roi1, 0);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAddC_8u_C3RSfs failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "add_constant.jpg", out_image);

  status = nppiAddC_8u_C3RSfs(in_ptr, image_width * 3, host_constant, out_ptr, image_width * 3, 
                              roi1, 1);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAddC_8u_C3RSfs failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "add_constant_scale.jpg", out_image);

  status = nppiAddC_8u_C3RSfs(in_ptr, image_width * 3, host_constant, out_ptr, image_width * 3, 
                              roi2, 0);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAddC_8u_C3RSfs failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "add_constant_roi.jpg", out_image);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(in_ptr2)
  CUDA_FREE(out_ptr)
  CUDA_FREE(roi_out_ptr)
}
make
cmake_minimum_required(VERSION 3.20)
project(test)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")

add_executable(test test.cpp)
target_link_libraries(test
                      ${OpenCV_LIBS}
                      ${CUDA_LIBS}
)
result

CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1),c++,CUDA,NPP
注意点:

  1. 对图像的进行值的范围进行一定的约束,最初的图像RGB的值都是[0, 255],如果对应的scale设置为1的时候,相当于将数值的范围变为2的-nScaleFactor倍数,即[0, 128],超过128的会变成128,因此整体的图像色调会变暗;同样的,如果设置为-1,则整体的会变为2倍,因为存图的限制只能是[0, 255],所以整体看起来会变亮。
  2. 如果指定的roi不是整张图的时候,由于roi的类型是NppiSize(width, height),因此输入的指针不是指向图像的起始位置,而是roi的起始位置。
  3. MulScale相较于MulC来说,默认nScaleFactor为0;
  4. AbsDiffC中主要功能就是得到整张图像与host_constant的绝对差值。
  5. 每个结果都有一个对应的包含cudastream的版本,按需使用。
Add

与AddC不同的是,Add输入的是两张图像。同样的还有Mul,MulScale,Sub,Div,Div_round,Abs,AbsDiff,Sqr,Sqrt,Ln,Exp。(由于Abs,AbsDiff,Sqr,Sqrt,Ln,Exp在图像出列方面使用的不是很多,就不细述)。
以uint8_t的三通道图像为例:

// 命名规则与nppiAddC*类似
NppStatus nppiAdd_8u_C3RSfs(const Npp8u * pSrc1,
							int nSrc1Step,
						    const Npp8u *pSrc2,
							int nSrc2Step,
							Npp8u * pDst,
							int nDstStep,
							NppiSize oSizeROI,
							int nScaleFactor);
NppStatus nppiAdd_8u_C3IRSfs(const Npp8u *pSrc,
							 int nSrcStep,
							 Npp8u *pSrcDst,
							 int nSrcDstStep,
							 NppiSize oSizeROI,
							 int nScaleFactor);
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define PRINT_VALUE(value) {  \
  std::cout << "[GPU] " << #value << " = " << value << std::endl; }

#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }

int main() {
  std::string directory = "../";
  // =============== load image ===============
  cv::Mat image = cv::imread(directory + "dog.png");
  if (image.empty()) {
    std::cout << "Load image error!" << std::endl;
    return -1;
  }

  int image_width = image.cols;
  int image_height = image.rows;
  int image_size = image_width * image_height * 3 * sizeof(uint8_t);
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  // =============== malloc && cpy ===============
  uint8_t *in_ptr, *in_ptr2, *out_ptr, *roi_out_ptr;
  cudaMalloc((void**)&in_ptr, image_size);
  cudaMalloc((void**)&in_ptr2, image_size);
  cudaMalloc((void**)&out_ptr, image_size);
  cudaMalloc((void**)&roi_out_ptr, image_size);
  cudaMemcpy(in_ptr, image.data, image_size, cudaMemcpyHostToDevice);
  cudaMemcpy(in_ptr2, image.data, image_size, cudaMemcpyHostToDevice);

  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;
  
  // nppiAdd_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_8UC3);
  NppStatus status;
  status = nppiAdd_8u_C3RSfs(in_ptr, image_width * 3, in_ptr2, image_width * 3, out_ptr, 
                             image_width * 3, roi1, 0);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAdd_8u_C3RSfs failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "add.jpg", out_image);

  status = nppiAdd_8u_C3RSfs(in_ptr, image_width * 3, in_ptr2, image_width * 3, out_ptr, 
                             image_width * 3, roi1, 1);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAdd_8u_C3RSfs failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "add_scale.jpg", out_image);

  status = nppiAdd_8u_C3RSfs(in_ptr, image_width * 3, in_ptr2, image_width * 3, out_ptr, 
                             image_width * 3, roi2, 0);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAdd_8u_C3RSfs failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size, cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "add_roi.jpg", out_image);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(in_ptr2)
  CUDA_FREE(out_ptr)
  CUDA_FREE(roi_out_ptr)
}
make
cmake_minimum_required(VERSION 3.20)
project(test)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")

add_executable(test test.cpp)
target_link_libraries(test
                      ${OpenCV_LIBS}
                      ${CUDA_LIBS}
)
result

CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1),c++,CUDA,NPP
注意点:

  1. nScaleFactor与AddC中的功能一致。roi的操作也与AddC中的一致。
  2. 由于使用的是两个相同的图片进行相加,因此在nScaleFactor为1的时候,所有的数值都变成原来的值,因此保存的图像与原图一致。
  3. 同样有cudastream版本,按需使用。
AddWeighted

将特定区域的图像进行填充weight

NppStatus nppiAddWeighted_8u32f_C1IR(const Npp8u *pSrc,
									 int nSrcStep,
									 Npp32f * pSrcDst,
									 int nSrcDstStep,
									 NppiSize oSizeROI,
								     Npp32f nAlpha);
NppStatus nppiAddWeighted_8u32f_C1IMR(const Npp8u *pSrc,
									  int nSrcStep,
									  const Npp8u *pMask,
									  int nMaskStep,
									  Npp32f * pSrcDst,
									  int nSrcDstStep,
									  NppiSize oSizeROI,
									  Npp32f nAlpha);	
code
#include <iostream>
#include <cuda_runtime.h>
#include <npp.h>
#include <opencv2/opencv.hpp>

#define PRINT_VALUE(value) {  \
  std::cout << "[GPU] " << #value << " = " << value << std::endl; }

#define CUDA_FREE(ptr) { if (ptr != nullptr) { cudaFree(ptr); ptr = nullptr; } }

int main() {
  std::string directory = "../";
  // =============== load image ===============
  cv::Mat image = cv::imread(directory + "dog.png");
  if (image.empty()) {
    std::cout << "Load image error!" << std::endl;
    return -1;
  }

  cv::Mat gray;
  cv::cvtColor(image, gray, CV_BGR2GRAY);
  cv::imwrite(directory + "gray.jpg", gray);

  int image_width = gray.cols;
  int image_height = gray.rows;
  int image_size = image_width * image_height;
  std::cout << "Image info : image_width = " << image_width
            << ", image_height = " << image_height << std::endl;

  cv::Mat mat_mask = cv::Mat::ones(image_height, image_width, CV_8UC1);

  cv::Rect rc_center = cv::Rect(image_width / 4, image_height / 4, 
                                image_width / 2, image_height / 2);
  mat_mask(rc_center) = cv::Mat::ones(image_height / 2, image_width / 2, CV_8UC1) * 255;
  cv::imwrite(directory + "mask.jpg", mat_mask);

  // =============== malloc && cpy ===============
  uint8_t *in_ptr, *mask;
  cudaMalloc((void**)&in_ptr, image_size * sizeof(uint8_t));
  cudaMalloc((void**)&mask, image_size * sizeof(uint8_t));
  cudaMemcpy(in_ptr, gray.data, image_size, cudaMemcpyHostToDevice);
  cudaMemcpy(mask, mat_mask.data, image_size, cudaMemcpyHostToDevice);

  float *out_ptr, *out_ptr1, *out_ptr2;
  cudaMalloc((void**)&out_ptr, image_size * sizeof(float));
  cudaMalloc((void**)&out_ptr1, image_size * sizeof(float));
  cudaMalloc((void**)&out_ptr2, image_size * sizeof(float));
  
  NppiSize roi1, roi2;
  roi1.width = image_width;
  roi1.height = image_height;
  roi2.width = image_width / 2;
  roi2.height = image_height / 2;
  
  // nppiAdd_8u_C3RSfs
  cv::Mat out_image = cv::Mat::zeros(image_height, image_width, CV_32FC1);
  NppStatus status;
  status = nppiAddWeighted_8u32f_C1IMR(in_ptr, image_width * sizeof(uint8_t), 
                                       mask, image_width * sizeof(uint8_t), 
                                       out_ptr, image_width * sizeof(float), 
                                       roi1, 1.0);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAddWeighted_8u32f_C1IMR failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr, image_size * sizeof(float), cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "addweight.jpg", out_image);

  status = nppiAddWeighted_8u32f_C1IMR(in_ptr, image_width * sizeof(uint8_t), 
                                       mask, image_width * sizeof(uint8_t), 
                                       out_ptr1, image_width * sizeof(float), 
                                       roi1, 0.5);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAddWeighted_8u32f_C1IMR failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr1, image_size * sizeof(float), cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "addweight_scale.jpg", out_image);

  status = nppiAddWeighted_8u32f_C1IMR(in_ptr, image_width * sizeof(uint8_t), 
                                       mask, image_width * sizeof(uint8_t), 
                                       out_ptr2, image_width * sizeof(float), 
                                       roi2, 0.5);
  if (status != NPP_SUCCESS) {
    std::cout << "[GPU] ERROR nppiAddWeighted_8u32f_C1IMR failed, status = " << status << std::endl;
    return false;
  }
  cudaMemcpy(out_image.data, out_ptr2, image_size * sizeof(float), cudaMemcpyDeviceToHost);
  cv::imwrite(directory + "addweight_roi_scale.jpg", out_image);

  // free
  CUDA_FREE(in_ptr)
  CUDA_FREE(mask)
  CUDA_FREE(out_ptr)
  CUDA_FREE(out_ptr1)
  CUDA_FREE(out_ptr2)
}
make
cmake_minimum_required(VERSION 3.20)
project(test)

find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})

find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
file(GLOB CUDA_LIBS "/usr/local/cuda/lib64/*.so")

add_executable(test test.cpp)
target_link_libraries(test
                      ${OpenCV_LIBS}
                      ${CUDA_LIBS}
)
result

CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1),c++,CUDA,NPP
注意点:
1.nAlpha是针对原图中的每一个像素的值需要添加的权重,mask仅影响目标位置中那些部分需要输出。
2. roi表示输入的区域约束。文章来源地址https://www.toymoban.com/news/detail-688637.html

到了这里,关于CUDA小白 - NPP(2) - Arithmetic and Logical Operations(1)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Dynamics 365 Finance and Operations 创建你的第一个项目框架

    第一章:浅谈Dynamics CRM开发转Dynamics AX开发的感受与差异 第二章:Dynamics 365 Finance and Operations 虚拟机安装及使用 第三章:Dynamics 365 Finance and Operations 创建你的第一个项目(Visual Studio) 本文为大家介绍如何在Visual Studio中创建Model和Solution。并且让你了解Model和solution的基本概念

    2024年02月06日
    浏览(53)
  • Packet Tracer - Configure Cisco Routers for Syslog, NTP, and SSH Operations

    配置OSPF MD5身份验证。 配置NTP服务。 设置路由器将消息记录到syslog服务器。 配置R3路由器以支持SSH连接。 在本练习中,您将配置OSPF MD5身份验证以实现安全的路由更新。 NTP服务器是本次活动中主NTP服务器。您需要在NTP服务器和路由器上配置身份验证,并设置路由器允许软件

    2024年02月01日
    浏览(41)
  • ubuntu系统(6):Nvidia Docker配置cuda+pytorch【纯小白版】

    目录 一、安装Nvidia Docker 二、安装显卡驱动 1、安装驱动 2、检查显卡驱动版本 3、查询驱动版本和显卡相关信息 三、Docker hub安装pytorch和对应版本cuda 1、在Docker hub中查询对应版本镜像 ​编辑2、查询pytorch/pytorch的镜像 3、devel版本和runtime版本的区别 4、拉取对应版本镜像 5、查

    2024年02月03日
    浏览(41)
  • (纯小白向)Windows配置GPU深度学习环境:Cuda+Anaconda+pytorch+Vscode

    目录 一、Cuda和Cudnn下载安装 1.1 确定自己的电脑显卡驱动支持的Cuda版本 1.2 Cuda下载与安装 1.3 Cudnn下载与安装 二、Anaconda下载安装 2.1 下载 2.2 安装 2.3 手动配置环境变量 2.4 测试是否安装成功 三、Pytorch下载安装 3.1 创建conda虚拟环境 3.2 Pytorch下载 四、Vscode下载与环境配置 4.1

    2024年02月05日
    浏览(75)
  • GPU版本pytorch(Cuda12.1)清华源快速安装一步一步教!小白教学~

    上面是官方链接,不知道为什么我科学上网了下的还是非常慢,而且看网上有下好之后还有问题的,于是果断选择清华源! 下面是一步一步教程: 首先确保安装了anaconda,在anaconda prompt命令行窗口创建虚拟环境,我命名为 pytorch310(Python版本不要低于3.8) 然后激活它: 设置

    2024年02月10日
    浏览(64)
  • RuntimeError: FlashAttention is only supported on CUDA 11 and above

    RuntimeError: FlashAttention is only supported on CUDA 11 and above 此错误的原因可能是 nvcc 的 CUDA 版本(通过键入“nvcc -V”获得,可能 11.0)与 torch (11.7) 的 CUDA 版本不匹配。 类似问题在这里解决: https://stackoverflow.com/questions/40517083/multiple-cuda-versions-on-machine-nvcc-v-confusion 我解决了这个问题通

    2024年02月07日
    浏览(44)
  • RuntimeError: CUDA out of memory See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF

    报错: If reserved memory is allocated memory try setting max_split_size_mb to avoid fragmentation. See documentation for Memory Management and PYTORCH_CUDA_ALLOC_CONF 当reserved memory is allocated memory,进行如下设置,可解决此bug: 代码如下:

    2024年02月11日
    浏览(52)
  • 小白水平理解面试经典题目LeetCode 121 Best Time to Buy and Sell Stock

    你好,2024年的第一个月,又是秋风萧瑟天气凉,草木摇落露为霜。.。。在这个特殊的时代,作为我们普通的一个打工人,我们用这道题,开启对这个不符合经济增长规律的股市反抗一把。 有这样一个数组 prices ,其中 prices[i] 是给定股票在 i th 天的价格。 我希望通过选择某

    2024年01月22日
    浏览(44)
  • Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same

    RuntimeError: Input type (torch.FloatTensor) and weight type (torch.cuda.FloatTensor) should be the same or input should be a MKLDNN tensor and weight is a dense tensor 错误原因: 这个错误提示表明输入数据的类型和模型权重的类型不匹配,可能是因为模型权重是在GPU上训练的,而输入数据是在CPU上进行的。 可以

    2024年02月06日
    浏览(69)
  • RuntimeError: Input type (torch.cuda.FloatTensor) and weight type (torch.FloatTensor) should be the

    问题描述: mobilenetv3在残差块中加入了注意力机制 用GPU 进行训练时报的错 解决方法1: 1,不用GPU 用CPU 就可以 CUDA 设置为False,确实可以解决,但是不用GPU 好像意义不大 解决方法2 : 用仍然用GPU ,看下面的的解决方案: 报错的原因:2 1,我直接在倒残差块的前向传播内对导

    2024年02月16日
    浏览(40)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包