簡體   English   中英

CMake/CUDA 共享庫的可重定位代碼

[英]Relocatable Code for a CMake/CUDA shared library

我偶然發現了一些我以前從未遇到過的笨拙的編譯錯誤。 無法共享確切的代碼,所以我將呈現一個類似的情況。 我有一個正在開發的共享庫,它編譯__device__標記的設備代碼。 這些設備函數必須能夠被用戶編寫的__global__函數使用。 這是一組簡化的代碼,可重新創建引發的錯誤:

共享庫的源代碼: device_function.cu

__device__ int deviceFunction()
{
    return 1;
}

用於調用設備 function 的可執行文件的源代碼: soure.cu

#include <stdio.h>

__device__ int deviceFunction();

__global__ void globalFunction()
{
    printf("%i", deviceFunction());
}

int main()
{
    globalFunction<<<1,1>>>();
    cudaDeviceSynchronize();

    return 0;
}

我嘗試使用以下命令編譯所有內容的 CMakeLists.txt 文件:

cmake_minimum_required(VERSION 3.21)

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR})

project(test)

find_package(CUDA REQUIRED)
enable_language(CUDA)

add_library(device_function SHARED device_function.cu)

add_executable(cu_test source.cu)
target_link_libraries(cu_test device_function)

在(嘗試)編譯后,我收到了這樣的問候:

[main] Building folder: relocatable-code 
[build] Starting build
[proc] Executing command: /snap/cmake/current/bin/cmake --build /home/legayone/Documents/research-pathfinding-projects/cuda-programming/relocatable-code/build --config Debug --target all -j 18 --
[build] Consolidate compiler generated dependencies of target device_function
[build] [ 50%] Built target device_function
[build] Consolidate compiler generated dependencies of target cu_test
[build] [ 75%] Building CUDA object CMakeFiles/cu_test.dir/source.cu.o
[build] ptxas fatal   : Unresolved extern function '_Z14deviceFunctionv'
[build] make[2]: *** [CMakeFiles/cu_test.dir/build.make:76: CMakeFiles/cu_test.dir/source.cu.o] Error 255
[build] make[1]: *** [CMakeFiles/Makefile2:111: CMakeFiles/cu_test.dir/all] Error 2
[build] make: *** [Makefile:91: all] Error 2
[build] Build finished with exit code 2

我試過的我已經搜索了 web 並找到了最終歸結為CUDA_SEPARABLE_COMPILATION ON或某種形式的解決方案-rdc=true-dc 我嘗試在device_functioncu_test的 3 種可能組合中添加可分離編譯,並且我對-rdc=true-dc做了同樣的事情,我先試了一個,然后試了另一個,然后兩個都試了。 這是我將-rdc=true-dc添加到以下內容的格式:

target_compile_options(cu_test PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-c "-lcudart -lcudadevrt -lcuda -rdc=true">)

〜或〜

target_compile_options(device_function PRIVATE $<$<COMPILE_LANGUAGE:CUDA>:-c "-lcudart -lcudadevrt -lcuda -rdc=true">)

我的問題我錯過了什么或我做錯了什么? 我真的希望任何可執行文件都能夠將共享庫device_function鏈接到它,並讓它能夠在該共享庫中調用 function。 在這適用的實際庫中,當然有標題,但我已經整理了包含:) 它只是鏈接。

我懷疑問題是我懷疑問題是代碼可重定位性。 我知道必須做一些特殊的事情才能允許來自不同編譯單元的設備功能被可執行文件(或另一個庫)使用? 但那些東西是什么,我如何在 CMake 中做到這一點?

一種解決方案

因此,似乎不可能__global__函數從單獨的編譯單元調用基於共享庫的__device__函數。 我應該注意到,有大量相互矛盾的信息,特別是來自這篇文章: https://developer.nvidia.com/blog/building-cuda-applications-cmake/ ,這似乎表明這是可能的,但是它提出的解決方案不起作用。 這對我有用:

CMakeLists.txt

cmake_minimum_required(VERSION 3.21)

set(CMAKE_CUDA_SEPARABLE_COMPILATION ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

project(test LANGUAGES CXX CUDA)

include(CTest)

add_library(device_function STATIC device_function.cu)
add_library(shared_function SHARED shared_device_function.cu)
target_link_libraries(shared_function PUBLIC device_function)

add_executable(cu_test source.cu)
target_link_libraries(cu_test shared_function)

什么有效

  • 鏈接有效,編譯也有效
  • device_function.cu 中的設備function可以從可執行源source.cu中的全局 function 調用

什么不起作用

  • 包含設備 function 的實際文件必須是 static 庫,但它可以鏈接到共享庫,允許用戶通過單個鏈接到整個共享庫來使用整個庫
  • 這個 static 庫方法顯然比共享庫方法慢

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM