使用Python写CUDA程序的方法
使用Python写CUDA程序有两种方式:
*Numba
*PyCUDA
numbapro现在已经不推荐使用了,功能被拆分并分别被集成到accelerate和Numba了。
例子
numba
Numba通过及时编译机制(JIT)优化Python代码,Numba可以针对本机的硬件环境进行优化,同时支持CPU和GPU的优化,并且可以和Numpy集成,使Python代码可以在GPU上运行,只需在函数上方加上相关的指令标记,
如下所示:
importnumpyasnp fromtimeitimportdefault_timerastimer fromnumbaimportvectorize @vectorize(["float32(float32,float32)"],target='cuda') defvectorAdd(a,b): returna+b defmain(): 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("vectorAddtook%fseconds"%vectorAdd_time) if__name__=='__main__': main()
PyCUDA
PyCUDA的内核函数(kernel)其实就是使用C/C++编写的,通过动态编译为GPU微码,Python代码与GPU代码进行交互,如下所示:
importpycuda.autoinit importpycuda.driverasdrv importnumpyasnp fromtimeitimportdefault_timerastimer frompycuda.compilerimportSourceModule mod=SourceModule(""" __global__voidfunc(float*a,float*b,size_tN) { constinti=blockIdx.x*blockDim.x+threadIdx.x; if(i>=N) { return; } floattemp_a=a[i]; floattemp_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") deftest(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) #copyatoaa aa=np.empty_like(a) aa[:]=a #GPUrun nTheads=256 nBlocks=int((N+nTheads-1)/nTheads) start=timer() func( drv.InOut(a),drv.In(b),N, block=(nTheads,1,1),grid=(nBlocks,1)) run_time=timer()-start print("gpuruntime%fseconds"%run_time) #cpurun start=timer() aa=(aa*10+2)*((b+2)*10-5)*5 run_time=timer()-start print("cpuruntime%fseconds"%run_time) #checkresult r=a-aa print(min(r),max(r)) defmain(): forninrange(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本身就是用CUDAC/C++写的。
以上这篇使用Python写CUDA程序的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持毛票票。