[C++][OpenCL] image3D an Kernel übergeben
Hallo Leute!
Ich bin am verzweifeln. Das Problem:
Ich habe eine sehr großes (> 100MB), eindimensionales Array aus BYTE-Werten (unsigned char), welches ein dreidimensionales Volumen darstellt. Es darf nicht verändert werden und muss an einen Kernel übergeben werden. Da man davon ausgehen kann, dass der PC mehr RAM hat, als die Grafikkarte würde ich gerne das Array in ein Image3D packen und per enqueueMapImage an den Kernel geben. Dabei möchte ich das Flag CL_MEM_USE_HOST_PTR benutzen, um Kopien des Arrays aus Zeit- und Speicherplatzgründen zu vermeiden.
Nun spuckt mir enqueueMapImage dauernd den Fehlercode -30 (CL_INVALID_VALUE ) aus. Ich habe schon alle möglichen Spezifikationen und Google bemüht, aber habe nichts gefunden. Deswegen würde ich mich über Hilfe freuen!
Hier der vereinfachte Code mit einen 3x3x3-Array, der den gleichen Fehler produziert:
Edit: Im Kernel einen Fehler ausgebügelt. Das Problem bleibt aber noch immer das gleiche
.
Hallo Leute!
Ich bin am verzweifeln. Das Problem:
Ich habe eine sehr großes (> 100MB), eindimensionales Array aus BYTE-Werten (unsigned char), welches ein dreidimensionales Volumen darstellt. Es darf nicht verändert werden und muss an einen Kernel übergeben werden. Da man davon ausgehen kann, dass der PC mehr RAM hat, als die Grafikkarte würde ich gerne das Array in ein Image3D packen und per enqueueMapImage an den Kernel geben. Dabei möchte ich das Flag CL_MEM_USE_HOST_PTR benutzen, um Kopien des Arrays aus Zeit- und Speicherplatzgründen zu vermeiden.
Nun spuckt mir enqueueMapImage dauernd den Fehlercode -30 (CL_INVALID_VALUE ) aus. Ich habe schon alle möglichen Spezifikationen und Google bemüht, aber habe nichts gefunden. Deswegen würde ich mich über Hilfe freuen!
Hier der vereinfachte Code mit einen 3x3x3-Array, der den gleichen Fehler produziert:
Code:
#include "CL\cl.hpp"
#include <iostream>
using namespace std;
using namespace cl;
typedef unsigned char BYTE;
#define STRINGIFY(...) #__VA_ARGS__
const char kernel_source[] = STRINGIFY(
__kernel void test( __read_only image3d_t vol, sampler_t volSampler, __global int* ret){
size_t idx = get_global_id(0);
size_t idy = get_global_id(1);
size_t idz = get_global_id(2);
ret[idx + 3* (idy + 3*idz)] = read_imagef(vol, volSampler, (int4)(idx, idy, idz, 0)).w*255;
}
);
std::vector<CommandQueue> m_Queues;
Program m_Program;
Context m_Context;
std::vector<Device> m_Devices;
Platform m_Platform;
Kernel m_TestKnl;
Image3D m_CLVol;
Sampler m_VolSampler;
const BYTE img3D[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 };
int main(){
m_Platform = Platform::get();
m_Platform.getDevices(CL_DEVICE_TYPE_ALL, &m_Devices);
m_Context = Context(m_Devices);
m_Program = Program(m_Context, kernel_source);
cl_int result = m_Program.build(m_Devices);
if ( result ){
cout<<"Error during compilation! ( "<<result<<" )\n";
STRING_CLASS errstr;
m_Program.getBuildInfo(m_Devices.front(), CL_PROGRAM_BUILD_LOG, &errstr);
cout<<errstr.c_str();
throw -1;
} else {
cout<<"OpenCL compiled correctly: "<<result<<endl;
}
m_Queues.clear();
for(int i = 0; i < m_Devices.size(); ++i){
m_Queues.push_back(CommandQueue(m_Context, m_Devices[i]));
}
cout<<"Queue-Size: "<<m_Devices.size()<<endl;
m_TestKnl = Kernel(m_Program, "test");
ImageFormat imgform(CL_A, CL_UNORM_INT8);
cl_int err = CL_SUCCESS;
m_CLVol = Image3D(
m_Context, CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR, imgform,
3, 3, 3, 0, 0, (void*)img3D, &err);
cout<<"\nVol-Image3D: "<<err<<endl;
m_VolSampler = Sampler(m_Context, CL_TRUE, CL_ADDRESS_NONE, CL_FILTER_LINEAR, &err);
cout<<"Vol-Image3D-Sampler: "<<err<<endl;
DWORD start = 0, end = 0;
float time;
start = GetTickCount();
cl_int retArr[27];
err = 0;
Buffer retBuf(m_Context, CL_MEM_WRITE_ONLY, sizeof(cl_int)*27, NULL, &err);
if(err != 0){
cout<<"Error PicBuffer: "<<err<<endl;
}
err = m_TestKnl.setArg(0, sizeof(cl_mem), &m_CLVol);
cout<<"Arg 0: "<<err<<endl;
err = m_TestKnl.setArg(1, m_VolSampler);
cout<<"Arg 1: "<<err<<endl;
err = m_TestKnl.setArg(2, retBuf);
cout<<"Arg 2: "<<err<<endl;
cl::size_t<3> origin, region;
origin.push_back(0);
origin.push_back(0);
origin.push_back(0);
region.push_back(3);
region.push_back(3);
region.push_back(3);
::size_t row_pitch = 0;
::size_t slice_pitch = 0;
m_Queues[0].enqueueMapImage(m_CLVol, CL_TRUE, CL_MAP_READ, origin, region, &row_pitch, &slice_pitch, NULL, NULL, &err);
cout<<"enqueue Image-Map: "<<err<<endl;
err = m_Queues[0].enqueueNDRangeKernel(m_TestKnl, NullRange, NDRange(3, 3, 3), NullRange, NULL, NULL);
cout<<"enqueue Kernel: "<<err<<endl;
err = m_Queues[0].enqueueReadBuffer(retBuf, CL_TRUE, 0, sizeof(cl_int)*27, retArr);
cout<<"enqueue retBuf: "<<err<<endl;
end = GetTickCount();
time = ((float)(end-start)/1000);
cout<<"Time: "<<time<<" s\n";
for(int i = 0; i < 27; ++i){
cout<<retArr[i]<<" ";
}
cout<<endl<<endl;
cin>>err;
return 0;
}
Edit: Im Kernel einen Fehler ausgebügelt. Das Problem bleibt aber noch immer das gleiche

Zuletzt bearbeitet: