目录

  • 基本编译配置
  • 一些常识
  • BN层的坑
  • cuda基础
  • 向cuda核函数传入结构体指针?

参考:http://galoisplusplus.coding.me/blog/2018/05/22/cudaErrorCudartUnloading/

主要是在linux下,使用cuda安装包里的cuda-memcheck来检查内存,它是类似于valgrind的存在。

基本编译配置

首先添加path:

vim ~/.zshrc
export PATH=$PATH:/usr/local/cuda/bin

基于CMake编写C程,cuda相关的内容:

option(use_cuda "Use CUDA?" ON)if (use_cuda)#list(APPEND CMAKE_PREFIX_PATH "/usr/local/cuda")if (CMAKE_SYSTEM_NAME MATCHES "Linux")set(CUDA_DIR "/usr/local/cuda")find_package(CUDA REQUIRED)include_directories("${CUDA_DIR}/include")link_directories("${CUDA_DIR}/lib64")elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")set(CUDA_DIR "$ENV{CUDA_PATH}")find_package(CUDA REQUIRED)include_directories("${CUDA_DIR}/include")link_directories("${CUDA_DIR}/lib/x64")endif()
endif()if(use_cuda)list(APPEND TESTBED_DEP_LIBScudartcudart_staticcudacublas_devicecudnncublas)
endif()target_link_libraries(testbed ${TESTBED_DEP_LIBS})

使用:

cd ~/work/mycode
mkdir build
cd build
cmake ..
makecuda-memcheck ./run

一些常识

如果cudaMalloc()后忘记cudaFree(),用cuda-memcheck检查不出来这个错误。。据网友说是会自动回收,不知道cuda是否自带了gc功能2333

BN层的坑

如果是卷积层,可以直接调用cudnnConvolutionForward()函数,它使用caffe一样的padding方式:它的内部默默的做了对称的padding(pad_left == pad_right),调用起来挺容易的。

倒是BN层卡了好久,主要是官方文档有错误。官方文章这样写的:

Note: The input transformation performed by this function is defined as: y := alpha*y + beta *(bnScale * (x-estimatedMean)/sqrt(epsilon + estimatedVariance)+bnBias)...alpha, beta
Inputs. Pointers to scaling factors (in host memory) used to blend the layer output value with prior value in the destination tensor as follows: dstValue = alpha[0]*resultValue + beta[0]*priorDstValue.

按照贴出来的文档内容,按它第一行的说法,alpha应该设定为0,beta应该设定为1;按照后面几行的说法,应该是alpha设定为1,beta设定为0。

  • Caffe:已经很久没有人来修了,它压根没有调用cudnnBatchNormalizationForwardInference()
  • TensorFlow: 并没有调用。。不信你grep查一下,或者github上网页里在repo中搜索,找不到的。
  • PyTorch: 还是比较良心,调用了cudnnBatchNormalizationForwardInference( )
  • mini-caffe: 也是调用了cudnnBatchNormalizationForwardInference( )

