一文详解如何用GPU来运行Python代码
作者:南瓜慢说 发布时间:2022-02-26 17:49:30
简介
前几天捣鼓了一下Ubuntu,正是想用一下我旧电脑上的N卡,可以用GPU来跑代码,体验一下多核的快乐。
还好我这破电脑也是支持Cuda的:
$ sudo lshw -C display
*-display
description: 3D controller
product: GK208M [GeForce GT 740M]
vendor: NVIDIA Corporation
physical id: 0
bus info: pci@0000:01:00.0
version: a1
width: 64 bits
clock: 33MHz
capabilities: pm msi pciexpress bus_master cap_list rom
configuration: driver=nouveau latency=0
resources: irq:35 memory:f0000000-f0ffffff memory:c0000000-cfffffff memory:d0000000-d1ffffff ioport:6000(size=128)
安装相关工具
首先安装一下Cuda的开发工具,命令如下:
$ sudo apt install nvidia-cuda-toolkit
查看一下相关信息:
$ nvcc --version
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2021 NVIDIA Corporation
Built on Thu_Nov_18_09:45:30_PST_2021
Cuda compilation tools, release 11.5, V11.5.119
Build cuda_11.5.r11.5/compiler.30672275_0
通过Conda安装相关的依赖包:
conda install numba & conda install cudatoolkit
通过pip安装也可以,一样的。
测试与驱动安装
简单测试了一下,发觉报错了:
$ /home/larry/anaconda3/bin/python /home/larry/code/pkslow-samples/python/src/main/python/cuda/test1.py
Traceback (most recent call last):
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/driver.py", line 246, in ensure_initialized
self.cuInit(0)
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/driver.py", line 319, in safe_cuda_api_call
self._check_ctypes_error(fname, retcode)
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/driver.py", line 387, in _check_ctypes_error
raise CudaAPIError(retcode, msg)
numba.cuda.cudadrv.driver.CudaAPIError: [100] Call to cuInit results in CUDA_ERROR_NO_DEVICE
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/larry/code/pkslow-samples/python/src/main/python/cuda/test1.py", line 15, in <module>
gpu_print[1, 2]()
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/compiler.py", line 862, in __getitem__
return self.configure(*args)
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/compiler.py", line 857, in configure
return _KernelConfiguration(self, griddim, blockdim, stream, sharedmem)
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/compiler.py", line 718, in __init__
ctx = get_context()
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/devices.py", line 220, in get_context
return _runtime.get_or_create_context(devnum)
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/devices.py", line 138, in get_or_create_context
return self._get_or_create_context_uncached(devnum)
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/devices.py", line 153, in _get_or_create_context_uncached
with driver.get_active_context() as ac:
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/driver.py", line 487, in __enter__
driver.cuCtxGetCurrent(byref(hctx))
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/driver.py", line 284, in __getattr__
self.ensure_initialized()
File "/home/larry/anaconda3/lib/python3.9/site-packages/numba/cuda/cudadrv/driver.py", line 250, in ensure_initialized
raise CudaSupportError(f"Error at driver init: {description}")
numba.cuda.cudadrv.error.CudaSupportError: Error at driver init: Call to cuInit results in CUDA_ERROR_NO_DEVICE (100)
网上搜了一下,发现是驱动问题。通过Ubuntu自带的工具安装显卡驱动:
还是失败:
$ nvidia-smi
NVIDIA-SMI has failed because it couldn't communicate with the NVIDIA driver. Make sure that the latest NVIDIA driver is installed and running.
最后,通过命令行安装驱动,成功解决这个问题:
$ sudo apt install nvidia-driver-470
检查后发现正常了:
$ nvidia-smi
Wed Dec 7 22:13:49 2022
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 470.161.03 Driver Version: 470.161.03 CUDA Version: 11.4 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
| | | MIG M. |
|===============================+======================+======================|
| 0 NVIDIA GeForce ... Off | 00000000:01:00.0 N/A | N/A |
| N/A 51C P8 N/A / N/A | 4MiB / 2004MiB | N/A Default |
| | | N/A |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: |
| GPU GI CI PID Type Process name GPU Memory |
| ID ID Usage |
|=============================================================================|
| No running processes found |
+-----------------------------------------------------------------------------+
测试代码也可以跑了。
测试Python代码
打印ID
准备以下代码:
from numba import cuda
import os
def cpu_print():
print('cpu print')
@cuda.jit
def gpu_print():
dataIndex = cuda.threadIdx.x + cuda.blockIdx.x * cuda.blockDim.x
print('gpu print ', cuda.threadIdx.x, cuda.blockIdx.x, cuda.blockDim.x, dataIndex)
if __name__ == '__main__':
gpu_print[4, 4]()
cuda.synchronize()
cpu_print()
这个代码主要有两个函数,一个是用CPU执行,一个是用GPU执行,执行打印操作。关键在于@cuda.jit
这个注解,让代码在GPU上执行。运行结果如下:
$ /home/larry/anaconda3/bin/python /home/larry/code/pkslow-samples/python/src/main/python/cuda/print_test.py
gpu print 0 3 4 12
gpu print 1 3 4 13
gpu print 2 3 4 14
gpu print 3 3 4 15
gpu print 0 2 4 8
gpu print 1 2 4 9
gpu print 2 2 4 10
gpu print 3 2 4 11
gpu print 0 1 4 4
gpu print 1 1 4 5
gpu print 2 1 4 6
gpu print 3 1 4 7
gpu print 0 0 4 0
gpu print 1 0 4 1
gpu print 2 0 4 2
gpu print 3 0 4 3
cpu print
可以看到GPU总共打印了16次,使用了不同的Thread来执行。这次每次打印的结果都可能不同,因为提交GPU是异步执行的,无法确保哪个单元先执行。同时也需要调用同步函数cuda.synchronize()
,确保GPU执行完再继续往下跑。
查看时间
我们通过这个函数来看GPU并行的力量:
from numba import jit, cuda
import numpy as np
# to measure exec time
from timeit import default_timer as timer
# normal function to run on cpu
def func(a):
for i in range(10000000):
a[i] += 1
# function optimized to run on gpu
@jit(target_backend='cuda')
def func2(a):
for i in range(10000000):
a[i] += 1
if __name__ == "__main__":
n = 10000000
a = np.ones(n, dtype=np.float64)
start = timer()
func(a)
print("without GPU:", timer() - start)
start = timer()
func2(a)
print("with GPU:", timer() - start)
结果如下:
$ /home/larry/anaconda3/bin/python /home/larry/code/pkslow-samples/python/src/main/python/cuda/time_test.py
without GPU: 3.7136273959999926
with GPU: 0.4040513340000871
可以看到使用CPU需要3.7秒,而GPU则只要0.4秒,还是能快不少的。当然这里不是说GPU一定比CPU快,具体要看任务的类型。
来源:https://www.cnblogs.com/larrydpk/p/17093627.html


