>백엔드 개발 >파이썬 튜토리얼 >Python을 사용하여 CUDA 프로그램을 작성하는 방법에 대한 자세한 소개

Python을 사용하여 CUDA 프로그램을 작성하는 방법에 대한 자세한 소개

高洛峰
高洛峰원래의
2017-03-28 09:29:194314검색

다음 편집자는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.