2017-07-06 30 views
1

我试图链接CUDA项目中的对象文件。下面是我的makefile:CUDA 8.0 nvcc fatal:指定ouputtfile时非链接阶段所需的单个输入文件

CUDA_PATH := /usr/local/cuda 
NVCC := $(CUDA_PATH)/bin/nvcc 

NVCCFLAGS := -arch=sm_37 --device-c -std=c++11 -cudart=shared -rdc=true 

LIBS := -lcutil -lcudpp -lcuda -lcudart -lcurand 

LIBPATH := $(CUDA_PATH)/lib64 
SOLIBS := $(LIBPATH)/*.so 

OBJS := main.o mtx.o mpamp_for_loop_funs.o cuBLAS_funs.o sparsify_threshold.o 

######################################################################## 

# link 
all: $(OBJs) 
    $(NVCC) $(NVCCFLAGS) $(OBJS) $(SOLIBS) $(LIBS) -o mpamp 
#--output-file mpamp.o 

######################################################################## 

# compile individually 
main.o: main.cu header.h 
    $(NVCC) $(NVCCFLAGS) -c main.cu 

mtx.o: mtx.cu header.h 
    $(NVCC) $(NVCCFLAGS) -c mtx.cu 

mpamp_for_loop_funs.o: mpamp_for_loop_funs.cu header.h 
    $(NVCC) $(NVCCFLAGS) -c mpamp_for_loop_funs.cu 

cuBLAS_funs.o: cuBLAS_funs.cu header.h 
    $(NVCC) $(NVCCFLAGS) -c cuBLAS_funs.cu 

sparsify_threshold.o: sparsify_threshold.cu header.h 
    $(NVCC) $(NVCCFLAGS) -c sparsify_threshold.cu 

######################################################################## 

run: build 
    $(EXEC) ./mpamp 

clean: 
    \rm *.o *~ mpamp 

######################################################################## 

我曾试图消除$(SOLIBS),它将返回相同的错误:

ece$ make all 
/usr/local/cuda/bin/nvcc -arch=sm_37 --device-c -std=c++11 -cudart=shared -rdc=true main.o mtx.o mpamp_for_loop_funs.o cuBLAS_funs.o sparsify_threshold.o /usr/local/cuda/lib64/*.so -lcutil -lcudpp -lcuda -lcudart -lcurand -o mpamp 
nvcc fatal : A single input file is required for a non-link phase when an outputfile is specified 
make: *** [all] Error 1 

此外,当我删除-o mpamp,该make all命令工作,但不产生输出文件然后执行。

有没有人有任何提示过去这个错误?

我最近从Windows中的Visual Studio移到了Linux机器上。 VS做了编译和链接 '自动'(我加斜杠和换行符):

nvcc -dlink -o x64\Debug\MPAMP.device-link.obj -Xcompiler "/EHsc /W3 /nologo /Od /Zi /RTC1 /MTd " \ 
-L"\lib\x64" cublas.lib cublas_device.lib cudadevrt.lib curand.lib 
cudart.lib cudart_static.lib \ 
kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib \ 
odbc32.lib odbccp32.lib -gencode=arch=compute_35,code=sm_35 -G \ 
--machine 64 x64\Debug\cuBLAS_funs.cu.obj x64\Debug\inner_loop.cu.obj x64\Debug\main.cu.obj \ 
x64\Debug\mpamp_for_loop_funs.cu.obj x64\Debug\mtx.cu.obj x64\Debug\sparsify_threshold.cu.obj 

更新:每下面的答案,相关的makefile线现在是:

NVCCFLAGS := -arch=sm_37 --device-c -std=c++11 

NVCCLFLAGS := -arch=sm_37 -std=c++11 -cudart=shared -rdc=true 

LDFLAGS := -I$(CUDA_PATH)/include -L$(CUDAPATH)/lib64 

LIBPATH := $(CUDA_PATH)/lib64 
SOLIBS := $(LIBPATH)/libcublas.so $(LIBPATH)/libcurand.so $(LIBPATH)/libcudart.so 

OBJS := main.o mtx.o mpamp_for_loop_funs.o cuBLAS_funs.o sparsify_threshold.o 

LIBS := -lcutil -lcudpp -lcuda -lcudart -lcurand -lcublas 

######################################################################## 

# link 
all: $(OBJs) 
    $(NVCC) $(NVCCLFLAGS) $(LDFLAGS) -o mpamp $(OBJS) $(SOLIBS) $(LIBS) 

但是,我收到以下错误:

ece$ make all 
/usr/local/cuda/bin/nvcc -arch=sm_37 -std=c++11 -cudart=shared -rdc=true -I/usr/local/cuda/include -L/lib64 -o mpamp main.o mtx.o mpamp_for_loop_funs.o cuBLAS_funs.o sparsify_threshold.o /usr/local/cuda/lib64/libcublas.so /usr/local/cuda/lib64/libcurand.so /usr/local/cuda/lib64/libcudart.so -lcutil -lcudpp -lcuda -lcudart -lcurand -lcublas 
nvlink error : Undefined reference to 'cublasDgemm_v2' in 'cuBLAS_funs.o' 
make: *** [all] Error 255 

我试图在连接语句,每this question重新排列标志,但没有成功。

解决!感谢您的帮助。下面是最终的变化:

LIBPATH := $(CUDA_PATH)/lib64 
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/cuda/lib64 
SOLIBS := $(LIBPATH)/libcublas.so $(LIBPATH)/libcurand.so 

OBJS := main.o mtx.o mpamp_for_loop_funs.o cuBLAS_funs.o sparsify_threshold.o 

LIBS := -lcuda -lcurand -lcublas -lcublas_device 
+0

虽然它不是问题的根源,对你的编译标志(' NVCCFLAGS')'--device-c'和'-rdc-true'的用法是多余的。如果你愿意,只指定'--device-c'就足够了。但是保留'-rdc = true'并不会伤害任何东西。同样,'-cudart = shared'是一个链接阶段的开关,所以它属于你的'NVCCLFLAGS'变量,但在编译时无关紧要,并且可以在编译阶段从NVCCFLAGS变量中安全省略。 –

回答

2

这里的根本问题是,你已经混乱编译和链接交换机连接在一起,试图使用同一套既为编译和链接开关。

与此相伴,您的代码似乎使用或依赖于CUDA separable compilation with device linking,并且在这种情况下,不可能在编译和链接中使用同一组开关,除非编译和链接阶段全部结合在一起,他们不在你的例子中。该nvcc manual您正在使用会找出问题的开关

仔细研究。

当指定--device-c,要表示给编译器(nvcc),该这是一个编译阶段/步骤仅(就像指定-c将用于GNU编译工具链)。因此,为任何类型的链接过程指定该开关都不明智。

具有最少数量更改的解决方案是从链接阶段命令中删除该更改。一种可能的方法是创建一个额外的Makefile变量:

NVCCLFLAGS := -arch=sm_37 -std=c++11 -cudart=shared -rdc=true 

和修改链接阶段命令来使用:

# link 
all: $(OBJs) 
    $(NVCC) $(NVCCLFLAGS) $(OBJS) $(SOLIBS) $(LIBS) -o mpamp 
+0

谢谢!这让我失去了这个错误,但现在我正面临一个新的问题。我在最后用一些新的makefile行编辑了我的文章。 –

+0

现在您需要链接到cublas设备库。将'-lcublas_device -lcudadevrt'添加到您的链接规范('LIBS')中。 –

+0

谢谢!有效。我做了更多更新。最终的Makefile附加到原始文章。 –