一个 cuda shared library 的通用Makefile

发布于:2024-04-23 ⋅ 阅读:(153) ⋅ 点赞:(0)

0. 文件结构

device 模版函数放在 library/dev/include/*.cuh

模版的实例化和调用封装在 library/dev/*.cu

针对主机代码调用dev 函数而提供的头文件放在 library/dev/*.h, 也就是*.cu中主机函数的声明;

业务逻辑放置在 lib/src/*.cpp中,调用library/dev/*.cu中的函数实现加速,并dafault visible 出去,供第三方调用(#define API_ __attribute__((visibility("default"))));

一个 cuda shared library 的通用Makefile

1,源码

library/Makefile

TARGET := libicarithmetic.so

DEBUG_FLAGS := -O3
#DEBUG_FLAGS := -g -gz -ggdb
HEADER_FLAGS := -MD -MF $*.d -MP 

all: $(TARGET)

include make.src.list

OBJ_CPP := $(SRC_CPP:.cpp=.cpp.o)
DEP_CPP := $(SRC_CPP:.cpp=.cpp.d)

OBJ_CU  := $(SRC_CU:.cu=.cu.o) 
DEP_CU  := $(SRC_CU:.cu=.cu.d)

CPP_FLAGS := $(DEBUG_FLAGS) -fPIC -fvisibility=hidden -fvisibility-inlines-hidden -Wno-unused-result -Werror=vla
INC_CPP   := -I./include/internal
LD_FLAGS  := -L/usr/local/cuda/lib64 -lcudart -lcudadevrt

# -Werror=vla -fvisibility=hidden -fvisibility-inlines-hidden  -Wno-unused-result
CU_FLAGS := -Xcompiler -fPIC 
INC_CU   :=
GPU_ARCH ?= -gencode arch=compute_60,code=sm_60 -gencode arch=compute_70,code=sm_70 -gencode arch=compute_75,code=sm_75 -gencode arch=compute_80,code=sm_80 -gencode arch=compute_80,code=compute_80

#-arch=sm_70
#CPP compiler
CXX := g++
#device code compiler
DXX := nvcc

-include $(DEP_CPP)
-include $(DEP_CU)

%.cpp.o: %.cpp
	$(CXX) $(CPP_FLAGS) $(INC_CPP) $< -c -o $@ -MMD -MF $*.cpp.d -MP 

#-MMD --generate-nonsystem-dependencies-with-compile 
#-MF --dependency-output
#-MP --generate-dependency-targets  
%.cu.o: %.cu
	$(DXX) $(GPU_ARCH) $(CU_FLAGS) $(INC_CU) $< -c -o $@ -MMD -MF $*.cu.d -MP
	
#--generate-nonsystem-dependencies-with-compile --dependency-output $*.cu.d --generate-dependency-targets

# -MD -MF $*.cu.d -MP

dev/icSvectorAdd_link.cu.o: dev/icSvectorAdd.cu.o
	nvcc -Xcompiler -fPIC $(GPU_ARCH) -dlink -o $@ $< $(LD_FLAGS)

$(TARGET): $(OBJ_CPP) $(OBJ_CU) dev/icSvectorAdd_link.cu.o
	$(CXX) -shared $^ -o $@


.PHONY: clean
clean:
	rm -rf $(OBJ_CPP) $(OBJ_CU) $(TARGET) $(DEP_CPP) $(DEP_CU) dev/icSvectorAdd_link.cu.o

#$(SRC_C:.c=.d)

2,用法

同一份shared lib 支持多种架构的编译方式:

make

#or

make GPU_ARCH="-gencode arch=compute_60,code=sm_60 -gencode arch=compute_70,code=sm_70"

3,扩展

上述Makefile可以为同一份cuda 代码分别生成不同的架构的二进制文件,但是如果想为每个架构使用不同的cuda代码,这个Makefile就做不到了。

这时需要使用 nvcc编译器内置的宏:

__CUDA_ARCH__

比如,为 sm_70写的代码
 

#if __CUDA_ARCH__ == 700

x = x+y;

#endif

参考:CUDA_Compiler_Driver_NVCC

某种意义上类似于做了如下分开的编译:

nvcc  -cubin   -arch=sm_70  -D__CUDA_ARCH__=700   icSvectorAdd.cu   -o   icSvectorAdd.sm70.cubin