python加速方法:GPU加速(numba库)Demo及编写注意事项

上周使用GPU加速了一个算法,效果特别惊艳,由于算法代码本身没有太大参考价值,所以这里只记录了一些心得体会,以便后续遇到问题进行参考排查

numba加速代码编写注意事项

numba加速代码编写一定要注意:
1、开辟空间,里面所有计算操作要返回的值需要开辟空间;
2、ID号,搞清楚要用一维矩阵进行计算还是二维矩阵进行计算,一维矩阵计算需搞清楚最关键的ID号对应的线程号,二维矩阵则要搞清楚两个ID分别对应的实际意义;
3、在进行GPU内部的函数中,numpy的一些操作是不支持的,尽量在外部定义好,或者搞清楚numpy函数的实际意义,然后用最原始的代码写出来,在CPU上测试等价然后放到GPU中进行测试,这样避免运行时候出错,却找不到原因;
4、在GPU运行的函数中返回的结果变量尽量不要使用切片包装传入,如果要用切片包装可以把变量及整体线程ID号带入实际函数内部。先测试直接输出或改写内部变量值再输出,看看能否正确输出,如果不能正确输出,则是否ID搞错了。(我上周写的代码中这里坑住我了)

如果运行出错不要慌,一般会有提示,根据提示想想原因,或者采用注释法排查问题,一句句代码保留出来进行测试运行,总能找到根本原因及解决办法;

GPU加速效果太惊艳了,编写过程也是很恼火,但看到了最终成果,中间编写的恼火过程可以忽略不计。

贴一个Demo程序,方便了解一般编写规则

一维矩阵GPU计算


from numba import cuda
import numpy as np
import math
from time import time# # 定义一个简单的设备函数
# @cuda.jit(device=True)
# def square(x):
#     return x * x# 定义一个简单的设备函数
@cuda.jit(device=True)
def add(a,b):return a+b@cuda.jit
def gpu_add(a, b, result, n):idx = cuda.threadIdx.x + cuda.blockDim.x * cuda.blockIdx.xif idx < n :result[idx] = add(a[idx] , b[idx])# result[idx] = a[idx] + b[idx]def main():n = 20000000x = np.arange(n).astype(np.int32)y = 2 * x# 拷贝数据到设备端x_device = cuda.to_device(x)y_device = cuda.to_device(y)# 在显卡设备上初始化一块用于存放GPU计算结果的空间gpu_result = cuda.device_array(n)cpu_result = np.empty(n)threads_per_block = 1024blocks_per_grid = math.ceil(n / threads_per_block)start = time()gpu_add[blocks_per_grid, threads_per_block](x_device, y_device, gpu_result, n)cuda.synchronize()print("gpu vector add time " + str(time() - start))start = time()cpu_result = np.add(x, y)print("cpu vector add time " + str(time() - start))if (np.array_equal(cpu_result, gpu_result.copy_to_host())):print("result correct!")if __name__ == "__main__":main()

二维矩阵GPU计算


import numpy as np
from numba import cuda# 使用Numba的@cuda.jit装饰器来编写CUDA加速的函数
@cuda.jit
def multiply_array(arr, result):i, j = cuda.grid(2)if i < arr.shape[0] and j < arr.shape[1]:result[i, j] = arr[i, j] * 2  # 将数组中的每个元素乘以2# 生成一个随机的二维数组
arr = np.random.rand(3, 3)# 将数据传入设备中
d_arr = cuda.to_device(arr)# 创建一个与输入数组形状相同的结果数组
result = np.empty_like(arr)# 将结果数组传入设备中
d_result = cuda.to_device(result)# 定义线程块和线程网格的大小
threads_per_block = (16, 16)
blocks_per_grid_x = (arr.shape[0] + threads_per_block[0] - 1) // threads_per_block[0]
blocks_per_grid_y = (arr.shape[1] + threads_per_block[1] - 1) // threads_per_block[1]
blocks_per_grid = (blocks_per_grid_x, blocks_per_grid_y)# 在设备上执行加速计算
multiply_array[blocks_per_grid, threads_per_block](d_arr, d_result)# 将结果拷贝回本地
d_result.copy_to_host(result)print("Original array:")
print(arr)
print("Result array:")
print(result)

记录一个调试错误,如下图
在这里插入图片描述
“AttributeError: ‘list’ object has no attribute ‘squeeze’”
该错误是说list没有’squeeze’方法,仔细检查GPU核函数好像没有调用’squeeze’方法,经过调查发现传入GPU设备的代码是list,将初始化方法list变为numpy即可,猜想GPU计算的时候会自动调numpy的’squeeze’方法

