지금 당장 OpenCL을 이해하기 위해 몇 가지 샘플을 프로그래밍하고 있습니다. 문제가있는 샘플에서 큰 8 비트 이미지를로드하고 픽셀 단위 평균 값 을 계산합니다.OpenCL - 특정 양의 입력 데이터를로드 할 때 빈 결과가 발생합니다.
결과 [X, Y = (이미지 1 [X, Y] + 이미지 2 [X, Y] + ...)이 0-9 이미지 매우 잘 작동
/ImageCount. 하지만 10 장 이상의 이미지를로드하면 결과는 검은 색 이미지 (모든 픽셀 0)가됩니다.
메모리 양에 문제가 있다고 생각했습니다. 그러나 10 장의 그림으로 된 이미지 데이터는 100MB에 불과합니다. 그래픽 카드는 256MB RAM이 장착 된 8600GTS입니다.
또한 모든 오류 코드를 확인하고 CL_SUCCESS와 다른 결과를 얻지는 않습니다.
호스트 프로그램 (델파이,하지만 난 것은 또한 C 사람들이 읽을 수) :
//Settings
MaxImg := 4; //Images from 0..4 Count = 5
SetLength(InImgs,MaxImg+1); //Array for images in Host memory
SetLength(GPUInMems,MaxImg+1); //Array for images in GPU memory
//Create Kernel
CLKernel := clCreateKernel(CLProgram, PChar('MainKernel'), @LastError);
//Create Queue
CLQueue := clCreateCommandQueue(CLContext, CLDevices[0].DeviceID, 0, @LastError);
//Load images
for I := 0 to MaxImg do
begin
InImgs[I] := TImageMem.Create;
InImgs[I].LoadFile('C:\Test\Img-' + IntToStr(I) + '.bmp');
GPUInMems[I] := clCreateBuffer(CLContext, CL_MEM_READ_ONLY or CL_MEM_COPY_HOST_PTR, InImgs[I].MemSize, InImgs[I].Memory, @LastError);
end;
//Prepare Outputimage
OutImg := TImageMem.Create;
OutImg.LoadFile('C:\Test\CLTestOut.bmp');//Temporary solution to get right memory size and headers
GPUOutMem := clCreateBuffer(CLContext, CL_MEM_WRITE_ONLY, OutImg.MemSize, nil, @LastError);
//Set parameter for kernel call
LastError := clSetKernelArg(CLKernel, 0, sizeof(cl_mem), @GPUOutMem); //Output image
LastError := clSetKernelArg(CLKernel, 1, sizeof(integer), @OutImg.Width);
LastError := clSetKernelArg(CLKernel, 2, sizeof(integer), @OutImg.Height);
//Add pointer to memory from images as parameters
for I := 0 to MaxImg do
begin
LastError := clSetKernelArg(CLKernel, I+3, sizeof(cl_mem), @GPUInMems[I]);
end;
//Specify Group and Grid sizes
GlobalWSize[0]:= (OutImg.Width div 512 + 1) * 512; //Calc groups needed for resolution
LocalWSize[0] := 512; //Max WorkItems per group possible
//Execute and transfer ouput to host memory
LastError := clEnqueueNDRangeKernel(CLQueue, CLKernel, 1, nil, @GlobalWSize, @LocalWSize, 0, nil, nil);
LastError := clEnqueueReadBuffer(CLQueue, GPUOutMem, CL_TRUE, 0, OutImg.MemSize, OutImg.Memory, 0, nil, nil);
//Write output
OutImg.SaveFile('C:\Test\CLTestOut.bmp');
커널 : 그것은 왜 누군가가 나에게 말할 수있는 경우
__kernel void MainKernel(
__global uchar* ret,
int xRes,
int yRes,
__global uchar* I0,
__global uchar* I1,
__global uchar* I2,
__global uchar* I3,
__global uchar* I4)
{
//Get line position
int y = get_global_id(0);
//Check inbound
if (y >= yRes) return;
//Set pointers to position
ret += xRes * y;
I0 += xRes * y;
I1 += xRes * y;
I2 += xRes * y;
I3 += xRes * y;
I4 += xRes * y;
//Set val for each pixel in line
for (int x = 0; x < xRes; ++x)
{
ret[x] = (I0[x] + I1[x] + I2[x] + I3[x] + I4[x])/5 ;
}
}
그것은 좋은 것입니다 9 개 이상의 이미지 작업 및 오류 코드가없는 이유는 무엇입니까?
도움 주셔서 감사합니다.
위에서 언급 한 것처럼 모든 OpenCL 호출 후에 오류 코드를 확인했습니다. 방금 'if'대신에 디버거로 검사했습니다. 모두 0 (CL_SUCCESS)이었습니다. 행 대신 열의 힌트를 주셔서 감사합니다. 나는 이것을 시도 할 것이다. – Marks
이전에 CL_DEVICE_MAX_WORK_GROUP_SIZE을 (를) 확인했습니다. 그 512, 내가 그것을 사용하는 것처럼. 또한 CL_DEVICE_MAX_WORK_ITEM_SIZES도 512인지 확인했습니다. 작은 작업 그룹도 성공없이 사용했습니다. – Marks
나는'clGetKernelWorkGroupInfo'에서 얻은 CL_KERNEL_WORK_GROUP_SIZE를 의미했습니다. –