2016-04-30 12 views
0

カーネルが使用する2つのローカルアレイを作成しようとしています。私の目標は、グローバル入力バッファを最初の配列(arr1)にコピーし、2番目の配列(arr2)をインスタンス化して後でその要素にアクセスして設定できるようにすることです。私のカーネルはこのようになりますローカルメモリアレイをインスタンス化するOpenCL:カーネルのポインタエラーが無効です

:私はからこれを呼んでいるC++のコードでは

__kernel void do_things (__global uchar* in, __global uchar* out, 
uint numIterations, __local uchar* arr1, __local uchar* arr2) 
{ 
    size_t work_size = get_global_size(0) * get_global_size(1); 

    event_t event; 
    async_work_group_copy(arr1, in, work_size, event); 
    wait_group_events(1, &event); 

    int cIndex = (get_global_id(0) * get_global_size(1)) + get_global_id(1); 
    arr2[cIndex] = 0; 

    //Do other stuff later 
} 

、私はこのようなカーネル引数を設定します。

myInputVectorがいっぱいベクトルである
//Create input and output buffers 
cl_mem inputBuffer = clCreateBuffer(context, CL_MEM_READ_ONLY | 
    CL_MEM_COPY_HOST_PTR, myInputVector.size(), (void*) 
    myInputVector.data(), NULL); 
cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, 
    myInputVector.size(), NULL, NULL); 

//Set kernel arguments. 
clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&inputBuffer)); 
clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&outputBuffer)); 
clSetKernelArg(kernel, 2, sizeof(cl_uint), &iterations)); 
clSetKernelArg(kernel, 3, sizeof(inputBuffer), NULL)); 
clSetKernelArg(kernel, 4, sizeof(inputBuffer), NULL)); 

uchars。

次に、2次元の作業サイズ、rows * cols bigでエンキューします。 myInputVectorのサイズはrows * colsです。

//Execute the kernel 
size_t global_work_size[2] = { rows, cols }; //2d work size 
status = clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL, 
    global_work_size, NULL, 0, NULL, NULL); 

問題は、カーネルを実行するとクラッシュするという問題です。具体的には、カーネル内でこの行:

arr2[cIndex] = 0; 

は、クラッシュのために責任がある(それはもうクラッシュしないように、それはそれを作る省略する)。エラーは次のように表示されます。

*** glibc detected *** ./MyProgram: free(): invalid pointer: 0x0000000001a28fb0 *** 

arr1と一緒にarr2にアクセスすることができます。 arr2はarr1と同じサイズでなければなりません。その場合、なぜこの奇妙なエラーが発生しますか?なぜこれは無効なポインタですか?

+0

「inputBuffer」はどのように定義されていますか? – simpel01

+0

cl_mem inputBuffer = clCreateBuffer(コンテキスト、CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR、myInputVector.size()、(void *) myInputVector.data()、NULL); – user3760657

+0

申し訳ありませんが、私は 'myInputVector'を意味しました。 – simpel01

答えて

0

ローカルバッファにはsizeof(cl_mem)しか割り当てられていないという問題があります。そして、cl_memは、ある種のポインタ型のtypedefです(したがって、システムによっては4〜8バイト)。

あなたが割り当てたローカルバッファのサイズを越えてアクセスしていて、GPUがメモリフォールトを起動しているのがあなたのカーネルで起こります。

clSetKernelArg(kernel, 3, myInputVector.size(), NULL); 
clSetKernelArg(kernel, 4, myInputVector.size(), NULL); 

問題を修正する必要があります。また、提供しているサイズはバイト単位のサイズなので、ベクトル要素タイプのsizeof(コードからはわかりません)を掛ける必要があります。

関連する問題