2

次の最小限の.cuファイルがあります

#include <cuda_runtime_api.h>
#include <cublas_v2.h>
#include <cstdio>

__global__ void test()
{
    cublasHandle_t handle = nullptr;
    cublasCreate(&handle);
}

int main(int, char**)
{
    void * data = nullptr;
    auto err = cudaMalloc(&data, 256);
    printf("%s\n", cudaGetErrorString(err));
    return 0;
}

ご覧のとおり、testカーネルは呼び出されていませんが、(不明なエラー)がcudaMalloc返されます。30このファイルは、分離可能なコンパイル (動的並列処理に必要) と計算機能 5.2 (3.5 と 5.0 も試しましたが、何も変更されませんでした) でコンパイルされています。への呼び出しを削除するとcublasCreatecudaMalloc戻り0ます (エラーなし)。

原因は何ですか?どうすれば修正できますか?理論的にサポートされている動的並列処理を使用してカーネルから CUBLAS を呼び出す必要があるため、「呼び出しを削除するだけ」はオプションではありません。

対応するものは次のCMakeLists.txtとおりです。

cmake_minimum_required(VERSION 3.3 FATAL_ERROR)
project(CublasError)

find_package(CUDA REQUIRED)

set(CUDA_SEPARABLE_COMPILATION ON)
set(CUDA_NVCC_FLAGS --gpu-architecture=compute_52 -Xptxas=-v)
list(APPEND CUDA_NVCC_FLAGS_DEBUG -G -keep -O0)

cuda_add_executable(${PROJECT_NAME} main.cu)
cuda_add_cublas_to_target(${PROJECT_NAME})

# FindCUDA.cmake does not automatically add (or find) cudadevrt which is required when separable compilation is on
if(CUDA_SEPARABLE_COMPILATION)
    get_filename_component(CUDA_LIB_PATH ${CUDA_CUDART_LIBRARY} DIRECTORY)
    find_library(CUDA_cudadevrt_LIBRARY cudadevrt PATHS ${CUDA_LIB_PATH})
    target_link_libraries(${PROJECT_NAME} ${CUDA_cudadevrt_LIBRARY})
endif()

以下は、理論的に類似したコンパイル コマンドのセットです (結果は少なくとも同じです)。

nvcc -dc --gpu-architecture=compute_52 -m64 main.cu -o main.dc.obj
nvcc -dlink --gpu-architecture=compute_52 -m64 main.dc.obj -o main.obj
link /SUBSYSTEM:CONSOLE /LIBPATH:"%CUDA_PATH%\lib\x64" main.obj main.dc.obj cudart_static.lib cudadevrt.lib cublas.lib cublas_device.lib
4

1 に答える 1

1

nvcc -dlink不足している依存関係を報告せず、エラーを発生させることなく喜んで続行することがわかりました。この問題を解決するには、cublas_device.libホスト リンクデバイス リンクの両方でリンクする必要があります。つまり、コンパイル コマンドは次のようになります。

nvcc -dc --gpu-architecture=compute_52 -m64 main.cu -o main.dc.obj
nvcc -dlink --gpu-architecture=compute_52 -m64 -lcublas_device main.dc.obj -o main.obj
link /SUBSYSTEM:CONSOLE /LIBPATH:"%CUDA_PATH%\lib\x64" main.obj main.dc.obj cudart_static.lib cudadevrt.lib cublas.lib cublas_device.lib

また、nvcc -dlink順序に依存しますが、 from とは逆に、ldそれを必要とするオブジェクト ファイルの-lcublas_deviceに表示する必要があります。

CMake 側では、デバイス リンク コマンドへのcuda_add_cublas_to_target追加に失敗しcublas_device.lib、ホスト リンク コマンドに追加するだけです。回避策として、依存関係を nvcc フラグのリストに明示的に追加します。

list(APPEND CUDA_NVCC_FLAGS -lcublas_device)
于 2016-09-19T11:51:07.180 に答える