2012-11-15 3 views
8

의 차이는Pyopencl : to_device 및 버퍼

import pyopencl as cl 
import pyopencl.array as cl_array 
import numpy 
a = numpy.random.rand(50000).astype(numpy.float32) 
mf = cl.mem_flags 

a_gpu = cl.Buffer(self.ctx, mf.READ_ONLY | mf.COPY_HOST_PTR, hostbuf=a) 

a_gpu = cl_array.to_device(self.ctx, self.queue, a) 

의 차이점은 무엇입니까하자?

그리고

result = numpy.empty_like(a) 
cl.enqueue_copy(self.queue, result, result_gpu) 

result = result_gpu.get() 

의 차이점은 무엇입니까?

답변

16

버퍼는 CL의 버전이 malloc이고 pyopencl.array.Array은 연산 장치에서 numpy 배열의 작업 영역입니다.

질문의 첫 번째 부분의 두 번째 버전에서는 a_gpu + 2을 작성하여 배열의 각 번호에 2가 추가 된 새 배열을 얻을 수 있습니다. Buffer의 경우 PyOpenCL은 가방 만 볼 수 있습니다. 바이트 수를 초과하여 이러한 작업을 수행 할 수 없습니다.

질문의 두 번째 부분은 반대입니다. PyOpenCL 배열이있는 경우 .get()은 데이터를 다시 복사하여 (호스트 기반) numpy 배열로 변환합니다. numpy 배열은 파이썬에서 인접한 메모리를 얻는 더 편리한 방법 중 하나이기 때문에 enqueue_copy의 두 번째 변형은 numpy 배열로 끝납니다. 그러나이 데이터를 어떤 크기의 배열에도 복사 할 수 있습니다 크기가 클수록) 그리고 모든 유형 - 복사는 바이트의 모음으로 수행되는 반면, .get()은 호스트에서 동일한 크기와 유형을 갖도록합니다.

보너스 사실 : 물론 각 PyOpenCL 배열의 기본 버퍼가 있습니다. .data 속성에서 가져올 수 있습니다.

+4

저는 방금 PyOpenCL의 저자임을 깨달았습니다. PyOpenCL과 답변에 감사드립니다. – petRUShka

3

첫 번째 질문에 대답하려면 (reference)을 구현하는 것으로 Buffer(hostbuf=...)을 호출 할 수 있습니다. pyopencl.array.to_device(...)ndarray (reference)과 함께 호출해야합니다. ndarray은 버퍼 인터페이스를 구현하며 두 위치에서 작동합니다. 그러나 hostbuf=...만이 예를 들어 bytearray (버퍼 인터페이스도 구현)과 함께 작동 할 것으로 예상됩니다. 나는 이것을 확인하지는 않았지만, 문서가 제안하는 것처럼 보인다. 두 번째 질문에

, 당신이, 어떤 경우 Buffer, Imagehost의 조합 사이 enqueue_copy() 작품을 그 위에 get()을 (당신이 Buffer.get_host_array()을 찾으시는 것입니까?) 호출 할 때 있어야하는데 어떤 종류의 result_gpu 확실하지 않다, 수 ( is_blocking=False과 함께) 비동기적일 수 있으며, 이러한 기능은 그 방법으로 만 사용할 수 있다고 생각합니다 ( get()은 전체 버퍼를 차단하고 반환합니다). ( reference)