2012-04-24 7 views
0

私のPCには、OpenCLをサポートしていないATI 3200 GPUを搭載したAMDプロセッサが搭載されています。残りのコードはすべて「CPU自体に落ちる」ことによって実行されます。このcuda "cudaMallocPitch"コードに相当するopenCLは何ですか?

コードの1つをCUDAからOpenCLに変換していますが、OpenCLに正確な変換コードがない特定の部分にはまっています。あなたのうちのどれかがうまくいくと思うなら、私はOpenCLの中にあまり経験を持っているので、私はこれを作ることができない、私にいくつかのソリューションを提案してください

CUDAコードは、

size_t pitch = 0; 
cudaError error = cudaMallocPitch((void**)&gpu_data, (size_t*)&pitch, 
          instances->cols * sizeof(float), instances->rows); 

for(int i = 0; i < instances->rows; i++){ 
    error = cudaMemcpy((void*)(gpu_data + (pitch/sizeof(float))*i), 
         (void*)(instances->data + (instances->cols*i)), 
         instances->cols * sizeof(float) ,cudaMemcpyHostToDevice); 

私はピッチ値を削除した場合上記から私はデバイスメモリ "gpu_data"に書き込まない問題に終わる。

誰かがこのコードをOpenCLに変換して返信してください。私はOpenCLに変換しましたが、動作していないので、データは "gpu_data"に書き込まれません。マイ変換されたOpenCLのコードは

gpu_data = clCreateBuffer(context, CL_MEM_READ_WRITE, ((instances->cols)*(instances->rows))*sizeof(float), NULL, &ret); 
for(int i = 0; i < instances->rows; i++){ 
    ret = clEnqueueWriteBuffer(command_queue, gpu_data, CL_TRUE, 0, ((instances->cols)*(instances->rows))*sizeof(float),(void*)(instances->data + (instances->cols*i)) , 0, NULL, NULL); 

は、時にはそれは、このコードのためによく実行され、すなわち

ret = clEnqueueReadBuffer(command_queue, gpu_data, CL_TRUE, 0,sizeof(float) * instances->cols* 1 , instances->data, 0, NULL, NULL); 

overhere読取部で立ち往生です。

CL_kmeans.exeの0x10001098で未処理の例外が発生しました:0xC000001D:不正な命令です。ブレークが押されたときに

は、それが与える:

ませシンボルは任意のコールスタックフレーム用にロードされていません。ソースコードを表示することはできません。

デバッグ中です。コールスタックでは、表示される:

OCL8CA9.tmp.dll 10001098()
[フレームは、以下の間違ったおよび/または欠落している可能性があり、OCL8CA9.tmp.dllのためにロードされていないシンボル]
amdocl!。 dll!5c39de16()

私は本当にそれが何を意味するのか知りません。誰か私はこの問題を取り除くのを助けてください。

答えて

3

まず、CUDAコードでは、データをコピーするのにひどく非効率的なことをしています。 CUDAランタイムには、異なる行をループすることによって、何をしようとしているのかを正確に実行する関数cudaMemcpy2Dがあります。

とは何かcudaMallocPitchは、新しい新しい行が合体に最適なアドレスから始まる最適なピッチ(= 2次元配列の行間のバイト単位の距離)を計算し、次にピッチのような大きさのメモリ領域を割り当てます指定した行数を倍します。最初に最適なピッチを計算してから正しいサイズの割り当てを行うことで、OpenCLで同じことをエミュレートできます。

最適ピッチは、(1)カードのベースアドレスのアライメント設定を取得することによって計算されます(clGDEDeviceInfoを持つCL_DEVICE_MEM_BASE_ADDR_ALIGNプロパティ:戻り値はビット単位であるため、バイトで取得するには8で割る必要があります) ;これをbase(2)baseの最大倍数が自然なデータピッチ(sizeof(type)×列数の倍数)以上であると見てみましょう。これはあなたのpitchになります。

次に、pitch倍の行数バイトを割り当て、pitch情報をカーネルに渡します。

また、ホストからデバイスへとデータをコピーするときは、clEnqueue{Read,Write}BufferRectを使用します。これは特に、2Dデータをコピーするように設計されています(cudaMemcpy2Dの対応部分です)。

関連する問題