CUDA incompatibile con la mia versione di gcc

Ho problemi nella compilazione di alcuni esempi forniti con CUDA SDK. Ho installato il driver per gli sviluppatori (versione 270.41.19) e il toolkit CUDA, infine l’SDK (entrambi versione 4.0.17).

Inizialmente non ha compilato affatto dando:

error -- unsupported GNU version! gcc 4.5 and up are not supported! 

Ho trovato la linea responsabile in 81: /usr/local/cuda/include/host_config.h e l’ho cambiata in:

 //#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 4) #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 6) 

da quel momento in poi ho solo alcuni esempi da compilare, si ferma con:

 In file included from /usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr.h:162:0, from /usr/include/c++/4.6/ext/atomicity.h:34, from /usr/include/c++/4.6/bits/ios_base.h:41, from /usr/include/c++/4.6/ios:43, from /usr/include/c++/4.6/ostream:40, from /usr/include/c++/4.6/iterator:64, from /usr/local/cuda/include/thrust/iterator/iterator_categories.h:38, from /usr/local/cuda/include/thrust/device_ptr.h:26, from /usr/local/cuda/include/thrust/device_malloc_allocator.h:27, from /usr/local/cuda/include/thrust/device_vector.h:26, from lineOfSight.cu:37: /usr/include/c++/4.6/x86_64-linux-gnu/bits/gthr-default.h:251:1: error: pasting "__gthrw_" and "/* Android's C library does not provide pthread_cancel, check for `pthread_create' instead. */" does not give a valid preprocessing token make[1]: *** [obj/x86_64/release/lineOfSight.cu.o] Error 1 

Come alcuni degli esempi compilati, ritengo che questo non sia un problema di driver, ma piuttosto deve avere qualcosa a che fare con una versione di gcc non supportata. Il downgrade non è un’opzione in quanto gcc4.6 ha un intero sistema come dipendenza a questo punto …

Come già sottolineato, nvcc dipende da gcc 4.4. È ansible configurare nvcc per utilizzare la versione corretta di gcc senza passare alcun parametro del compilatore aggiungendo i softlink alla directory bin creata con l’installazione di nvcc.

La directory cuda binary predefinita (l’impostazione predefinita di installazione) è / usr / local / cuda / bin, l’aggiunta di un collegamento software alla versione corretta di gcc da questa directory è sufficiente:

sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc

gcc 4.5 e 4.6 non sono supportati con CUDA – il codice non verrà compilato e il resto della toolchain, incluso cuda-gdb, non funzionerà correttamente. Non è ansible utilizzarli e la restrizione non è negoziabile.

La tua unica soluzione è installare una versione di gcc 4.4 come secondo compilatore (la maggior parte delle distribuzioni lo permetteranno). Esiste un’opzione per nvcc --compiler-bindir che può essere utilizzato per puntare a un compilatore alternativo. Creare una directory locale e quindi creare collegamenti simbolici agli eseguibili della versione gcc supportati. Passa la directory locale a nvcc tramite l’opzione --compiler-bindir e dovresti essere in grado di compilare il codice CUDA senza influenzare il resto del tuo sistema.


MODIFICA :

Nota che questa domanda, e la risposta, riguardano CUDA 4. Da quando è stato scritto, NVIDIA ha continuato ad espandere il supporto per le versioni successive di gcc nella nuova versione della toolchain CUDA

  • A partire dalla versione 4.1 di CUDA, gcc 4.5 è ora supportato. gcc 4.6 e 4.7 non sono supportati.
  • A partire dalla versione 5.0 di CUDA, gcc 4.6 è ora supportato. gcc 4.7 non è supportato.
  • A partire dalla versione 6.0 CUDA, gcc 4.7 è ora supportato.
  • A partire dalla versione CUDA 7.0, gcc 4.8 è completamente supportato, con supporto di 4.9 su Ubuntu 14.04 e Fedora 21.
  • A partire dalla versione 7.5 di CUDA, gcc 4.8 è completamente supportato, con supporto 4.9 su Ubuntu 14.04 e Fedora 21.
  • A partire dalla versione CUDA 8, gcc 5.3 è completamente supportato su Ubuntu 16.06 e Fedora 23.
  • A partire dalla versione CUDA 9, gcc 6 è completamente supportato su Ubuntu 16.04, Ubuntu 17.04 e Fedora 25.
  • La versione 9.2 di CUDA aggiunge il supporto per gcc 7

