5

に変換すると、転置行列が異なって見えるのはなぜpycuda.gpuarrayですか?

これを再現できますか?何が原因でしょうか? 間違ったアプローチを使用していますか?

サンプルコード

from pycuda import gpuarray
import pycuda.autoinit
import numpy

data = numpy.random.randn(2,4).astype(numpy.float32)
data_gpu = gpuarray.to_gpu(data.T)
print "data\n",data
print "data_gpu.get()\n",data_gpu.get()
print "data.T\n",data.T

出力

data
[[ 0.70442784  0.08845157 -0.84840715 -1.81618035]
 [ 0.55292499  0.54911566  0.54672164  0.05098847]]
data_gpu.get()
[[ 0.70442784  0.08845157]
 [-0.84840715 -1.81618035]
 [ 0.55292499  0.54911566]
 [ 0.54672164  0.05098847]]
data.T
[[ 0.70442784  0.55292499]
 [ 0.08845157  0.54911566]
 [-0.84840715  0.54672164]
 [-1.81618035  0.05098847]]
4

2 に答える 2

6

基本的な理由は、numpyトランスポーズはビューのみを作成し、基になる配列ストレージには影響を与えないことと、デバイスメモリへのコピーが実行されるときにPyCUDAが直接アクセスするストレージであるためです。解決策は、転置を行うときにこのメソッドを使用することですcopy。これにより、ホストメモリに転置された順序でデータを含む配列が作成され、それがデバイスにコピーされます。

data_gpu = gpuarray.to_gpu(data.T.copy())
于 2011-08-01T16:14:46.490 に答える
6

numpy ではdata.T、基になる 1D 配列には何もしません。単純にストライドを操作して転置を取得します。これにより、定数時間および定数メモリ操作になります。

pycuda.to_gpu()ストライドを尊重しておらず、基になる 1D 配列を単にコピーしているように見えます。これにより、観察している正確な動作が生成されます。

私の見解では、あなたのコードに問題はありません。むしろ、これは のバグだと思いpycudaます。

私はぐるぐる回って、この問題について詳しく説明しているスレッドを見つけました。

numpy.ascontiguousarray(data.T)回避策として、 に渡してみることができますgpuarray.to_gpu()。もちろん、これにより、ホスト RAM にデータの 2 つ目のコピーが作成されます。

于 2011-08-01T16:10:08.110 に答える