cancel
Showing results for 
Search instead for 
Did you mean: 

Archives Discussions

char86
Journeyman III

How can I use user made funcions in a OpenCL Kernel ?

Hello Guys.

inside my kernel I have a local memory storage:

__local float Uin[Xmax][Ymax]

Now i want to make mathimatical differentials with data from __local Uin. I want this many many times in my code so I want to make it with a funcion.

But i get these errors --------------------------------------------------------------

OpenCL Compile Error: clBuildProgram failed (CL_BUILD_PROGRAM_FAILURE).

Line 8: error: expression must
          have pointer-to-object type
      OUT = IN[ 4*XL + i + 2 ][ YL ] - IN[ 4*XL + i ][ YL ];
                 ^

Line 8: error: expression must
          have pointer-to-object type
      OUT = IN[ 4*XL + i + 2 ][ YL ] - IN[ 4*XL + i ][ YL ];
                                                      ^

Line 209: error: argument of
          type "local float (*)[4]" is incompatible with parameter of type
          "local float *"
          BUFX = DIFFX(XL, i, YL, UinLOC );
                                                 ^

3 errors detected.

---------------------------------------------------------------------------

 

 



// My Funcion // float DIFFX(int XL, int i, int YL, __local float *IN ) { float OUT; OUT = IN[ 4*XL + i + 2 ][ YL ] - IN[ 4*XL + i ][ YL ]; return(OUT); } // My code inside Kernel to call it // define LS 4 __local float UinLOC[ LS+2 ][ LS ]; BUFX = DIFFX(XL, i, YL, UinLOC );

0 Likes
4 Replies
Jawed
Adept II

In the DIFFX function, the parameter:

__local float *IN

should be:

 __local float **IN 

or:

 __local float *IN[LS] (you have to move the #define LS higher in your code) 

The compiler still warns for both of these(not sure why), but the code compiles. You might be better off defining UinLOC as one-dimensional:

__local float UinLOC[ (LS+2) * LS ];

 and computing the addresses as:

   OUT = IN[ (4*XL + i + 2 ) * LS + YL ] - IN[ (4*XL + i) * LS + YL ];

0 Likes

Thank you.

The first way compiles, but it gives me wrong numbers.

The second way is to hard, cause i must change many lines of code, so i think i will use the easy known way.

Thanks again.

0 Likes

I think the problem is that you're trying to use 2D indexing from a pointer type. To use 2D array, you have to know how many elements are in the leading dimension. While Fortran passes this information off to functions behind the scenes, C (and hence OpenCL) does not. As such, you'll need to explicitly pass the leading dimension of UinLoc to DIFFX() in another parameter and a 1D array lookup. Since C is row-major, DIFFX should look up values as

OUT=IN[4*XL+i+2 + YL*ld] - IN[4XL + i + YL*ld];

where ld is the leading dimension parameter you need to add to DIFFX. ld in this case is 4, since array dimensions go from right to left.

0 Likes

Generally I've always advised people against pretending that C has 2D arrays in their code. Invariable it wrecks code maintenance because of all the sizes you have to pass statically to things, or if you pass a ** you still need the size anyway. Generally I'd stick with 1D arrays and sizes in code like this, it's less messy if you always do it that way and more flexible.

0 Likes