Al momento ci sono (come da CUDA 9) nessun supporto per gcc 8 in CUDA.

Notare che NVIDIA ha recentemente aggiunto una tabella molto utile qui che contiene il compilatore supportato e la matrice OS per l’attuale versione di CUDA.

La soluzione di Gearoid Murphy funziona meglio per me dato che sulla mia distro (Ubuntu 11.10), gcc-4.4 e gcc-4.6 sono nella stessa directory, quindi –compiler-bindir non è di aiuto. L’unica avvertenza è che ho anche dovuto installare g ++ – 4.4 e colbind anche symlink:

 sudo ln -s /usr/bin/gcc-4.4 /usr/local/cuda/bin/gcc sudo ln -s /usr/bin/g++-4.4 /usr/local/cuda/bin/g++ 

Aggiornare:

Per CUDA 9:

 sudo ln -s /usr/bin/gcc-6 /usr/local/cuda/bin/gcc sudo ln -s /usr/bin/g++-6 /usr/local/cuda/bin/g++ 

È necessario aver prima installato gcc e g ++ 6:

 sudo apt install gcc-6 g++-6 

Vecchia risposta:

Per CUDA 8:

 sudo ln -s /usr/bin/gcc-5 /usr/local/cuda/bin/gcc sudo ln -s /usr/bin/g++-5 /usr/local/cuda/bin/g++ 

È necessario aver prima installato gcc e g ++ 5:

 sudo apt install gcc-5 g++-5 

Per CUDA7.5 queste linee funzionano:

 sudo ln -s /usr/bin/gcc-4.9 /usr/local/cuda/bin/gcc sudo ln -s /usr/bin/g++-4.9 /usr/local/cuda/bin/g++ 

Scopri come utilizzare “update-alternative” per ovviare a questo problema:

… Se si installa gcc 4.6, è anche ansible utilizzare il comando update-alternatives per consentire di passare facilmente da una versione all’altra. Questo può essere configurato con:

 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-4.6 sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.7 40 --slave /usr/bin/g++ g++ /usr/bin/g++-4.7 sudo update-alternatives --config gcc 

Sulla maggior parte delle distribuzioni hai la possibilità di installare un’altra versione gcc e g ++ accanto a un compilatore più recente come gcc-4.7. Inoltre, molti sistemi di build sono a conoscenza delle variabili di ambiente CC e CXX , che consentono di specificare rispettivamente altri compilatori C e C ++. COSÌ propongo qualcosa come:

 CC=gcc-4.4 CXX=g++-4.4 cmake path/to/your/CMakeLists.txt 

Per i Makefile dovrebbe esserci un modo simile. Non è consigliabile impostare collegamenti simbolici personalizzati in / usr / local a meno che tu non sappia cosa stai facendo.

Questo funziona per fedora 23. I repository di compat gcc saranno leggermente diversi in base alla tua versione di fedora.

Se si installano i seguenti repository:

 sudo yum install compat-gcc-34-c++-3.4.6-37.fc23.x86_64 compat-gcc-34-3.4.6-37.fc23.x86_64 

Ora crea i collegamenti software come menzionato sopra assumendo che la cartella cuda bin si trovi in /usr/local/cuda/

 sudo ln -s /usr/bin/gcc-34 /usr/local/cuda/bin/gcc sudo ln -s /usr/bin/g++-34 /usr/local/cuda/bin/g++ 

Ora dovresti essere in grado di compilare con nvcc senza l’errore di versione di gcc.

La soluzione di Gearoid Murphy funziona come un fascino. Per me ho avuto due directory per cuda –

 /usr/local/cuda /usr/local/cuda-5.0 

