the parser is very wrong in my context
I'm having parsing issues that reders the SDK unusable.
My platform :
OS : linux AMD64 (virtual machine with ubuntu 11.10 AMD64 guest on a windows7 x64 host)
CPU : AMD A8
APP SDK version : 2.6
The following code will build and execute fine, but as soon as I change some random meaning less part of it it fails. For example, if I remove the blank line before #pragma [...] the build fails with :
BUILD LOG
************************************************
/tmp/OCLQcu9fF.cl(1): warning: null (zero) character in input line ignored
pragma OPENCL EXTENSION cl_amd_printf : enable
^
/tmp/OCLQcu9fF.cl(1): error: identifier "pragma" is undefined
pragma OPENCL EXTENSION cl_amd_printf : enable
^
/tmp/OCLQcu9fF.cl(1): error: expected a ";"
pragma OPENCL EXTENSION cl_amd_printf : enable
^
./src/Types.h(33): warning: parsing restarts here after previous syntax error
} Transform;
^
./src/ElementData.h(16): error: identifier "Transform" is undefined
Transform transform;
^
/tmp/OCLQcu9fF.cl(11): error: function "printf" declared implicitly
printf("global id = %u element id = %u \n", id, iid);
^
4 errors detected in the compilation of "/tmp/OCLQcu9fF.cl".
Internal error: clc compiler invocation failed.
************************************************
Program::build() failed (-11)
#pragma OPENCL EXTENSION cl_amd_printf : enable #include "Types.h" #include "ElementData.h" __kernel void transform(__global ElementData * elements, __global const size_t * ids) { int id = get_global_id(0); size_t iid = ids[id]; printf("global id = %u element id = %u \n", id, iid); }
Follow up...
It seems to indicate some buffer overflow error, here is the code I use to compile my kernel :
///////////////////// OpenCL : initialization ///////////////////////// cl_int status; vector<cl::Device> devices; cl::Context context = cl::Context::getDefault(&status); CHECK_OPENCL_ERROR(status, "Context::Context()"); devices = context.getInfo<CL_CONTEXT_DEVICES>(&status); CHECK_OPENCL_ERROR(status, "Context::getInfo<CL_CONTEXT_DEVICES>()"); cl::CommandQueue queue(context, devices[0], 0, &status); CHECK_OPENCL_ERROR(status, "CommandQueue::CommandQueue()"); ///////////////////// OpenCL : Transform.cl compilation ///////////////////////// fstream sourcesFile("./src/Transform.cl", fstream::in); stringstream stringStream; stringStream << sourcesFile.rdbuf(); cl::Program::Sources sourcesCL(1, make_pair(stringStream.str().c_str(), stringStream.str().length())); cl::Program program = cl::Program(context, sourcesCL, &status); status = program.build(devices, "-I ./src", NULL, NULL); if (status != CL_SUCCESS) { if(status == CL_BUILD_PROGRAM_FAILURE) { string str = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0]); cout << " \n\t\t\tBUILD LOG\n"; cout << " ************************************************\n"; cout << str.c_str() << endl; cout << " ************************************************\n"; } cout << "Program::build() failed (" << status << ")\n"; exit(1); } sourcesFile.close();
Hi
Are you editing the file on windows and running it on linux ?
Thx
No, editing with Eclipse CDT on linux. Tried different encodings and
verified with xxd that the termination character were unix type.
Thanks
malem03,
we need Types.h and ElementData.h to compile correctly.
I can't but here is a simpler test case which, I think, reproduce an equivalent bug :
*********** Transform.cl sources ********
// test test test
#pragma OPENCL EXTENSION cl_amd_printf : enable
#include "Types.h"
__kernel void transform(__global Transform * elements, __global const size_t * ids)
{
size_t id = ids[get_global_id(0)];
Transform element = elements[0];
element.quaternion = (float4)(0,0,0,1);
elements[0] = element;
printf("global id = %u element id = %u \n", id);
printf("x = %f \n", element.translation.x);
}
****************size() = 413 vs 413
BUILD LOG
************************************************
/tmp/OCLIqXpfb.cl(21): error: unrecognized token
printf("x = %f \n", element.translation.x�
^
/tmp/OCLIqXpfb.cl(21): error: expected a ")"
printf("x = %f \n", element.translation.x�
^
/tmp/OCLIqXpfb.cl(21): error: unrecognized token
printf("x = %f \n", element.translation.x�
^
/tmp/OCLIqXpfb.cl(21): warning: null (zero) character in input line ignored
printf("x = %f \n", element.translation.x�
^
/tmp/OCLIqXpfb.cl(21): warning: null (zero) character in input line ignored
printf("x = %f \n", element.translation.x�
^
/tmp/OCLIqXpfb.cl(21): warning: null (zero) character in input line ignored
printf("x = %f \n", element.translation.x�
^
At end of source: error: expected a ";"
At end of source: error: expected a "}"
5 errors detected in the compilation of "/tmp/OCLIqXpfb.cl".
Internal error: clc compiler invocation failed.
************************************************
Program::build() failed (-11)
Message was edited by: Micah Villmow
The edit is working out a kink in the system
... adding '//////' and a newline makes the compilation sucessful :
Transform.cl becomes :
// test test test
#pragma OPENCL EXTENSION cl_amd_printf : enable
#include "Types.h"
__kernel void transform(__global Transform * elements, __global const size_t * ids)
{
size_t id = ids[get_global_id(0)];
Transform element = elements[0];
element.quaternion = (float4)(0,0,0,1);
elements[0] = element;
printf("global id = %u element id = %u \n", id);
printf("x = %f \n", element.translation.x);
//////
}
Thank you for providing the test case. I cannot reproduce the failure with our internal builds, so this issue looks to have been fixed already.
Since you have a work-around, can you use this until the next catalyst release which should have a working version?
The problem is that I have no universal workaround. It is always case by case and finding the random modification that I have to do in order to successfully build can take an unpredictable amount of time.
When is the next AMD APP version scheduled for?
Thank you
You can get a preview version here:
http://support.amd.com/us/kbarticles/Pages/Catalyst121apreviewdriver.aspx
The runtime/compiler gets updated in each version of catalyst, and that usually occurs in the third week of the month.
I don't use GPU drivers, I'm in a virtual machine. I would need a preview version of AMD APP SDK...
Right now I just spent 15 minutes adding spaces and poking empty code to try to evitate parsing holes. This is not very amusing.
I may soon run it natively on my A8. but the rest of my team rely on virtual machines... I may try the intel SDK.
Thanks
<body><p>I install intel sdk on top of AMD APP SDK. I can now report two platforms. If I chose intel as platform, I get a seg fault in CommandQueue::CommandQueue()</p></body>
<code>
cl_int status;
vector<cl::Platform> platforms;
status = cl::Platform::get(&platforms);
CHECK_OPENCL_ERROR(status, "Platform::get()");
// cl::Platform chosenPlatform = chosePlatform(platforms, "Advanced Micro Devices, Inc.");
cl::Platform chosenPlatform = chosePlatform(platforms, "Intel(R) Corporation");
cl::Device chosenDevice;
vector<cl::Device> devices;
status = chosenPlatform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
CHECK_OPENCL_ERROR(status, "Platform::getDevices()");
for (cl::Device device : devices)
{
cl_device_type deviceType;
status = device.getInfo(CL_DEVICE_TYPE, &deviceType);
CHECK_OPENCL_ERROR(status, "Device::getInfo()");
if(deviceType == CL_DEVICE_TYPE_CPU)
chosenDevice = device;
}
// return 0;
cl::Context context(devices);
CHECK_OPENCL_ERROR(status, "Context::Context()");
cl::CommandQueue queue(context, chosenDevice, 0, &status);
CHECK_OPENCL_ERROR(status, "CommandQueue::CommandQueue()");
</code>
Please contact Intel for issues with their SDK.
I was not looking for support on the intel issue, just sharing my experiences.
On the other hand, I still haven't found a way to make the parser work under my configuration, which is supposed to be officially supported. AFAIK, I can't install fglrx on a VM.
Thank you.
SOLVED
Found out the bug was due to a strange stringstream behavior.
using this code to load the kernel source code seems to solve the bug completely
cl_int status = 0; |
fstream sourceCodeFile;
string sourceCode;
// Open file stream
sourceCodeFile.open(fileName, (fstream::in | fstream::binary));
// Check if we have opened file stream
if (sourceCodeFile.is_open()) {
size_t size; | |
// Find the stream size | |
sourceCodeFile.seekg(0, fstream::end); | |
size = (size_t)sourceCodeFile.tellg(); | |
sourceCodeFile.seekg(0, fstream::beg); |
char* str = (char*)alloca(size + 1); |
// Read file | |
sourceCodeFile.read(str, size); | |
sourceCodeFile.close(); | |
str[size] = '\0'; |
sourceCode = str; |
}
cl::Program::Sources sourcesCL = cl::Program::Sources(1, make_pair(sourceCode.c_str(), sourceCode.size()));
cl::Program program(context, sourcesCL, &status);
CHECK_OPENCL_ERROR(status, "Program::Program()");
status = program.build(devices, "-I ./src", NULL, NULL);
if (status != CL_SUCCESS) {
for (auto device : devices) | ||
{ | ||
string str = program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(device); |
cout << " \n\t\t\tBUILD LOG\n"; | ||
cout << " ************************************************\n"; | ||
cout << str.c_str() << endl; | ||
cout << " ************************************************\n"; | ||
} |
cout << "Program::build() failed (" << status << ")\n"; |
exit(1); |
}
A colleague found the nature of the bug :
the following version works
fstream sourcesFile;
sourcesFile.open(fileName, fstream::in);
stringstream stringStream;
stringStream.str("");
stringStream << sourcesFile.rdbuf();
string sourceCode = stringStream.str(); // This is the fix, stringstream::str() return type is a string (copy), not const string & (reference)
cl::Program::Sources sourcesCL = cl::Program::Sources(1, make_pair(sourceCode.c_str(), sourceCode.size())); //stringStream.str().c_str() assigned a pointer to a temporary string