2012-07-12 46 views
0

使用蠻力匹配我已經存儲在字符數組a [正文長度],和圖案中的文本的數組b [patternLength]模式中的OpenCL

cl_char *a = (cl_char *) malloc(textLength*sizeof(cl_char)); 

for(int i =0; i<textLength;i++) 
{ 
    a[i]=text[i]; 
    } 

// A buffer object is a handle to a region of memory 
cl_mem a_buffer = clCreateBuffer(context, 
           CL_MEM_READ_ONLY | // buffer object read only for kernel 
           CL_MEM_COPY_HOST_PTR, // copy data from memory referenced 
           // by host pointer 
           textLength*sizeof(cl_char), // size in bytes of buffer object 
           a, // host pointer 
           NULL); // no error code returned 

// for text and pattern kernal arguments 
cl_char *b = (cl_char *) malloc(patternLength*sizeof(cl_char)); 

for(int i =0; i<patternLength;i++) 
{ 
    b[i]=pattern[i]; 
} 

// A buffer object is a handle to a region of memory 
/*cl_mem b_buffer = clCreateBuffer(context, 
           CL_MEM_READ_ONLY | // buffer object read only for kernel 
           CL_MEM_COPY_HOST_PTR, // copy data from memory referenced 
           // by host pointer 
           patternLength*sizeof(cl_char), // size in bytes of buffer object 
           b, // host pointer 
           NULL); // no error code returned */ 
cl_mem b_buffer = NULL; 


    clSetKernelArg(kernel, 0, sizeof(a_buffer), (void*) &a_buffer); 
clSetKernelArg(kernel, 1, sizeof(cl_mem), NULL); 
clSetKernelArg(kernel, n, sizeof(cl_mem), &b_buffer); 
    size_t global_work_size = numberofWorkItem; 
    cl_int error= clEnqueueNDRangeKernel(queue, kernel, 
         1, NULL, // global work items dimensions and offset 
         &global_work_size, // number of global work items 
         &patternLength, // number of local work items 
         0, NULL, // don't wait on any events to complete 
         &timeEvent); // no event object returned 

I have read that in clSetKernelArg, for __local indentifiers, the arg_value should be NULL. I have done that by doing b_buffer=NULL; 

但是這樣做將防止b_buffer從存儲值b [](pattern) 我該怎麼做?

另外, 如果我沒有錯,local_work_size不能大於CL_DEVICE_MAX_WORK_ITEM_SIZES給出的值。因爲local_work_size受底層設備/硬件的約束。另一方面,global_work_size可以像任何人想要的那樣大。 是否必須是local_work_size的倍數? 如果是,爲什麼?

回答

0

你的錯誤是在clSetKernelArg行:內核執行後

//incorrect 
clSetKernelArg(kernel, n, sizeof(cl_mem), &b_buffer); 

//correct 
clSetKernelArg(kernel, n, sizeof(cl_char)*patternLength, NULL); 

本地內存將被清除,所以你不能用你的方法來獲得b_buffer的副本。另外,本地內存不是由主機分配的。您需要從全局參數中複製到LDS中。

要獲取本地數據複製,您需要傳入全局cl_mem以及本地參數。拷貝可以在內核結束時完成,並使用clEnqueueReadBuffer紅回到主機。

更新

這裏有一個如何使用動態本地緩衝區,併爲其分配一個全局緩衝區的內容的具體例子。

__kernel void copyBufferExample(__global int* srcBuff, __local int* localBuff, const int copyCount) 
{ 
    int lid = get_local_id(0); 
    int ls = get_local_size(0); 
    int i; 

    for(i=lid; i<copyCount; i+=ls){ 
     localBuff[i] = srcBuff[i]; 
    } 

    //use localBuff here 
    //copy result back to global memory if needed 
} 
+0

非常感謝你回答:) cl_mem b_buffer = NULL; clSetKernelArg(kernel,0,sizeof(a_buffer),(void *)&a_buffer); clSetKernelArg(kernel,1,sizeof(cl_mem),NULL); clSetKernelArg(kernel,n,sizeof(cl_mem),&b_buffer); 以上幾行錯了? 你能解釋一下如何分配本地內存嗎?如果它沒有被主機分配? – Remy 2012-07-12 19:58:04

+0

您需要將數據作爲全局數據以及未初始化的本地緩衝區傳遞,並讓內核複製+使用數據。我發佈了上面顯示的內核代碼的更新。 – mfa 2012-07-13 04:04:32

+0

謝謝.. :) 它清除了我的疑惑。謝謝! – Remy 2012-07-13 06:03:48

0

上面的代碼沒有做並行副本...

這樣做......

_ 內核無效copyBufferExample( _global INT * srcBuff,__local INT * localBuff ,const int的copyCount) {

int i = get_local_id(0); 

如果(ⅰ< copyCount) localBuff [i] = srcBuff [i]; //每個線程複製1個int。沒有for循環需要

barrier(CLK_LOCAL_MEM_FENCE); // synchronize all threads before using the local memory 


//use localBuff here 
//copy result back to global memory if needed 

}

+0

它是否必須是(我 Remy 2012-07-17 05:37:10

+0

如果您的x維度中的GWG大小> copyCount,則可以使用!爲什麼?因爲你比copyCount啓動更多的線程(內核)。每個線程複製1個int。所有這些線程並行運行 – 2012-07-17 15:05:59

+0

謝謝Tim! 我明白了.. :) – Remy 2012-07-17 15:26:17