Gcc 创建CUDA共享库和libpthread时出现问题

Gcc 创建CUDA共享库和libpthread时出现问题,gcc,linker,cuda,pthreads,ld,Gcc,Linker,Cuda,Pthreads,Ld,我目前正试图用CUDA例程创建一个库,但我遇到了麻烦。我将用一个非常简单的例子来解释我的问题,我的实际库将更大 我已经成功地编写了test.cu,这是一个源文件,其中包含\uuuuuu global\uuuuCUDA函数及其包装(用于分配和复制内存)。我还可以使用以下命令将此文件成功编译到共享库中: nvcc -c test.cu -o test.o -lpthread -lrt -lcuda -lcudart -Xcompiler -fPIC gcc -m64 -shared -fPIC -o

我目前正试图用CUDA例程创建一个库,但我遇到了麻烦。我将用一个非常简单的例子来解释我的问题,我的实际库将更大

我已经成功地编写了
test.cu
,这是一个源文件,其中包含
\uuuuuu global\uuuu
CUDA函数及其包装(用于分配和复制内存)。我还可以使用以下命令将此文件成功编译到共享库中:

nvcc -c test.cu -o test.o -lpthread -lrt -lcuda -lcudart -Xcompiler -fPIC
gcc -m64 -shared -fPIC -o libtest.so test.o -lpthread -lrt -lcuda -lcudart -L/opt/cuda/lib64
结果是
libtest.so
导出我需要的所有符号

我现在编译我的纯C
main.C
,并将其链接到我的库:

gcc -std=c99 main.c -o main -lpthread -ltest -L.
此步骤也成功,但在执行
/main
所有被调用的CUDA函数时,返回一个错误:

test.cu:17:cError(): cudaGetDeviceCount: [38] no CUDA-capable device is detected
test.cu:17:cError(): cudaMalloc: [38] no CUDA-capable device is detected
test.cu:17:cError(): cudaMemcpy: [38] no CUDA-capable device is detected
test.cu:17:cError(): cudaMemcpy: [38] no CUDA-capable device is detected
test.cu:17:cError(): cudaFree: [38] no CUDA-capable device is detected
(错误消息是通过我自己的调试功能创建的)

在最初的步骤中,我遇到了完全相同的问题,因为我忘记了链接libpthread(
-lpthread
),所以直接从
test.cu
创建一个可执行文件。但是,正如您在上面看到的,我已经针对libpthread链接了所有源文件。根据
ldd
,libtest.so和
main
都应该依赖libpthread

我在ArchLinux上使用带有GCC4.6.3和nvidia驱动程序版本302.06.03的CUDA 5(是的,我知道它是测试版)


如果您能帮我解决这个问题,我们将不胜感激

这里有一个简单的例子

// File: test.cu
#include <stdio.h>

__global__ void myk(void)
{
    printf("Hello from thread %d block %d\n", threadIdx.x, blockIdx.x);
}

extern "C"
void entry(void)
{
    myk<<<1,1>>>();
    printf("CUDA status: %d\n", cudaDeviceSynchronize());
}

编译/链接gcc-std=c99-o main-L-ltest main.c

// File: test.cu
#include <stdio.h>

__global__ void myk(void)
{
    printf("Hello from thread %d block %d\n", threadIdx.x, blockIdx.x);
}

extern "C"
void entry(void)
{
    myk<<<1,1>>>();
    printf("CUDA status: %d\n", cudaDeviceSynchronize());
}

编译/链接到
gcc-std=c99-o main-L-ltest main.c

您确定这不仅仅是一个线程关联问题吗?无论哪个线程在设备上创建/保存上下文,都是唯一可以使用该设备的线程。如果您想让多个线程使用上下文,则需要使用上下文迁移API。因为我没有分叉或任何东西,如果我没有大错特错的话,应该只有一个线程。很抱歉问一个显而易见的问题,但是您有支持CUDA的设备吗?你有没有检查过其他CUDA代码在同一个工具包/驱动程序下是否正常工作?@Tom:不用担心:-)是的,我有一个支持CUDA的设备。其他CUDA代码工作正常。我还测试了如何将测试代码与主函数一起编译成一个可执行文件,这也可以正常工作。你确定这不仅仅是一个线程亲和性问题吗?无论哪个线程在设备上创建/保存上下文,都是唯一可以使用该设备的线程。如果您想让多个线程使用上下文,则需要使用上下文迁移API。因为我没有分叉或任何东西,如果我没有大错特错的话,应该只有一个线程。很抱歉问一个显而易见的问题,但是您有支持CUDA的设备吗?你有没有检查过其他CUDA代码在同一个工具包/驱动程序下是否正常工作?@Tom:不用担心:-)是的,我有一个支持CUDA的设备。其他CUDA代码工作正常。我还测试了将我的测试代码与主函数一起编译成一个可执行文件,这也很好,我试过了,但没有成功。标度上没有打印任何内容。我还扩展了
entry()
函数来打印
cudaDeviceSynchronize()
的返回值,这与我自己的示例(38)中的相同,这意味着找不到支持CUDA的设备。顺便说一句,我的示例假设您有一个Fermi设备或更新的设备-旧设备不支持设备printf。如果您的设备是费米或开普勒,那么如果其他CUDA代码工作,那么没有理由不这样做。您使用的是一个不受支持的发行版/GCC,所以libs或链接步骤可能有些奇怪,但不确定是什么。你能试试旧的GCC或其他发行版吗?我有一个费米设备(GeForce 560 Ti,GF114)。使用另一个发行版进行测试有点困难,但我现在将安装GCC4.5并再次测试。我发现了我的错误,这实际上是非常愚蠢的:我并行安装了GCC4.7和4.6,并创建了一个从
/opt/cuda/bin/gcc
/usr/bin/gcc-4.6
的符号链接,因此,
nvcc
使用GCC4.6。但我错过的是:
nvcc
不仅使用了
gcc
,而且还使用了
g++
,我还没有为其创建这样的符号链接。通常,如果您使用gcc 4.7并尝试使用
nvcc
编译CUDA代码,您会收到一条错误消息,告诉您不兼容的编译器,但显然
nvcc
只检查
gcc
的兼容性,而不检查
g++
。。。以上代码现在可以与GCC4.5和4.6一起使用,非常感谢您的帮助!我试过了,但没用。标度上没有打印任何内容。我还扩展了
entry()
函数来打印
cudaDeviceSynchronize()
的返回值,这与我自己的示例(38)中的相同,这意味着找不到支持CUDA的设备。顺便说一句,我的示例假设您有一个Fermi设备或更新的设备-旧设备不支持设备printf。如果您的设备是费米或开普勒,那么如果其他CUDA代码工作,那么没有理由不这样做。您使用的是一个不受支持的发行版/GCC,所以libs或链接步骤可能有些奇怪,但不确定是什么。你能试试旧的GCC或其他发行版吗?我有一个费米设备(GeForce 560 Ti,GF114)。使用另一个发行版进行测试有点困难,但我现在将安装GCC4.5并再次测试。我发现了我的错误,这实际上是非常愚蠢的:我并行安装了GCC4.7和4.6,并创建了一个从
/opt/cuda/bin/gcc
/usr/bin/gcc-4.6
的符号链接,因此,
nvcc
使用GCC4.6。但我错过的是:
nvcc
不仅使用了
gcc
,而且还使用了
g++
,我还没有为其创建这样的符号链接。通常,如果您使用GCC4.7并尝试使用
nvcc
编译CUDA代码,您会收到一条错误消息,告诉您