使用python写cuda程序的方法详细介绍

下面小编就为大家带来一篇使用python写cuda程序的方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧

使用python写cuda程序有两种方式:

* numba * pycuda

numbapro现在已经不推荐使用了,功能被拆分并分别被集成到accelerate和numba了。

例子

numba

numba通过及时编译机制(jit)优化python代码,numba可以针对本机的硬件环境进行优化,同时支持cpu和gpu的优化,并且可以和numpy集成,使python代码可以在gpu上运行,只需在函数上方加上相关的指令标记,

如下所示:

import numpy as np
from timeit import default_timer as timer
from numba import vectorize
@vectorize([“float32(float32, float32)”], target=’cuda’)
def vectoradd(a, b):
return a + b
def main():
n = 320000000
a = np.ones(n, dtype=np.float32 )
b = np.ones(n, dtype=np.float32 )
c = np.zeros(n, dtype=np.float32 )
start = timer()
c = vectoradd(a, b)
vectoradd_time = timer() – start
print(“c[:5] = ” + str(c[:5]))
print(“c[-5:] = ” + str(c[-5:]))
print(“vectoradd took %f seconds ” % vectoradd_time)
if name == ‘main’:
main()

pycuda

pycuda的内核函数(kernel)其实就是使用c/c++编写的,通过动态编译为gpu微码,python代码与gpu代码进行交互,如下所示:

import pycuda.autoinit
import pycuda.driver as drv
import numpy as np
from timeit import default_timer as timer
from pycuda.compiler import sourcemodule
mod = sourcemodule(“””
global void func(float *a, float *b, size_t n)
{
const int i = blockidx.x * blockdim.x + threadidx.x;
if (i >= n)
{
return;
}
float temp_a = a[i];
float temp_b = b[i];
a[i] = (temp_a * 10 + 2 ) * ((temp_b + 2) * 10 – 5 ) * 5;
// a[i] = a[i] + b[i];
}
“””)
func = mod.get_function(“func”)
def test(n):
# n = 1024 * 1024 * 90 # float: 4m = 1024 * 1024
print(“n = %d” % n)
n = np.int32(n)
a = np.random.randn(n).astype(np.float32)
b = np.random.randn(n).astype(np.float32)
# copy a to aa
aa = np.empty_like(a)
aa[:] = a
# gpu run
ntheads = 256
nblocks = int( ( n + ntheads – 1 ) / ntheads )
start = timer()
func(
drv.inout(a), drv.in(b), n,
block=( ntheads, 1, 1 ), grgpu run time %f seconds ” % run_time)
# cpu run
start = timer()
aa = (aa * 10 + 2 ) * ((b + 2) * 10 – 5 ) * 5
run_time = timer() – start
print(“cpu run time %f seconds ” % run_time)
# check result
r = a – aa
print( min(r), max(r) )
def main():
for n in range(1, 10):
n = 1024 * 1024 * (n * 10)
print(“————%d—————” % n)
test(n)
if name == ‘main’:
main()

对比

numba使用一些指令标记某些函数进行加速(也可以使用python编写内核函数),这一点类似于openacc,而pycuda需要自己写kernel,在运行时进行编译,底层是基于c/c++实现的。通过测试,这两种方式的加速比基本差不多。但是,numba更像是一个黑盒,不知道内部到底做了什么,而pycuda就显得很直观。因此,这两种方式具有不同的应用:

* 如果只是为了加速自己的算法而不关心cuda编程,那么直接使用numba会更好。

* 如果为了学习、研究cuda编程或者实验某一个算法在cuda下的可行性,那么使用pycuda。

* 如果写的程序将来要移植到c/c++,那么就一定要使用pycuda了,因为使用pycuda写的kernel本身就是用cuda c/c++写的。

以上就是使用python写cuda程序的方法详细介绍的详细内容,更多请关注 第一php社区 其它相关文章!

Posted in 未分类