CMake and cuPrintf

I am trying to incorporate the cuPrintf example from NVIDIA in my CUDA CMake project but encountered some problems.

I downloaded the cuPrintf.cu and cuPrintf.cuh from the NVIDIA website.

My program compiles and runs fine, when I do not use cuPrintf.

My CMakeLists.txt for creating a static library out of my CUDA Code looks like this

SET(MyProjectCUDA_SRCS

  test.cu

)

CUDA_ADD_LIBRARY(MyProjectCUDA ${MyProjectCUDA_SRCS})

TARGET_LINK_LIBRARIES(MyProjectCUDA ${CUDA_LIBRARIES})

If I now add cuPrintf.cu to MyProjectCUDA_SRCS I get the following error when calling make:

[ 72%] Built target MyProjectGUI

[ 81%] Building NVCC (Device) object src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

-- Removing /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

/usr/bin/cmake -E remove /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

-- Generating dependency file: /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.NVCC-depend

/opt/cuda/bin/nvcc /local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA/cuPrintf.cu --host-compilation C -m64 -DQT_DLL -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_XML_LIB -DQT_CORE_LIB -Xcompiler ,\"-g\" -DNVCC -M -o /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.NVCC-depend -I/opt/cuda/include -I/opt/net/gcc41/boost/include -I/opt/cuda/include -I/usr/include -I/usr/include/opencv -I/usr/include/qt4 -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/include -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/app -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyProjectGUI -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyProjectGUI -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtXml -I/usr/include/qt4/QtCore

-- Generating temporary cmake readable file: /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend.tmp

/usr/bin/cmake -D input_file:FILEPATH=/local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.NVCC-depend -D output_file:FILEPATH=/local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend.tmp -P /local/Testprograms/CUDA/BasicCMakeQTCUDA/CMakeModules/make2cmake.cmake

-- Copy if different /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend.tmp to /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend

/usr/bin/cmake -E copy_if_different /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend.tmp /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend

-- Removing /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend.tmp and /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.NVCC-depend

/usr/bin/cmake -E remove /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.depend.tmp /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/MyProjectCUDA_generated_cuPrintf.cu.o.NVCC-depend

-- Generating /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

/opt/cuda/bin/nvcc /local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA/cuPrintf.cu --host-compilation C -m64 -DQT_DLL -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_XML_LIB -DQT_CORE_LIB -Xcompiler ,\"-g\" -DNVCC -c -o /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o -I/opt/cuda/include -I/opt/net/gcc41/boost/include -I/opt/cuda/include -I/usr/include -I/usr/include/opencv -I/usr/include/qt4 -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/include -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/app -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyProjectGUI -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyProjectGUI -I/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA -I/usr/include/qt4/QtOpenGL -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtXml -I/usr/include/qt4/QtCore

/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA/cuPrintf.cu(308): warning: function "copyArg(char *, const char *, char *)" was declared but never referenced

/opt/cuda/bin/../include/cuda_runtime.h:184: error: inline function ‘_Z18cudaMemcpyToSymbolI19cuPrintfRestrictionE9cudaErrorRK

T_PKvmm14cudaMemcpyKind’ cannot be declared weak

/opt/cuda/bin/../include/cuda_runtime.h:184: error: inline function ‘_Z18cudaMemcpyToSymbolIPVcE9cudaErrorRKT_PKvmm14cudaMemcp

yKind’ cannot be declared weak

/opt/cuda/bin/../include/cuda_runtime.h:184: error: inline function ‘_Z18cudaMemcpyToSymbolIiE9cudaErrorRKT_PKvmm14cudaMemcpyK

ind’ cannot be declared weak

/opt/cuda/bin/../include/cuda_runtime.h:238: error: inline function ‘_Z20cudaMemcpyFromSymbolIPVcE9cudaErrorPvRKT_mm14cudaMemc

pyKind’ cannot be declared weak

/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA/cuPrintf.cu: In function ‘_Z16outputPrintfDataPcS_’:

/local/Testprograms/CUDA/BasicCMakeQTCUDA/src/libMyCUDA/cuPrintf.cu:643: warning: format not a string literal and no format arguments

/opt/cuda/bin/../include/cuda_runtime.h: At top level:

/opt/cuda/bin/../include/cuda_runtime.h:184: error: inline function ‘_Z18cudaMemcpyToSymbolI19cuPrintfRestrictionE9cudaErrorRK

T_PKvmm14cudaMemcpyKind’ cannot be declared weak