I collegamenti software devono essere aggiunti solo alla directory indicata di seguito:

 /usr/local/cuda 

Inoltre, sono stati richiesti entrambi i soft link g ++ e gcc come menzionato da SchighSchagh.

Un altro modo per configurare nvcc per utilizzare una versione specifica di gcc (gcc-4.4, ad esempio), è modificare nvcc.profile e alterare PATH per includere il percorso del gcc che si desidera utilizzare per primo.

Ad esempio (gcc-4.4.6 installato in / opt):

 PATH += /opt/gcc-4.4.6/lib/gcc/x86_64-unknown-linux-gnu/4.4.6:/opt/gcc-4.4.6/bin:$(TOP)/open64/bin:$(TOP)/share/cuda/nvvm:$(_HERE_): 

La posizione di nvcc.profile varia, ma dovrebbe essere nella stessa directory dell’eseguibile nvcc stesso.

Questo è un po ‘un hack, dato che nvcc.profile non è inteso per la configurazione utente come da manuale nvcc, ma è stata la soluzione che ha funzionato meglio per me.

CUDA è in procinto di apportare alcune modifiche all’intestazione compatibili con gcc4.7 e forse versioni successive: https://www.udacity.com/wiki/cs344/troubleshoot_gcc47

Ho dovuto installare le versioni precedenti di gcc, g ++.

  sudo apt-get install gcc-4.4 sudo apt-get install g++-4.4 

Controlla che gcc-4.4 sia in / usr / bin /, e lo stesso per g ++ Allora potrei usare la soluzione sopra:

  sudo ln -s /usr/bin/gcc-4.4 /opt/cuda/bin/gcc sudo ln -s /usr/bin/g++-4.4 /opt/cuda/bin/g++ 

Per le persone come me che si confondono durante l’uso di cmake , lo script FindCUDA.cmake sovrascrive alcune delle cose da nvcc.profile . È ansible specificare il compilatore host CUDA_HOST_COMPILER impostando CUDA_HOST_COMPILER come per http://public.kitware.com/Bug/view.php?id=13674 .

Se si usa cmake per me nessuno degli hack di modificare i file e il collegamento ha funzionato, quindi ho compilato usando i flag che specificano la versione gcc / g ++.
cmake -DCMAKE_C_COMPILER=gcc-6 -DCMAKE_CXX_COMPILER=g++-6 ..

Ha funzionato come un fascino.

In $CUDA_HOME/include/host_config.h , trova linee come queste (può variare leggermente tra le diverse versioni di CUDA):

 //... #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9) #error -- unsupported GNU version! gcc versions later than 4.9 are not supported! #endif [> __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 9) <] //... 

Rimuovere o modificarli in base alle condizioni.

Nota questo metodo è potenzialmente pericoloso e potrebbe interrompere la tua build. Ad esempio, gcc 5 utilizza C ++ 11 come impostazione predefinita, tuttavia questo non è il caso di nvcc a partire da CUDA 7.5. Una soluzione alternativa è aggiungere

--Xcompiler="--std=c++98" per CUDA <= 6.5

o

--std=c++11 per CUDA> = 7.0.

Per compilare gli esempi CUDA 8.0 su Ubuntu 16.10, ho fatto:

 sudo apt-get install gcc-5 g++-5 cd /path/to/NVIDIA_CUDA-8.0_Samples # Find the path to the library (this should be in NVIDIA's Makefiles) LIBLOC=`find /usr/lib -name "libnvcuvid.so.*" | head -n1 | perl -pe 's[/usr/lib/(nvidia-\d+)/.*][$1]'` # Substitute that path into the makefiles for the hard-coded, incorrect one find . -name "*.mk" | xargs perl -pi -e "s/nvidia-\d+/$LIBLOC/g" # Make using the supported compiler HOST_COMPILER=g++-5 make 

Questo ha il vantaggio di non modificare l’intero sistema o di creare collegamenti simbolici ai soli binari (ciò potrebbe causare problemi di collegamento alla libreria).