Using CMake to link C++ and CUDA Object file

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Using CMake to link C++ and CUDA Object file

Quang Ha
Hi all,

Following upon how to perform code linking between CUDA and C++ (here at https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/), I have successfully come up with a Makefile that is currently working for my test case:

##################################Makefile#################################################
main_objects = main.o
host_objects = host.o
device_objects = device.o

all: $(main_objects) $(host_objects) $(device_objects)
        g++ -O3 -fopenmp $(main_objects) $(host_objects) $(device_objects) -L/usr/local/cuda/lib64 -lcudart -o main

$(main_objects): $(main_objects:.o=.cpp)
        g++ -O3 -I/usr/local/cuda/include -c $< -o $@

$(host_objects): $(host_objects:.o=.cpp)
        g++ -O3 -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP -fopenmp -c $< -o $@

$(device_objects): $(device_objects:.o=.cu)
        nvcc -O3 -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA -c $< -o $@

clean:
        rm -f *.o main
######################################################################################################

Now, I am trying to write a CMake for this, my current attempt is as followed:

##############################################CMakeLists.txt############################################
cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)

# check requirements
find_package(CUDA REQUIRED)
find_package(OpenMP)

if (CUDA_FOUND AND OPENMP_FOUND)
    # OpenMP
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")

    # CUDA
    include_directories(${CUDA_INCLUDE_DIRS})
    set(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
    set(LIBS ${LIBS} ${ALL_CUDA_LIBS})
    set(CUDA_SEPARABLE_COMPILATION OFF)
    set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--maxrregcount 32)

    set(OMP_SOURCES host.cpp)
    add_library(Host_OMP SHARED ${OMP_SOURCES})
    set_target_properties(Host_OMP PROPERTIES COMPILE_FLAGS "-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP")
    set(LIBS ${LIBS} ${Host_OMP})

    set(CUDA_SOURCES device.cu)
    cuda_add_library(Device_CUDA SHARED ${CUDA_SOURCES})
    set_target_properties(Device_CUDA PROPERTIES COMPILE_FLAGS "-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA")
    set_target_properties(Device_CUDA PROPERTIES CUDA_SEPERABLE_COMPILATION ON)
    set(LIBS ${LIBS} ${Device_CUDA})

    add_executable(main main.cpp)
    target_link_libraries(main ${LIBS})

endif(CUDA_FOUND AND OPENMP_FOUND)
######################################################################################################

It is still, unfortunately, not working. If I commented out the add_executable line, the object code for Host_OMP and Device_CUDA is compiled. I can then use the terminal and link them with main.cpp using gcc and generate the executable - i.e. using the final command in the Makefile above.

What am I doing wrong here? It seems to be very fundamental, but I can't seem to get it right...

Any suggestions would be greatly appreciated!!

Thanks,
Quang

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using CMake to link C++ and CUDA Object file

Robert Maynard
if you are using the new first class cuda language, as seen by `project(MyTest LANGUAGES CXX CUDA)` you shouldn't use the old find cuda package or the associated cuda_add_library calls. When using the first class cuda language simply use add_library.

The other difference I notice is that you makefile example is not building shared libraries but object files, so to the same in CMake you need to use 'add_library' with the OBJECT keyword not the SHARED keyword.



On Fri, Jul 6, 2018 at 12:01 AM Quang Ha <[hidden email]> wrote:
Hi all,

Following upon how to perform code linking between CUDA and C++ (here at https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/), I have successfully come up with a Makefile that is currently working for my test case:

##################################Makefile#################################################
main_objects = main.o
host_objects = host.o
device_objects = device.o

all: $(main_objects) $(host_objects) $(device_objects)
        g++ -O3 -fopenmp $(main_objects) $(host_objects) $(device_objects) -L/usr/local/cuda/lib64 -lcudart -o main

$(main_objects): $(main_objects:.o=.cpp)
        g++ -O3 -I/usr/local/cuda/include -c $< -o $@

$(host_objects): $(host_objects:.o=.cpp)
        g++ -O3 -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP -fopenmp -c $< -o $@

$(device_objects): $(device_objects:.o=.cu)
        nvcc -O3 -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA -c $< -o $@

clean:
        rm -f *.o main
######################################################################################################

Now, I am trying to write a CMake for this, my current attempt is as followed:

##############################################CMakeLists.txt############################################
cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)

# check requirements
find_package(CUDA REQUIRED)
find_package(OpenMP)

