Monday, March 23, 2009

CUDA in Code::Blocks - First things second

While my first post highlighted the key sticking-points I faced when I first tried to use the nvcc compiler within the Code::Blocks IDE, it was probably jumping the gun a bit. Here I'll outline the procedure for setting up the nvcc compiler in Code::Blocks from scratch.

First we create a new compiler within Code::Blocks.
  • Settings --> Compiler and debugger...
  • At the top under Selected compiler, make sure "GNU GCC Compiler" is selected, and click the Copy button.
  • Enter a name for the compiler. Something like "NVIDIA NVCC CUDA Compiler", but perhaps with less shouting.
  • Do exactly what you're told, and go to the Toolchain executables tab.
  • Enter nvcc's installation directory (e.g., /opt/local/cuda).
  • Enter C compiler: nvcc
  • C++ compiler: nvcc
  • Linker for dynamic libs: nvcc
  • Linker for static libs: nvcc
  • Debugger: cuda-gdb? (I haven't actually tried it yet)
  • Under the Search directories tab, add /your_location/NVIDIA_CUDA_SDK2/common/inc to the Compiler box (so that headers like cutil.h will be found).
  • Add /your_location/NVIDIA_CUDA_SDK2/lib to the Linker box.
  • Add /your_location/NVIDIA_CUDA_SDK2/common/lib/linux (modify for your OS) to the Linker box.
  • OK.
So now we have the basics set up. Before we get into the really fun stuff (as described in my original blog post), we'll do a couple of easy things to make life more convenient.
  • Project --> Project tree --> Edit file types & categories...
  • Click the Add button.
  • Enter something like "CUDA sources"
  • In the file masks box, enter: *.cu;
  • OK.
Now, when you want to compile a lovely .cu file, you'll have to do something slightly annoying, because I haven't found a way to automate it. You must:
  • NOTE: Do this only for .cu files that need to be compiled, not for those acting as headers that are included by another file!
  • Right-click on your .cu file(s) in the file tree on the left and go to Properties.
  • In the Build tab, tick Compile file and Link file.
  • OK.
That's it for the basics. But those nasty issues I discussed in the first post remain to be dealt with. Here's a step-by-step guide, because I'm feeling typeative:
  • Settings --> Compiler and debugger...
  • Select your new NVIDIA NVCC CUDA Compiler from the list at the top.
  • Scroll right (i.e., not left) through the tabs until you can see the Other settings tab.
  • Take a deep breath, then click Advanced options... (down the bottom).
  • You will be prompted with a very frightening warning about goblins attacking your home if you dare continue. Bravely click Yes.
  • Within the Commands tab, select Compile single file to object file.
  • Replace the Command line macro with this: $compiler --compiler-options "$options" $includes -c $file -o $object
  • Go to the Output parsing tab.
  • Select 'Instantiated from' info and replace the regular expression (regexp) with: ([][{}() #%$~A-Za-z0-9_:+/\.-]+)[(:]([0-9]+)\)?:[ ]+([iI]nstantiated from .*)
  • Select Compiler warning and replace the regexp with: ([][{}() #%$~A-Za-z0-9_:+/\.-]+)[(:]([0-9]+)\)?:[ ]([Ww]arning:[ ].*)
  • Select Compiler error and replace the regexp with: ([][{}() #%$~A-Za-z0-9_:+/\.-]+)[(:]([0-9]+)\)?:[ ](.*)
  • OK.
  • OK.
  • Start breathing again.
Woot, that's it! Now you can try making a project that uses the NVCC compiler. If you want to try compiling the SDK sample projects, this may be of use, which contains Code::Blocks project files I created for a few of the samples. Just extract it to your SDK directory and open projects.workspace. Note that many of the SDK samples need to be linked against the cutil library. If you're setting up a project yourself, just add cutil to the Link libraries box in your project's build settings. Alternatively you could add it to the global compiler settings.

Now go forth and test thy new-fandangled compiler and report back to me if you find yourself in more trouble than you began (I hope not). Good luck! I will update here if I find any further improvements to the system. One thing to try is adding another compiler for running in CUDA's device-emulation mode. I might find time to post the details of doing that some time, depending on how much nagging I receive.