Don’t trust fseek(), it lies!

When I press the Build button I Always hope to see a compilation without errors. Obviously this almost never happens, but yesterday it did! Too good to be true: when I ran the application OpenCL failed to compile the rendering kernel and I got errors at lines beyond the end of the file. Since I was sure that the error was not in my code I started blaming everyone: Intel for a buggy compiler, NVIDIA for his lack of support and Khronos for some other invented reason. Of course it wasn’t their fault, I just should have been a bit more careful when reading the .cl files. This was my code:

// Read the source code file
char* buffer;
FILE* file = fopen(fileName, "r");

fseek(file , 0 , SEEK_END);
long size = ftell(file);
buffer = (char*)malloc(size);
fread(buffer, 1, size, file);

// Create OpenCL program
char* sources[] = { buffer };
size_t lengths[] = { size };
cl_program program = clCreateProgramWithSource(
     context, 1, (const char**)sources, lengths, &error);

It turned out that the problem was in the function fseek(). The C standard states:

A binary stream need not meaningfully support fseek calls with a whence value of SEEK_END.

This means that the code above doesn’t really get the real size of the file. In my case the value of size was sometimes bigger than the real file size, causing dirty memory to be included in the source code. To fix this problem I took advantage of a powerful library that I was already using for other tasks: boost.

boost::filesystem::ifstream fIn;, std::ios::in);

std::stringstream ss;
ss << fIn.rdbuf();
char* buffer = ss.str().c_str();

This solved the problem. Now the kernel compiles smoothly. I had an access violation exception in nvcompiler.dll when running the kernel on x64 but I fixed it recompiling everything for x86 and then for x64 again. Don’t ask me why does it work! I have no idea and the NVIDIA OpenCL compiler is well-known for his bugs. Anyway I was finally able to run a basic raytracing pipeline with OpenCL!


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s