/opt/cuda/bin/../include/cuda_runtime.h:184: error: inline function ‘_Z18cudaMemcpyToSymbolIPVcE9cudaErrorRKT_PKvmm14cudaMemcp

yKind’ cannot be declared weak

/opt/cuda/bin/../include/cuda_runtime.h:184: error: inline function ‘_Z18cudaMemcpyToSymbolIiE9cudaErrorRKT_PKvmm14cudaMemcpyK

ind’ cannot be declared weak

/opt/cuda/bin/../include/cuda_runtime.h:238: error: inline function ‘_Z20cudaMemcpyFromSymbolIPVcE9cudaErrorPvRKT_mm14cudaMemc

pyKind’ cannot be declared weak

In file included from /tmp/tmpxft_00000eda_00000000-1_cuPrintf.cudafe1.stub.c:6,

				 from /opt/cuda/bin/../include/cuda_runtime.h:251:

/opt/cuda/bin/../include/crt/host_runtime.h:178: warning: ‘struct surfaceReference’ declared inside parameter list

/opt/cuda/bin/../include/crt/host_runtime.h:178: warning: its scope is only this definition or declaration, which is probably not what you want

-- Removing /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

/usr/bin/cmake -E remove /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

CMake Error at MyProjectCUDA_generated_cuPrintf.cu.o.cmake:205 (message):

  Error generating file

  /local/Testprograms/CUDA/BasicCMakeQTCUDA/bin/src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o

make[2]: *** [src/libMyCUDA/./MyProjectCUDA_generated_cuPrintf.cu.o] Error 1

make[1]: *** [src/libMyCUDA/CMakeFiles/MyProjectCUDA.dir/all] Error 2

make: *** [all] Error 2

I heard that this might have something to do with the gcc compiler.

I am using Ubuntu 9.10 64-bit with gcc-4.4 and g+±4.4 and the CUDA 2.3 Toolkit.

But if I set

SET(CMAKE_CXX_COMPILER g++-4.3)

SET(CMAKE_C_COMPILER gcc-4.3)

The same error appears.

Yeah, you can’t currently use gcc 4.4 (search around for other posts on this).

In order to get cmake to see the different compiler, you must set the compiler before calling cmake (see CMAKE_C_COMPILER at http://www.itk.org/Wiki/CMake_Useful_Varia…lers_and_Tools). Once you’ve set the compiler, you can’t change it. You need to start with a clean build directory.

Try setting the following environment variables before calling cmake:

export CC=gcc-4.3

export CXX=g++-4.3

cmake <path-to-src>

In addition (or alternatively) you might need to set the --compiler-bindir (or -ccbin) to where gcc-4.3 lives with your CUDA_NVCC_FLAGS. You can do this from ccmake or from the initial configuration:

cmake "-DCUDA_NVCC_FLAGS:STRING=-ccbin;/usr/bin/<path to gcc-4.3>" <path-to-src>

Thanks for the advice, it works fine now.

I also added

SET(CUDA_NVCC_FLAGS "-ccbin;/usr/bin/gcc-4.3")

to my CMakeLists.txt, then I can simply call cmake and make without any additional exports or passed arguments.

I just wonder, why does one have to include the cuPrintf.cu instead of the cuPrintf.cuh?

Plus it does not seem to matter, whether I include the cuPrintf.cu to my sources in the CMakeLists.txt file.

This is somewhat unusual for my programming experience.

Cool. I’m glad that fixed your problem with that.

What do you mean by include? Are you talking about including cuPrintf.cu in your sources or including the cuPrintf.cu in the list of files specified by CMake?

I mean I have to write

#include "cuPrintf.cu"

in my source file which starts the kernel.

Actually it does not matter if I include cuPrintf.cu in my CMakeLists.txt.

This is somehow surprising for me, as I would have expected that one would have to include the .cuh instead of the .cu file in the source code and add cuPrintf.cu to the CMakeLists.txt.

Unlike C which can reference functions in other objects, CUDA inlines all the device functions. This is why you need to include cuPrintf.cu. The function bodies are in cuPrintf.cu which are then inlined into your code.

So the Header or the .cuh files are only needed if there is a host function declared which I do not want to be inlined on the CPU?
Good to know. I will keep that in mind.

Thank you for all the help.

I’m not sure there is any difference between a .cu and .cuh file aside from where the files might be included from. I can’t speak for cuPrintf, but I organize my code into header files that can be included by both cu and cpp files. This is mainly, so that I can reuse code or have similar definitions of structs, so that I can get the sizes consistent between host and device code. Ultimately file names are just a convention, and you have to look for host and device to determine what code can be placed where.