使用 CUBLAS 库给矩阵运算提速
前言
编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时。那么有没有一些现成的 CUDA 库来调用呢?
答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库。
本文将大致介绍如何使用 CUBLAS 库,同时演示一个使用 CUBLAS 库进行矩阵乘法的例子。
CUBLAS 内容
CUBLAS 是 CUDA 专门用来解决线性代数运算的库,它分为三个级别:
Lev1. 向量相乘
Lev2. 矩阵乘向量
Lev3. 矩阵乘矩阵
同时该库还包含状态结构和一些功能函数。
CUBLAS 用法
大体分成以下几个步骤:
1. 定义 CUBLAS 库对象
2. 在显存中为待运算的数据以及需要存放结果的变量开辟显存空间。( cudaMalloc 函数实现 )
3. 将待运算的数据传输进显存。( cudaMemcpy,cublasSetVector 等函数实现 )
3. 调用 CUBLAS 库函数 ( 根据 CUBLAS 手册调用需要的函数 )
4. 从显存中获取结果变量。( cudaMemcpy,cublasGetVector 等函数实现 )
5. 释放申请的显存空间以及 CUBLAS 库对象。( cudaFree 及 cublasDestroy 函数实现 )
代码示例
如下程序使用 CUBLAS 库进行矩阵乘法运算,请仔细阅读注释,尤其是 API 的参数说明:
// CUDA runtime 库 + CUBLAS 库
#include "cuda_runtime.h"
#include "cublas_v2.h" #include <time.h>
#include <iostream> using namespace std; // 定义测试矩阵的维度
int const M = ;
int const N = ; int main()
{
// 定义状态变量
cublasStatus_t status; // 在 内存 中为将要计算的矩阵开辟空间
float *h_A = (float*)malloc (N*M*sizeof(float));
float *h_B = (float*)malloc (N*M*sizeof(float)); // 在 内存 中为将要存放运算结果的矩阵开辟空间
float *h_C = (float*)malloc (M*M*sizeof(float)); // 为待运算矩阵的元素赋予 0-10 范围内的随机数
for (int i=; i<N*M; i++) {
h_A[i] = (float)(rand()%+);
h_B[i] = (float)(rand()%+); } // 打印待测试的矩阵
cout << "矩阵 A :" << endl;
for (int i=; i<N*M; i++){
cout << h_A[i] << " ";
if ((i+)%N == ) cout << endl;
}
cout << endl;
cout << "矩阵 B :" << endl;
for (int i=; i<N*M; i++){
cout << h_B[i] << " ";
if ((i+)%M == ) cout << endl;
}
cout << endl; /*
** GPU 计算矩阵相乘
*/ // 创建并初始化 CUBLAS 库对象
cublasHandle_t handle;
status = cublasCreate(&handle); if (status != CUBLAS_STATUS_SUCCESS)
{
if (status == CUBLAS_STATUS_NOT_INITIALIZED) {
cout << "CUBLAS 对象实例化出错" << endl;
}
getchar ();
return EXIT_FAILURE;
} float *d_A, *d_B, *d_C;
// 在 显存 中为将要计算的矩阵开辟空间
cudaMalloc (
(void**)&d_A, // 指向开辟的空间的指针
N*M * sizeof(float) // 需要开辟空间的字节数
);
cudaMalloc (
(void**)&d_B,
N*M * sizeof(float)
); // 在 显存 中为将要存放运算结果的矩阵开辟空间
cudaMalloc (
(void**)&d_C,
M*M * sizeof(float)
); // 将矩阵数据传递进 显存 中已经开辟好了的空间
cublasSetVector (
N*M, // 要存入显存的元素个数
sizeof(float), // 每个元素大小
h_A, // 主机端起始地址
, // 连续元素之间的存储间隔
d_A, // GPU 端起始地址
// 连续元素之间的存储间隔
);
cublasSetVector (
N*M,
sizeof(float),
h_B,
,
d_B, ); // 同步函数
cudaThreadSynchronize(); // 传递进矩阵相乘函数中的参数,具体含义请参考函数手册。
float a=; float b=;
// 矩阵相乘。该函数必然将数组解析成列优先数组
cublasSgemm (
handle, // blas 库对象
CUBLAS_OP_T, // 矩阵 A 属性参数
CUBLAS_OP_T, // 矩阵 B 属性参数
M, // A, C 的行数
M, // B, C 的列数
N, // A 的列数和 B 的行数
&a, // 运算式的 α 值
d_A, // A 在显存中的地址
N, // lda
d_B, // B 在显存中的地址
M, // ldb
&b, // 运算式的 β 值
d_C, // C 在显存中的地址(结果矩阵)
M // ldc
); // 同步函数
cudaThreadSynchronize(); // 从 显存 中取出运算结果至 内存中去
cublasGetVector (
M*M, // 要取出元素的个数
sizeof(float), // 每个元素大小
d_C, // GPU 端起始地址
, // 连续元素之间的存储间隔
h_C, // 主机端起始地址
// 连续元素之间的存储间隔
); // 打印运算结果
cout << "计算结果的转置 ( (A*B)的转置 ):" << endl; for (int i=;i<M*M; i++){
cout << h_C[i] << " ";
if ((i+)%M == ) cout << endl;
} // 清理掉使用过的内存
free (h_A);
free (h_B);
free (h_C);
cudaFree (d_A);
cudaFree (d_B);
cudaFree (d_C); // 释放 CUBLAS 库对象
cublasDestroy (handle); getchar(); return ;
}
运行测试

