views:

74

answers:

2

I just upgraded from OpenCL 1.0 to 1.1. When I make my call to the min() function, I get error output:

    <program source>:45:44: error: call to 'min' is ambiguous
            int nFramesThisKernelIngests = min(nFramesToIngest  - nAvg*nPP*get_global_id(2), nAvg*nPP);

<built-in>:3569:27: note: candidate function
double16 __OVERLOADABLE__ min(double16, double16);                                               
                           ^
<built-in>:3568:26: note: candidate function
double8 __OVERLOADABLE__ min(double8, double8);   

The error output continues for more lines with different types.

When I tried to isolate the problem, get_global_id(2) appears to be the problem. I thought that casting get_global_id(2) to an int from a uint (I believe it returns a uint) would solve the problem but it doesn't. Does anybody know what is going on? I looked at the 1.0 and 1.1 specs and I am still confused as to why this is happening.

+1  A: 

I don't really know OpenCL, but it looks like the compiler doesn't know if it should promote min's arguments to double8 or double16. Since those types are vectors and not scalars, I guess min is not the function you're looking for. Try fmin instead.

EDIT: Do you see the following in the error messages?

<built-in>:xxxx:yy: note: candidate function
int __OVERLOADABLE__ min(int, int);

JAB IN THE DARK: Cast everything to int:

int nFramesThisKernelIngests = (int) min(
    (int) (nFramesToIngest - nAvg * nPP * get_global_id(2)),
    (int) (nAvg * nPP));

If that compiles, remove the casts in descending order of silliness (e.g. the first cast is probably meaningless, but YMMV).

Frédéric Hamidi
Just a note about the double8 and double16. There are literally 20 other lines of error output saying the same thing but with different types, like ushort, uint, float2, float4, float8, float16
Okay... what are the types of `nFramesToIngest`, `nAvg` and `nPP`? What is the result type of `get_global_id()`? :)
Frédéric Hamidi
They are all int type.
yes I see, <built-in>:3435:22: note: candidate function int __OVERLOADABLE__ min(int, int);
+1  A: 

The OpenCL 1.0 and 1.1 specifications define min to have the following function signatures:

gentype min (gentype x, gentype y) 
gentype min (gentype x, sgentype y)

As such, the argument types must be the same, or 1 vector and a scalar matching the vector element type e.g.

int4 a,b;
int c; 
min(a,b); // All arguments have the same type
min(a,c); // 2nd element may be scalar, matching the 
          // element type of the 1st argument ( a vector type )

Note also that the return type of get_global_id is size_t, which may be 32 or 64bits in size.

You will have to cast the expression results to select a specific overload of min.

There are many overloads of min (as the compiler error message is somewhat unhelpfully indicating) e.g.

min(float  a, float  b);
min(float2 a, float2 b);
min(float2 a, float  b);
min(float3 a, float3 b);
min(float3 a, float  b);
min(float4 a, float4 b);
... // and vector sizes 4,8,16
min(double a, double b); // With an OpenCL 64bit floating point extension enabled
min(double2 a, double b); // With an OpenCL 64bit floating point extension enabled
... // and integral scalar and vector types (char, schar, short, ushort, int, etc)

...
grrussel
I did, convert_int(get_global_id(2)). This gets rid of the error I wrote before, but now I am getting seg faults. Could this have something to do with the size being 32 or 64bits? I am really lost...
A segmentation fault is probably due to incorrectly indexing into memory or reading / writing via out of bounds pointers. The convert_int call is probably overkill versus a C style cast. There isn't enough context in the question's source code to diagnose any more precisely.
grrussel
The segmentation fault appears to be coming from an unrelated part of my program. I believe this problem is solved and it is just a matter of OpenCL 1.1 being stricter on how that parameter was calculated.