【问题标题】:Linking cuda object file链接 cuda 目标文件
【发布时间】:2012-09-04 16:22:02
【问题描述】:

我有一个 .cu 文件,其中包含我的 cuda 内核,以及一个调用内核的包装函数。我也有一堆 .c 文件,其中一个包含主要功能。这些 .c 文件之一从 .cu 调用包装函数来调用内核。

我将这些文件编译如下:

LIBS=-lcuda -lcudart
LIBDIR=-L/usr/local/cuda/lib64
CFLAGS = -g -c -Wall -Iinclude -Ioflib
NVCCFLAGS =-g -c -Iinclude -Ioflib
CFLAGSEXE =-g -O2 -Wall -Iinclude -Ioflib

CC=gcc
NVCC=nvcc
objects := $(patsubst oflib/%.c,oflib/%.o,$(wildcard oflib/*.c))

table-hash-gpu.o: table-hash.cu table-hash.h
        $(NVCC) $(NVCCFLAGS) table-hash.cu -o table-hash-gpu.o

main: main.c $(objects) table-hash-gpu.o
    $(CC) $(CFLAGSEXE) $(objects) table-hash-gpu.o -o udatapath udatapath.c $(LIBS) $(LIBDIR)

到目前为止一切都很好。 table-hash-gpu.cu 从 .c 文件之一调用函数。链接 main 时,我收到该函数不存在的错误。谁能告诉我这是怎么回事?

【问题讨论】:

  • 哪个函数不存在???是内核不存在?

标签: object compilation cuda


【解决方案1】:

nvcc 使用主机 C++ 编译器编译设备和主机代码,这意味着 name mangling。如果需要在 C++ 中调用使用 C 编译器编译的函数,则必须告诉 C++ 编译器它使用 C 调用约定。我认为您看到的错误与此类似:

$ cat cfunc.c 

float adder(float a, float b, float c)
{
    return a + 2.f*b + 3.f*c;
}

$ cat cumain.cu 

#include <cstdio>
float adder(float, float, float);

int main(void)
{
    float result = adder(1.f, 2.f, 3.f);
    printf("%f\n", result);
    return 0;
}

$ gcc -m32 -c cfunc.c
$ nvcc -o app cumain.cu cfunc.o
Undefined symbols:
  "adder(float, float, float)", referenced from:
      _main in tmpxft_0000b928_00000000-13_cumain.o
ld: symbol(s) not found
collect2: ld returned 1 exit status

这里我们使用 nvcc(即宿主 C++ 编译器)编译的代码试图调用 C 函数并出现链接错误,因为 C++ 代码需要在提供的目标文件中为 adder 提供一个错误名称。如果 main 改成这样:

$ cat cumain.cu 

#include <cstdio>
extern "C" float adder(float, float, float);

int main(void)
{
    float result = adder(1.f, 2.f, 3.f);
    printf("%f\n", result);
    return 0;
}
$ nvcc -o app cumain.cu cfunc.o
$ ./app
14.000000

有效。使用extern "C" 来限定对C++ 编译器的函数声明,它在引用adder 时不会使用C++ 修改和链接规则,并且生成的代码链接正确。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 1970-01-01
    • 1970-01-01
    • 2012-08-30
    相关资源
    最近更新 更多