python与cuda的交互——pycuda

        由于读研期间需要用并行实现图像预处理,然后用深度学习的模型进行进一步处理,所以需要实现python和cuda的交互,就会用到一个很重要的库pycuda。

大部分内容参考  https://zhuanlan.zhihu.com/p/32062796?utm_source=qq&utm_medium=social

共享存储器:每个线程块(block)都有独立的共享内存,block与Block之间不能相互通信,同一个block中的threads可以通过共享内存进行通信。使用pycuda将数据放进共享内存时,格式如 __shared__ float gpu[64];,需要提前计算好共享内存的大小,相当于为该block中的每个thread都创建了一个64维的矩阵,然后计算机就会将该线程所需要的数据提前放进该矩阵中。

在使用PyCuda的时候,原始数据都是以NumPy数组的形式存储在宿主系统(host)中的。大多数常用的NVIDIA显卡只支持单精度浮点数,输入的数组必须是float32型,输入全局存储器中的变量必须是int32型的。

简化内存拷贝

PyCuda提供了pycuda.driver.In, pycuda.driver.Out, 以及pycuda.driver.InOut 这三个参数处理器(argument handlers),能用来简化内存和显存之间的数据拷贝。例如,咱们可以不去创建一个a_gpu,而是直接把a移动过去,下面的代码就可以实现:

func(cuda.InOut(a), block=(4, 4, 1))

有准备地调用函数

使用内置的 pycuda.driver.Function.call() 方法来进行的函数调用,会增加类型识别的资源开销(参考显卡接口)。 要实现跟上面代码同样的效果,又不造成这种开销,这个函数就需要设定好参数类型(如Python的标准库中的结构体模块struct所示),然后再去调用该函数。这样也就不用需要再使用numpy.number类去制定参数的规模了:

grid = (1, 1)
block = (4, 4, 1)
func.prepare("P")
func.prepared_call(grid, block, a_gpu)

抽象以降低复杂度

使用 pycuda.gpuarray.GPUArray,同样效果的代码实现起来就更加精简了:

import pycuda.gpuarray as gpuarray
import pycuda.driver as cuda
import pycuda.autoinit
import numpy

a_gpu = gpuarray.to_gpu(numpy.random.randn(4,4).astype(numpy.float32))
a_doubled = (2*a_gpu).get()
print a_doubled
print a_gpu

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值