Hi. I have a simple problem that I can’t seem to figure out. I have two files: cuda.c and cudak.cu. The cu is the kernel, and the .c is a C program that calls the kernel. When I try to compile my program, I receive a linking error stating that runKernel in cuda.c is an unresolved external symbol.
This is just like the 'extern “C” ’ bit that I have seen and used in C++ programs with no problems, expect that I dropped the “C”. I have tried it with the “C” and with/without ‘extern’ in every possible combination, and it won’t work. What am I doing wrong? It is such a trivial thing, I am sure, but it is all that is holding me back right now.
I have split the program into two parts because I can’t get the cuda and mpi libs/headers to play nicely so I seperated the two. The mpi stuff is in cuda.c and the cuda stuff is in cudak.cu.
Using extern “C” in both of your files should work, i.e. extern “C” void runKernel().
Also make sure that linker is aware of .obj file created by nvcc.
When I try that it VS2005 tells me that there is a problem with having a string after “extern”. If I get rid of the “C” part it does not give me that error, but I get an unresolved symbol still. How do I make the linker aware of the .obj file? Is that the output field under custom build rules? I have that set…
Try this and let us know whether it works. In your cudak.cu file, split the definition and declaration of the function. So, you’ll end up with something like:
I’m attaching a small VS2005 project that has a kernel and kernel-launching function in a .cu file, the main in a .cpp file. Files are compiled into separate object files and then linked.
Note that the project assumes that CUDA library and include file directories are set in the VS environment. You can either add those to your environment, or modify the compilation rule for the .cu file (right-click, properties, custom-build step, general).
I had tried that before posting here, and I tried it again to make sure, and it still does not work. I’ve used the extern “C” before with no problems, but that was in a .cpp file. This is a .c file, so it is written in C, not C++, and C does not seem to allow a string after ‘extern’.
In the project you gave me, try changing the main.cpp to main.c and then you will see the problem (I think), after adding the argc,argv stuff. I cannot compile your project because of the “cuda_runtime.h” include file. What is this file? I have been using cutil.h, is this correct? I have written a test program that does some basic multiplication on my GPU, and it works great (using cutil.h), so I know that cutil.h can be used.
In the .c file I have to do “extern void runKernel(…);” and in the .cu file I have to do “extern “C” void runKernel(…);”. It is strange that I have to mix them like that, but it seems to work now.
cutil.h only gives you CUDA utility macros and a few functions that come with the SDK. It’s important to understand, that cutil stuff is not part of CUDA, it’s an optional add-on.
You don’t need to include cuda headers in .cu files that get processed by nvcc. However, if you’re using CUDA types or calls in files processed by a C/C++ compiler (without going through nvcc first) you must include some CUDA headers. cuda_runtime.h has the definitions of the host run-time functions. You also get the vector types through it. All of the CUDA toolkit includes are in the “include” directory inside the directory where CUDA toolkit is installed (C:\CUDA\include in default Win installations).
I think the problem is down to the fact there is no common declaration - despite the “extern void runKernel(…);”, which would be considered a C++ function declaration when compiled in a .cu file by nvcc.
Having said that, I think it’s also cleaner to have runKernel(…) defined in the C file, and leave only the kernels in the ‘.cu’ file.