다음 편집자는 Python을 사용하여 CUDA 프로그램을 작성하는 방법에 대한 기사를 가져올 것입니다. 편집자님이 꽤 좋다고 생각하셔서 지금 공유하고 모두에게 참고용으로 드리고자 합니다. 편집기를 따라가서 살펴보겠습니다.
Python을 사용하여 CUDA 프로그램을 작성하는 방법에는 두 가지가 있습니다:
* Numba
* PyCUDA
Numbapro는 이제 더 이상 사용되지 않으며 기능은 각각 Accelerator와 Numba로 분할 및 통합되었습니다.
예
numba
Numba는 just-in-을 사용합니다. Python 코드를 최적화하기 위한 시간 컴파일 메커니즘(JIT), Numba는 로컬 하드웨어 환경에 맞게 최적화될 수 있고 CPU 및 GPU 최적화를 모두 지원하며 Numpy와 통합되어 Python 코드가 에서 GPU에서 실행될 수 있습니다. function 위의 관련 명령 태그
를 다음과 같이 추가합니다.
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의 커널 함수(커널)는 실제로 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 ), grid=( nBlocks, 1 ) ) run_time = timer() - start print("gpu 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는 자체 커널을 작성하고 런타임에 컴파일해야 하며 맨 아래 레이어는 C/C++를 기반으로 구현됩니다. 테스트를 통해 이 두 가지 방법의 가속 비율은 기본적으로 동일합니다. 그러나 numba는 블랙박스에 가깝고 내부적으로 무슨 일이 일어나는지 알 수 없는 반면 PyCUDA는 매우 직관적인 것 같습니다. 따라서 이 두 가지 방법은 서로 다른 용도로 사용됩니다.
* 자신의 알고리즘 속도만 높이고 CUDA 프로그래밍에 관심이 없다면 numba를 직접 사용하는 것이 더 좋습니다.
* CUDA 프로그래밍을 배우고 연구하고 싶거나 CUDA에서 특정 알고리즘의 타당성을 실험하고 싶다면 PyCUDA를 사용하세요.
* 여러분이 작성한 프로그램이 향후에 C/C++로 포팅된다면 반드시 PyCUDA를 사용해야 합니다. 왜냐하면 PyCUDA를 사용하여 작성된 커널 자체가 CUDA C/C++로 작성되었기 때문입니다.
위 내용은 Python을 사용하여 CUDA 프로그램을 작성하는 방법에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!