if (CUDA_FOUND AND OPENMP_FOUND)
    # OpenMP
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")

    # CUDA
    include_directories(${CUDA_INCLUDE_DIRS})
    set(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
    set(LIBS ${LIBS} ${ALL_CUDA_LIBS})
    set(CUDA_SEPARABLE_COMPILATION OFF)
    set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--maxrregcount 32)

    set(OMP_SOURCES host.cpp)
    add_library(Host_OMP SHARED ${OMP_SOURCES})
    set_target_properties(Host_OMP PROPERTIES COMPILE_FLAGS "-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP")
    set(LIBS ${LIBS} ${Host_OMP})

    set(CUDA_SOURCES device.cu)
    cuda_add_library(Device_CUDA SHARED ${CUDA_SOURCES})
    set_target_properties(Device_CUDA PROPERTIES COMPILE_FLAGS "-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA")
    set_target_properties(Device_CUDA PROPERTIES CUDA_SEPERABLE_COMPILATION ON)
    set(LIBS ${LIBS} ${Device_CUDA})

    add_executable(main main.cpp)
    target_link_libraries(main ${LIBS})

endif(CUDA_FOUND AND OPENMP_FOUND)
######################################################################################################

It is still, unfortunately, not working. If I commented out the add_executable line, the object code for Host_OMP and Device_CUDA is compiled. I can then use the terminal and link them with main.cpp using gcc and generate the executable - i.e. using the final command in the Makefile above.

What am I doing wrong here? It seems to be very fundamental, but I can't seem to get it right...

Any suggestions would be greatly appreciated!!

Thanks,
Quang
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using CMake to link C++ and CUDA Object file

Quang Ha
Thanks for your response, Robert. If I don't use find_package(CUDA), I run into the following problem:

 fatal error: thrust/host_vector.h: No such file or directory

I guess this is needed if I am using Thrust/CUDA?

Thanks,
Quang

On Fri, 6 Jul 2018 at 06:38, Robert Maynard <[hidden email]> wrote:
if you are using the new first class cuda language, as seen by `project(MyTest LANGUAGES CXX CUDA)` you shouldn't use the old find cuda package or the associated cuda_add_library calls. When using the first class cuda language simply use add_library.

The other difference I notice is that you makefile example is not building shared libraries but object files, so to the same in CMake you need to use 'add_library' with the OBJECT keyword not the SHARED keyword.



On Fri, Jul 6, 2018 at 12:01 AM Quang Ha <[hidden email]> wrote:
Hi all,

Following upon how to perform code linking between CUDA and C++ (here at https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/), I have successfully come up with a Makefile that is currently working for my test case:

##################################Makefile#################################################
main_objects = main.o
host_objects = host.o
device_objects = device.o

all: $(main_objects) $(host_objects) $(device_objects)
        g++ -O3 -fopenmp $(main_objects) $(host_objects) $(device_objects) -L/usr/local/cuda/lib64 -lcudart -o main

$(main_objects): $(main_objects:.o=.cpp)
        g++ -O3 -I/usr/local/cuda/include -c $< -o $@

$(host_objects): $(host_objects:.o=.cpp)
        g++ -O3 -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP -fopenmp -c $< -o $@

$(device_objects): $(device_objects:.o=.cu)
        nvcc -O3 -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA -c $< -o $@

clean:
        rm -f *.o main
######################################################################################################

Now, I am trying to write a CMake for this, my current attempt is as followed:

##############################################CMakeLists.txt############################################
cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)

# check requirements
find_package(CUDA REQUIRED)
find_package(OpenMP)

if (CUDA_FOUND AND OPENMP_FOUND)
    # OpenMP
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")

    # CUDA
    include_directories(${CUDA_INCLUDE_DIRS})
    set(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
    set(LIBS ${LIBS} ${ALL_CUDA_LIBS})
    set(CUDA_SEPARABLE_COMPILATION OFF)
    set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--maxrregcount 32)

    set(OMP_SOURCES host.cpp)
    add_library(Host_OMP SHARED ${OMP_SOURCES})
    set_target_properties(Host_OMP PROPERTIES COMPILE_FLAGS "-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP")
    set(LIBS ${LIBS} ${Host_OMP})

    set(CUDA_SOURCES device.cu)
    cuda_add_library(Device_CUDA SHARED ${CUDA_SOURCES})
    set_target_properties(Device_CUDA PROPERTIES COMPILE_FLAGS "-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA")
    set_target_properties(Device_CUDA PROPERTIES CUDA_SEPERABLE_COMPILATION ON)
    set(LIBS ${LIBS} ${Device_CUDA})

    add_executable(main main.cpp)
    target_link_libraries(main ${LIBS})

endif(CUDA_FOUND AND OPENMP_FOUND)
######################################################################################################

It is still, unfortunately, not working. If I commented out the add_executable line, the object code for Host_OMP and Device_CUDA is compiled. I can then use the terminal and link them with main.cpp using gcc and generate the executable - i.e. using the final command in the Makefile above.

What am I doing wrong here? It seems to be very fundamental, but I can't seem to get it right...

Any suggestions would be greatly appreciated!!

