2012-11-15 18 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配列の類似したものです。

質問の最初の部分の2番目のバージョンでは、a_gpu + 2と書いて、配列内の各番号に2を加えた新しい配列を得ることができます。Bufferの場合、PyOpenCLはバッグこのような操作は実行できません。

質問の2番目の部分は逆です。PyOpenCL配列がある場合、.get()はデータを元に戻し、それを(ホストベースの)numpy配列に変換します。 numpy配列はPythonで連続したメモリを取得する便利な方法の1つで、enqueue_copyの2番目の変種もnumpy配列になりますが、このデータを任意のサイズの配列にどんなタイプでも、コピーはバイトの袋として実行されますが、.get()はホスト上で同じサイズとタイプを取得します。

ボーナスの事実:もちろん、各PyOpenCL配列の基礎となるバッファがあります。 .data属性から取得できます。

+4

私はあなたがPyOpenCLの著者であることに気付きました。 PyOpenCLとあなたの答えに感謝します! – petRUShka

3

最初の質問に答えるには、(reference)を実装するものでBuffer(hostbuf=...)を呼び出すことができます。 pyopencl.array.to_device(...)ndarrayreference)で呼び出す必要があります。 ndarrayはバッファインターフェイスを実装し、どちらの場所でも動作します。しかしながら、hostbuf=...だけが、例えばbytearray(これもバッファインタフェースを実装する)で動作することが期待される。私はこれを確認していないが、ドキュメントが示唆しているものと思われる。

2番目の質問では、私はわからないどのようなタイプresult_gpuは、あなたがそれにget()を呼び出すときことになっている(あなたがBuffer.get_host_array()を意味するのですか?)どのような場合には、BufferImagehostの組み合わせの間enqueue_copy()作品、持つことができます(is_blocking=Falseで)非同期である可能性がありますが、これらの機能はそのようにしか使えないと考えています(get()はバッファ全体をブロックして返します)。 (reference