更改前:

linearSuccess =[0]* AllNumber # 初始化CPU变量
d_linearSuccess = cuda.to_device(linearSuccess)#变量传入GPU设备
...

更改后:


linearSuccess = np.zeros([AllNumber])  # 初始化CPU变量
d_linearSuccess = cuda.to_device(linearSuccess)#变量传入GPU设备
...

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

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

相关文章

【Java并发】聊聊不安全的HashMap以及ConcurrentHashMap

在实际的开发中&#xff0c;hashmap是比较常用的数据结构&#xff0c;如果所开发的系统并发量不高&#xff0c;那么没有问题&#xff0c;但是一旦系统的并发量增加一倍&#xff0c;那么就可能出现不可控的系统问题&#xff0c;所以在平时的开发中&#xff0c;我们除了需要考虑正…

Python从入门到精通(黑马课程)

目录 运算符 数字运算符 比较运算符 逻辑运算符 转义字符 变量使用 变量定义 变量类型 变量命名 变量函数 input函数 type函数 条件语句 If 格式 案例1&#xff0c;判断年龄 案例2&#xff0c;借钱 案例3&#xff0c;and、or应用 循环语句 for 格式 案例…

如何使用Cloudreve将个人电脑打造为私有云盘并实现远程访问

文章目录 1、前言2、本地网站搭建2.1 环境使用2.2 支持组件选择2.3 网页安装2.4 测试和使用2.5 问题解决 3、本地网页发布3.1 cpolar云端设置3.2 cpolar本地设置 4、公网访问测试5、结语 1、前言 云存储概念兴起后&#xff0c;现在市面上也已经有了很多公有云盘。但一段时间后…

redis基本数据结构

Redis入门&#xff1a;五大数据类型 文章目录 Redis入门&#xff1a;五大数据类型一.概述二.Redis的基本了解三.Redis五大数据类型1.String (字符串)2.List(列表)3.Set集合(元素唯一不重复)4.Hash集合5.zSet(有序集合) 一.概述 什么是Redis Redis&#xff08;Remote Dictiona…

Java 之 lambda 表达式(一)

目录 一. 前言 二. lambda 表达式语法 2.1. 语法1&#xff1a;无参&#xff0c;无返回值 2.2. 语法2&#xff1a;一个参数&#xff0c;无返回值 2.3. 语法3&#xff1a;两个参数&#xff0c;lambda 体中有多条语句 2.4. 语法4&#xff1a;两个以上参数&#xff0c;有返回…

C++ STL-----容器

STL容器就是将运用最广泛的一些数据结构实现出来 常用的数据结构&#xff1a;数组, 链表,树, 栈, 队列, 集合, 映射表 等 这些容器分为序列式容器和关联式容器两种: 序列式容器:强调值的排序&#xff0c;序列式容器中的每个元素均有固定的位置。 关联式容器:二叉树结构&…

深入了解Java8新特性-日期时间API:LocalDateTime类

阅读建议 嗨&#xff0c;伙计&#xff01;刷到这篇文章咱们就是有缘人&#xff0c;在阅读这篇文章前我有一些建议&#xff1a; 本篇文章大概22000多字&#xff0c;预计阅读时间长需要20分钟以上。本篇文章的实战性、理论性较强&#xff0c;是一篇质量分数较高的技术干货文章&…

c++没有返回值的返回值

