我的简单CUDA包装器和Makefile不起作用

时间:2014-02-20 20:06:49

标签: c cuda makefile openmp nvcc

这是我在这里的第一篇文章 - 所以pelase对我很耐心。我目前正在试图弄清楚如何编译一个包含普通* .c文件的简单项目,为简单起见,一个* .cu文件。显然我想使用 nvcc 来做到这一点我有两个“libs”应该基本上做同样的但是一个依赖于OMP而另一个依赖于CUDA。但经过大约一天浏览网页并爬过stackoverflow后,我完全陷入困境。这是我得到的:

我的来源/ main.c:

#include <math.h>
#include <stdlib.h>
#include <stdio.h>

#include "../include/mylib_omp.h"
#include "../include/mylib_cuda.h"

int main(){

    myfunc_CUDA(3.0,4);

    return 0;
}

我的include / mylib_omp.h:

#ifndef __MYLIB_OMP_H__
#define __MYLIB_OMP_H__

#include <omp.h>

void myfunc_OMP(float, int);

#endif

我的include / mylib_cuda.h:

#ifndef __MYLIB_CUDA_H__
#define __MYLIB_CUDA_H__

#include <cuda_runtime_api.h>
#include <cuda.h>

void myfunc_CUDA(float, int);

#endif

我的来源/ mylib_omp.c:

#ifndef __MYLIB_OMP_C__
#define __MYLIB_OMP_C__

#include "../include/mylib_omp.h"

void myfunc_OMP(float, int){
    int i;

    #pragma omp parallel
    {
        #pragma omp for
        for (i = 0; i < 1000; i++){
            int k = 0;
        }
    }
}

#endif

我的来源/ mylib_cuda.cu

#ifndef __MYLIB_CUDA_CU__
#define __MYLIB_CUDA_CU__

extern "C"{
#include "../include/mylib_cuda.h"
}

extern "C"
void myfunc_CUDA(float a, int b){
    float* i;
    cudaMalloc((void **) &i,5*sizeof(float));
}

#endif

最后是我的Makefile:

CC = nvcc
OUT = main

INCL_DIR = -I include
SOUR_DIR = sources

SOURCES =   ${SOUR_DIR}/main.c \
        ${SOUR_DIR}/mylib_omp.c \

CUDA_SOURCES =  ${SOUR_DIR}/mylib_cuda.cu 

H_FILES =   ${wildcard ${INCL_DIR}/*.h}

OBJECTS = ${SOURCES:.c=.o}
NVOBJECTS = ${CUDA_SOURCES:.cu=.o}

CFLAGS = -O3

NVCCFLAGS = -arch=sm_12 -ccbin=g++-4.4 -Xcompiler -openmp -x c++

LFLAGS = -lm -lcuda

INCLUDES = -I/opt/cuda/include
LIBS = -L/opt/cuda/lib64

${OUT}: ${OBJECTS} ${NVOBJECTS}
    $(CC) $(INCL_DIR) $(INCLUDES) $(LIBS) $(CFLAGS) $(LFLAGS) -o $@ $^ 

$(SOUR_DIR)/%.o : $(SOUR_DIR)/%.cu $(H_FILES)
    $(CC) $(NVCCFLAGS) $(INCL_DIR) $(INCLUDES) $(LIBS) -c -o $@ $<

$(SOUR_DIR)/%.o : $(SOUR_DIR)/%.c
    $(CC) $(NVCCFLAGS) $(INCL_DIR) $(INCLUDES) $(LIBS) -c -o $@ $<



clean :
    rm -f ${OBJECTS} ${NVOBJECTS} $(OUT)

很抱歉有很多文件,但这基本上就像它一样短。我昨天才知道如何处理makefile,因为我从未真正试图用任何语言开展更大的项目。所以现在问题。当我跑步时,会发生以下情况:

[seb@seb-desktop make_cuda]$ make clean
rm -f sources/main.o sources/mylib_omp.o sources/mylib_cuda.o main
[seb@seb-desktop make_cuda]$ make
nvcc -arch=sm_12 -ccbin=g++-4.4 -Xcompiler -openmp -x c++ -I include -I/opt/cuda/include -L/opt/cuda/lib64 -c -o sources/main.o sources/main.c
nvcc -arch=sm_12 -ccbin=g++-4.4 -Xcompiler -openmp -x c++ -I include -I/opt/cuda/include -L/opt/cuda/lib64 -c -o sources/mylib_omp.o sources/mylib_omp.c
nvcc -arch=sm_12 -ccbin=g++-4.4 -Xcompiler -openmp -x c++ -I include -I/opt/cuda/include -L/opt/cuda/lib64 -c -o sources/mylib_cuda.o sources/mylib_cuda.cu
nvcc -I include -I/opt/cuda/include -L/opt/cuda/lib64 -O3 -lm -lcuda -o main sources/main.o sources/mylib_omp.o sources/mylib_cuda.o 
sources/main.o: In function `main':
main.c:(.text+0x12): undefined reference to `myfunc_CUDA(float, int)'
collect2: Fehler: ld gab 1 als Ende-Status zurück
Makefile:27: recipe for target 'main' failed
make: *** [main] Error 1

在我的时间机器上第一次乘坐的拥抱和门票,我们将非常高兴地获得任何帮助!提前谢谢!

1 个答案:

答案 0 :(得分:1)

您的main.c文件需要一个c ++可链接入口点myfunc_CUDA,但您的mylib_cuda.cu文件正在导出一个可链接的入口点到该函数。

通过修改main.c中的包含序列以匹配您在其他地方所做的事情,我能够纠正您描述的问题:

#include "../include/mylib_omp.h"
extern "C"{
#include "../include/mylib_cuda.h"
}

然而,实现这一目标的方法不止一种。由于您明确指定nvcc将有问题的文件编译为c ++源代码(-x c++),因此我不确定是否需要将任何内容导出为c-linkable。您应该能够丢弃所有extern "C"装饰品并获得相同的结果。 C ++链接将解决所有问题。

顺便说一句,我不确定在编译-x c++文件时将nvcc切换传递给.cu是否有意义。我认为这是有效的,因为您的mylib_cuda.cu文件中没有实际的设备代码,只是一个CUDA API调用(即使在C ++文件中也是合法的)。如果您实际将设备代码放在该文件中(例如内核函数),我认为您将无法使用该文件上的-x c++开关。您可以参考nvcc documentation