58

I am looking for help getting started with a project involving CUDA. My goal is to have a project that I can compile in the native g++ compiler but uses CUDA code. I understand that I have to compile my CUDA code in nvcc compiler, but from my understanding I can somehow compile the CUDA code into a cubin file or a ptx file.

Here are my questions:

  1. How do I use nvcc to compile into a cubin file or a ptx file? Don't I need a -c or something?
  2. Which file type do I want to use?
  3. What are the g++ commands to correctly compile and link the project together?

Assume the following:

  1. I have a file called "main.cpp" that has a main function in it and includes cuda.h.
  2. I have another file called "cudaFunc.cu" that has CUDA code in it. Let's say, for instance, that I want to add two integer arrays that exist in main.cpp.
Shadow
  • 3,926
  • 5
  • 20
  • 41
Matthew
  • 3,886
  • 7
  • 47
  • 84

3 Answers3

66

I was able to resolve my issue with a couple of different posts including these ones. Don't forget that if you are using a 64 bit machine to link to the 64 bit library! It seams kind of obvious, but for clowns like me, that is something I forgot. Here is the make file that I now use... if you can digest this make file, you should be able to do what I was trying to do which was separate compilation of cuda code and other G++ code. Also keep in mind that you have to have the gcc, g++ compilers at certain versions (I am using g++-4.4 and it is working for me) Anyway, here is the make file...

all: program

program: cudacode.o
    g++ -o program -L/usr/local/cuda/lib64 -lcuda -lcudart main.cpp  cudacode.o 

cudacode.o:
    nvcc -c -arch=sm_20 cudacode.cu 

clean: rm -f *.o program

Hopefully you can see that the first thing I do is compile the cudacode (that has been saved as a .cu) using the nvcc compiler and -c option (also note that you may want to remove the -arch=sm_20). This created a cudacode.o. I then use the g++ compiler with the -o option and link to the lib64 library and link the -lcuda and -lcudart libraries along with compiling my main.cpp and then linking the cudacode.o. Hope this helps someone!

Parker
  • 7,244
  • 12
  • 70
  • 92
Matthew
  • 3,886
  • 7
  • 47
  • 84
  • 1
    Can you also provide a minimal `.cu` and `.cpp` files you tested with? Curious about the includes used, cpp, in particular how to see the kernel `__global__` functions from `.cu`. – Ciro Santilli OurBigBook.com Apr 09 '17 at 09:36
  • 4
    Careful there, your clean target will remove all files ending with 'o'. You probably want `clean: rm -rf *.o program` – gerowam Jul 21 '17 at 12:25
  • I'm getting mangled names in the generated object files (for the function that I need to call from my non-`.cu` file). Anyone have an idea how to fix that up? – interestedparty333 Feb 25 '18 at 06:11
  • How can I write this using automake? – Abhishek Kumar Nov 24 '22 at 05:52
  • Just because I had some issues with this myself: https://stackoverflow.com/questions/3811539/can-i-call-cuda-runtime-function-from-c-code-not-compiled-by-nvcc/75843299#75843299 this SO post has more detail on how you can call CUDA-functions from cpp files. – darclander Apr 05 '23 at 17:07
17

My answer to this recent question likely describes what you need.

A couple of additional notes:

  1. You don't need to compile your .cu to a .cubin or .ptx file. You need to compile it to a .o object file and then link it with the .o object files from your .cpp files compiled with g++.
  2. In addition to putting your cuda kernel code in cudaFunc.cu, you also need to put a C or C++ wrapper function in that file that launches the kernel (unless you are using the CUDA driver API, which is unlikely and not recommended). Also add a header file with the prototype of this wrapper function so that you can include it in your C++ code which needs to call the CUDA code. Then you link the files together using your standard g++ link line.
Parker
  • 7,244
  • 12
  • 70
  • 92
harrism
  • 26,505
  • 2
  • 57
  • 88
  • Harrism, Thank you for your answer. I am much closer now. I can compile just fine using the nvcc compiler and the .cu file (which I renamed to cudacode.cu) and I have a cudacode.o object, but now when I try to compile on the g++ I get cudacode.o: In function `wrapper(int*, int*, int*, int)': tmpxft_00000d3a_00000000-1_cudacode.cudafe1.cpp:(.text+0x30): undefined reference to `cudaMalloc' – Matthew Feb 24 '12 at 14:36
  • You need to link libcudart. First figure out where libcudart.so is -- by default I think it goes into /usr/local/bin/cuda, but that varies by installation. Once you find the path, add this to your link line: `-L -lcudart`. – harrism Feb 25 '12 at 00:36
  • 1
    you are my hero! thank you. an additional issue i was having was that i am on a 64 bit machine, so i had to link to the lib64 file. just three hours ago i didnt know how to use g++, i didn't know what a make file was, and i didnt know how to link. i guess that is what i get for growing up on windows. – Matthew Feb 25 '12 at 02:55
11

I found that linking the compiled cuda object code with g++ can be troublesome. Try compiling it like this:

all:
nvcc cudafile.cu mainfile.cpp -o executable

clean: rm -rf *.o
Jean-Luc Nacif Coelho
  • 1,006
  • 3
  • 14
  • 30
  • I'd use rm -f rather than rm -rf, because the *.o files should be regular files and I'm scared of making a fatal error: https://www.theregister.co.uk/2015/01/17/scary_code_of_the_week_steam_cleans_linux_pcs/ – Adam P. Goucher Jul 21 '17 at 00:59
  • @Adam P. Goucher If on Ubuntu, you can install `safe-rm` :) – juzzlin Dec 28 '18 at 15:41