【问题标题】:Problems with creating a CUDA shared library and libpthread创建 CUDA 共享库和 libpthread 的问题
【发布时间】:2012-08-09 14:22:43
【问题描述】:

我目前正在尝试使用 CUDA 例程创建一个库,但遇到了麻烦。我将使用一个相当简单的示例来解释我的问题,我的实际库会更大。

我已经成功编写了test.cu,一个包含__global__ 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

(错误消息是通过我自己的调试功能创建的)

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

我在 ArchLinux 上使用带有 gcc 4.6.3 和 nvidia 驱动程序版本 302.06.03 的 CUDA 5(是的,我确实意识到它是一个测试版)。

对于解决这个问题的一些帮助将不胜感激!

【问题讨论】:

  • 您确定这不仅仅是线程关联问题吗?无论哪个线程在设备上创建/持有上下文,都是唯一可以使用该设备的线程。如果希望多个线程使用上下文,则需要使用上下文迁移 API。
  • 因为我没有分叉或任何东西,如果我没有大错特错的话,应该只有一个线程。
  • 很抱歉问了这么明显的问题,但是您有支持 CUDA 的设备吗?您是否检查过其他 CUDA 代码是否可以在相同的工具包/驱动程序中正常工作?
  • @Tom:不用担心 :-) 是的,我确实有一个支持 CUDA 的设备。其他 CUDA 代码完美运行。我还测试了将我的测试代码与 main 函数一起编译成一个可执行文件,它也可以正常工作。

标签: gcc linker cuda pthreads ld


【解决方案1】:

这是一个简单的例子......

// 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());
}

编译/链接nvcc -m64 -arch=sm_20 -o libtest.so --shared -Xcompiler -fPIC test.cu

// File: main.c
#include <stdio.h>

void entry(void);

int main(void)
{
    entry();
}

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

【讨论】:

  • 我试过了,但它不起作用。标准输出上没有打印任何内容。我还扩充了entry() 函数以打印cudaDeviceSynchronize() 的返回值,这与我自己的示例(38)相同,这意味着找不到支持CUDA 的设备。
  • 顺便说一句,我的示例假设您有 Fermi 设备或更新的设备 - 旧设备不支持设备 printf。如果您的设备是 Fermi 或 Kepler,那么如果其他 CUDA 代码有效,那么没有理由不这样做。您使用的是不受支持的发行版/GCC,因此库或链接步骤可能有些奇怪,但不确定是什么。你可以试试旧的 GCC 或不同的发行版吗?
  • 我有一个费米设备(GeForce 560 Ti,GF114)。使用另一个发行版进行测试会有点困难,但我现在将安装 gcc 4.5 并再次测试。
  • 我发现了我的错误,这实际上非常愚蠢:我同时安装了 gcc 4.7 和 4.6,并创建了一个从 /opt/cuda/bin/gcc/usr/bin/gcc-4.6 的符号链接,因此 nvcc 使用 gcc 4.6.但我错过的是:nvcc 不仅使用了gcc,还使用了g++,我没有为此创建这样的符号链接。通常,如果您使用 gcc 4.7 并尝试使用 nvcc 编译 CUDA 代码,您会收到一条错误消息,告诉您编译器不兼容,但显然 nvcc 只检查 gcc 的兼容性,而不检查 g++.. . 上面的代码现在适用于 gcc 4.5 和 4.6
  • 非常感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-06
  • 2015-08-18
  • 2014-08-14
  • 2016-01-02
  • 2011-11-07
  • 1970-01-01
  • 2012-01-14
相关资源
最近更新 更多