Integrating a kernel into a pre-existing makefile

Hi,

I’m trying to replace a single function in a pre-existing C++ project with a GPU kernel. The project already has its own Makefile (snippets seen below). Apart from this, I have two new files now, say gpu_setup.cu and gpu_kernel.cu which I need to integrate with the makefile. Would it be better to use Nvidia’s common.mk to make a new makefile or just add some rules to the existing one?

Also, I’m assuming I’ll have to declare the function in gpu_setup as an extern so that I can call it through the C++ code. Or do I need to create a header file (gpu_setup.h) which has the function declaration and include it into the C++ file which has to call the gpu_setup function?

Would it be any easier if I combine the two .cu files into a single one?

Thanks

The relevant portion of the existing makefile:

CC_DIR = /usr/local/apps/gcc/4.3.2/bin

CC  = icc #$(CC_DIR)/gcc

CXX = icpc #$(CC_DIR)/g++

# -Wall -Wno-sign-compare 

CFLAGS   = -g -MMD ${INCLUDES}

CXXFLAGS = -g -MMD ${INCLUDES}

ifeq ($(MODE),debug)

else

	CFLAGS 	+=  -O3 -msse3 -DNDEBUG

	CXXFLAGS +=  -O3 -msse3 -DNDEBUG

endif

LDFLAGS = ${LIBS}

MEX = mex

RANLIB = ranlib

# rules

%.o: %.cpp

	$(CXX) $(CXXFLAGS) -c $*.cpp

%.o: %.c

	$(CC) $(CFLAGS) -c $<

I haven’t done this – sorry, wish I had better info – but I’d start looking at the output from NVIDIA’s makefile by doing “make verbose=1” in one of the SDK sample projects and looking at the common makefile NVIDIA_CUDA_SDK/common/common.mk

Have you seen the CMake stuff for CUDA? Might be worth a look also if you anticipate any growth in build complexity

Edit - btw, how I do the extern “C” stuff:
in the .CU “driver” file containing the host code:
extern “C” void cudaFunction(int a) {
// function implementation
}

Then I declare the same extern “C” function in the .hpp file, after which I can call it from C++ code in the .cpp files

Thanks for this. The project isn’t really going to be extended, so even a very ugly hack would do for now.

Stay away from the NVIDIA Makefile :lol:

You just need to add a rule:
%.o: %.cu
(NVCC) (NVCFLAGS) -c $*.cu

after the proper definition of NVCC and the flags you want to use. To avoid problems with the name mangling of different compilers, use the suggested extern “C”. You may need to add the cudart/cuda/cublas/cufft libraries when you link.

You should be able to get by just creating a rule to make .o files from .cu files.

something like

NVCC = nvcc

NVCCFLAGS = -arch=sm_13  # for example......

%.o: %.cu

	$(NVCC) $(NVCCFLAGS) -c $*.cu

Although I’m not makefile hacker and I’m not quite sure if $* is what you want for the .cu list… This should get you started at least. nvcc really isn’t that different from gcc as far as command line options go.

And there is no need to #include multiple .cu files into one like the SDK examples do (unless you want them to share texture references or constant variables)

Thanks for the replies. After getting a bit of help with the makefiles, I finally have the rules in place which compile the .cu files to .o files. However, while linking everything to make the final executable, I get a bunch of linker errors in the cuda code

undefined reference to `cudaSetDevice'

undefined reference to `cudaMalloc'

and so on for every cuda function call. Is there any switch or path I have to provide to the linker so that it will link these correctly?

This is where “make verbose=1” in the sample projects would help, sorry I can’t give better info but I don’t know … you probably also need something in your LD_LIBRARY_PATH like /usr/local/cuda/lib if you don’t have it already - but check the linker flags the common.mk does to find where the references are from

Personally, I just hacked the common.mk stuff and learned to love it :D

I’m looking at common.mk right now. Hopefully, it’ll help.

EDIT: Alright it’s solved. The linker was not finding the libcuda and libcudart files (but was now complaining either). I had to do a -L to set the correct path.