Compiling CUDA with clang on math functions - c++

Compiling the following CUDA code helloWorld.cu with clang-11,
int main() {
return max(1.0f, 2.0f);
}
, using command clang++-11 -o helloWorld helloWorld.cu --cuda-gpu-arch=sm_75 -ldl -lrt -lcudart_static -pthread -L/usr/local/cuda/lib64, encountered the error:
helloWorld.cu:2:12: error: no matching function for call to 'max'
return max(1.0f, 2.0f);
^~~
/usr/lib/llvm-11/lib/clang/11.0.0/include/__clang_cuda_math.h:194:16: note: candidate function not viable: call to __device__ function from __host__ function
__DEVICE__ int max(int __a, int __b) { return __nv_max(__a, __b); }
...
/usr/local/cuda-10.2/include/crt/math_functions.hpp:1079:31: note: candidate function not viable: call to __device__ function from __host__ function
__MATH_FUNCTIONS_DECL__ float max(float a, float b)
...
Note that the matching function was actually located correctly by the compiler (ie, "math_functions.hpp:1079:31"), but was mistakenly inferred as a "_device_" function.
Thanks for any help in advance.

The code you have written is host code and it is not syntactically valid C++. That code should not compile, and the compiler behaviour is correct. The code should look like this in order to compile:
#include <algorithm>
int main() {
return std::max(1.0f, 2.0f);
}
i.e. you have to actually include the standard library header which defines the max function, and you have to use the correct namespace. C++ has no built-in max function. CUDA does. All you are seeing is an artifact of the clang CUDA compilation trajectory.

Related

Why gcc5.4 doesn't compile a constexpr function calling a non-constexpr function, but icpc does?

gcc5.4 doesn't compile the following code:
// source.cpp
int nonconstexprfunc()
{
return 14;
}
constexpr int func(int n)
{
if (n < 0)
return nonconstexprfunc();
return n*n;
}
int main()
{
constexpr int t1 = func(0);
return 0;
}
The command I use:
$ g++ -std=c++14 -c source.cpp
The output:
In function ‘constexpr int func(int)’:
error: ‘constexpr int func(int)’ called in a constant expression
constexpr int t1 = func(0);
In function ‘int main()’:
error: ‘constexpr int func(int)’ called in a constant expression
constexpr int t1 = func(0);
But I can compile that source.cpp using gcc6.4. Doesn't gcc5.4 fully support constexpr functions?
More interestingly I can compile that source.cpp using icpc (Intel C++ compiler) that uses gcc5.4 - I suppose there must be an option to compile that code using gcc5.4.
$ icpc -v
icpc version 19.0 (gcc version 5.4.0 compatibility)
$ icpc -std=c++14 -c source.cpp
no errors
The first limitation is concerning the use gcc 5.4 with -std=c++11 which produces the error because of the two return statement see The body of constexpr function not a return-statement so in order to lift your first issue you need to use -std=c++14
It then produces
'#1 with x86-64 gcc 5.4
: In function 'constexpr int func(int)':
:10:32: error: call to non-constexpr function 'int
nonconstexprfunc()'
return nonconstexprfunc(); ^
: In function 'int main()':
:16:28: error: 'constexpr int func(int)' called in a constant
expression
constexpr int t1 = func(0);
Compiler returned: 1
This next error produced seems to be a known GCC bug (misinterpretation of c++14) see
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86678
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67026
You can also check out calling non constexpr function from constexpr allowed in some conditions
However judging from the error it produces:
It seems pretty obvious that doing
constexpr int nonconstexprfunc()
{
return 14;
}
will solve the error and will be more efficient in your case.
Check the difference with https://www.godbolt.org/ of adding constexpr or not using gcc 8.2 for example.

Undefined reference error for one specific library function

