CUDA 8.0 nvcc fatal:指定输出文件时,非 link 阶段需要单个输入文件
CUDA 8.0 nvcc fatal: single input file required for a non-link phase when an ouputtfile is specified
我正在尝试 link 我的 CUDA 项目中的目标文件。下面是我的 makefile:
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)
,它 returns 同样的错误:
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 进行了编译和 linking 'automatically'(我添加了斜杠和换行符):
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 重新排列 linking 语句中的标志,但无济于事。
已解决!感谢您的帮助。这是最后的更改:
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
这里的根本问题是您将编译和 link 开关混在一起,试图对编译和 link 使用同一组开关。
与此相结合,您的代码似乎使用或依赖于 CUDA separable compilation with device linking,在这种情况下不可能对编译和 link 使用同一组开关,除非编译和 link 阶段全部组合在一起,它们不在您的示例中。
仔细研究您正在使用的开关的 nvcc manual 将找出问题所在。
当您指定 --device-c
时,您是在向编译器 (nvcc
) 指示 这只是一个编译 phase/step (只是因为指定 -c
将用于 gnu 编译器工具链)。因此,为任何类型的 link 进程指定该开关是不明智的。
更改次数最少的解决方案是从 link 阶段命令中删除它。一种可能的方法是创建一个额外的 Makefile 变量:
NVCCLFLAGS := -arch=sm_37 -std=c++11 -cudart=shared -rdc=true
并修改您的 link 阶段命令以使用:
# link
all: $(OBJs)
$(NVCC) $(NVCCLFLAGS) $(OBJS) $(SOLIBS) $(LIBS) -o mpamp
我正在尝试 link 我的 CUDA 项目中的目标文件。下面是我的 makefile:
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)
,它 returns 同样的错误:
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 进行了编译和 linking 'automatically'(我添加了斜杠和换行符):
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 重新排列 linking 语句中的标志,但无济于事。
已解决!感谢您的帮助。这是最后的更改:
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
这里的根本问题是您将编译和 link 开关混在一起,试图对编译和 link 使用同一组开关。
与此相结合,您的代码似乎使用或依赖于 CUDA separable compilation with device linking,在这种情况下不可能对编译和 link 使用同一组开关,除非编译和 link 阶段全部组合在一起,它们不在您的示例中。
仔细研究您正在使用的开关的 nvcc manual 将找出问题所在。
当您指定 --device-c
时,您是在向编译器 (nvcc
) 指示 这只是一个编译 phase/step (只是因为指定 -c
将用于 gnu 编译器工具链)。因此,为任何类型的 link 进程指定该开关是不明智的。
更改次数最少的解决方案是从 link 阶段命令中删除它。一种可能的方法是创建一个额外的 Makefile 变量:
NVCCLFLAGS := -arch=sm_37 -std=c++11 -cudart=shared -rdc=true
并修改您的 link 阶段命令以使用:
# link
all: $(OBJs)
$(NVCC) $(NVCCLFLAGS) $(OBJS) $(SOLIBS) $(LIBS) -o mpamp