Processing math: 0%

Installation du GPU pour Numba

\newcommand{\ds}{\displaystyle} \newcommand{\Frac}{\ds\frac} \renewcommand{\r}{\mathbb{ R}} \newcommand{\C}{\mathbb{ C}} \newcommand{\n}{\mathbb{ N}} \newcommand{\z}{\mathbb{ Z}} \newcommand{\Q}{\mathbb{ Q}} \newcommand{\N}{\mathbb{ N}} \newcommand{\n}{\mathbb{ N}} \newcommand{\ol}{\overline} \newcommand{\abs}[1]{\left| \,{#1} \right|} \newcommand{\pv}{\;;\;} \newcommand{\ens}[1]{\left\{ {#1} \right\}} \newcommand{\mens}[1]{\setminus\left\{ {#1} \right\}} \newcommand{\Par}[1]{\left({#1}\right)} \newcommand{\pe}[1]{\left\lfloor {#1} \right\rfloor}

Installation du GPU pour Numba

GPU sous Numba : que dois-je utiliser ?

Ce paragraphe donne juste des instructions rapides pour pouvoir utiliser un GPU avec Numba. Des informations sur la programmation GPU et sur Cuda suivront.

Numba permet d’utiliser un GPU (processeur graphique) pour effectuer des calculs massivement parallèles. Pour cela, Numba utilise l’environnement Cuda de Nvidia.

Solution recommandée

Le plus simple et qui fonctionne toujours est d’utiliser la plateforme en ligne Google Colaboratory qui met à disposition dans des feuilles Jupyter Notebook le package Numba et un GPU, sans aucune installation à réaliser et gratuitement.

Il existe peut-être d’autres solutions en ligne (Cloud Azure, AWS) mais probablement payantes ou avec des restrictions (étudiants).

Matériel sur votre machine

Si vous n’utilisez pas un service en ligne, il faut que

  • votre machine (PC ou laptop) dispose d’une carte graphique dédiée (et pas seulement une carte graphique intégrée)
  • cette carte graphique soit équipée d’un GPU Nvidia.

De nombreuses machines, même utilisées par des gamers, ne sont pas forcément pourvues de GPU Nvidia. A fortiori, des machines dédiées à un usage basique ont souvent une carte graphique intégrée Intel ou AMD.

Concernant Apple, suite à un conflit avec Nvidia, le support de Cuda s”arrête à la version 10.2. Comme indiqué dans la documentation officielle de Cuda :

CUDA 11.0 does not support macOS for developing and running CUDA applications.

De nombreux MacBook Pro ont une carte graphique Intel sans support de Cuda.

Si vous disposez d’un GPU Nvidia, vous devrez installer deux applications :

  • les pilotes Nvidia les plus récents
  • les bibliothèques dynamiques Cuda.

L’installation des pilotes sous Linux n’est pas automatique et peut être compliquée si vous devez mettre à jour le pilote. Concernant la mise à disposition de Cuda, le plus simple est d’utiliser la suite Anaconda.

Pour macOS, je n’ai pas eu accès à une machine ayant une carte graphique compatible Cuda. Mais si votre carte l’est, je vous conseille d’essayer d’installer Cuda sous Anaconda suivant la même procédure que sous Linux ou Windows.

Dans ce qui suit, sauf recours à un GPU sur Google Colab, les codes sont exécutés sur une carte graphique GeForce GTX 970.

Utiliser Numba avec un GPU sous Google Colab

Sous Google Colab, Numba peut directement exécuter du code sur les GPU, sans aucune installation préalable. Pour illustrer, on va utiliser le code suivant et qu’il n’est pas nécessaire de comprendre pour notre propos :

tester_gpu_simple.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
from numba import cuda, int64

@cuda.jit('(int64[:], int64[:], int64[:])')
def cuda_sum(a, b, c):
    i = cuda.grid(1)
    c[i] = a[i] + b[i]

griddim = 5, 1
blockdim = 2, 1, 1
N = griddim[0] * blockdim[0]
cuda_sum_configured = cuda_sum.configure(griddim, blockdim)

a = np.array(np.random.randint(4, size=N), dtype=np.int64)
b = np.array(np.random.randint(4, size=N), dtype=np.int64)
c = np.empty_like(a)
print("a =", a)
print("b =", b)

cuda_sum_configured(a, b, c)

print('-'*(2*N+7))
print("c =", c)

Ce code est une adaptation d’un exemple fourni dans un repo Github de Numba.

Ce code utilise le GPU (cf. lignes 4, 9-12 et 20) pour effectuer la somme c de deux tableaux Numpy a et b d’entiers aléatoires.

Si vous exécutez sans précaution ce code, il va renvoyer une erreur :

CudaSupportError: Error at driver init:
[100] Call to cuInit results in CUDA_ERROR_NO_DEVICE:

En effet, par défaut, sous Colab, les GPU ne sont pas activés. Pour les rendre disponibles, effectuer l’opération suivante :

../../../../_images/colab_menu_execution_frame.png

puis

../../../../_images/colab_to_gpu.png

plus précisément, cliquer sur :

Menu Exécution > Modifier le type d'exécution > Accélérateur matériel
                                              > GPU à la place de None

Une fois ce changement effectué, le code s’exécutera et affichera par exemple :

a = [0 2 1 1 2 1 2 1 2 2]
b = [3 1 1 3 1 2 1 0 2 3]
---------------------------
c = [3 3 2 4 3 3 3 1 4 5]

et on voit bien que le tableau c est la somme positionnelle des tableaux a et b.

Inversement, si vous exécutez du code Python avec ou sans Numba et qui n’utilise pas de GPU alors qu’il est activé vous recevrez peut-être un message du type : Pour tirer le meilleur parti de Colab, évitez d’utiliser un GPU si vous n’en avez pas besoin.

GPU disponibles

D’après la documentation de Google Colab, les processeurs graphiques disponibles dans la version gratuite sont parmi les modèles Nvidia suivants :

Pour savoir quel GPU vous utilisez, exécutez le code suivant :

from numba import cuda
print(cuda.detect())

qui dans mon cas affiche

Found 1 CUDA devices
id 0             b'Tesla T4'                              [SUPPORTED]
                      compute capability: 7.5
                           pci device id: 4
                              pci bus id: 0
Summary:
    1/1 devices are supported
True

mais, plus souvent, c’est un GPU K80 qui est proposé (et qui est moins rapide).

GPU, Cuda et Numba

Les cartes graphiques utilisées par les jeux vidéos sont munis de processeurs spécifiques qu’on appelle des GPU. A la différence des CPU, un GPU possède plusieurs milliers de cœurs et son architecture est parallèle puisqu’il doit gérer des matrices de pixels. Depuis le début des années 2000, les GPU sont utilisés pour faire du calcul scientifique à la manière des CPU. Cette utilisation détournée des GPU s’appelle du GPGPU. En 2019, 40% de la puissance de calcul du top 500 des super-calculateurs provient de GPU. Le GPGPU est utilisé dans de nombreuses applications.

Cuda est une plateforme développée par le fabriquant de processeurs de puces graphiques Nvidia permettant la programmation GPGPU sans avoir de connaissance en programmation de cartes graphiques. Cuda n’est supporté que par les cartes ayant un GPU Nvidia (par exemple, les cartes AMD Radeon ne sont pas compatibles). Le langage de programmation utilisé sur Cuda est le C++.

Des domaines comme l’apprentissage automatique, et les sciences des données ont des gros besoins en calculs. Depuis les années 2015, des bibliothèques Python très populaires (TensorFlow, PyTorch, Chainer) utilisent Cuda via du code C++. Mais il existe aussi des bibliothèques Python permettant d’utiliser directement Cuda, essentiellement Numba, Cupy et PyCuda. Il existe aussi Pyculib pour des besoins spécialisés mais il semblerait que Cupy soit amené à le remplacer.

Quand on code en Cuda, on écrit des kernels. Un kernel est juste une fonction, souvent assez simple dans son objectif de calcul, qui va être exécutée en parallèle sur le GPU sur des centaines ou des milliers de fils d’exécution (je dirai parfois threads). Numba permet d’écrire assez simplement des kernels Cuda. En particulier, on écrit ses kernels exclusivement en Python et non pas en C++ comme avec PyCuda.

Pour programmer en Cuda, vous devez exécuter votre code sur une machine disposant d’une carte graphique Nvidia (ou compatible). Il est également possible d’utiliser, gratuitement et avec des limitations, des GPU à distance (Google Colaboratory par exemple).

Dans cette documentation, seul un usage limité et simple de Cuda est présenté. Pour bien connaître Cuda, il vaut mieux utiliser Cuda Toolkit en C++.

Les cartes graphiques des ordinateurs

Si vous avez une carte graphique Nvidia et si elle n’est pas trop ancienne, il est possible que vous l’utilisiez pour faire du GPGPU en passant par Numba. Toutefois, cela nécessite l’installation de divers outils.

La puissance de calcul d’un carte graphique Nvidia est déterminée par un indice (dit compute capability) et sa sophistication est déterminée par son architecture (qui porte le nom d’un scientifique célèbre, par exemple Képler). Pour une carte de PC de gamer de bonne facture des années 2015 (architecture Maxwell), l’indice vaut un peu plus de 5. En 2020, une carte graphique de gamer de moyenne gamme et d’architecture Turing a un indice de l’ordre de 7 (compter quelques centaines d’euros). Les cartes graphiques de data center disponibles gratuitement sur Google sont souvent des tesla K80, d’une architecture Képler, d’indice 3.7. Vous pouvez trouver en 2020 des cartes graphiques pour PC d’architecture Képler et d’indice 3 de calcul, comme la Nvidia GT710 à moins de 50 euros. Il existe aussi la possibilité, pour ordinateur portable ayant un port Thunderbolt, de le connecter à un boitier contenant une carte graphique externe (compter des centaines d’euros !).

Pour être utilisable sous Numba, l’indice de calcul doit être supérieure ou égal à 2. Vous trouverez les puissances de calcul des cartes graphiques Nvidia ici : Your GPU Compute Capability et cherchez votre modèle en cliquant dans les catégories.

En général, les spécifications des PC ou d’un ordinateur portable donnent la référence de la carte graphique, ce qui permet de connaître ses caractéristiques. Chercher ensuite sur Internet si elle est compatible Nvidia. Le nom de la marque de la carte n’est généralement pas Nvidia puisque ce dernier est fabriquant de GPU (comme Intel ou ARM sont des fabriquants de CPU) et pas un assembleur de cartes. Les marques sont par exemple MSI, Asus, GigaByte.

Il est aussi possible d’acheter une carte graphique et de l’installer matériellement dans son PC. Voici un document pour installer une carte graphique à intention de GPGPU : Changing your hardware to achieve faster Deep Learning on your PC.

Une machine peut très bien être configurée avec deux cartes graphiques réparties ainsi (voir par exemple un montage ICI):

  • une carte graphique intégrée branchée à l’écran ou aux écrans d’affichage
  • une carte graphique Nvidia débranchée de toute sortie graphique et dédiée uniquement à du calcul GPU.

Cette configuration permet (peut-être) d’avoir plus de mémoire disponible sur le GPU. Elle ne semble toutefois pas être plus rapide, au moins sur les quelques exemples que j’ai essayés.

Sous Linux, vous pouvez très bien disposer d’une carte graphique Nvidia, en particulier sur ordinateur portable, mais que sa présence ne soit pas visible dans les paramètres ; en effet, par défaut, les distributions Linux installent la carte graphique intégrée (Intel le plus souvent). Enfin, si vous installez Ubuntu 20.04, il détecte automatiquement et installe une carte graphique Nvidia placée sur un port PCIe.

Installer Cuda pour utilisation dans Numba : principe général

Avertissement

Il ne suffit pas que votre machine personnelle dispose d’une carte graphique Nvidia pour que la carte soit utilisable par Numba. Vous pouvez très bien importer le module de Numba appelé cuda :

from numba import cuda

sans que votre GPU soit opérationnel pour Numba.

Principe général d’installation

Je suppose que votre carte graphique a un GPU Nvidia et que vous avez installé Numba. Pour que vous puissiez utiliser votre propre GPU dans Numba, les deux conditions suivantes sont requises :

  • étape 1 : installer un pilote Nvidia suffisamment récent de votre carte carte graphique
  • étape 2 : installer les bibliothèques Cuda compatibles avec les pilotes de votre carte.

Par ailleurs, la réalisation de ces étapes va dépendre de votre système d’exploitation (et éventuellement de sa version) et, pour la 2de étape, de si vous utilisez ou pas Anaconda.

  • Concernant le pilote, sauf pour Ubuntu 20 qui installe automatiquement, c’est une opération que vous devez faire vous-même, elle n’est pas automatique. Vous devez vous rendre sur le site de Nvidia pour télécharger les pilotes les plus récents ou éventuellement, désinstaller les pilotes déjà installés et les remplacer par de plus récents sinon, vous risquez de vous trouver en incompatibilité avec l’étape 2.
  • Concernant la 2de étape, il s’agit d’installer des bibliothèques partagées (dll sous Windows) que Numba va appeler quand vous utiliserez Cuda. Cela peut se faire, sous Windows, comme sous Linux, assez facilement en utilisant Anaconda. Sous Linux, on peut aussi installer ces bibliothèques en utilisant le kit de développement Cuda téléchargé depuis le site de Nvidia.

Programme de test

Lorsque la première étape est satisfaite, le programme suivant s’exécute sans erreur :

numba_detect_cuda.py

from numba import cuda
print(cuda.detect())

Il devrait afficher quelque chose comme :

Found 1 CUDA devices
id 0      b'GeForce GTX 970'                              [SUPPORTED]
                      compute capability: 5.2
                           pci device id: 0
                              pci bus id: 1
Summary:
    1/1 devices are supported
True

Cela ne suffit pas à utiliser pleinement votre GPU sous Numba, il faut encore installer Cuda.

Pour tester le plein fonctionnement de Numba sur GPU, vous pourrez utiliser ce fichier de test suivant :

tester_gpu_simple.py

import numpy as np
from numba import cuda, int64

@cuda.jit('(int64[:], int64[:], int64[:])')
def cuda_sum(a, b, c):
    i = cuda.grid(1)
    c[i] = a[i] + b[i]

griddim = 5, 1
blockdim = 2, 1, 1
N = griddim[0] * blockdim[0]
cuda_sum_configured = cuda_sum.configure(griddim, blockdim)

a = np.array(np.random.randint(4, size=N), dtype=np.int64)
b = np.array(np.random.randint(4, size=N), dtype=np.int64)
c = np.empty_like(a)
print("a =", a)
print("b =", b)

cuda_sum_configured(a, b, c)

print('-'*(2*N+7))
print("c =", c)

qui doit afficher quelque chose du genre :

a = [1 2 1 0 2 1 2 2 0 1]
b = [0 3 0 3 3 1 0 2 0 3]
---------------------------
c = [1 5 1 3 5 2 2 4 0 4]

Installation du pilote Nvidia sous Windows

Ce qui suit a été testé sous Windows 10.

Déterminer sa carte graphique

Pour connaître les caractéristiques de votre carte graphique (en supposant qu’elle soit connectée à un écran, après tout, ce n’est pas obligé) :

Menu Démarrer > Paramètres Windows (la roue dentée) > Système
              > Affichage > Paramètres d'affichage avancés
../../../../_images/parametres_affichage_windows10.png

Sous le nom de l’écran vous devriez lire la référence de la carte graphique. En cliquant sur le lien Propriétés de la carte vidéo pour l’affichage vous devriez avoir plus d’information, en particulier sur le pilote mais rien de très utile pour programmer avec Cuda.

Vous pouvez aussi, via le raccourci Alt + Ctrl + Suppr puis Gestionnaire des tâches, obtenir des informations sur l’état courant de votre carte graphique (référence, mémoire utilisée, activité):

../../../../_images/gpu_moniteur_windows.png

Votre obtiendrez aussi des informations à l’aide du gestionnaire de périphériques :

Menu démarrer > Clic Droit : gestionnaire de périphériques
              > Cartes graphiques

Si vous avez déjà installé vos pilotes Nvidia, cliquez droit sur le bureau et ouvrez le Panneau de configuration de Nvidia :

../../../../_images/panneau_config_nvidia.png

puis en bas à gauche cliquer sur Informations système:

../../../../_images/nvidia_info_sys.png

ce qui vous donnera le nom de la carte graphique et la version du pilote ayant un sens pour Cuda (version 451 dans mon cas).

Installation ou mise à jour des pilotes

Si vous voulez mettre à jour vos pilotes (ce que j’ai préféré faire), de mon expérience, il n’est pas nécessaire de désinstaller les précédents car l’installeur mettra à jour.

Se rendre sur le site de Nvidia et dans l’application en ligne :

../../../../_images/driver_nvidia_site.png

entrez les références de votre carte graphique et validez. Puis téléchargez le pilote proposé (de taille volumineuse, dans mon cas presque 600 Mo) :

../../../../_images/driver_nvidia_site_download.png

Une fois téléchargé, exécutez le fichier. N’acceptez que les options utiles pour l’installation du pilote sinon l’outil va vous installer des applications sans intérêt pour programmer :

../../../../_images/ge_force_experience.png

Choisir l’option d”installation expresse. L’installation dure au total une dizaine de minutes et pendant celle-ci, parfois, l’écran deviendra noir. A la fin de mon installation, le menu Démarrer n’était plus actif.

Vérifiez comme indiqué plus haut que vos pilotes ont bien été mis-à-jour en consultant comme expliqué ci-dessus le Panneau de configuration de Nvidia. Il ne me semble pas nécessaire de redémarrer le système.

Installation sous Windows et Anaconda 3 de Cuda pour Numba

Pour disposer de Numba et pouvoir utiliser le GPU via Numba (ce qui suppose que vous ayez un pilote Nvidia d’installé), je vais utiliser la suite Anaconda 3. Je suppose que vous l’avez déjà installé.

Détection de votre GPU

Numba est en mesure de détecter votre GPU. Dans une feuille Jupyter saisir le code suivant :

1
2
from numba import cuda
cuda.detect()

Il utilise Numba (cf. ligne 1), il doit s’exécuter sans erreur et afficher un message du genre :

Found 1 CUDA devices
id 0      b'GeForce GTX 970'                              [SUPPORTED]
                      compute capability: 5.2
                           pci device id: 0
                              pci bus id: 1
Summary:
    1/1 devices are supported

La feuille apparaît sous cette forme :

../../../../_images/essai_numba_jit_detect_anaconda.png

Mais Numba ne peut pas aller plus loin, et lancer des programmes qui s’exécuteraient sur votre GPU. Si vous le faisiez, vous auriez un message tel que

NvvmSupportError: libNVVM cannot be found. Do
`conda install cudatoolkit`: Could not find module 'nvvm.dll'
(or one of its dependencies). Try using the full
path with constructor syntax.

Comme le message le dit, il manque une bibliothèque dynamique (fichier dll) car vous n’avez pas installé Cuda via le paquet cudatoolkit (c’est indiqué dans le message).

Installation de cudatoolkit

Nous allons utiliser l’installeur d’Anaconda en mode graphique. Le lancer à partir de

Menu Démarrer > Anaconda3 > Anaconda-Navigator

et l’interface se présente ainsi :

../../../../_images/anaconda-navigator_gui.png

Cliquez sur le menu Environments :

../../../../_images/anaconda-navigator_gui_cadre.png

ce qui ouvre cette vue

../../../../_images/Anaconda_Navigator_install.png

cliquez sur le bouton Update index pour faire apparaître les nouveaux packages disponibles :

../../../../_images/Anaconda_Navigator_install.png

on voit qu’il y en a 325.

Cliquez sur le menu déroulant pour faire apparaître la ligne Not installed, dans la barre de recherche écrire cuda et validez. Cela devrait sélectionner au moins deux packages dont un des deux est nommé cudatoolkit et que l’on va installer. Cliquer sur la case devant cudatoolkit ce qui fait apparaître deux boutons en bas à droite de la fenêtre et valider le bouton vert Apply :

../../../../_images/package_cudatoolkit_case.png

Attendre que le système regarde s’il peut installer le package. Un panneau va finir par s’ouvrir indiquant les packages à installer, ici un seul :

../../../../_images/install_package_cudatoolkit.png

en particulier on voit qu’il va installer Cuda en version 10.2. Valider en cliquant sur le bouton vert Apply du panneau ce qui va lancer un téléchargement puis une installation (compter plusieurs minutes) :

../../../../_images/download_package_cudatoolkit.png

Une fois l’installation terminé (ce n’est pas clairement annoncé), assurez-vous que cudatoolkit est bien installé ; pour cela, positionnez le menu déroulant sur Installed, en ayant gardé dans la barre de recherche le mot cuda et vous verrez que la ligne cudatoolkit apparaît :

../../../../_images/install_package_cudatoolkit_end.png

Tester un programme Numba sous GPU

Ouvrir la feuille Jupyter Notebook déjà utilisée, ou une autre, pensez à réinitialiser l’environnement de la feuille :

Menu Kernel > Restart and clear output

et placer le code Numba suivant dans une cellule :

tester_gpu_simple.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import numpy as np
from numba import cuda, int64

@cuda.jit('(int64[:], int64[:], int64[:])')
def cuda_sum(a, b, c):
    i = cuda.grid(1)
    c[i] = a[i] + b[i]

griddim = 5, 1
blockdim = 2, 1, 1
N = griddim[0] * blockdim[0]
cuda_sum_configured = cuda_sum.configure(griddim, blockdim)

a = np.array(np.random.randint(4, size=N), dtype=np.int64)
b = np.array(np.random.randint(4, size=N), dtype=np.int64)
c = np.empty_like(a)
print("a =", a)
print("b =", b)

cuda_sum_configured(a, b, c)

print('-'*(2*N+7))
print("c =", c)

Ce code effectue des calculs sur le GPU (cf. ligne 4). Si on lance l’exécution, aucun message d’erreur ne doit apparaître et on lira une sortie du genre :

a = [1 2 1 0 2 1 2 2 0 1]
b = [0 3 0 3 3 1 0 2 0 3]
---------------------------
c = [1 5 1 3 5 2 2 4 0 4]

Votre installation de Numba est alors pleinement opérationnelle !

Voici une vue du résultat :

../../../../_images/numba_cuda_ok.png

Anaconda n’est pas infaillible

Les installations sous Anaconda ne se passent pas toujours aussi facilement, en particulier lorsque les packages utilisent le GPU. Sur notre lancée, essayons d’installer Cupy qui est un module Python permettant d’utiliser les bibliothèques Cuda. On fait comme précédemment mais pour cupy au lieu de cudatoolkit , qui est bien listé dans les packages

../../../../_images/install_package_cupy.png

et à l’étape de préparation de l’installation, après une attente assez longue, on obtient un message d’erreur :

../../../../_images/cupy_error.png

et dont voici le contenu :

UnsatisfiableError: The following specifications were found
to be incompatible with the existing python installation in your
environment:

Specifications:

  - cupy -> python[version='>=3.5,<3.6.0a0|>=3.6,<3.7.0a0|>=3.7,
  <3.8.0a0']

Your python: python=3.8

If python is on the left-most side of the chain, that's the version
you've asked for. When python appears to the right, that indicates
that the thing on the left is somehow not available for the python
version you are constrained to. Note that conda will not change your
python version to a different minor version unless you explicitly specify
that.

The following specifications were found to be incompatible with your CUDA
driver:

  - feature:/win-64::__cuda==11.0=0

Your installed CUDA driver is: 11.0

J’ai ensuite essayé d’installer cupy en utilisant une autre source (conda-forge) sans davantage de succès.

Installation du pilote Nvidia sous Ubuntu 20

A partir d’Ubunutu 20.04, les pilotes Nvidia adaptés à votre matériel sont automatiquement disponibles car installés lors de l’installation de l’OS. Pour le confimer, lancer la commande

$ nvidia-settings

ce qui montre un applet graphique qui donne les caractéristiques du GPU

../../../../_images/nvidia-settings-20-04.png

Linux : détection de la carte graphique

Je ne parlerai ci-dessous que des distributions Ubuntu (séries 18 à 20, les LTS ayant un support jusqu’en 2023 ou 2025).

Précision : tout ce qui est expliqué dans cette section est sans rapport avec Anaconda qui ne se charge pas d’installer un driver matériel.

Détection du matériel

Pour connaître les périphériques graphiques potentiellement disponibles, on peut exécuter la commande suivante :

$ sudo lshw -C video
[sudo] Mot de passe de po :
  *-display
       description: VGA compatible controller
       produit: GM204 [GeForce GTX 970]
       fabriquant: NVIDIA Corporation
       identifiant matériel: 0
       information bus: pci@0000:01:00.0
       version: a1
       bits: 64 bits
       horloge: 33MHz
       fonctionnalités: pm msi pciexpress vga_controller bus_master cap_list rom
       configuration: driver=nouveau latency=0
       ressources: irq:34 mémoire:f6000000-f6ffffff mémoire:e0000000-efffffff
                   mémoire:f0000000-f1ffffff portE/S:e000(taille=128)
                   mémoire:c0000-dffff

La commande ci-dessus a été exécutée sur une Ubuntu 18.04 fraîchement installée. On voit qu’il y a une carte graphique Nvidia et que le pilote s’appelle nouveau. Ce pilote n’est pas du tout capable de permettre de réaliser du GPGPU avec Cuda. Quand on regarde dans les paramètres, rubrique À propos, on lit que la carte graphique s’appelle NV124

../../../../_images/a_propos_avant.png

qui correspond à un pilote dit nouveau.

Pour que vous puissiez utiliser votre GPU avec Numba, le pilote doit être un pilote Nvidia avec une ligne comme celle-ci :

$ sudo lshw -C video
...
       configuration : driver=nvidia latency=0
...

Une autre façon de connaître ses cartes graphiques est par la commande hwinfo (à installer au préalable et exécuter en sudo) :

$ hwinfo --gfxcard --short
graphics card:
                       nVidia GM204 [GeForce GTX 970]

Primary display adapter: #14

On peut aussi essayer ceci (je crois que ça affiche les drivers propriétaires installés ou installables) :

$ sudo ubuntu-drivers devices
== /sys/devices/pci0000:00/0000:00:01.0/0000:01:00.0 ==
modalias : pci:v000010DEd000013C2sv000010DEsd00001116bc03sc00i00
vendor   : NVIDIA Corporation
model    : GM204 [GeForce GTX 970]
driver   : nvidia-driver-440 - third-party free
driver   : nvidia-driver-435 - distro non-free
driver   : nvidia-driver-418-server - distro non-free
driver   : nvidia-driver-450 - third-party free recommended
driver   : nvidia-driver-390 - distro non-free
driver   : nvidia-driver-440-server - distro non-free
driver   : xserver-xorg-video-nouveau - distro free builtin

La commande peut très bien ne rien afficher (situation déjà rencontrée) même si vous avez une carte graphique compatible Nvidia, par exemple si votre affichage se fait (par défaut) via une carte graphique intégrée Intel.

Autre possibilité :

$lspci | grep -i nvidia
01:00.0 VGA compatible controller: NVIDIA Corporation GM204
                                   [GeForce GTX 970] (rev a1)
01:00.1 Audio device: NVIDIA Corporation GM204 High Definition
                                   Audio Controller (rev a1)

Linux : installation automatique des pilotes Nvidia

Il se trouve qu’Ubuntu (en version 18 et sans doute 19) permet de lancer l’installation de pilotes propriétaires (il paraît que ce n’est pas le cas pour les versions antérieures). Pour cela aller dans la logithèque (dite Logiciels Ubuntu), taper pilotes dans la barre de recherche et choisir Software & Updates, cliquer sur le bouton lancer

../../../../_images/software.png

cliquer sur l’onglet Pilotes additionnels :

../../../../_images/nouveau.png

(attendre que le panneau soit chargé). Une case à cocher vous indique le pilote éventuellement utilisé.

Choisir le pilote recommandé et l’installer (en cliquant sur le bouton) ce qui prend plusieurs minutes :

../../../../_images/pilotes_add_18-04.png

Ensuite, il faut absolument redémarrer l’ordinateur (opération normalement très rare sous Linux) pour que les changements soient pris en compte.

Au redémarrage, pour vérifier, lancer la commande

$ nvidia-settings

qui doit montrer :

../../../../_images/nvidia_settings_440.png

Une alternative (je pense équivalente) à la méthode ci-dessus d’installation du pilote est décrite ICI, regarder la première méthode.

Faire fonctionner Cuda pour Numba sous Linux avec Anaconda

Je suppose que vous avez installé

  • Anaconda 3 sous Linux, comme expliqué dans un paragraphe précédent.
  • le pilote Nvidia de votre carte graphique.

Reste à faire fonctionner le GPU sous Numba. Pour cela, il suffit juste de demander à Anaconda d’installer le package cudatoolkit. La procédure est exactement la même que sous Windows. Il suffit juste

  • d’ouvrir Anaconda Navigator,
  • de cliquer sur le menu Environments,
  • d’entrer cuda dans la barre de recherche
  • de positionner le menu déroulant sur Not installed
  • de sélectionner cudatoolkit en cochant la case
  • de valider en cliquant sur le bouton Apply
  • de valider à nouveau quand Anaconda à trouvé le package à installer.

Comme sous Windows, faire un test avec le fichier tester_gpu_simple.py pour s’assurer que le GPU exécute sans erreurs les calculs sous Numba + Cuda.

Linux : installation manuelle des pilotes Nvidia

On va installer en ligne de commande les pilotes de la carte Nvidia GeForce 970. Le site de Nvidia indique, en utilisant l’application en ligne :

../../../../_images/drivers_970.png

que le pilote 450 prend en charge la 970 :

../../../../_images/970_ok.png

Donc, j’essaye le pilote 450. Le code à lancer est le suivant :

sudo apt-get purge nvidia*
sudo add-apt-repository ppa:graphics-drivers
sudo apt-get update
sudo apt-get install nvidia-driver-450

La première ligne sert à désinstaller des pilotes Nvidia éventuellement déjà installés. La dernière ligne installe le pilote en version 450. L’installation est relativement longue (compter un bon quart d’heure).

Il faut redémarrer la machine sinon le nouveau pilote n’est pas reconnu. J’en veux pour preuve que si on lance

numba_detect_cuda.py

from numba import cuda
cuda.detect()

on obtient :

$ python3 numba_detect_cuda.py
Traceback (most recent call last):

... omis ...

[100] Call to cuInit results in CUDA_ERROR_NO_DEVICE:

Et de même si on ne reboote pas, on obtient

$ nvidia-settings

ERROR: NVIDIA driver is not loaded


ERROR: Unable to load info from any available system

Une fois redémarré, le panneau À propos des paramètres montre le changement de pilote :

../../../../_images/a_propos_18-04.png

La commande suivante montre aussi que le pilote Nvidia est installé :

$ sudo lshw -C video
[sudo] Mot de passe de po :
  *-display
       description: VGA compatible controller
       produit: GM204 [GeForce GTX 970]
       fabriquant: NVIDIA Corporation
       identifiant matériel: 0
       information bus: pci@0000:01:00.0
       version: a1
       bits: 64 bits
       horloge: 33MHz
       fonctionnalités: pm msi pciexpress vga_controller bus_master cap_list rom
       configuration: driver=nvidia latency=0
       ressources: irq:34 mémoire:f6000000-f6ffffff mémoire:e0000000-efffffff
       mémoire:f0000000-f1ffffff portE/S:e000(taille=128) mémoire:c0000-dffff

Avant installation, la commande

lsmod | grep nvidia

n’affichait rien. Cette fois, elle affiche :

$ lsmod | grep nvidia
nvidia_uvm            970752  0
nvidia_drm             49152  7
nvidia_modeset       1183744  13 nvidia_drm
nvidia              19681280  591 nvidia_uvm,nvidia_modeset
drm_kms_helper        184320  1 nvidia_drm
drm                   491520  10 drm_kms_helper,nvidia_drm

Le comportement de Numba a changé, il détecte le GPU :

numba_detect_cuda.py

from numba import cuda
cuda.detect()

qui lancé donne

$ python3 numba_detect_cuda.py
Found 1 CUDA devices
id 0      b'GeForce GTX 970'                              [SUPPORTED]
                      compute capability: 5.2
                           pci device id: 0
                              pci bus id: 1
Summary:
    1/1 devices are supported

Toutefois, il est incapable de l’utiliser pour faire des calculs :

$ python3 tester_cuda_matmul.py

... omis ...

numba.cuda.cudadrv.error.NvvmSupportError: libNVVM cannot be found.
Do `conda install cudatoolkit`: libnvvm.so: cannot open shared object
file: No such file or directory

L’applet graphique

$ nvidia-settings

fonctionne et montre la version du pilote (450) :

../../../../_images/nvidia_settings_18-04.png

De même, la commande ci-dessous montre le comportement en direct du GPU :

$ nvidia-smi
Wed Jul 29 19:32:53 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.57       Driver Version: 450.57       CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  GeForce GTX 970     Off  | 00000000:01:00.0  On |                  N/A |
| 34%   44C    P8    21W / 173W |    277MiB /  4041MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|    0   N/A  N/A      1217      G   /usr/lib/xorg/Xorg                 15MiB |
|    0   N/A  N/A      1275      G   /usr/bin/gnome-shell               49MiB |
|    0   N/A  N/A      1451      G   /usr/lib/xorg/Xorg                117MiB |
|    0   N/A  N/A      1600      G   /usr/bin/gnome-shell               85MiB |
|    0   N/A  N/A      1918      G   gnome-control-center                2MiB |
+-----------------------------------------------------------------------------+

Installation de Cuda Toolkit sous Linux

Cette vidéo applique sous Ubuntu 16.04 le même procédé d’installation que celui qui est proposé ci-dessous (mais elle n’explique pas clairement comment choisir la version de Cuda adaptée au pilote)

Je suppose que votre driver Nvidia est installé. Je rappelle que l’installation des bibliothèques Cuda est indispensable à l’utilisation du GPU sous Numba. L’objectif ici est d’utiliser Numba et le GPU sans passer par Anaconda. Je me suis basé sur ce compte-rendu.

Par défaut, Cuda s’installera dans le répertoire /usr/local que voici avant installation :

../../../../_images/usr-local_avant.png

Trouver la version et l’installer

Cherchons la version du Cuda toolkit à installer. Pour cela, lancer la ligne de commande suivante :

$ nvidia-smi
Wed Jul 29 00:30:29 2020
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 440.100      Driver Version: 440.100      CUDA Version: 10.2     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|===============================+======================+======================|
|   0  GeForce GTX 970     Off  | 00000000:01:00.0  On |                  N/A |
| 37%   47C    P8    22W / 173W |    226MiB /  4041MiB |      2%      Default |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                       GPU Memory |
|  GPU       PID   Type   Process name                             Usage      |
|=============================================================================|
|    0      1226      G   /usr/lib/xorg/Xorg                            16MiB |
|    0      1282      G   /usr/bin/gnome-shell                          49MiB |
|    0      1455      G   /usr/lib/xorg/Xorg                            85MiB |
|    0      1589      G   /usr/bin/gnome-shell                          68MiB |
+-----------------------------------------------------------------------------+

[smi veut dire System Management Interface]

En haut du tableau, on lit que le pilote matériel 440 est capable de prendre en charge au plus la version de Cuda 10.2. C’est celle-là que j’installerai ci-dessous. Se rendre sur le site de Nvidia pour télécharger les binaires de Cuda toolkit en version 10.2. Pour trouver la page correspondant à ma version, j’ai consulté cette page CUDA Toolkit Archive du site de Nvidia et j’ai choisi la version 10.2.

Depuis la page de téléchargement, indiquer dans l’application en ligne

  • son OS (Linux),
  • l’architecture (x86_64),
  • la distribution (Ubuntu),
  • la version (18.4),
  • le type de fichier, à savoir deb(local).

Une fois toutes les options choisies, un panneau s’ouvre :

../../../../_images/cuda10-2-download.png

qui contiennent des lignes de commande, et qui placées dans un fichier bash donnerait :

wget "https://developer.download.nvidia.com/compute/"
"cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin"

sudo mv cuda-ubuntu1804.pin \
/etc/apt/preferences.d/cuda-repository-pin-600

wget "http://developer.download.nvidia.com/compute/cuda/10.2/\
Prod/local_installers/cuda-repo-ubuntu1804-\
10-2-local-10.2.89-440.33.01_1.0-1_amd64.deb"

sudo dpkg -i cuda-repo-ubuntu1804-10-2-local-\
10.2.89-440.33.01_1.0-1_amd64.deb

sudo apt-key add /var/cuda-repo-10-2-local-\
10.2.89-440.33.01/7fa2af80.pub

sudo apt-get update

sudo apt-get -y install cuda

et indique les commandes à entrer. Les exécuter ligne par ligne dans un terminal (oudans un fichier bash). Une fois cela terminé, Cuda est installé, vous pouvez d’ailleurs vous en assurer en allant voir le dossier /usr/local :

../../../../_images/usr-local-cuda.png

qui contient désormais un répertoire pour Cuda (l’image, c’était pour la version 11 de Cuda).

Au passage, cela vous donne accès aux outils de développement C++ de Cuda, par exemple son compilateur :

$ /usr/local/cuda/bin/nvcc -V
nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2020 NVIDIA Corporation
Built on Thu_Jun_11_22:26:38_PDT_2020
Cuda compilation tools, release 11.0, V11.0.194
Build cuda_11.0_bu.TC445_37.28540450_0

Linux : installation des dernières versions du pilote et de Cuda

Soit toujours à configurer Cuda pour une carte GeForce 970. Cette fois, on voudrait installer les versions compatibles les plus récentes possibles.

Les cartes supportées par version de pilotes Linux sont détaillées sur une page du site de Nvidia : Pilotes Unix. Plus le numéro de pilote est élevé plus le pilote est à jour et les pilotes sont rétro-compatibles avec d’anciennes versions de Cuda. Plus précisément, cliquez sur une version de pilote puis regardez s’il est adapté à votre matériel (onglet Produits supportés). En août 2020, le dernière pilote est le 450, En cliquant sur le lien 450, on arrive à une page de téléchargement :

../../../../_images/pilote_450_cuda11.png

et en regardant l’onglet Produits supportés, on voit que la GeForce 970 est prise en charge :

../../../../_images/prod_support.png

Le fichier à télécharger est un fichier run mais je préfère télécharger un fichier deb. Il suffit donc de se rendre sur la page de téléchargement de Cuda Toolkit et en utilisant l”application en ligne :

../../../../_images/commandes_cuda_11.png

puis de lancer les commandes indiquées. Ecrit dans un fichier bash, cela donnerait :

wget "https://developer.download.nvidia.com/compute/"
"cuda/repos/ubuntu1804/x86_64/cuda-ubuntu1804.pin"

sudo mv cuda-ubuntu1804.pin \
/etc/apt/preferences.d/cuda-repository-pin-600

wget "http://developer.download.nvidia.com/compute/cuda/"
"11.0.2/local_installers/cuda-repo-ubuntu1804-"
"11-0-local_11.0.2-450.51.05-1_amd64.deb"

sudo dpkg -i \
cuda-repo-ubuntu1804-11-0-local_11.0.2-450.51.05-1_amd64.deb

sudo apt-key add \
/var/cuda-repo-ubuntu1804-11-0-local/7fa2af80.pub

sudo apt-get -y install cuda

Une fois Cuda installé, tester immédiatement un fichier Numba utilisant le GPU, par exemple le suivant :

tester_gpu_simple.py

import numpy as np
from numba import cuda, int64

@cuda.jit('(int64[:], int64[:], int64[:])')
def cuda_sum(a, b, c):
    i = cuda.grid(1)
    c[i] = a[i] + b[i]

griddim = 5, 1
blockdim = 2, 1, 1
N = griddim[0] * blockdim[0]
cuda_sum_configured = cuda_sum.configure(griddim, blockdim)

a = np.array(np.random.randint(4, size=N), dtype=np.int64)
b = np.array(np.random.randint(4, size=N), dtype=np.int64)
c = np.empty_like(a)
print("a =", a)
print("b =", b)

cuda_sum_configured(a, b, c)

print('-'*(2*N+7))
print("c =", c)

qui affiche

a = [2 3 2 2 3 1 1 0 2 0]
b = [0 1 1 1 3 2 0 2 2 1]
---------------------------
c = [2 4 3 3 6 3 1 2 4 1]

Cela signifie que désormais, Numba peut s’exécuter sur le GPU de votre machine et avec les dernières versions.

Linux : autres méthodes pour installer les pilotes Nvidia

D’autres méthodes que celles présentées ci-dessus sont expliquées ici : How to install Nvidia driver in Ubuntu 18.04? en particulier si vous avez besoin de désinstaller un pilote Nvidia pas assez à jour. La méthode utilisant autoinstall est particulièrement simple et fonctionne.

Vous verrez parfois dans des forums ou des documentations des commandes d’installation du type :

sudo apt-get install nvidia-driver-xxxxx

sans que le xxxx soit précisé ni expliqué. D’après ce que j’ai compris, il s’agit de la version Nvidia du pilote (en juillet 2020, cela doit être 450). Cette valeur dépend des spécifications de votre carte et de la version d’Ubuntu. Le tableau ICI permet de savoir comment choisir. Par exemple, pour une Ubuntu 19.10, vous écrirez

sudo apt-get install nvidia-driver-390

Il est possible d’installer ses pilotes directement depuis le site de Nvidia avec un fichier run ou un fichier deb.

Il est également possible et paraît-il plus simple d’installer l’environnement Cuda via Docker. Voir un tutoriel ICI

Problèmes de compatibilité entre Cuda et le pilote matériel

Cuda est aussi un environnement de programmation et d’exécution, il est donc amené à évoluer même si votre carte graphique ne change pas. Votre version du Cuda toolkit doit être adaptée à votre pilote matériel. Chaque version du Cuda toolkit suppose une certaine version minimale de votre pilote graphique. Si votre pilote graphique Nvidia a été installé assez longtemps, il se peut qu’il ne fonctionne pas avec votre version de Cuda Toolkit. Toutefois, les programmes utilisant Cuda sont rétro-compatibles. Ainsi, la commande

$ nvidia-smi

+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.57       Driver Version: 450.57       CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+

montre que le pilote matériel installé (n° 450) peut supporter au maximum les possibilités de Cuda 11.0. Pour utiliser Cuda 11.5, il faudra mettre à jour le pilote, cf. explication ICI.

Pour plus de détails, voir