2017-07-06 3 views
1

J'essaye de lier des fichiers objets dans mon projet CUDA. Ci-dessous mon makefile:CUDA 8.0 nvcc fatal: fichier à entrée unique requis pour une phase sans lien lorsqu'un fichier ouputt est spécifié

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 

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

J'ai essayé d'enlever le $(SOLIBS), il retourne la même erreur:

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 

En outre, lorsque je retire -o mpamp, la commande fonctionne make all, mais ne génère pas fichier de sortie à exécuter ensuite.

Quelqu'un a-t-il des conseils pour surmonter cette erreur?

J'ai récemment déménagé de Visual Studio sous Windows vers une machine Linux. VS a fait la compilation et la liaison 'automatiquement' (j'ai ajouté des barres obliques et des sauts de ligne):

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 

Mise à jour: par la réponse ci-dessous, les lignes de makefile pertinentes sont maintenant:

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) 

Mais, je l'erreur suivante:

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 

J'ai essayé réorganisant les drapeaux dans la déclaration de liaison selon this question, en vain.

Résolu! Merci pour votre aide. Voici les dernières modifications:

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

bien que son pas la source du problème, sur vos drapeaux de compilation (' NVCCFLAGS') l'utilisation de '--device-c' et' -rdc-true' est redondante. Il suffit de spécifier uniquement '--device-c' si vous le souhaitez.Mais garder '-rdc = true' ne blesse rien. De même, '-cudart = shared' est un commutateur de phase de lien, donc il appartient à votre variable' NVCCLFLAGS', mais n'est pas pertinent au moment de la compilation, et peut être omis de manière sûre de votre variable 'NVCCFLAGS' pour les phases de compilation. –

Répondre

2

Le problème fondamental est que vous avez pêle-mêle Compilez et liez les commutateurs ensemble, en essayant d'utiliser le même ensemble de commutateurs à la fois pour la compilation et le lien. Couplé avec ceci, votre code semble utiliser ou dépendre de CUDA separable compilation with device linking, et il n'est pas possible dans ce cas d'utiliser le même ensemble de commutateurs pour la compilation et la liaison, sauf si les phases de compilation et de liaison sont toutes combinées, ce qu'ils ne sont pas dans votre exemple.

Une étude attentive du nvcc manual pour les commutateurs que vous utilisez identifiera les problèmes.

Lorsque vous spécifiez --device-c, vous indiquez au compilateur (nvcc) qui ceci est une phase de compilation/étape seulement (comme la spécification -c serait pour un ensemble d'outils du compilateur gnu). Par conséquent, spécifier ce commutateur pour tout type de processus de lien n'est pas judicieux.

La solution avec le plus petit nombre de modifications consiste à supprimer cela de votre commande de phase de liaison. Une approche possible serait de créer une variable Makefile supplémentaire:

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

et modifier votre commande de phase de lien pour l'utiliser:

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

Merci! Cela m'a fait passer l'erreur, mais je suis confronté à un nouveau maintenant. J'ai édité mon post avec quelques nouvelles lignes de makefile à la fin. –

+0

maintenant vous devez lier à la bibliothèque de périphériques cublas. ajoutez '-lcublas_device -lcudadevrt' à votre spécification de lien (' LIBS'). –

+0

Merci! Ça a marché. J'ai fait quelques mises à jour supplémentaires. Final Makefile ajouté à la publication d'origine. –