How to call a CUDA kernel from a C project? (not C++)

This may be a very introductory question, but I can’t seem to find a solution online.

I have a C project that I’m looking to speed up using CUDA. The problem seems to be that the compiler does not understand the <<< >>> brackets for the CUDA kernel call with in the .CU file. I’m not sure if this is a C vs C++ issue, but I get a “expression must have integral type” at the kernel call. Converting this project to C++ is not feasible as the portion I am working on is a small part of a much larger (and C) project. I am not familiar with C, as opposed to using C++.

What I have done so far

  • Updated VS2013 Professional to support CUDA 7.5
  • Added CUDA 7.5 to the project dependencies
  • Linked the cudart.lib in the C/C++ linker

Doing simple things within the .C and .CU files like allocating and freeing GPU memory works. Defining host/device function works. It’s the calling of them such as,


that causes the build to fail.

Probably you don’t have the CUDA build rules added to the project.

Does the file name that contains the gpu_kernel<<<1,1>>>(); call end in .cu?
Is that file being compiled by nvcc? (look at the output console window where the error is being reported)

Essentially, both of the above must be true for you to have any success with kernel calls, whether your project is primarily C or C++.

nvcc will always generate C++ style linkage by default, so you must explicitly force it to create C-style linkage using wrapper functions that begin with

extern “C” {

int my_wrapper_function(…){ …; gpu_kernel<<<1,1>>>(); … ; };

Your other .c files in the project should then be able to link to and call my_wrapper_function.

my_wrapper_function as well as gpu_kernel should be defined in a .cu file that is linked into the project and being compiled by nvcc. The GPU kernel function definitions can be outside of any extern “C” {} wrapper, as they will not be/should not be called from any other module.

This is more or less trivial to map out in linux using command line tools, but visual studio complicates things (IMO).

The first step is to make sure that CUDA build customizations are selected for your project. Then make sure the project is linking against cudart. Then make sure that all CUDA kernel calls are in .cu files. Then build wrapper functions with extern “C” to connect to your C modules.

Thank you txbob. I was doing everything except for the extern “C” part, which I had to wrap with a #ifdef __cplusplus to get it compiling. It seems like it’s working now, though more testing tomorrow! Thanks again.