Il y a Joe (tout le monde s'en fou mais je le dis)
MPI + X n'est pas forcément une bonne solution quand on cherche de la performance et l'efficacité énergétique
Quand on scale sur plusieurs GPU, on peut traiter plus de données mais on pert en efficacité énergétique
NVShmem (parallélisme implicite, les threads sont lancés au runtime) a l'air d'être plus scalable que Cuda + OpenMP
Point to point communication (pas de all to all, car ce n'est pas scalable). Le gros point de cette bibliothèque est qu'elle est scalable.
C'est un algorithme par Graph
Bibliothèque de communication basée sur Open SHMEM
On dit quelle mémoire on veut accéder et la Bibliothèque se débrouille (NVLink, Infiniband, etc)
Certaines parties de la mémoire des GPU sont accéssibles à distance mais pas toutes
Le modèle mémoire est symétrique (même allocation sur tous les GPU)
Normalement les gens familier avec MPI peuvent utiliser NVShmem facilement
Pour le moment NVShmem n'est pas intégré dans Omniverse, mais ça viendra
Comme toujours le placement des données est le plus important pour avoir une application scalable
On peut aussi utiliser NVShmem sur 2 GPU autant que sur 100 sans changement de code
Des codes de QCD utilisent déjà NVShmem
Il y aura des backend NVShmem pour Tensorflow et Pytorch
NVShmem s'utilise avec les Cuda Stream
NVShmem s'occupe de l'aggrégation des nessages pour ne pas échanger des paquets trop petits
On peut utiliser NVShmem dans un contexte MPI
UCX supporte RAPIDS, mais pas NVShmem
Pour l'instant les communications via le réseau sont faites avec un thread CPU qui récupère la réquette du thread GPU. Mais la communication directe est en travaux
On peut utiliser Shmem (pour l'hôte) et NVShmem (pour les GPU) dans la même application
cuDF en python (développé en C++, utilise numba pour l'intégration avec Python)
PyOptix : NVidia Optix pour python
Il faut utiliser un décorateur @cuda.jit pour faire du GPU avec Numba
Les types sont déterminés automatiquement
Le type retourné est unifié par rapport à toutes les possibilités si il y a des branchements
Si ce n'est pas possible (genre on a un tuple dans un cas et un float dans l'autre). Ça foire, il n'y a pas de conversion pour que la fonction renvoie toujours un tuple
L'assembleur généré ne diffère pas trop de celui du CUDA C++.
Il y a plein d'algo de compression (sans perte) : de LZ4 à Cascaded en passant par Snappy et GDeflate (basé sur LZ77) et compatibles avec leurs équivalents CPU
Les algo propriétaires Bitcomp (qui a aussi un mode avec perte), ANS (Asymetric Numeral System) et GDeflate
L'API haut niveau de nvCOMP 2.2 a été simplfiée
Ils ont en train de travailler sur ZStandard
Peut-être utilisé avec le GPU Direct Storage
Sur les données tests, la compression la plus lente est à 4 GB/s (sur une A100)
La Décompréssion la plus lente est à 18 GB/s (sur une A100)
Ils sont en train de faire des benchmarks pour les A30 et les autres cartes du genre
Il faut au moins des fichiers de quelques Mo pour avoir de bonnes performances en compression/décompression
Pour le moment on ne peut pas appeler une fonction de compression dans un kernel Cuda
Ils vont ajouter une passe de BitShuffle pour mieux compresser (séparer les exposants des mantisses dans les float, etc)
Il vont ajouter d'autres compresion avec perte
Utiliser des chunk de moins de 8kB n'est pas efficace en terme de perf
Les données à décompresser doivent être accessible par le GPU