猜你喜欢
- 很多年以前,面对上古时代遗留的 HTML 发出的腐臭,我捂住鼻子唉声叹气。刚练熟 web 标准的我,恨不得寝其尸食其肉,把一切推翻重来。但经
- 本文实例讲述了Python实现随机创建电话号码的方法。分享给大家供大家参考,具体如下:当需要随机的生成一些电话号码的时候,可以使用以下脚本,
- 目录一、 文件的操作1.1创建文件1.2写入数据1.3读数据1.4 2读数据1.5读写数据1.6删除文件1.7写入文件1.8读取图片1.9备
- 今天主要来实现一个权限管理系统,它主要是为了给不同的用户设定不同的权限,从而实现不同权限的用户登录之后使用的功能不一样,首先先看下数据库总共
- 如下所示:# coding = utf-8import requestsimport jsonhost = "http://47.
- 在oracle中有很多关于日期的函数,如:1、add_months()用于从一个日期值增加或减少一些月份date_value:=add_mo
- 本文实例为大家分享了python实现微信自动回复的具体代码,供大家参考,具体内容如下新年到了,不想让一早上给你发送祝福的人心里一阵寒风,可以
- 上周接到个需求,需求是这样的:用户扫一扫二维码会产生一个链接,该链接会向后端发送个请求,返回一个 apk 的下载地址,用户点击下载按钮可以下
- 本文实例为大家分享了python mysql个人论文管理系统的具体代码,供大家参考,具体内容如下1.mysql数据库建表在mysql数据库里
- 小朋友你可能有很多问号~,上一小节不是已经一顿操作猛如虎搭建好 Python + PyCharm 可用开发环境了吗?为什么这节又来个项目运行
- asp之家注:学习asp网页编程的朋友一定用过ACCESS数据库,access的简单方便,大大降低了asp初学者学习asp的门槛,对于学习a
- 目录1、Unittest为Python内嵌的测试框架,不需要特殊配置2、编写规范总结1、Unittest为Python内嵌的测试框架,不需要
- 下面是一个简单的Family Tree 示例: DECLARE @TT TABLE (ID int,Relation varchar(25)
- 1. 介绍 SQLite 是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。 其特点是高度便携、使用方便、结构紧
- 昨天在做一道CTF题的时候碰到了一个图片异或的问题,操作大概如下:将一个图片读入,然后每字节进行异或操作,核心代码可简化为以下:#codin
- 前言写过前端Javascript代码的同学肯定不会对console对象感到陌生,在调试的过程中我们经常会用console对象在控制台输出一些
- identity-card验证身份证号码的正确性,不能仅仅通过正则表达式来验证,我们都知道我国的身份证一共是18位,由十七位数字本体码和一位
- 最近网上再度兴起了CSS布局和Table 布局的争论。我最初颇有些不以为然:我原以为CSS 布局的意义早已深入人心,却没想到还有这么多设计师
- MySQL安装与配置1、所用MySQL的版本为:MySQL_5_1_26.msi;2、下载好软件后双击进入以下界面: 3、点击Ne
- 本文实例讲述了微信小程序学习笔记之表单提交与PHP后台数据交互处理。分享给大家供大家参考,具体如下:前面一篇结介绍了微信小程序函数定义、页面