上面的函数search没有返回值,因为a不等于1,但是输出的时候会输出6.这恰巧是x的值,如果我们希望a不等于1时返回x,那么这种结果反而是正确的.有时候这种错误的代码可能产生正确的结果反而会加大debug难度 int search(int n) { 00007FF66DB723E0 mov dword ptr [rsp8],e…

简易版扫雷+代码分析

前言&#xff1a; 实验一个简易版的扫雷&#xff0c;也要两百来行的代码&#xff0c;因此为了代码整洁&#xff0c;维护起来方便&#xff0c;这里我们和前期实现的三子棋一样&#xff0c;也弄一个游戏的头文件game.h用来装各种头文件以及函数的声明以及宏定义、预处理信息&…

视频文件+EasyDarwin做摄像机模拟器模拟RTSP流很方便,还能做成系统服务,方法与流程

之前我看到过一家人工智能做算法的企业&#xff0c;用EasyDarwinFFMPEG做了一个摄像机的模拟器&#xff0c;方法大概是&#xff1a; 用ffmpeg读取mp4等类型的视频文件&#xff08;当然ffmpeg啥都能读取&#xff09;&#xff0c;再以RTSP协议的形式推送给EasyDarwin&#xff1b…

为IP地址申请SSL证书

SSL&#xff08;Secure Sockets Layer&#xff09;是一种网络协议&#xff0c;用于在浏览器与服务器之间建立安全、加密的连接。SSL证书是用于证明您的网站身份并启用HTTPS&#xff08;超文本传输安全协议&#xff09;的安全文件。这种协议可以确保用户与您的网站之间的所有通信…

统计学中两组数据如何进行差异性(相关性)分析?

变量说明&#xff1a; 在确定分析方法前&#xff0c;我们需要了解手中的数据类型&#xff0c;这是最基础也是有必要的&#xff0c;在所有的数据类型中&#xff0c;我们将数据类型分为分类变量也为定类变量和连续变量也称为定量变量&#xff0c;那么什么是定类变量&#xff1f;…

C语言--每日选择题--Day25

第一题 1. 对于C/C语言的函数&#xff0c;下列叙述中正确的是&#xff08; &#xff09; A&#xff1a;函数的定义不能嵌套&#xff0c;但函数调用可以嵌套 B&#xff1a;函数的定义可以嵌套&#xff0c;但函数调用不能嵌套 C&#xff1a;函数的定义和调用都不能嵌套 D&#xf…

凝聚数字经济发展新力量,四象科技受邀出席2023全球数商大会

11月25日&#xff0c;2023全球数商大会在上海开幕。本届大会以“数联全球、商通未来”为主题&#xff0c;上海市委副书记、市长龚正出席大会并宣布大会开幕&#xff0c;国家发展改革委党组成员&#xff0c;国家数据局党组书记、局长刘烈宏&#xff0c;上海市副市长陈杰致辞。四…

奇异值分解SVD(Singular Value Decomposition)

一种理解方式&#xff0c;值得学习&#xff08;分解时空矩阵&#xff09; 先在这里阐述一下SVD的用途吧&#xff0c;具体细节稍后再做补充 1.通过SVD对数据的处理&#xff0c;我们可以使用小得多的数据集来表示原始数据集&#xff0c;这样做实际上是去除了噪声和冗余信息&…

SA与NSA网络架构的区别

SA与NSA网络架构的区别 1. 三大运营商网络制式&#xff1a;2. 5G组网方式及业务特性3. NSA-3系列4. NSA—4系列5. NSA-7系列6. 5G SA网络架构7. 运营商策略 1. 三大运营商网络制式&#xff1a; 联通&#xff1a;3G(WCDMA)\4G(FDD-LTE/TD-LTE)\5G(SA/NSA)移动&#xff1a;2G(GS…

【备忘录】快速回忆ElasticSearch的CRUD

导引——第一条ElasticSearch语句 测试分词器 POST /_analyze {"text":"黑马程序员学习java太棒了","analyzer": "ik_smart" }概念 语法规则 HTTP_METHOD /index/_action/IDHTTP_METHOD 是 HTTP 请求的方法&#xff0c;常见的包括…

Rocket mq namesrv源码分析

NameServer 作为注册中心&#xff0c;提供路由注册、路由踢出、路由发现功能&#xff0c;舍弃强一致&#xff0c;保证高可用&#xff0c;集群中各个节点不会实时通讯&#xff0c;其中一个节点下线之后&#xff0c;会提供另外一个节点保证路由功能。 启动入口 org.apache.rock…

【带头学C++】----- 八、C++面向对象编程 ---- 8.5 struct结构体类型增强使用说明

目录 8.5 struct结构体类型增强使用说明 8.5.1 C结构体可以定义成员函数 8.5.2 c中定义结构体变量可以不加struct关键字 8.6 bool布尔类型关键字 8.5 struct结构体类型增强使用说明 第六章对结构体的使用、内存对齐以及数组、深拷贝和浅拷贝进行了一个详细的说明&#xff0c…

【数据结构实验】排序(二)希尔排序算法的详细介绍与性能分析

文章目录 1. 引言2. 希尔排序算法原理2.1 示例说明2.2 时间复杂性分析 3. 实验内容3.1 实验题目&#xff08;一&#xff09;输入要求&#xff08;二&#xff09;输出要求 3.2 算法实现3.3 代码解析3.4 实验结果 4. 实验结论 1. 引言 排序算法在计算机科学中扮演着至关重要的角色…