2017-07-06 2 views
1

Ich versuche, Objektdateien in meinem CUDA-Projekt zu verknüpfen. Unten ist mein Make-Datei:CUDA 8.0 nvcc fatal: einzelne Eingabedatei für eine Nicht-Link-Phase erforderlich, wenn eine Ausgabedatei angegeben wird

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 

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

ich die $(SOLIBS) entfernen versucht haben, gibt es den gleichen Fehler:

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 

Darüber hinaus, wenn ich -o mpamp, die make all Befehl funktioniert entfernen, aber ein nicht erzeugen Ausgabedatei, um dann auszuführen.

Hat jemand irgendwelche Tipps, um diesen Fehler zu umgehen?

Ich bin kürzlich von Visual Studio in Windows auf einen Linux-Rechner umgezogen. VS hat die Kompilieren und Linken 'automatisch' (I hinzugefügt Schrägstriche und Zeilenumbrüche):

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 

Update: Pro die Antwort unten sind die zugehörigen Make-Datei Linien sind jetzt:

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) 

Aber ich die folgende Fehlermeldung:

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 

ich die Flaggen in der Verknüpfung Aussage Neuanordnung haben versucht, nach this question, ohne Erfolg.

Gelöst! Danke für Ihre Hilfe. Hier ist die letzten Änderungen:

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

obwohl es nicht die Ursache des Problems, auf der Kompilierung Flags (' NVCCFLAGS') die Verwendung von '--device-c' und' -rdc-true' ist redundant. Es genügt, wenn Sie nur '--device-c' angeben.Aber '-rdc = true' zu halten, tut nichts weh. Ebenso ist "-cudart = shared" ein Link-Phase-Schalter, also gehört er in Ihre 'NVCCLFLAGS'-Variable, ist aber zur Kompilierzeit irrelevant und kann in Ihrer' NVCCFLAGS' -Variable für Kompilierphasen sicher weggelassen werden. –

Antwort

2

Das grundlegende Problem ist, dass Sie purzeln haben Kompilierung und Link Switches zusammen, versucht, den gleichen Satz von Schaltern zu verwenden, sowohl für die Kompilierung und Link.

Verbunden damit scheint Ihr Code CUDA separable compilation with device linking zu verwenden oder davon abhängig zu sein, und es ist in diesem Fall nicht möglich, den gleichen Satz von Switches sowohl für Kompilierung als auch für Link zu verwenden, sofern die Kompilierungs- und Linkphasen nicht kombiniert werden. was sie nicht in deinem Beispiel sind.

Sorgfältige Untersuchung der nvcc manual für die Schalter, die Sie verwenden, wird die Probleme identifizieren.

Wenn Sie --device-c angeben, geben Sie an, an den Compiler (nvcc), dass dies ist eine Kompilierung Phase/Schritt nur (wie -c würde für ein Gnu Compiler Toolchain Angabe). Daher ist es nicht sinnvoll, den Switch für jede Art von Verbindungsprozess zu spezifizieren.

Die Lösung mit der geringsten Anzahl von Änderungen besteht darin, diese aus dem Befehl link phase zu entfernen. Ein möglicher Ansatz wäre ein zusätzliches Makefile-Variable zu erstellen:

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

und ändern Sie Ihren Link Phase Befehl, zu verwenden:

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

Vielen Dank! Das hat mich über den Fehler hinweg gebracht, aber ich stehe jetzt vor einem neuen. Ich habe meinen Beitrag mit einigen neuen Makefile-Zeilen am Ende bearbeitet. –

+0

Jetzt müssen Sie mit der cublas Gerätebibliothek verknüpfen. füge '-lcublas_device -lcudadevrt' zu deiner Link-Spezifikation ('LIBS') hinzu. –

+0

Danke! Es funktionierte. Ich habe noch ein paar Updates gemacht. Das endgültige Makefile wurde an den ursprünglichen Post angehängt. –

Verwandte Themen