函数定义在 .cu 中声明的 .h 中

function define in .h declared in .cu

本文关键字:声明 cu 定义 函数      更新时间:2023-10-16

我把一个项目分成了三个文件夹:src,include,obj 我正在使用 CImg.h 和 cuda.h 库。 我在卷积中声明void convolve(cimg_library::CImg<float>&, cimg_library::CImg<float> const &);。 并在 convolve.cu 中定义它

我的文件 :

主要.cpp :

#include "CImg.h"
#include "../include/convolve.h" 
using namespace cimg_library;
int main(){
CImg<float> var1("/*path*/");
CImg<float> var2("/*path2*/");
convolve(var1,var2);
//some code
}

卷积:

1 #ifndef CONVOLVE_H
2 #define CONVOLVE_H
//some define
10 void convolve(cimg_library::CImg<float>&, cimg_library::CImg<float> const &);
11 #endif //CONVOLVE_H

convolve.cu :

1 void convolve(CImg<float>& img, const CImg<float>& kernel){
//some code
24     kernel<<<dimGrid,dimBlocks>>>(/*some arg*/);
}

和我的新制作文件:

1 CC=nvcc
2 CX=g++
3 IDIR =../include
4 special_IDIR = /usr/local/cuda-9.0/include
5 LDIR = /usr/local/cuda-9.0/lib64
6 CFLAGS=-I$(special_IDIR) -L$(LDIR)
7 
8 LIBS = -lX11 -lpthread -lcudart
9 ODIR = ../obj
10 
11 
12 _DEPS = convolve.h kernel.cuh
13 DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
14 
15 _OBJ = main.o convolve.o kernel.o
16 OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
17 
18 $(ODIR)/%.o: %.cpp $(DEPS)
19         $(CX) -x c++ -o $@ $< $(CFLAGS) $(LIBS)
20 
21 $(ODIR)/%.o: %.cu $(DEPS)
22         $(CC) -cu -o $@ $< $(CFLAGS)
23 
24 all: $(OBJ)
25         $(CC) -o $@ $^ $(CFLAGS) 
26 
27 
28 .PHONY: clean
29 
30 clean:
31         rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~ 

这是我的问题:它说对void convolve(cimg_library::CImg<float>&, cimg_library::CImg<float> const &)的引用是未定义的。

我认为这是因为我从来没有向编译器明确说过卷积的定义是 convolve.cu 的。但是我没有找到如何正确建立此链接。

感谢您的帮助!

  1. 请不要发布带有行号的代码(或Makefile内容)。 通常,它只是碍事。
  2. 这里的编译过程遵循编译...链接过程。 第一阶段是编译阶段,在此阶段,您应该对g++nvcc都使用-c(即对于两种类型的 Makefile 目标)
  3. nvcc没有-cu选择。 我想也许你的意思是-x cu

我还删除了函数调用上的与号。

这是一个基于您展示内容的简化示例,主要删除CImg内容和其他一些不必要的项目:

$ cat main.cpp
#include "convolve.h"
int main(){
int var1 = 0;
int var2 = 1;
convolve(var1, var2);
}
$ cat convolve.h
void convolve(int &, int &);
$ cat convolve.cu
#include "convolve.h"
__global__ void kernel(){};
void convolve(int & i1, int & i2){
kernel<<<1,1>>>();
}
$ cat Makefile
CC=nvcc
CX=g++
IDIR = .
special_IDIR = /usr/local/cuda-9.1/include
LDIR = /usr/local/cuda-9.1/lib64
CFLAGS=-I$(special_IDIR) -L$(LDIR)
LIBS =
ODIR = .
_DEPS = convolve.h
DEPS = $(patsubst %,$(IDIR)/%,$(_DEPS))
_OBJ = main.o convolve.o
OBJ = $(patsubst %,$(ODIR)/%,$(_OBJ))
$(ODIR)/%.o: %.cu $(DEPS)
$(CC) -c -x cu -o $@ $< $(CFLAGS)
$(ODIR)/%.o: %.cpp $(DEPS)
$(CX) -c -x c++ -o $@ $< $(CFLAGS) $(LIBS)
all: $(OBJ)
$(CC) -o $@ $^ $(CFLAGS)
.PHONY: clean
clean:
rm -f $(ODIR)/*.o *~ core $(INCDIR)/*~
$ make clean
rm -f ./*.o *~ core /*~
$ make
g++ -c -x c++ -o main.o main.cpp -I/usr/local/cuda-9.1/include -L/usr/local/cuda-9.1/lib64
nvcc -c -x cu -o convolve.o convolve.cu -I/usr/local/cuda-9.1/include -L/usr/local/cuda-9.1/lib64
nvcc -o all main.o convolve.o -I/usr/local/cuda-9.1/include -L/usr/local/cuda-9.1/lib64
$

如果您的设置中有 CUDA 9.0,请将上述 Makefile 中的cuda-9.1实例更改为cuda-9.0。 然而,编译命令并不真正需要链接器库(-L)。 当我们像我们在这里所做的那样与nvcc链接时,也没有必要传递引用 CUDA 包含和作为工具包一部分的 CUDA 库的-I-L开关。nvcc已经知道如何找到这些。

Makefile可能还有许多额外的建议或调整,例如-x cu-x c++开关可能是不必要的(至少对于我的简化示例来说是不必要的),但我的目标不是创建完美的Makefile,而是给你一个路线图,以解决你当前目睹的问题。