Search code examples
copenclopencl-c

OpenCl kernel returns strangely huge numbers


I have been trying to move my Marching Cubes algorithm from the CPU to the GPU with an OpenCL kernel for a while now.

The problem I´m getting is that a function in my kernel returns strange values, so I wrote a test case where I specify the possible return values in an array of 12 float3s with the float3 components being 0, 0.5 and 1 (see code below)

For some reason I get weirdly large numbers though, e.g. an edgeIndex of "11" returns the float3: (-145085952., 6.600e-43#DEN, 0) while it should be (1, 0, 0.5). The y coordinate basically is 0 though as far as I´m aware so that´s not the problem, but the x coordinate is what´s giving me headaches.

At first I thought OpenCL might have a problem with converting the given values to float3s so I specified them with ".f" (e.g. (float3)(0.f, 0.5f, 0.f)). This only resulted in even more strange and different results which makes me think that I have to make a mistake somewhere. I´m fairly new to OpenCL (this is my first real project using it) and I haven´t been programming in general that long either so I hope I´m not making some newbie mistake here but I tried to tackle this and related problems for days now and I can´t find a solution.

I narrowed down the problem as far as I could and tested whether the code is doing what it should for each step that it takes. Up to the function call of "CalculateEdgePos" everything seems to be going fine and I get the expected results. I stripped the function of all the unnecessary code (therefore you can ignore the "values" parameter as it´s not being used right now) but now I´m at my wits end.

the function returning the strange results:

float3 CalculateEdgePos(int edgeIndex, __global int* values) 
{ 
    if(edgeIndex == -1) 
    { 
        return (float3)(-1,-1,-1); 
    } 

        float3 EdgePositions[12] = {(float3)(0, 0.5, 0), (float3)(0.5, 1, 0), (float3)(1, 0.5, 0), (float3)(0.5, 0, 0), (float3)(0, 0.5, 1), (float3)(0.5, 1, 1), (float3)(1, 0.5, 1), (float3)(0.5, 0, 1), (float3)(0, 0, 0.5), (float3)(0, 1, 0.5), (float3)(1, 1, 0.5), (float3)(1, 0, 0.5)};

        return EdgePositions[edgeIndex];
} 


and the part of the kernel with the function call and the result getting send back to the CPU 
(edgeIndex is calculated fine beforehand):

__kernel void MarchCubes(__global float* outVertices, __global int* values, __global int* edges) 
{ 
.
.
.
    float3 vertexPos = CalculateEdgePos(edgeIndex, values); 
    float coords[3] = {vertexPos.x, vertexPos.y, vertexPos.z}; 

    outVertices[get_global_id(0)] = coords[coordIndex]; 
}

If anyone of you has any tips or help to offer, I´d greatly appreciate it. If you need any more code snippets let me know but I think this should be sufficient as it´s only the specified function that acts weirdly.

Kind regards, foodius


Solution

  • Of course, right after I post this problem I´ve been sitting on for so long, I find the solution...

    So if anyone has a similar problem:

    It seems like OpenCL really doesn´t like it if you declare array elements right in the declaration of the array itself. So instead of writing:

     float3 EdgePositions[12] = {(float3)(0, 0.5, 0), (float3)(0.5, 1, 0), (float3)(1, 0.5, 0), (float3)(0.5, 0, 0), (float3)(0, 0.5, 1), (float3)(0.5, 1, 1), (float3)(1, 0.5, 1), (float3)(0.5, 0, 1), (float3)(0, 0, 0.5), (float3)(0, 1, 0.5), (float3)(1, 1, 0.5), (float3)(1, 0, 0.5)};
    

    I now wrote:

    float3 pos0 = (float3)(0.f, 0.5f, 0.f);
        float3 pos1 = (float3)(0.5f, 1.f, 0.f);
        float3 pos2 = (float3)(1.f, 0.5f, 0.f);
        float3 pos3 = (float3)(0.5f, 0.f, 0.f);
        float3 pos4 = (float3)(0.f, 0.5f, 1.f);
        float3 pos5 = (float3)(0.5f, 1.f, 1.f);
        float3 pos6 = (float3)(1.f, 0.5f, 1.f);
        float3 pos7 = (float3)(0.5f, 0.f, 1.f);
        float3 pos8 = (float3)(0.f, 0.f, 0.5f);
        float3 pos9 = (float3)(0.f, 1.f, 0.5f);
        float3 pos10 = (float3)(1.f, 1.f, 0.5f);
        float3 pos11 = (float3)(1.f, 0.f, 0.5f);
    
        float3 EdgePositions[12] = {pos0, pos1, pos2, pos3, pos4, pos5, pos6, pos7, pos8, pos9, pos10, pos11};
    

    and it works like a charm now.

    I still don´t really get why this isn´t allowed or returns false values, so if anyone knows and likes to elaborate, I would very much apprecitate it.