CUDA and ROS - ACRVMonash/LabWiki GitHub Wiki

CUDA and ROS

Using CUDA and ROS together is actually pretty easy. This guide assumes that you are using catkin as your build system. You will also need to be using catkin simple to create your CMake file, though I would strongly recommend doing this anyways, since it will make your life so much easier.

The following setup is illustrated through a simple Hello World example. In your project folder, the files CMakeLists.txt and package.xml. Then create a folder called src and inside there a file called hello.cu. If you are unfamiliar with catkin-simple, the package.xml defines the ROS dependencies you have and will automatically go through and find them for you. Nice huh?

You can download the code in the correct folder structure here

CMakeLists.txt

This is a bare-bones CMakeLists example of how CUDA and ROS can be cross-compiled.

cmake_minimum_required(VERSION 2.8.3)
project(cuda_test)
set(CMAKE_CUDA_COMPILER  /usr/local/cuda-9.1/bin/nvcc)

find_package(catkin_simple REQUIRED)
find_package(CUDA REQUIRED)

catkin_simple()

#Here you can set any ncvv compiler flags, if you so wish
#SET(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} -DMY_DEF=1")

#Here you can set any gcc/cmake compiler flags, if you so wish
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3")

#Add all of your sources here
cuda_add_executable(
  cuda_test_cu
  src/hello.cu
)

#Link the executable to the necessary libs
target_link_libraries(
   cuda_test_cu
   ${catkin_LIBRARIES}
   ${CUDA_LIBRARIES}
)

# CMake Indexing
FILE(GLOB_RECURSE LibFiles "include/*")
add_custom_target(headers SOURCES ${LibFiles})

cs_install()

package.xml

Since we have basically no dependencies here, our package.xml is very empty. Have a look at the catkin-simple wiki page for more help with this.

<?xml version="1.0"?>
<package format="2">
  <name>cuda_test</name>
  <version>0.0.0</version>
  <description>Hello World via CUDA, ROS and STL</description>
  <maintainer email="[email protected]">Timo S</maintainer>
  <license>GNU GPL</license>

  <buildtool_depend>catkin</buildtool_depend>
  <buildtool_depend>catkin_simple</buildtool_depend>

  <depend>roscpp</depend>

</package>

hello.cu

This is the actual code that will run.

#include <ros/ros.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include <iostream>

const int N = 7;
const int blocksize = 7;

__global__
void hello(char *a, int *b)
{
  a[threadIdx.x] += b[threadIdx.x];
}

int testmain()
{
  char a[N] = "Hello ";
  int b[N] = {15, 10, 6, 0, -11, 1, 0};

  char *ad;
  int *bd;
  const int csize = N*sizeof(char);
  const int isize = N*sizeof(int);

  printf("%s", a);

  cudaMalloc( (void**)&ad, csize );
  cudaMalloc( (void**)&bd, isize );
  cudaMemcpy( ad, a, csize, cudaMemcpyHostToDevice );
  cudaMemcpy( bd, b, isize, cudaMemcpyHostToDevice );

  dim3 dimBlock( blocksize, 1 );
  dim3 dimGrid( 1, 1 );
  hello<<<dimGrid, dimBlock>>>(ad, bd);
  cudaMemcpy( a, ad, csize, cudaMemcpyDeviceToHost );
  cudaFree( ad );

  printf("%s using CUDA\n", a);
  return EXIT_SUCCESS;
}

int main(int argc, char** argv)
{
  ros::init(argc, argv, "hello");
  ros::NodeHandle nh;
	ROS_INFO_STREAM("Hello world! using ROS");
	std::cout << "Hello world! using STL" << std::endl;
	testmain();
  return 0;
}

Building it all

To build this, navigate to your project folder (which should be in your catkin workspace in the folder src, for example /home/student/catkin_ws/src/cuda_test/) and type catkin build --this. It should compile fine. The executable will be placed in the folder /home/student/catkin_ws/devel/lib/cuda_test.

Running it all

To run all of this, you will first have to type roscore into a terminal window. Then, in a new terminal window, navigate to your executable using cd /home/student/catkin_ws/devel/lib/cuda_test. Then type ./cuda_test to run it.

You should see the output

[ INFO] [1551662050.441073148]: Hello world! using ROS
Hello world! using STL
Hello World! using CUDA

When you run this.

In Eclipse

You can eclipsify this project now, however Eclipse will not recognize CUDA keywords such as __global__. In order to get it to autocorrect CUDA, you will need to change the project properties:

1: In C/C++ build -> Environment ->

Add -> Name: "PATH" Value: "/usr/local/cuda/bin" -> OK
Select PATH -> Edit -> Value: change ";/usr/local/cuda/bin" to ":/usr/local/cuda/bin"

2: Window -> Preferences -> in C/C++ -> File Types -> New ->

enter "*.cu" and select "C++ Source File"
⚠️ **GitHub.com Fallback** ⚠️