I'm writing software to control a bladeRF radio card but I'm running into a strange compiler/linker error that I haven't been able to figure out. My code uses several functions and data structures defined in the library, libbladeRF, but for some reason I can't reference to one specific function.
However, if I modify the call with an improper argument type, g++ will throw an error to let me know that it doesn't conform to the definition, which seems to tell me that the linker is actually able to locate the reference.
What am I missing?
Initial error:
$ g++ bladeRF_test.cpp -o bladeRF_test -lbladeRF
/tmp/ccTWZzdJ.o: In function `enable_xb300()':
bladeRF_test.cpp:(.text+0x36a): undefined reference to `bladerf_xb300_set_amplifier_enable'
Code excerpt:
#include <iostream>
#include <string>
#include <libbladeRF.h>
using namespace std;
...
int set_xb300_pa(bool enable) {
bladerf_xb300_amplifier amp = BLADERF_XB300_AMP_PA;
if ( bladerf_xb300_set_amplifier_enable(dev, amp, enable) ) {
// Print error message
return -1;
} else {
// Print success message
return 0;
}
}
...
Function arguments changed from (dev, amp, enable) to (&dev, amp, enable):
$ g++ blade_hello.cpp -o blade_hello -lbladeRF
blade_hello.cpp: In function ‘int set_xb300_pa()’:
blade_hello.cpp:62:59: error: cannot convert ‘bladerf**’ to ‘bladerf*’ for argument ‘1’ to ‘int bladerf_xb300_set_amplifier_enable(bladerf*, bladerf_xb300_amplifier, bool)
^
In file included from blade_hello.cpp:4:0:
/usr/local/include/libbladeRF.h:2226:15: note: declared here
int CALL_CONV bladerf_xb300_set_amplifier_enable(struct bladerf *dev,
^

Ambiguous Function Call when One Definition is in a Namespace

I have a simple program containing the following code:
namespace nam
{
struct S{};
void f(S *){}
}
void f(nam::S *){}
int main()
{
nam::f(nullptr);
nam::S s;
f(&s);
return 0;
}
I expect that this will compile fine because I am calling f the second time without specifying namespace nam. However, upon compiling the code, I get this error:
$ g++ main.cpp -std=c++11 -Wall -Wextra
main.cpp: In function ‘int main()’:
main.cpp:14:9: error: call of overloaded ‘f(nam::S*)’ is ambiguous
f(&s);
^
main.cpp:7:6: note: candidate: void f(nam::S*)
void f(nam::S *){}
^
main.cpp:4:10: note: candidate: void nam::f(nam::S*)
void f(S *){}
Compiler and version:
$ gcc --version
gcc (Debian 5.3.1-14) 5.3.1 20160409
After trying this with different compilers, similar errors are returned. This seems to be a defined part of C++. I can't find anywhere on the internet where it says that calling a function with a struct in namespace nam as a parameter effectively implies using namespace nam; and requires ::f to remove ambiguity. I have 2 questions about this:
Where is this defined in the C++ standard?
Is there a good reason for this behavior?
Personally I like to avoid using namespace x; and similar. I want the compiler to give me an error when I don't specify a namespace. This behavior stops the compiler from doing so, and this means my code is inconsistent in places, because I occasionally forget to specify the namespace when calling functions like f that are not declared globally anywhere.
Your implementation of f(nam::S*) is outside of the namespace of 'nam'
change:
void f(nam::S *){}
to:
void nam::f(nam::S *){}
(or just move the enclosing namespace bracket) and all should be fine.
if your call to f(&s) in the current namespace was intentional then you need to specify this by changing the function call to
::f(&s)
As was said in the comments, this is due to argument-dependent lookup. I guess now I'll have to figure out now if I want to always specify the namespace in my code where this would make it unnecessary, or never specify it.

Get the following errors when I compile with G++

I am a bit new to programming as you can probably tell from my prior question(s). I was wondering if anyone could help me with this recent problem I've had. I am trying to compile a script main.cpp using g++ but I get the following errors:
Donny#Donny-PC /cygdrive/c/Users/Donny/Desktop/equation/equations/equations
$ g++ main.cpp -o don.exe
main.cpp:3:11: error: ‘::main’ must return ‘int’
void main(){
^
main.cpp: In function ‘int main()’:
main.cpp:36:22: error: ‘pow’ was not declared in this scope
float n=pow(10.0,9.0);
^
main.cpp:43:27: error: ‘sin’ was not declared in this scope
float R56=(lb1/sin(theta1)) * ((tan(theta1))-theta1) + (lb2/sin(theta1)) * ((tan(theta1))-theta1) +
^
main.cpp:43:44: error: ‘tan’ was not declared in this scope
float R56=(lb1/sin(theta1)) * ((tan(theta1))-theta1) + (lb2/sin(theta1)) * ((tan(theta1))-theta1) +
^
main.cpp:48:40: error: ‘cos’ was not declared in this scope
d*((pow(tan(theta1),2))/cos(theta1)) +
^
The weird thing is that this code works when compiled with microsoft visual studio 2010 C++. Any help would be greatly appreciated!
EDIT:
So, the fixed a lot of the errors shown above, but I am still having a little difficulty fixing the void main error. Here is how my code looks:
#include<iostream>
#include<cmath>
using namespace std;
void main(){
float r, i, f, beta, alpha;
cout<<"Enter value of R : ";............
Any help or examples would be greatly appreciated.
The first error should be self-explanatory. The standard says that the main function must return int but you have declared it as void. Return 0 from your main function to indicate normal termination. The Microsoft compiler is not as strict on this point.
All your remaining errors can be remedied by using #include <math.h>.

Clang: Template deduction failed 'double' vs '<double>'

Consider the following code, which uses a function with variable arguments:
#include <iostream>
// Typedef function type
template<typename... Output>
using Func = void(Output*...);
// Function runner
template<typename... Output>
void run_func(Func<Output...>& func, Output*... output) {
for (int i=0 ; i < 10 ; ++i) {
func(output...);
}
}
void f(double* d) {
*d *= 2;
};
int main() {
double value = 1.0;
run_func(f, &value);
printf("%f\n", value);
}
Compiling this with g++ 4.7.3 works fine, and running produces 1024.0 as expected.
Compiling using icpc 14.0.2 crashes it...
templ.cc(21): internal error: assertion failed: lower_expr: bad kind (shared/cfe/edgcpfe/lower_il.c, line 18582)
run_func(f, &value);
^
Compiling with clang 3.5.0-1 gives the following error message:
templ.cc:21:3: error: no matching function for call to 'run_func'
run_func(f, &value);
^~~~~~~~
templ.cc:9:6: note: candidate template ignored: deduced conflicting types for parameter 'Output' ('double' vs. <double>)
void run_func(Func<Output...>& func, Output*... output) {
^
Is this a bug, or should have g++ not compiled this?
Why is clang deducing these "conflicting" types of double and <double>, is <double> meant to represent an unpacked arglist for example?
Update icpc 14.0.3 does not crash, and the program compiles and runs correctly.
See DPD200244439 at Intel® Composer XE 2013 SP1 Compilers Fixes List
Following the above discussion, it seems that this is indeed a bug in clang.
As pointed out by gha.st, skipping template using and using the native function type directly works:
void run_func(void (&func)(Output*...), Output*... output) {
I have a filed a bug against this here.