如何用cublas计算逆矩阵?

2023-11-15

cublas的文档中提供了一个用LU分解求逆矩阵的方法,需要用到两个函数:

cublas<t>getrfBatched()

cublas<t>getriBatched()

第一个函数用于做LU分解,第二个函数把LU分解的结果变为逆矩阵。

但官方文档对这两个函数的用法语焉不详,我花了几个小时才把这个问题搞定。主要遇到两个问题:

函数有一个参数是 const float *[] 类型,直接把 float **指针传进去的话编译通不过,以前没接触过这个类型的指针,费了不少功夫,上网查了些资料才搞定。

编译通过后,又遇到第二个问题:运行两个函数都会提示:

unspecified launch failure

这是显存变量越界造成的。但仔细检查代码,也没找到问题。后来翻墙到http://stackoverflow.com/看看有没有人遇到过类似问题,不得不说国外的社区就是强大,果然有人遇到过类似问题,别且找到了症结所在。

原来,CUDA 的指针的指针(例如 float **)就像普通数据一样,也分为 host和 device, host上的,例如:

float ** hostPrt = (float **)malloc(sizeof(float *));//这是host上的定义方法
float ** devicePrt ;
cudaMalloc((void **) & devicePrt, sizeof(float *));//这是device上的定义方法。

而这两个函数参数中,接受的float * [] 参数都是 device指针, 传入host指针就出出错。

解决了这个问题后,用cublas求逆矩阵就顺利通过了。
但最后又遇到一个问题:
我测试了用cublas计算逆矩阵的时间,和CPU上用EIGEN计算用的时间,(我的显卡是GTX980ti 算是不错的显卡了),计算矩阵大小是1000 x 1000。结果cublas用的时间是CPU的5倍!!!看来用cublas计算逆矩阵,毫无速度优势。我又想是不是矩阵不够大?就改为2000 x 2000的矩阵试试看,结果是显卡直接罢工了(cublas的文档上就说求逆的矩阵不宜过大),而EIGEN也只是用了0.6秒左右的时间。究其原因,应该是求逆矩阵并不是一个可以通过并行方法解决的问题(求特征矩阵也是如此)。
那么为何cublas为何还要提供一个求逆矩阵的函数呢?
因为cublas提供的这两个函数,并非计算单个逆矩阵,而是可以计算逆矩阵组,比如你有几十个相同大小的矩阵需要求逆,就可以发挥并行运算的威力,可能计算几十个的时间比计算一个的时间多不了太多,这样GPU的优势就显示出来了。毕竟在实际应用中,求一系列矩阵的逆矩阵的情况还是常见的,比如做岭回归分析的时候。
最后,我就把用这两个函数计算逆矩阵组的代码贴出来,供大家参考:
	cublasHandle_t handle;
	cublasCreate(&cublasHandle);
	int  size = 50; //矩阵的行和列
	int num = 100;//矩阵组的矩阵个数
	int * info ;//用于记录LU分解是否成功
	int * pivo;//用于记录LU分解的信息
	cudaMalloc((void **) & info, sizeof(int)  * num);
	cudaMalloc((void **) & pivo, sizeof(int) * size * num);
	float ** mat = new float *[num];//待求逆的矩阵组
	float ** invMat = new float *[num];//存放逆矩阵的矩阵组
	for(int i = 0; i< num; i++){
		cudaMalloc((void **) & mat[i], sizeof(float)  * size * size);
		cudaMalloc((void **) & invMat[i], sizeof(float)  * size * size);
		/*
		这里将矩阵的数据载入mat[i]中,这里假设矩阵的数据在内存中是连续存放的
		*/
	}
	float  ** gpuMat;
	cudaMalloc((void **) & gpuMat, sizeof(float *)  * num);
	cudaMemcpy(gpuMat, mat, sizeof(float *) * num,  cudaMemcpyHostToDevice);
	//以上三步的目的是把host上的float ** 指针转变为 device上的 float ** 指针

	cublasSgetrfBatched(handle, size,  gpuMat, size ,  pivo, info, num);//第四个参数是矩阵的主导维,由于这里假设数据在内存中的存放是连续的,所以是size

	const float ** constMat;
	cudaMalloc((void **) & constMat,  sizeof(float *)  * num);
	cudaMemcpy(constMat,  gpuMat, sizeof(float *) * num,  cudaMemcpyDeviceToDevice);
	//以上三步的目的是把 float ** 指针转变为 float *[]指针

	float  ** gpuInvMat;
	cudaMalloc((void **) & gpuInvMat, sizeof(float *)  * num);
	cudaMemcpy(gpuInvMat, invMat, sizeof(float *) * num,  cudaMemcpyHostToDevice);
	
	//以上三步的目的是把host上的float ** 指针转变为 device上的 float ** 指针

	cublasSgetriBatched(handle, size, constMat, size,  pivo, gpuInvMat, size, info, num);	

	cudaFree(info);
	cudaFree(pivo);
	cudaFree(mat);
	cudaFree(gpuMat);
	cudaFree(gpuInvMat);
	cudaFree(constMat);



