CUBLAS库入门教程(从环境配置讲起)

文章目录

  • 前言
  • 一、搭建环境
  • 二、简单介绍
  • 三、 具体例子
  • 四、疑问


前言

CUBLAS库是NVIDIA CUDA用于线性代数计算的库。使用CUBLAS库的原因是我不想去直接写核函数。
(当然,你还是得学习核函数该怎么写。但是人家写好的肯定比我自己写的更准确!)


一、搭建环境

  1. 安装CUDA库,具体可以看我上一篇文章:在C++项目中集成CUDA程序加速(从环境配置讲起)
  2. 如果你是装在默认路径下,那么 CUBLAS库的头文件就在:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.0\include 路径下面,以cublas开头的.h文件。
  3. 所以,还是按照步骤1的文章进行环境配置,然后只需要多在添加依赖项中增加一个cublas.lib就可以了。

二、简单介绍

  1. CUBLAS Introdution 是官方文档。(全英文的,还有不少数学公式。大家有不理解的可以直接留言区问相关API,我们一起讨论学习。)
  2. CUBLAS Samples 是官方示例,所有API都有。
  3. 对于API名称,都是cublasl<t>...,其中有下述类型选择:
    在这里插入图片描述
  4. CUBLAS库的矩阵是列向量的,跟glm一致。
  5. CUBLAS对于矩阵或者向量的index是从1开始的。所以,如果有函数的返回结果是个index(比如查找矩阵中的最大值),记得要index - 1才是我们要的。

三、 具体例子

下面我以矩阵与向量相乘的函数进行举例,看看是怎么用的。

  1. 首先,通过查找官方文档,知道是如下的函数:
cublasStatus_t cublasDgemv(cublasHandle_t handle, cublasOperation_t trans,int m, int n,const double          *alpha,const double          *A, int lda,const double          *x, int incx,const double          *beta,double          *y, int incy)
/*
* handle		: CUBLAS的句柄,用以管理CUBLAS库的上下文和资源
* CUBLAS_OP_N	: 指定矩阵操作模式。CUBLAS_OP_N代表正常模式(列向量);CUBLAS_OP_T代表转置模式(行向量)
* m				: 矩阵A的行数
* n				: 矩阵A的列数
* alpha			: 与矩阵A相乘的标量
* A				: 指向存储在device上面的矩阵数据指针
* lda			: 矩阵的列数,代表矩阵在内存中的存储方式
* x				: 向量X
* incx			: 向量x中相邻两个元素的index间隔,一般为1
* beta			: 与向量y相乘的标量
* y				: 向量y
* incy			: 向量y中相邻两个元素的index间隔,一般为1
*/

具体计算公式如下:
这是具体的计算公式

  1. 如果我们只是想计算矩阵和向量相乘,那么我们只需要令 α = 1.0, β = 0.0,然后传入我们要的Ax就行了。
  2. 最后,具体代码如下:
