OpenCL 커널에서 하나의 전역 값에 추가하는 것과 관련된 버그와 싸우고 있습니다.OpenCL - 하나의 전역 값에 추가하기
__kernel some_kernel(__global unsigned int *ops) {
unsigned int somevalue = ...; // a non-zero value is assigned here
*ops += somevalue;
}
I가 clCreateBuffer
및 clEnqueueWriteBuffer
통해 0으로 초기화 인수에 건네
__kernel some_kernel(__global unsigned int *ops) {
unsigned int somevalue = ...; // a non-zero value is assigned here
atomic_add(ops, somevalue);
}
아아, 아니 주사위 - 호스트 포인터로 다시 값을 읽은 후, 그것은 제로는 아직. 나는 이미 somevalue
이 커널 실행에서 0이 아닌 값을 가지며 손실되었다고 확인했다. 요청에 의해
, 메모리를 생성하는 코드는 : 그것은 오류가 밖으로하지 않기 때문에
unsigned int *cpu_ops = new unsigned int;
*cpu_ops = 0;
cl_mem_flags flags = CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR;
cl_int error;
cl_mem buffer = clCreateBuffer(context, flags, sizeof(unsigned int), (void*)cpu_ops, &error);
// error code check snipped
error = clEnqueueWriteBuffer(queue, buffer, CL_TRUE, 0, sizeof(unsigned int), (void*)cpu_ops, 0, NULL, NULL);
// error code check snipped
// snip: program setup - it checks out, no errors
cl_kernel some_kernel = clCreateKernel(program, "some_kernel", &error);
// error code check snipped
cl_int error = clSetKernelArg(some_kernel, 0, sizeof(cl_mem), &buffer);
// error code check snipped
//global_work_size and local_work_size set elsewhere
cl_int error = clEnqueueNDRangeKernel(queue, some_kernel, 1, NULL, &global_work_size, &local_work_size, 0, NULL, NULL);
// error code check snipped
clFinish(queue);
cl_int error = clEnqueueReadBuffer(queue, buffer, CL_TRUE, 0, sizeof(unsigned int), (void*)cpu_ops, 0, NULL, NULL);
// error code check snipped
// at this point, cpu_ops still has it's initial value (whatever that value might have been set to)'
나는 코드를 검사 오류를 생략했습니다. 실제로 데이터를 송수신하고, 플랫폼 및 컨텍스트를 설정하고, 프로그램을 컴파일하는 등의 사용자 정의 도우미 함수를 사용하고 있으므로 위의 매개 변수 이름이 적절한 헬퍼의 본문으로 구성됩니다. 말이 되네.
나는 이것이 슬립 업이거나 내 부분에 대한 이해가 부족하지만 필자는이 부분에 대한 필사적 인 의견이 필요하다고 확신한다.
코드를 게시하여 메모리 영역 만들기, 메모리 영역 읽기 및 쓰기, 커널 실행? 게시 한 코드 조각의 문제는 아니지만 다른 곳의 문제입니다. – DarkZeros
자, 자. 앞에서 설명한 것처럼 몇 가지 도우미 함수를 사용하지만 다르게 작동합니다. 다른 데이터가 제대로 보내고 변경되고 수신됩니다. 서명되지 않은 int *는 작동하지 않습니다. –