C++ with classes example? Does anyone know of one/have one?

So I am attempting to use CUDA in a C++ class based program that I have written. The way I have done it so far is basically I have my class, (HPM.cc and HPM.h files), a separate hpm_cuda.cu file (which includes my extern “C” function that sets up my device, allocates memory, etc), and my hpm_cuda_kernel.cu file (my kernel). However, I have been having general difficulties doing a few things, most importantly, getting the device memory pointers back to the C++ class.

My basic goal is to use my HPM C++ class for a portion of the program, but I have a single HUGE array of floating points I want pass to the card, perform calculations, then copy the results back to the main class. I don’t want to have to re-malloc everything on the card each time I call. Does anyone have any advice or example code of doing something similarly? I wanted to try and get rid of the hpm_cuda.cu file alltogether, and just do my device set up and kernel call within my C++ class, but it errors on compile time. My makefile is listed below:

[codebox]EXECUTABLE := HPM

CUFILES := hpm_cuda.cu

CU_DEPS := hpm_cuda_kernel.cu

CCFILES := \

        main.cc\

        HPM.cc\[/codebox]

Thanks for the help!

I use a similar setup, where *_cuda.cu only include kernel driver functions for launching kernels. All device pointers are just passed to it. All allocation (via cudaMalloc) and initialization (via cudaMemcpy) is done in the *.cc files. All you have to do is #include <cuda_runtime_api.h> and your normal c++ code can call all of the CUDA API functions, except the texture binds and cudaMemcpyTo(/from)Symbol.

Right, that’s what I tried to do as well. I try to use “#include <cuda_runtime_api.h>” in my HPM.h file. However, when I make my Makefile, I get “HPM: error: cuda_runtime_api.h: No such file or directory”.

Am I missing something in my Makefile? Thanks for the help too, its greatly appreciated!

Sounds like you’re missing the additional include path to the header file. cuda_runtime_api.h is in the include directory with CUDA…

You should be able to pass the path to the compiler using a -I or /I flag depending on your compiler

-I"C:\CUDA\include"

or

/I "C:\CUDA\include"

I’ll check it out, thanks! But why is it OK when I do the #include in my *.cu file, but not my .cpp files?

Because nvcc knows where the .h file is and automatically includes the -I command line option.

Aha, got ya. That makes sense. So is there a best way to do this, and still just use my Makefile? Should I just change my #include<cuda_runtime_api.h>'s to #include “cuda/cuda_runtime_api.h”

The typical solution for a by-hand makefile is:

CUDA_INCLUDE=/usr/local/cuda/include

CXXFLAGS = blah blah -I${CUDA_INCLUDE}

# assuming your build rule uses CXXFLAGS....

Note: I may have the syntax a little off. It has been a long time since I wrote a makefile by hand. The idea is that you set the include directory in a variable so when you go to compile your code on a system where CUDA is installed in a different place you just need to change one line near the top of the makefile.

Build systems for production code (i.e. automake, CMake, scons, …) will identify the directory and automatically setup the flags for you. I highly recommend CMake with FindCUDA.cmake. It is great for projects big and small, it takes a lot less coding and trouble than a by-hand makefile, and it will generate project files on all major operating systems.

A cmake configuration file for a simple project is as easy as:

SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/CMake/cuda" ${CMAKE_MODULE_PATH})

FIND_PACKAGE(CUDA)

CUDA_ADD_EXECUTABLE(test

  test_bin.cu

  main.cc

  )

See: https://gforge.sci.utah.edu/gf/project/find…2FFindCuda.html

Thanks, yeah this sounds like a better solution. So I am attempting to compile and run the example included with FindCUDA and I am wondering if I am doing something wrong. The steps I took were

  1. Get cmake (sudo apt-get apparently installs version 2.4.7 on ubuntu, but I doubt this is my problem even though FindCUDA wants ver 2.6)

  2. Get CMake-cuda from the repository you pointed me to

  3. The following steps on the command line:

$ cd CMake-cuda

$ mkdir build

$ cd build

$ cmake …

Now, when I run cmake, one of the messages I get is “The end of a CMakeLists file was reached with an IF statement that was not closed properly.”, but it doesnt seem to crash because of this. I get 3 files and a new directory in my “build” dir, including a Makefile. On the command line I run

$ make

And nothing happens. did I miss something? Also, if this has moved completely off topic by this point, let me know if its more appropriate to re-post. Again, thanks for the guidance through this starting off process!

Hmm… I’m guessing the configure step didn’t complete properly then and that is why you only have a partially generated makefile. Try running ccmake … instead of cmake (note the extra c). Press c to configure and g to generate the make file. It should clarify whether that message is a warning or an error.

Strangely enough, the message you are getting actually might be caused by running cmake 2.4.x. There was a default change in behavior of the syntax of IF() statements between 2.4.x and 2.6.x. It has been so long since I switch to 2.6 I don’t remember any of the other changes, so I couldn’t say whether the rest of FindCUDA.cmake is compatible with 2.4.x. Fortunately, installing 2.6 into your home directory is easy. Download and extract the binaries from here http://www.cmake.org/cmake/resources/software.html and put the /home/user/cmake-…/bin on your PATH.

Yup, you were right that was the problem all along. I didn’t think it was a problem at first since findCUDA says its backwards compatible to version cmake 2.4. However, once I got that done, everything is running smoothly.

Anyone who hasn’t done it, I’d take MisterAnderson42’s advice and get findCUDA working for your project. Obviously I had a few hiccups here setting everything up, but once its done, its really convenient! Thanks again for all the help everyone!

Hi, I use cudaMemcpyToSymbol() in my C++ code and it works just fine. I simply do #include “cuda_runtime.h”. Could you elaborate on your experience with it?

I mean you can’t use the convenience cudaMemcpyToSymbol() that takes the actual symbol as an argument. I guess the one that takes a symbol name as an argument from C++. I just don’t like it much because now you don’t have the compiler doing error checking on the call and you can get runtime bugs from typos in the variable name.

Sure, one has to use the old copy/paste with the weird symbol name convention here that’s a bit annoying, as C++ compiler has no way of knowing about the global variables declared in .cu file.

Cheers.