/// MyCublas.cuh#pragma once#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include "cublas_v2.h"extern "C" void MatrixMulVectorCublas(const double* matrix, const int row, const int col, const double* vector, double* result
);
/// MyCublas.cu#include "MyCublas.cuh"
#include "CublasUtility.h"void MatrixMulVectorCublas(const double* matrix, const int row, const int col,const double* vector, double* result)
{// 1. 初始化句柄cublasHandle_t handle;CUBLAS_CHECK(cublasCreate(&handle));// 2. 分配内存double* dev_matrix = NULL;double* dev_vector = NULL;CUDA_CHECK(cudaMalloc((void**)&dev_matrix, sizeof(double) * row * col));CUDA_CHECK(cudaMalloc((void**)&dev_vector, sizeof(double) * row));CUDA_CHECK(cudaMemcpy(dev_matrix, matrix, sizeof(double) * row * col, cudaMemcpyHostToDevice));CUDA_CHECK(cudaMemcpy(dev_vector, vector, sizeof(double) * row, cudaMemcpyHostToDevice));// 3. 执行矩阵乘法double* dev_result = NULL;CUDA_CHECK(cudaMalloc((void**)&dev_result, sizeof(double) * col));CUDA_CHECK(cudaMemset(dev_result, 0, sizeof(double) * col));const double alpha = 1.0;const double beta = 0.0;CUBLAS_CHECK(cublasDgemv(handle, CUBLAS_OP_N, row, col, &alpha, dev_matrix, col, dev_vector, 1, &beta, dev_result, 1));CUDA_CHECK(cudaMemcpy(result, dev_result, sizeof(double) * col, cudaMemcpyDeviceToHost));// 4. 释放内存CUDA_CHECK(cudaFree(dev_matrix));CUDA_CHECK(cudaFree(dev_vector));CUDA_CHECK(cudaFree(dev_result));CUBLAS_CHECK(cublasDestroy(handle));}
/// CublasUtility.h#pragma once
#include <string>
#include <stdexcept>
// CUDA API error checking
#define CUDA_CHECK(err)                                                                            \do {                                                                                           \cudaError_t err_ = (err);                                                                  \if (err_ != cudaSuccess) {                                                                 \std::printf("CUDA error %d at %s:%d\n", err_, __FILE__, __LINE__);                     \throw std::runtime_error("CUDA error");                                                \}                                                                                          \} while (0)// cublas API error checking
#define CUBLAS_CHECK(err)                                                                          \do {                                                                                           \cublasStatus_t err_ = (err);                                                               \if (err_ != CUBLAS_STATUS_SUCCESS) {                                                       \std::printf("cublas error %d at %s:%d\n", err_, __FILE__, __LINE__);                   \throw std::runtime_error("cublas error");                                              \}                                                                                          \} while (0)
/// main.cpp#include "MyCublas.cuh"#include <iostream>int main()
{double matrix[12] = { 1.0, 2.0, 3.0, 4.0,5.0, 6.0, 7.0, 8.0,9.0, 10.0, 11.0, 12.0};double vector[4] = { 1.0, 2.0, 3.0};double result[4] = { 0.0 };MatrixMulVectorCublas(matrix, 3, 4, vector, result);for (int i = 0; i < 4; ++i){std::cout << result[i] << ", ";}return 0;
}

四、疑问

对于上述代码,我还有以下的疑问:

  1. 我在运行下面这句的时候,VS显示我的进程内存会到2.2GB左右,难道真的需要这么大吗?
CUBLAS_CHECK(cublasCreate(&handle));
  1. 上述代码运行的结果是:38, 44, 50, 0。但是实际结果应该是:38, 44, 50, 56。查了很久还是没差出来为什么。希望有细心的小伙伴帮我检查一下!

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[PyTorch][chapter 54][Variational Auto-Encoder 实战]

前言&#xff1a; 这里主要实现&#xff1a; Variational Autoencoders (VAEs) 变分自动编码器 其训练效果如下 训练的过程中要注意调节forward 中的kle ,调参。 整个工程两个文件&#xff1a; vae.py main.py 目录&#xff1a; vae main 一 vae 文件名&#xff1a; vae…

typora使用

1.主题配置 先打开主题文件夹&#xff0c; 文件–>>偏好设置–>>外观–>>打开主题文件夹 1.1字体 修改字体需要修改css文件&#xff0c;确定当前所用主题&#xff0c;可以在typora菜单点击主题&#xff0c;看看当前勾选的是哪个主题&#xff0c;比如gith…

iPhone 15 Pro与iPhone 13 Pro:最大的预期升级

如果你在2021年首次发布iPhone 13 Pro时就抢到了它,那么你的合同很可能即将到期。虽然距离iPhone 15系列还有几周的时间,但你可能已经在想:是时候把你的旧iPhone升级为iPhone 15 Pro了吗? 我们认为iPhone 13 Pro是你现在能买到的最好的手机之一。但如果你想在2023年晚些时…

微信小程序 趣味学习与益智游戏系统APP

管理员、用户可通过HBuilder系统手机打开系统&#xff0c;注册登录后可进行管理员后端&#xff1b;首页、个人中心、用户管理、学生分类管理、学一学管理、玩一玩管理、听一听管理、试题管理、练一练管理、系统管理、考试管理&#xff0c;用户前端&#xff1b;首页、学一学、玩…

音视频入门基础理论知识

文章目录 前言一、视频1、视频的概念2、常见的视频格式3、视频帧4、帧率5、色彩空间6、采用 YUV 的优势7、RGB 和 YUV 的换算 二、音频1、音频的概念2、采样率和采样位数①、采样率②、采样位数 3、音频编码4、声道数5、码率6、音频格式 三、编码1、为什么要编码2、视频编码①、…

同一台电脑测.Net和Mono平台浮点运算的差异

float speed 0.1f;float distance 2.0f;long needTime (long)(distance / speed);Log.Debug($"needTime{needTime}"); 结果&#xff1a; .Net平台算出20 Mono平台算出19

【传输层】网络基础 -- UDP协议 | TCP协议

再谈端口号端口号范围划分netstatpidof UDPUDP的特点面向数据报UDP的缓冲区 基于UDP的应用层协议 TCP认识TCP协议的报头理解封装解包理解可靠性TCP工作模式16位窗口大小6位标志位URGACKPSHRSTSYNFIN 再谈端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序 在TCP/I…

力扣92. 局部反转链表

92. 反转链表 II 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], left 2, right 4 输出&am…

计算机网络 | TCP 三次握手四次挥手 |半关闭连接

