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,它们没有改变任何东西)进行编译。删除对返回cublasCreate原因的调用(无错误)。cudaMalloc0

可能是什么原因?我该如何解决?我需要使用理论上支持的动态并行性从内核调用 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

此外,它依赖于顺序,但与 from :nvcc -dlink的使用方式相反,它必须出现需要它的目标文件之前。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 回答