欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

cublascudnn优化笔记

时间:2023-04-23
文章目录

前言cublas 常用API

数据格式cublasGemmEx & cublasLtMatmul cuDNN 常用API

cudnnConvolutionForward


前言

cublas。
官方指南:https://docs.nvidia.com/cuda/cublas/
头文件 cublas_v2.h
官方例子:https://github.com/NVIDIA/CUDALibrarySamples/

cuDNN。
cuDNN官方指南:https://docs.nvidia.com/deeplearning/cudnn/developer-guide/index.html
入门例子:http://www.goldsborough.me/cuda/ml/cudnn/c++/2017/10/01/14-37-23-convolutions_with_cudnn/ (API已过时,看个思路就好)


cublas 常用API 数据格式

cuBLAS library uses column-major storage, and 1-based indexing.
c++ 对接cublas需要把二维数组转置。一般c++的矩阵都是 0-based indexing,也就是row-major storage。可以用Sgeam的api,m * n 的矩阵,转置。

cublasSgeam(cublas_handle, CUBLAS_OP_T, CUBLAS_OP_N, m, n, &alpha, in_addr, n, &beta, out_addr, m, out_addr, m)

但是,如果后面的操作带cublasOperation_t的对输入的操作的话,不用单独先转置。
比如,可以直接调用matmul:

const int lda = k;const int ldb = n;const int ldc = m;cublasGemmEx(cublas_handle, CUBLAS_OP_T, CUBLAS_OP_T, m, n, k, &alpha, a_addr, type_a, lda, b_addr, type_b, ldb, &beta, c_addr, type_c, ldc, type_compute, CUBLAS_GEMM_DEFAULT_TENSOR_OP))

cublasGemmEx & cublasLtMatmul

测下来什么都默认的情况,这俩性能差不错,所以用简单的cublasGemmEx。输入是fp32的数据,cublasComputeType_t 设置为CUBLAS_COMPUTE_32F_FAST_16F有将近50%的性能提升,精度差别也只是从0.01%降到0.1%。alpha和beta的数据类型需要跟input一样。CublasGemmAlgo_t 用 CUBLAS_GEMM_DEFAULT_TENSOR_OP。


cuDNN 常用API cudnnConvolutionForward

cudnnConvolutionForward API

构图阶段可以做的一次性操作

// kernel_descriptor_ 和convolution_descriptor_ 可以重复使用,对于动态batchsize的算子,这俩永远固定的CUDNN_CHECK(cudnnCreateFilterDescriptor(&kernel_descriptor_));CUDNN_CHECK(cudnnSetFilter4dDescriptor(kernel_descriptor_, CUDNN_DATA_FLOAT, CUDNN_TENSOR_NHWC, n, k, h, w));CUDNN_CHECK(cudnnCreateConvolutionDescriptor(&convolution_descriptor_));CUDNN_CHECK(cudnnSetConvolution2dDescriptor(convolution_descriptor_, pad_h, pad_w, u, v, dilation_h, dilation_w, CUDNN_CONVOLUTION, CUDNN_DATA_FLOAT));

runtime的操作

// 因为动态batchsize,只有runtime才能知道具体的dim信息,需要重新set descriptorcudnnTensorDescriptor_t runtime_input_descriptor{nullptr};cudnnTensorDescriptor_t runtime_output_descriptor{nullptr};CUDNN_CHECK(cudnnCreateTensorDescriptor(&runtime_input_descriptor));CUDNN_CHECK(cudnnCreateTensorDescriptor(&runtime_output_descriptor));CUDNN_CHECK( cudnnSetTensor4dDescriptor(runtime_input_descriptor, CUDNN_TENSOR_NHWC, CUDNN_DATA_FLOAT, n, c, h, w));CUDNN_CHECK( cudnnSetTensor4dDescriptor(runtime_output_descriptor, CUDNN_TENSOR_NHWC, CUDNN_DATA_FLOAT, n, c, h, w));int returned_algo_count = 0;// 1是因为只取最优的算法即可CUDNN_CHECK(cudnnGetConvolutionForwardAlgorithm_v7(cudnn_handle_, runtime_input_descriptor, kernel_descriptor_, convolution_descriptor_, runtime_output_descriptor, 1, &returned_algo_count, cudnn_algos_));// cudnn_algos_[0].memory 最优算法需要的workspace// cudnn_algos_[0].alog 最优算法

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。