本来是不愿意写的&#xff0c;可是在实际场景&#xff0c;对具体的描述标志还是模糊不清&#xff0c;基础不扎实&#xff0c;就得承认&#xff01;&#xff01;&#xff01; TCP 连接建立需要解决三大问题&#xff1a; 知道双方存在约定一些参数&#xff0c;如最大滑动窗口值、…

Kotlin,解决调用了函数但是函数体内没有执行的问题,什么时候使用invoke

fun main() {listOf(1,2,3).forEach{ foo(it)} } fun foo(a:Int) {print(a) }这段代码按照代码逻辑来说打印的是 123 但是没有这个打印 把foo函数转成java的代码如下 JvmStaticNotNullpublic static final Function0 foo(final int var0) {return (Function0)(new Function0 ()…

Ubuntu 22.04安装 —— Win11 22H2

目录 Ubuntu使用下载UbuntuVmware 安装图示安装步骤图示 Ubuntu使用 系统环境&#xff1a; Windows 11 22H2Vmware 17 ProUbutun 22.04.3 Server Ubuntu Server documentation | Ubuntu 下载 Ubuntu 官网下载 建议安装长期支持版本 ——> 可以选择桌面版或服务器版(仅包…

UI界面自动化BagePage

常用basepage模块代码 # -*- coding: utf-8 -*- # Desc: UI自动化测试的一些基础浏览器操作方法# 第三方库导入 import time from logging import config import randomimport allure from selenium.webdriver.common.alert import Alert from selenium.webdriver.remote.webe…

【Leetcode】130.被围绕的区域

一、题目 1、题目描述 给你一个 m x n 的矩阵 board ,由若干字符 X 和 O ,找到所有被 X 围绕的区域,并将这些区域里所有的 O 用 X 填充。 示例1: 输入:board = [[“X”,“X”,“X”,“X”],[“X”,“O”,“O”,“X”],[“X”,“X”,“O”,“X”],[“X”,“O”,“X”,“…

高德地图jsapi报错INVALID_USER_SCODE

看了各种网上方法&#xff0c;还是搞不定。无奈在高德开放平台提了工单。 很快高德的技术人员就给出了答复“您好&#xff0c;您检查一下您的安全密钥是否在key之前&#xff0c;安全密钥设置必须是在JS API 脚本加载之前进行设置&#xff0c;否则设置无效。” 并给出了推荐的…

【数据结构】C语言队列(详解)

前言: &#x1f4a5;&#x1f388;个人主页:​​​​​​Dream_Chaser&#xff5e; &#x1f388;&#x1f4a5; ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--C语言实现队列 目录 一.队列概念及结构 1.1队列的概念 1.2队列的结构 二.队列的实现 2.1头文…

【linux命令讲解大全】035.文件删除命令:rm 和 rmdir 的用法详解

文章目录 rm补充说明语法选项参数实例 rmdir补充说明语法选项参数实例 从零学 python rm 用于删除给定的文件和目录 补充说明 rm命令可以删除一个目录中的一个或多个文件或目录&#xff0c;也可以将某个目录及其下属的所有文件及其子目录均删除掉。对于链接文件&#xff0c;…

【python爬虫】6.爬虫实操(带参数请求数据)

文章目录 前言项目&#xff1a;狂热粉丝分析过程什么是带参数请求数据如何带参数请求数据 代码实现被隐藏的歌曲清单什么是Request Headers如何添加Request Headers 复习 前言 先来复习一下上一关的主要知识吧&#xff0c;先热个身。 Network能够记录浏览器的所有请求。我们最…

React Navigation 使用导航

在 Web 浏览器中&#xff0c;您可以使用锚标记链接到不同的页面。当用户单击链接时&#xff0c;URL 会被推送到浏览器历史记录堆栈中。当用户按下后退按钮时&#xff0c;浏览器会从历史堆栈顶部弹出该项目&#xff0c;因此活动页面现在是以前访问过的页面。React Native 不像 W…

AZ900备考

文章目录 云服务的概念云服务模型云服务类型消费的模型云服务的好处可靠性和可预测性的优势云中的管理 Azure 体系结构和服务核心结构组件物理基础结构组件 Azure计算和网络服务Azure 存储服务身份认证AD身份认证 Azure 管理和治理成本管理治理合规性的功能和工具管理和部署Azu…

代码随想录算法训练营第17期第34天 | 1005. K 次取反后最大化的数组和、134. 加油站、135. 分发糖果

1005. K 次取反后最大化的数组和 这里说一下卡哥和我的区别&#xff0c;基本思路是一样的&#xff0c; 只是卡哥这里只需要一次排序&#xff0c;而我这边排了两次&#xff1b; 卡哥思路&#xff1a; 1.按照绝对值大小从大到小排序 2.从前往后遍历&#xff0c;遇到负数将其转…