本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何用cublas计算逆矩阵? 的相关文章

  • CentOS 8 最新阿里YUM源

    前文 由于CentOS8 已停止服务 相关源已经停止 前期官方自带的源和前期 阿里 清华 网易 等等的源 都已无法再使用 需要更换源 安装程序时报错 Failed to synchronize cache for repo AppStrea
  • 【Spring源码系列】Bean生命周期-Bean销毁

    文章目录 前言 一 Bean销毁介绍 bean销毁的时机 spring注册DestroyBean时机 定义bean销毁方式以及源码调试 使用 PreDestroy注解 实现DisposableBean或者AutoCloseable接口 手动
  • 使用Redisson实现Java分布式锁

    在分布式系统中 实现并发控制是一个重要的问题 分布式锁是一种常见的解决方案 它可以确保在分布式环境下只有一个进程能够访问共享资源 Redis是一种流行的内存数据存储系统 它提供了分布式锁的功能 在Java中 可以使用Redisson库来集成
  • SpringBoot(三):集成Mybatis

    1 Mybatis逆向工程 逆向工程即为通过数据库逆向生成model类和mapper文件以及接口文件 步骤如下 1 1在pom文件中加入mybatis相关依赖
  • Android系列开发博客资源汇总

    CSDN博客本期热文推荐 为您介绍有关Android应用开发的10个博客 分享他们的日积月累的宝贵经验 希望这些文章对Android开发者们能有所启发和帮助 1 张国威 Android从入门到提高系列 前面写了十四篇关于界面的入门文章 大家
  • Ansible自动化运维工具之playbook剧本编写

    内容预知 目录 内容预知 1 playbook的相关知识 1 1 playbook 的简介 1 2 playbook的 各部分组成 2 基础的playbook剧本编写实例 实例1 playbook编写 apache的yum安装部署剧本 实例
  • 数据治理体系解决方案(附PPT下载)

    下载方式 迎加入星球下载所有资料 转发朋友圈截图回复666亦可下载 加入星球好资料一直有 推荐阅读 世界的真实格局分析 地球人类社会底层运行原理 不是你需要中台 而是一名合格的架构师 附各大厂中台建设PPT 亿级 无限级 并发 没那么难 论
  • java基于微信小程序的四六级英语学习测试系统 uinapp 计算机毕业设计

    通过本课题的研究与分析 能够建立一种基于微信小程序的四六级助手系统 以MySQL为数据库 后端采用Java语言SSM框架 并对系统中的各个模块功能及它们之间相互协调工作进行了详细的分析与设计 尤其是对实现方法和过程进行了细致的设计与实现 最
  • Python动态的拼接变量名

    1 可以通过python的内置函数locals 来完成 locals是python的内置函数 他可以以字典的方式去访问局部和全局变量 python里面用名字空间记录着变量 就像javascript的window一样 他记录着各种全局变量 每
  • R语言数据可视化之初级绘图(上)

    1 条形图barplot 条形图通过垂直的或者水平的条形展示了类别型变量的频数分布 barplot 可实现条形图的绘制 其调用格式为 barplot x xlab yalb horiz F barplot x xlab ylab besid
  • 3.when表达式

    val week 0 Java的 if 语句 KT的 if 是表达式 有返回值的 val info when week 1 gt 今天是星期一 非常忙碌的一天开会 2 gt 今天是星期二 非常辛苦的写需求 3 gt 今天是星期三 努力写Bu
  • GirdLayout布局实现九宫格

    利用GirdLayout布局显示3 3布局的9张图片 每张图片宽度为屏幕的1 3
  • oracle 列相同编号,Oracle查询结果中:一列中相同的值或一列中重复的值,只显示一次...

    http www itpub net thread 1768915 1 1 html 问题 CREATE TABLE test ob id VARCHAR 32 ob name VARCHAR 32 INSERT INTO test VAL
  • Ioc容器refresh总结(2)--- Spring源码从入门到精通(三十二)

    上篇文章介绍了refresh里beanFactory的创建预准备工作 refresh获取到的beanFactory是先刷新创建 在getBeanFactory获取到的 之后再给他配置忽略自动装配的依赖接口 和配置自动装配的组件 Ioc容器r
  • IAR修改字体大小,source insight中文乱码

  • Gradle学习笔记 使用插件

    前面说了不少内容 但是我看了一下Gradle官方文档内容太多太详细 其中大部分内容其实我们不需要知道 一般情况下我们应用一部分插件就可以了 自己编写Gradle任务的情况并不多见 Java插件 在build gradle文件中添加以下一句
  • 搭建GitHub授权登录

    功能 搭建 功能 实现GitHub授权 获取用户在GitHub的有关信息 搭建 注册app 在GitHub的setting gt Developer Settings 开发者设置 中 点击New OAuth App 新建OAuth应用 根据
  • WebService 四种发布方式总结

    1 CXF方式 CXF与spring搭建webservice是目前最流行的方式 但是传闻cxf与jdk1 5有些不兼容 我没有遇到过 我遇到的问题是cxf与was6 1 1不兼容 表现在cxf必须的jar包 wsdl4j 1 6 2 jar
  • C++11 constexpr简单用法

    关键字 constexpr 是C 11中引入的关键字 声明为constexpr类型的变量 编译器会验证该变量的值是否是一个常量表达式 声明为constexpr的变量一定是一个常量 而且必须用常量表达式初始化 constexpr int mf
  • 如何使用GPT-4:一步步指南

    人工智能技术的发展 让自然语言处理成为了一个备受关注的领域 其中 GPT 4是当今最先进的自然语言处理模型之一 本文将详细介绍如何使用GPT 4进行自然语言生成 第一步 了解GPT 4 GPT 4是由OpenAI开发的自然语言处理模型 它采

随机推荐