主要参考mini-caffe和PyTorch,发现BN层应该设定alpha为1, beta为0,这样才能正确算出结果来。看看PyTorch的调用:

    AT_CUDNN_CHECK(cudnnBatchNormalizationForwardInference(handle, mode, &one, &zero, //这里,alpha是one, beta是zeroidesc.desc(), input->data_ptr(),idesc.desc(), output->data_ptr(),wdesc.desc(),weight->data_ptr(),bias->data_ptr(),running_mean->data_ptr(),running_var->data_ptr(),epsilon));

当然这里还有一个教训:但凡用CuDNN的xxxDescriptor参数说明的地方,它后面紧接着的几个变量,应该是gpu指针,也就是其值为GPU上的地址,而如果是CPU上的地址就会导致内存错误,比如代码为4或77

举例:

cudnnStatus = cudnnBatchNormalizationForwardInference(layer_base->handle_cudnn,CUDNN_BATCHNORM_PER_ACTIVATION,&alpha,&beta,bnlayer->bn_layer_input_desc,layer_base->bottom_blobs_ptr[0]->gpu_data_ptr, //gpu上的bnlayer->bn_layer_output_desc,layer_base->top_blobs_ptr[0]->gpu_data_ptr, //gpu上的bnlayer->bn_layer_scale_bias_mean_var_desc,bnlayer->scale_dev,  //gpu上的bnlayer->shift_dev,    //gpu上的bnlayer->mean_dev,  //gpu上的bnlayer->variance_dev,//gpu上的bnlayer->eps
);

cuda基础

CUDA架构的目的,就是减轻早期GPU计算中存在的限制,这些限制使之前的GPU在通用计算中没有广泛应用。
换言之,CUDA就是为了让NVIDIA GPU用于通用计算的技术。

CUDA编程,使用C/C++即可,它仅仅是增加了个别关键字。不需要使用Shader Language,不需要掌握OpenGL,因此编程门槛降低。

编译器:CUDA C程序需要同时在CPU和N卡上执行计算,分别需要各自的编译器。GPU上的编译器,也就是nvcc了。CPU上的话cl.exe/gcc/clang等。

host和device: CPU以及main memory,叫做host;GPU上的memory称为device。 内存拷贝的时候,用cudaMemcpy(),要指定内存拷贝的来源和目的地,是host还是device。

kernel: GPU上执行的函数称为kernel。

向cuda核函数传入结构体指针?

C语言传参,本质上是拷贝一份,因此:简单数据类型直接传入即可,反正复制成本低;复杂类型则传入指针,复制成本低。

而如果需要向函数传入多个参数,就希望传入一个结构体或其指针,作为他们的一个封装。

然而,直接向cuda kernel函数传入CPU下的结构体指针是不行的。问题很明显:把host上的指针给device用,寻址会出现问题。

解决思路有三种:

  1. 使用host和device的统一寻址
  2. 分别创建host和device上的结构体指针,参考https://blog.csdn.net/u013701860/article/details/52605137
  3. 向cuda kernel函数传入多个参数

举个栗子:传入结构体的拷贝是OK的(just_demo),传入host上结构体指针的拷贝,cuda kernel函数会报废的(just_demo2):

#include <stdio.h>#define CHECK_CUDA(call) \
{ \const cudaError_t cudaStatus = call; \if (cudaStatus != cudaSuccess) { \printf("Error! in file %s, line %d, ", __FILE__, __LINE__); \printf("code: %d, reason: %s\n", cudaStatus, cudaGetErrorString(cudaStatus)); \exit(1); \} \
}typedef struct Pad{int left;int right;int top;int bottom;
}Pad;__global__ void just_demo(Pad pad) {printf("blockIdx: (%d, %d, %d), threadIdx: (%d, %d, %d)",blockIdx.x, blockIdx.y, blockIdx.z,threadIdx.x, threadIdx.y, threadIdx.z);printf("pad: left=%d, right=%d, top=%d, bottom=%d\n",pad.left,pad.right,pad.top,pad.bottom);
}__global__ void just_demo2(Pad* pad) {printf("blockIdx: (%d, %d, %d), threadIdx: (%d, %d, %d)",blockIdx.x, blockIdx.y, blockIdx.z,threadIdx.x, threadIdx.y, threadIdx.z);printf("pad: left=%d, right=%d, top=%d, bottom=%d\n",pad->left,pad->right,pad->top,pad->bottom);
}int main(void){Pad pad;pad.left = 1;pad.right = 0;pad.top = 1;pad.bottom = 0;size_t buf_size = 3*4*4*sizeof(float);float* data_host = (float*)malloc(buf_size);float* data_dev;CHECK_CUDA(cudaMalloc(&data_dev, buf_size));just_demo<<<3, 5>>> (pad);  // this is OK//just_demo2<<<3, 5>>> (&pad); // this will cause unspecified launch failureCHECK_CUDA(cudaMemcpy(data_host, data_dev, buf_size, cudaMemcpyDeviceToHost));return 0;
}

转载于:https://www.cnblogs.com/zjutzz/p/10242535.html

封装cuda/cudnn写卷积网络前向计算程序相关推荐

  1. 深度学习:使用卷积网络实现计算机图像识别,卷积和max pooling操作介绍

    深度学习在计算机图像识别上的应用非常成功.利用深度学习,我们能够对图片进行高精度识别,实现这一功能的,主要依靠神经网络中的一种分支,名为卷积网络.卷积网络与我们前面实现的网络不通之处在于,它可以直接接 ...

  2. 学习笔记CB009:人工神经网络模型、手写数字识别、多层卷积网络、词向量、word2vec...

    人工神经网络,借鉴生物神经网络工作原理数学模型. 由n个输入特征得出与输入特征几乎相同的n个结果,训练隐藏层得到意想不到信息.信息检索领域,模型训练合理排序模型,输入特征,文档质量.文档点击历史.文档 ...

  3. CUDA、CUDNN跑卷积神经网络报错CUDA error: CUBLAS_STATUS_EXECUTION_FAILED和CUDNN_STATUS_EXECUTION_FAILED

      笔者跑神经网络的时候遇到显存溢出问题. 系统:Ubuntu 16.04 CUDA:10.0.130 CUDNN:7.6.4.38 Python:3.6.12 PYTORCH: 1.2 TORCHV ...

  4. 神经网络学习(三)比较详细 卷积神经网络原理、手写字体识别(卷积网络实现)

    之前写了一篇基于minist数据集(手写数字0-9)的全连接层神经网络,识别率(85%)并不高,这段时间学习了一些卷积神经网络的知识又实践了一把, 识别率(96%左右)确实上来了 ,下面把我的学习过程 ...

  5. 【Tensorflow】深度学习实战02——Tensorflow实现进阶的卷积网络(CIFAR-10)

    [fishing-pan:https://blog.csdn.net/u013921430转载请注明出处] 前言 之前使用Tensorflow实现了一个简单卷积神经网络用于手写数字识别,那是一个简单的 ...

  6. 论文推荐|【KSII TIIS 2021】DP-LinkNet:一种用于古籍文档图像二值化的卷积网络(有源码)...

    今日分享来自[KSII TIIS 2021]的论文『DP-LinkNet: A convolutional network for historical document image binariza ...

  7. Pytorch(GPU)配环境原理:cuda+cudnn+pytorch配环境的每一步到底干了些什么?

    作者:18届cyl 时间:2022.5.11 参考文章:https://blog.csdn.net/qq_42406643/article/details/109545766 最近帮舍友配pytorc ...

  8. Ubuntu 18.04/16.04/14.04 + RTX 2070 + CUDA + cuDNN环境配置

    1.英伟达显卡驱动 1.1.第一种安装方法: 对于新出Nvidia显卡,本人并不建议大家到官网手动下载安装NVIDIA的显卡驱动,有可能因为缺少显卡安装包的依赖条件导致最后没有办法安装成功.特别是我刚 ...

  9. 通过深度卷积网络,把移动设备上的照片提高到单反级别画质(已开源)

    简评:可以应用于任何手机,把相片提高到单反级别.相关下载请看文末. 本文翻译,以下我们都代表原作者团队. 尽管智能手机的内置相机质量连年提高,但由于物理限制(传感器尺寸.镜头紧凑.缺乏特定的硬件)的存 ...

  10. 图卷积网络-多标签分类

    首先理解一些以下: 1. 二分类:每一张图像输出一个类别信息2. 多类别分类:每一张图像输出一个类别信息3. 多输出分类:每一张图像输出固定个类别的信息4. 多标签分类:每一张图像输出类别的个数不固定 ...

最新文章

  1. 多数编程语言里的0.1+0.2≠0.3?
  2. 从0梳理1场时间序列赛事!
  3. Android SQLite数据库的详细使用
  4. Linux文本处理之printf:规定输出内容与样式 %规定内容样式 \规定排版样式
  5. C# DataTable的Distinct解决方案及表的复制
  6. hb-550s计算机电源,XFX TS 550金牌电源拆解及电路分析
  7. js for in遍历对象_JS中轻松遍历对象属性的几种方式
  8. C++深拷贝与浅拷贝以及写时复制
  9. 推荐一款思维在线思维导图,为什么?
  10. arcgis开发 多版本之间如何兼容_arcgis api 4.x for js 结合 react 入门开发系列初探篇(附源码下载)...
  11. Emacs代码折叠/显示
  12. 我是如何学习Android源码的
  13. c语言题库打不开软件,编写题库程序_想把一个老师编的做题练习的软件里面的题库弄出来貌似是用VB60编写的要怎么做啊_淘题吧...
  14. MySQL数据库执行Update卡死问题解决
  15. 6款沙发背景墙装饰画 总有一幅你喜欢的
  16. Unity粒子系统学习笔记
  17. 计算机怎样保存文件格式,word文档怎样保存为pdf格式
  18. 从PC到Mac —— 写给Mac新新手的入门教程
  19. C++常用函数汇总(持续更新)
  20. 6.2 新浪财经——资产负债表获取(打印js渲染后的网页表格)

热门文章

  1. 计算机应用基础第3次平时作业,计算机应用基础第3次作业.doc
  2. java服务器访问html_浏览器输入服务器端口号来访问html网页
  3. 介质簇结构不正确_电动蝶阀的结构特征以及优点,值得看完
  4. 新勒索软件在受害者阅读两篇勒索软件文章后解密
  5. BZOJ1114 : [POI2008]鲁滨逊逃生Rob
  6. Java 下一代: Groovy、Scala 和 Clojure
  7. 美了美了!22款精美的 iOS 应用程序图标模板
  8. liunx 监控工具sar
  9. BN=批归一化+缩放位移=(batchNorm层+scale层)
  10. 2月7日 SVM线性回归逻辑回归