PS:矩阵元素是随机生成的
小结
1. 使用 CUDA 库固然方便,但也要仔细的参阅函数手册,其中每个参数的含义都要很清晰才不容易出错。
2. 如果程序仅使用 CUDA 库的话,用 .cpp 源码文件即可 (不用 .cu)
使用 CUBLAS 库给矩阵运算提速的更多相关文章
- 第四篇:使用 CUBLAS 库给矩阵运算提速
前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...
- [Python学习] python 科学计算库NumPy—矩阵运算
NumPy库的核心是矩阵及其运算. 使用array()函数可以将python的array_like数据转变成数组形式,使用matrix()函数转变成矩阵形式. 基于习惯,在实际使用中较常用array而 ...
- cuda中用cublas库做矩阵乘法
这里矩阵C=A*B,原始文档给的公式是C=alpha*A*B+beta*C,所以这里alpha=1,beta=0. 主要使用cublasSgemm这个函数,这个函数的第二个参数有三种类型,这里CUBL ...
- cublas相关的知识
下面链接给出了一个例子,怎么用cublas进行矩阵的运算提速,也说明了cublas的大致的使用方法. http://www.cnblogs.com/scut-fm/p/3756242.html cub ...
- python中的矩阵运算
摘自:http://m.blog.csdn.net/blog/taxueguilai1992/46581861 python的numpy库提供矩阵运算的功能,因此我们在需要矩阵运算的时候,需要导入nu ...
- 有关CUBLAS中的矩阵乘法函数
关于cuBLAS库中矩阵乘法相关的函数及其输入输出进行详细讨论. ▶ 涨姿势: ● cuBLAS中能用于运算矩阵乘法的函数有4个,分别是 cublasSgemm(单精度实数).cublasDgemm( ...
- python 常见矩阵运算
python 的 numpy 库提供矩阵运算的功能,因此我们在需要矩阵运算的时候,需要导入 numpy 的包. 1.numpy 的导入和使用 from numpy import *;#导入numpy的 ...
- Cublas矩阵加速运算
前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...
- Numba——python面向数组高性能计算库
python在计算性能上相对c是比较弱鸡的,有了numpy后计算性能短板是补了一些,而Numba库又给python计算性能加了发动机(忽然想到西虹市首富王多鱼的名言:我再加200万,给冰山提提速.), ...
随机推荐
- 学习记录014-ssh批量分发
一.ssh服务介绍 1.ssh安全的加密协议用于远程连接服务器 2.默认端口是22,安全协议版本ssh2,它能同时支持RSA和DSA秘钥,SSH1只支持RSA 3.服务端主要包含两个服务功能ssh远程 ...
- Android 浮动搜索框 searchable 使用(转)。
Android为程序的搜索功能提供了统一的搜索接口,search dialog和search widget,这里介绍search dialog使用.search dialog 只能为于activity ...
- [Jquery]网页定位导航特效
描述:左右联动的导航,非常适合展示页面内容多,区块划分又很明显的,点击右边固定导航项时,左边的内容跟着切换.滑动滚动条的时候,右边的导航也随着左边的展示而进行高亮切换. 思路:比较滚动距离和楼层距离( ...
- 2.精通前端系列技术之seajs和gruntJs结合开发(三)
1.我们先来了解下模块化历史 模块化历史 nodeJS的出现(http://nodejs.org/) commonJS规范(http://www.commonjs.org/) 浏览器JS的模块化? A ...
- mongoose
var mongoose = require('mongoose');mongoose.connect('mongodb://localhost/test'); var Cat = mongoose. ...
- 一看就懂的ReactJs入门教程(精华版)
一看就懂的ReactJs入门教程(精华版) 现在最热门的前端框架有AngularJS.React.Bootstrap等.自从接触了ReactJS,ReactJs的虚拟DOM(Virtual DOM)和 ...
- Service相关--读书笔记
2013-12-30 18:16:11 1. Service和Activty都是从Context里面派生出来的,因此都可以直接调用getResource(),getContentResolver()等 ...
- 基于MVC的应用框架之Struts前奏
1.JSP&Servlet中的MVC MVC的关键是,业务逻辑要与表示分离.通过把业务逻辑放在一个“模型”中,这样业务逻辑本身就能作为一个可重用的JAVA类存在. 在JSP&Servl ...
- android 禁止viewPager 滑动
public class ContainerViewPager extends MyViewPager { public ContainerViewPager(Context context, Att ...
- Oracle GoldenGate 12c实时捕获SQL Server数据
在Oracle GoldenGate 12c中,对一些最新的数据库提供了支持,比如SQL Server 2012/2014,当然12c也支持sql server 2008.主要新增特性有: 捕获进程可 ...