Compiling code with both Boost and Cuda

If I compile boost using code in a .cu, then the make fails with strange errors.
If I simply rename the .cu file to .cpp, the boost code compiles, but the cuda code fails, due to unknown references to cuda-specific things like threadIdx.x.

Any suggestions on working around this?

Are you trying to use boost code in a kernel/device function or just in a calling function?

What is the error when you compile with a .cu extension?

Also, what version of CUDA do you have installed. Only CUDA 2.2 and newer can handle boost in host code.

I’m using 2.3, and boost is in the host code.

The error is that shows up when including thread.hpp is:
$ nvcc -Xcompiler -fPIC -shared -o libCudaCallC.so main.cu -I/opt/cuda/sdk/C/common/inc/
/usr/include/boost/lexical_cast.hpp(328): error: expected an expression

/usr/include/boost/lexical_cast.hpp(328): error: expected a “;”

2 errors detected in the compilation of “/tmp/tmpxft_00000823_00000000-4_regression.cpp1.ii”.

There appears to be nothing wrong with the lexical_cast file as both the file itself, and thread.hpp, can be correctly included in other projects.

Trivial example

[codebox]$ cat main.cpp

#include <boost/thread.hpp>

int main() {

    return 0;

}

$ nvcc main.cpp

$ cp main.cpp main.cu

$ nvcc main.cu

/usr/include/boost/lexical_cast.hpp(328): error: expected an expression

/usr/include/boost/lexical_cast.hpp(328): error: expected a “;”

2 errors detected in the compilation of “/tmp/tmpxft_000008e3_00000000-4_main.cpp1.ii”.

$[/codebox]

I would suggest separating your host and device code.

Place your host code in a cpp file and your device code in a cu file. You can then compile your host code with gcc and the device code with nvcc and link them. I’d imagine gcc would handle the boost includes without any problems.

This is always an option but I still consider this bad behaviour. According to the documentation of build pipeline, host code should be automatically handed over to the base compiler. If nvcc trips over this, it might mean it tries to compile more than it should?

I could reproduce this with nvcc 2.3 & gcc 4.3.3 and filed a bug report.

In the meantime, I would do as jph4599 suggests and sequester the code that requires this Boost header to a .cpp compiled with the native compiler.

Ok, thanks for the input :)
How do I go about this in pratice then?

I keep all boost code in a .cpp file,
compile it with g++ instead of nvcc, use nvcc for the rest, and then link things together how?

By far, the easiest way is to use an automated build tool to do this, like CMake using FindCUDA.cmake.

If you just want to do quick and dirty tests on the command line, build just the way you normally would:

nvcc -o file1.o -c file1.cu

gcc -o file2.o -c file2.cpp

gcc -o executable file1.o file2.o

Maybe I will look at a cmake solution if you recommend that.
But right now I’d like to understand this :)

If I do what was suggested,

forumboost:
nvcc -o regression.o -c regression.cu $(INCLUDEDIRS)
gcc -o boost.o -c regressionBoost.cpp
gcc -o cuda boost.o regression.o

Then I get loads of undefined references to cuda-xyz errors.

I experimented with:
nvcc -cuda regression.cu (INCLUDEDIRS) -o regression.cc gcc -fPIC -c regression.cc -o regression.o g++ -fPIC -c regressionBoost.cpp -o regressionBoost.o g++ regressionBoost.o regression.o -shared -o libCudaCallC.so (INCLUDEDIRS)

Which compiles, but doesn’t run due to:
undefined symbol: __cudaRegisterFatBinary

Oh, sorry. I forgot the -lcudart in the finally linking step. That should solve your undefined symbol: __cudaRegisterFatBinary problem. You may also need -L /dir/to/cuda

Thanks, that solved it :)

Any updates on this problem? I am encountering it with the CUDA 3.0 Beta. It would be really nice if nvcc could pass boost to the host compiler correctly…