Thanks,
Quang
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using CMake to link C++ and CUDA Object file

Robert Maynard
To be clear the FindCUDA module currently does two things it finds the location of the CUDA SDK and it also adds the 'cuda_' commands.

In your case you might still need to use FindCUDA to find the location of the thrust include directory, or you can find the location yourself by
using find_path like:

```
find_path(CUDA_TOOLKIT_INCLUDE
  device_functions.h # Header included in toolkit
  PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES}
  PATH_SUFFIXES include ../include
  NO_DEFAULT_PATH
  )
```


On Fri, Jul 6, 2018 at 11:30 AM Quang Ha <[hidden email]> wrote:
Thanks for your response, Robert. If I don't use find_package(CUDA), I run into the following problem:

 fatal error: thrust/host_vector.h: No such file or directory

I guess this is needed if I am using Thrust/CUDA?

Thanks,
Quang

On Fri, 6 Jul 2018 at 06:38, Robert Maynard <[hidden email]> wrote:
if you are using the new first class cuda language, as seen by `project(MyTest LANGUAGES CXX CUDA)` you shouldn't use the old find cuda package or the associated cuda_add_library calls. When using the first class cuda language simply use add_library.

The other difference I notice is that you makefile example is not building shared libraries but object files, so to the same in CMake you need to use 'add_library' with the OBJECT keyword not the SHARED keyword.



On Fri, Jul 6, 2018 at 12:01 AM Quang Ha <[hidden email]> wrote:
Hi all,

Following upon how to perform code linking between CUDA and C++ (here at https://devblogs.nvidia.com/separate-compilation-linking-cuda-device-code/), I have successfully come up with a Makefile that is currently working for my test case:

##################################Makefile#################################################
main_objects = main.o
host_objects = host.o
device_objects = device.o

all: $(main_objects) $(host_objects) $(device_objects)
        g++ -O3 -fopenmp $(main_objects) $(host_objects) $(device_objects) -L/usr/local/cuda/lib64 -lcudart -o main

$(main_objects): $(main_objects:.o=.cpp)
        g++ -O3 -I/usr/local/cuda/include -c $< -o $@

$(host_objects): $(host_objects:.o=.cpp)
        g++ -O3 -DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP -fopenmp -c $< -o $@

$(device_objects): $(device_objects:.o=.cu)
        nvcc -O3 -DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA -c $< -o $@

clean:
        rm -f *.o main
######################################################################################################

Now, I am trying to write a CMake for this, my current attempt is as followed:

##############################################CMakeLists.txt############################################
cmake_minimum_required(VERSION 3.8)
project(MyTest LANGUAGES CXX CUDA)

# check requirements
find_package(CUDA REQUIRED)
find_package(OpenMP)

if (CUDA_FOUND AND OPENMP_FOUND)
    # OpenMP
    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
    set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")

    # CUDA
    include_directories(${CUDA_INCLUDE_DIRS})
    set(ALL_CUDA_LIBS ${CUDA_LIBRARIES} ${CUDA_cusparse_LIBRARY} ${CUDA_cublas_LIBRARY})
    set(LIBS ${LIBS} ${ALL_CUDA_LIBS})
    set(CUDA_SEPARABLE_COMPILATION OFF)
    set(CUDA_NVCC_FLAGS ${CUDA_NVCC_FLAGS};--maxrregcount 32)

    set(OMP_SOURCES host.cpp)
    add_library(Host_OMP SHARED ${OMP_SOURCES})
    set_target_properties(Host_OMP PROPERTIES COMPILE_FLAGS "-DTHRUST_HOST_SYSTEM=THRUST_HOST_SYSTEM_OMP")
    set(LIBS ${LIBS} ${Host_OMP})

    set(CUDA_SOURCES device.cu)
    cuda_add_library(Device_CUDA SHARED ${CUDA_SOURCES})
    set_target_properties(Device_CUDA PROPERTIES COMPILE_FLAGS "-DTHRUST_DEVICE_SYSTEM=THRUST_DEVICE_SYSTEM_CUDA")
    set_target_properties(Device_CUDA PROPERTIES CUDA_SEPERABLE_COMPILATION ON)
    set(LIBS ${LIBS} ${Device_CUDA})

    add_executable(main main.cpp)
    target_link_libraries(main ${LIBS})

endif(CUDA_FOUND AND OPENMP_FOUND)
######################################################################################################

It is still, unfortunately, not working. If I commented out the add_executable line, the object code for Host_OMP and Device_CUDA is compiled. I can then use the terminal and link them with main.cpp using gcc and generate the executable - i.e. using the final command in the Makefile above.

What am I doing wrong here? It seems to be very fundamental, but I can't seem to get it right...

Any suggestions would be greatly appreciated!!

Thanks,
Quang
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake