这是我在这里的第一篇文章 - 所以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
在我的时间机器上第一次乘坐的拥抱和门票,我们将非常高兴地获得任何帮助!提前谢谢!
答案 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。