消えたCUDA関連の旧ブログ記事を復元するひとり Advent Calendar 2024の記事です。

最近CUDAのテンプレートを整備し直していたのでその備忘録を.

やりたいこと

コンパイル時間が長引くのが嫌なので分割コンパイル.
オブジェクトファイルがソースコードと同じディレクトリにできるのは嫌なのでobjディレクトリに出力.
  1. cppやcuを別々にobj/~.oにコンパイルする
  2. obj/~.oをまとめる
.SUFFIXES: .o .cpp .cu
.cu.o:
    $(NVCC) ...
.cpp.o:
    $(CXX) ...
このような書き方ではオブジェクトファイルはできるもののobjディレクトリに作る事はできませんでした...

どう書いたか

nvccコマンドには--cudaというオプションがあり,cuコードをcppコードに変換する. これを使えば
  1. nvcc --cudaでcuをcppに変換する
  2. g++等でcppをobj/~.oにコンパイル
のようにしてやりたかったことができた.

普段使っているMakefile

CXX=g++
CXXFLAGS=-std=c++11
NVCC=nvcc
NVCCFLAGS= -arch=sm_61 -lcurand -lcublas $(CXXFLAGS) --compiler-bindir=$(CXX)
SRCDIR=src
SRCS=$(shell find $(SRCDIR) -name '*.cu' -o -name '*.cpp')
OBJDIR=objs
OBJS=$(subst $(SRCDIR),$(OBJDIR), $(SRCS))
OBJS:=$(subst .cpp,.o,$(OBJS))
OBJS:=$(subst .cu,.o,$(OBJS))
TARGET=hoge

$(TARGET): $(OBJS)
	$(NVCC) $(NVCCFLAGS) $+ -o $@

$(SRCDIR)/%.cpp: $(SRCDIR)/%.cu
	$(NVCC) $(NVCCFLAGS) --cuda $< -o $@

$(OBJDIR)/%.o: $(SRCDIR)/%.cpp
	[ -d $(OBJDIR) ] || mkdir $(OBJDIR)
	$(CXX) $(CXXFLAGS) $< -c -o $@

clean:
	rm -rf $(OBJS)
	rm -rf $(TARGET)
これを使うとSRCDIRディレクトリ内のcpp,cuファイルをobjファイル(OBJDIR下に作られる)にし,TARGETという名の実行ファイルが作られる.