Search code examples
c++cmakecudaclion

Linking CUDA with a project added as external project from subdirectory


I am working on a fork of a project here. As you can see the main project and other dependencies are all added with ExternalProject_Add() in the outer CMakeList.txt. I want to add a simple CUDA project that I had written here, to the main iris-distro project that I have forked. Simply put, I want to be able to call funcs_cuda.cuh inside iris_demo.cpp. My desired goal is to achieve some .cpp file (similar to iris_demo.cpp) like this:

#include <iostream>
#include <Eigen/Core>
#include "iris/iris.h"
#include "funcs_cuda.cuh"
int main(int argc, char** argv) {

  int m {900};
  int n {900};
  int k {900};

  ///////////// HERE 

  MatricesClass mat_class(m,n,k);

  ////////////
  iris::IRISProblem problem(2);
  problem.setSeedPoint(Eigen::Vector2d(0.1, 0.1));

  Eigen::MatrixXd obs(2,2);
  // Inflate a region inside a 1x1 box
  obs << 0, 1,
         0, 0;
  problem.addObstacle(obs);
  obs << 1, 1,
         0, 1;
  problem.addObstacle(obs);
  obs << 1, 0,
         1, 1;
  problem.addObstacle(obs);
  obs << 0, 0,
         1, 0;
  problem.addObstacle(obs);

  iris::IRISOptions options;
  iris::IRISRegion region = inflate_region(problem, options);

  std::cout << "C: " << region.ellipsoid.getC() << std::endl;
  std::cout << "d: " << region.ellipsoid.getD() << std::endl;


  /* Some other calculation using matrices in mat_class */ 

  return 0;
}

I have tried multiple ways to see if it is possible to simply add funcs_cuda.cu/funcs_cuda.cuh files to the project, and add CUDA as the language for iris project, however, none of my efforts came out to be useful. Can you help me to find a solution for this problem? Any help, ideas or hints would be appreciated.


I admit that I'm pretty novice in this field, but I have been struggling with this problem for DAYS. I have tried several approaches based on my own incomplete knowledge of CMake, but all of them led to a dead end. For instance, one thing that bothered me first, was the fact that I cannot simply add CUDA language to iris project here (I tried to keep the rest similar to my simple cuda project) (e.g. project(iris LANGUAGES CXX CUDA)).

Or I could not build and link the CUDA header files completely, when the files where in one of the sub-directories (e.g. iris-distro/src/cxx/). I could build them in the main (outer) directory (e.g. iris-distro/), but again I did not know how to link it with iris_demo.cpp.

My operating system is Ubuntu 16.04 and my goal is to benefit from the graphical processor on my computer to accelerate some matrix multiplications in IRIS project. I have already built and run the cuda-matmul project and I'm using CLion with gcc-5.4.0. Thus, I think it is probably due to my lack of knowledge about CMake since everything with CUDA is working.


Solution

  • After spending a few more hours, it seems that I have found some way to fix it.

    1. I copied funcs_cuda.cuh, funcs_cuda.cu and directory of helper functions cuda-matmul/inc into iris-distro/src/cxx.
    2. In iris-distro/CMakeLists.txt: cmake variable for CUDA root was set: set(CUDA_TOOLKIT_ROOT_DIR "/usr/local/cuda-8.0")
    • Also this variable was added to IRIS_CMAKE_ARGS which will be used when adding the main project using ExternalProject_Add. In other words, "-DCUDA_TOOLKIT_ROOT_DIR=${CUDA_TOOLKIT_ROOT_DIR}" was added to IRIS_CMAKE_ARGS list.
    1. In iris-distro/src/cxx/CMakeLists.txt, the following commands where added:
    enable_language(CUDA)
    include_directories(${CUDA_TOOLKIT_ROOT_DIR}/include)
    add_library(funcs_cuda STATIC funcs_cuda.cuh funcs_cuda.cu )
    target_link_libraries(funcs_cuda -lcublas Eigen3::Eigen)
    target_include_directories(funcs_cuda PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc> $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/inc>)
    set_target_properties(funcs_cuda PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
    set_target_properties(funcs_cuda PROPERTIES LINKER_LANGUAGE CUDA)
    set_property(TARGET funcs_cuda PROPERTY CUDA_RESOLVE_DEVICE_SYMBOLS ON)
    

    Moreover, the new library should be considered in install command:

    install(TARGETS iris iris_geometry iris_mosek funcs_cuda
      EXPORT iris-targets
      INCLUDES DESTINATION ${IRIS_INCLUDE_DIR}
      LIBRARY DESTINATION ${IRIS_LIBRARY_DIR}
      PUBLIC_HEADER DESTINATION ${IRIS_INCLUDE_DIR}/iris
      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
    

    And finally, the executable file is to be linked with this new funcs_cuda library:

    add_executable(irisDemo iris_demo.cpp)
    target_link_libraries(irisDemo iris funcs_cuda)