NVIDIA publie son HPC SDK

NVIDIA publie son HPC SDK

OneAPI es-tu là ?

Avatar de l'auteur
David Legrand

Publié dans

Hardware

07/08/2020 4 minutes
6

NVIDIA publie son HPC SDK

Le lancement d'Ampere (A100) n'était pas qu'une offensive matérielle. NVIDIA l'avait annoncé, de nouveaux outils (v)ont être mis à disposition des développeurs. C'est notamment le cas du HPC SDK qui doit faciliter l'exploitation du GPU depuis du code de bas niveau en C(++) et Fortran.

NVIDIA le sait, la guerre de la performance ne se gagne pas simplement en proposant les puces les plus performantes du marché. Il faut aussi réussir à fédérer un large écosystème autour de soi, tant de constructeurs que de développeurs. C'était l'enjeu de CUDA ces 10 dernières années.

Face à NVIDIA et son CUDA, la oneAPI d'Intel

Mais cela demande également de constamment revoir sa manière de faire, aller plus loin pour toucher de nouveaux marchés. Et surtout, s'adapter à l'environnement concurrentiel. Et celui du caméléon va être profondément bouleversé sous peu : Intel débarque dans les GPU et se donne les moyens de convaincre.

C'est une menace bien différente de la multitude d'accélérateurs que l'on voit émerger ici ou là, qui nécessitent en général un développement et des optimisations spécifiques, là où les CPU et GPU sont partout. Ils visent ainsi une clientèle (et une réponse) particulière.

Mais en se plaçant sur le terrain des processeurs graphiques, Intel ajoute la corde qui manquait à son arc : une solution haute performance pour du calcul massivement parallèle, sans commune mesure avec ce que savent faire les CPU en la matière, tout en bénéficiant d'un panel très large de possibilités.

C'est dans la nature même des GPU, mais aussi ce que permet la couche logicielle qui les accompagne, composée de standards mais pas que. Intel l'a lui aussi bien compris en développant sa OneAPI. Un ensemble d'outils de plus ou moins bas niveau permettant de produire du code une seule fois pour profiter d'accélérations diverses : CPU, GPU, FPGA, ASIC, instructions spécifiques et autres accélérateurs intégrés. Une sorte de super CUDA.

Cela va d'ailleurs plus loin, puisqu'Intel propose des outils pour importer du code CUDA existant, promettant que le code produit par la OneAPI ne fonctionnera pas que sur sa plateforme, s'ouvrant à des puces tierces (dont les GeForce). Le tout porté par un développement open source. On a ainsi vu la version 1.6 de oneDNN intégrer un support préliminaire des processeurs IBM Power et des optimisations pour les SoC ARM 64 bits (aarch64).

HPC SDK pour accélérer l'exploitation du GPU

NVIDIA ne pouvait donc pas rester les bras croisés. C'est là qu'intervient son HPC SDK, qui doit lui aussi faciliter la vie des développeurs. Annoncé en marge de l'A100, il est désormais accessible à tous. Sa documentation livre les détails de sa composition, notamment les compilateurs qu'il embarque.

Multiplateforme, il peut être utilisé sur CPU x86, Power PC ou ARM 64 bits, NVIDIA poussant notamment à la création de serveurs ARM/GeForce, adaptant CUDA en ce sens. L'objectif est ainsi de fournir un ensemble d'outils permettant de compiler du code C(++) ou Fortran parallélisé pour qu'il tire parti du GPU et pas seulement du CPU.

Puis de pousser à la transition vers un code plus efficace avec des bibliothèques, analyseurs de performances et autres logiciels prévus à cet effet. Mais NVIDIA ne proposant pas lui-même de CPU et ayant le plus souvent une approche assez fermée de ses outils, se limitant à son propre écosystème, cela sera-t-il suffisant ?

Vu les moyens qu'Intel met dans l'évolution de sa oneAPI et l'importance de l'enjeu pour le géant de Santa Clara dans les mois à venir, il faudra sans doute frapper un peu plus fort.

Écrit par David Legrand

Tiens, en parlant de ça :

Sommaire de l'article

Introduction

Face à NVIDIA et son CUDA, la oneAPI d'Intel

HPC SDK pour accélérer l'exploitation du GPU

Fermer

Commentaires (6)


Ça serait sympa d’avoir un retour de ceux qui utilisent ce genre de techno pour savoir ce qu’ils en pensent de toutes ces API et de l’intérêt / coût du passage de l’une à l’autre :)


Je suis pas sur de comprendre la phrase : “L’objectif est ainsi de fournir un ensemble d’outils permettant de compiler du code C(++) ou Fortran parallélisé pour qu’il tire parti du GPU et pas seulement du CPU.”. On pourra compiler son code C/C++ avec son GPU en plus du CPU ? Ou alors il sera possible de faire du code qui exploitent des ressources, peu importe que ça soit un CPU ou GPU ?



Magyar a dit:





Réponse 2, du code qui exploite CPU et/ou GPU.



(quote:48563:Perfect Slayer)
Ça serait sympa d’avoir un retour de ceux qui utilisent ce genre de techno pour savoir ce qu’ils en pensent de toutes ces API et de l’intérêt / coût du passage de l’une à l’autre :)




Pour la faire courte : Pourquoi faire ? il existe autre chose que CUDA ?



Oui, comme dit dans l’article, NVidia et largement dominant dans le domaine du calcule sur GPU (et avec les carte RTX, les TensorCore sont presque des ASIC dédié uniquement au produit matriciel). La dessus, NVidia arrive à s’imposer avec ses solutions matérielles mais aussi logicielles. OpenCL n’a jamais décollé et ROCm semble aussi prendre la même voie. Du coup, dans le domaine du calcule scientifique, les solutions intègre généralement uniquement le support de CUDA, tout le reste passe au second plan. Au niveau des grilles de calculs, c’est la même chose, on ne trouve que des cartes graphique NVidia.




Magyar a dit:


Je suis pas sur de comprendre la phrase : “L’objectif est ainsi de fournir un ensemble d’outils permettant de compiler du code C(++) ou Fortran parallélisé pour qu’il tire parti du GPU et pas seulement du CPU.”. On pourra compiler son code C/C++ avec son GPU en plus du CPU ? Ou alors il sera possible de faire du code qui exploitent des ressources, peu importe que ça soit un CPU ou GPU ?




La seconde. La première me parrait pas terrible : je ne pense pas qu’il soit possible de réellement accélérer la compilation en utilisant du GPU, je ne vois pas trop comment on peut transformer la compilation en calculs matriciels.



Non, le but est d’avoir un code agnostique du matériel. En effet, tu n’a pas forcément un GPU Nvidia avec CUDA d’installer et sur CPU, tu peux tirer partie des instruction SSE/AVX pour avantageusement remplacer le calcul sur GPU. Mais je suis assez curieux de voir à quel point c’est transparent et bien optimisé. Dans le genre, il existe Numba en python qui semble faire quelque chose de similaire, mais ce n’est pas 100% transparent.



tazvld a dit:


Pour la faire courte : Pourquoi faire ? il existe autre chose que CUDA ?Oui, comme dit dans l’article, NVidia et largement dominant dans le domaine du calcule sur GPU (et avec les carte RTX, les TensorCore sont presque des ASIC dédié uniquement au produit matriciel). La dessus, NVidia arrive à s’imposer avec ses solutions matérielles mais aussi logicielles. OpenCL n’a jamais décollé et ROCm semble aussi prendre la même voie. Du coup, dans le domaine du calcule scientifique, les solutions intègre généralement uniquement le support de CUDA, tout le reste passe au second plan. Au niveau des grilles de calculs, c’est la même chose, on ne trouve que des cartes graphique NVidia.La seconde. La première me parrait pas terrible : je ne pense pas qu’il soit possible de réellement accélérer la compilation en utilisant du GPU, je ne vois pas trop comment on peut transformer la compilation en calculs matriciels.Non, le but est d’avoir un code agnostique du matériel. En effet, tu n’a pas forcément un GPU Nvidia avec CUDA d’installer et sur CPU, tu peux tirer partie des instruction SSE/AVX pour avantageusement remplacer le calcul sur GPU. Mais je suis assez curieux de voir à quel point c’est transparent et bien optimisé. Dans le genre, il existe Numba en python qui semble faire quelque chose de similaire, mais ce n’est pas 100% transparent.




Ok, merci pour la réponse



Magyar a dit:


Ok, merci pour la réponse




Pour te donner une analogie de la différence entre un CPU et un GPU, j’utilise souvent l’exemple de la différence enrte une équipe de recherche avec quelques couples directeur de thèse et son doctorant et collège avec un prof et plein d’élève.



Dans une équipe de recherche tu as quelque couples directeurs de thèse doctorant. Le directeur de thèse va donner des instructions à son doctorant que ce dernier va réaliser une a une. Ca permet de faire des instruction complexe, mais le doctorant n’est capable de faire qu’une instruction que sur une donnée à la fois. S’il doit faire la somme de deux table pair à pair, il devra faire ligne par ligne l’une après l’autre. C’est l’équivalent d’1 seul cœur dans un CPU. Aujourd’hui on a des PC multicœurs, mais c’est grossièrement la même chose.



Cependant, à coté, tu as le collège, qui est composé de plusieurs classe contenant 1 prof et des dixaines d’élèves (64 sur un architecture Ampère). Le prof ne peut donner qu’une seul instruction à l’ensemble de sa classe, cependant il peut demander à chaque élève de travailler sur une position différente d’un tableaux. Du coup, dans le cas d’une addition de 2 tables, s’il y a 64 élève dans la classe, les opération se feront par lot de 64. Cependant, on reste au collèges, et tu ne t’attends pas forcément à faire des truc complexe il faut que les instruction soit simple et claire (les condition, les boucles… tout ce qui est branchement dans le code, le GPU n’aime pas trop ça.).



Au niveau de la programmation, le paradigme est assez différent à la base entre CPU et GPU. Autant sur CPU, tu vas facilement faire des embranchement, des boucles, des conditions…. Et si tu veux parallèliser, chaque exécution parallèle sur chaque cœur va être fait de manière indépendante des autre, et pourra avoir donc suivre sa propre suite d’instruction. Autant sur GPU, le paradigme et plutôt de penser comme une suite sans embranchement de manipulation de donnée dans des tables. Le parallélisme ici est surtout dû au fait que chaque opération travaille directement sur des tables.
La façon de penser est très différente. C’est assez déroutant parfois de devoir se contraindre à manipuler les données dans des tables (des tenseurs) lors qu’il aurait été tellement simple de faire une boucle où une condition, et devoir jouer avec le broadcast et l’ajout de dimension. Typiquement si tu as 2 vecteurs, et tu souhaite faire une table de multiplication des 2 tu devrais faire un truc dans le genre :



sur CPU de manière classique :



#on va utiliser la bibliothèque numpy pour  manipuler des table multidimensionnelles. Même si ça ne fonctionne que sur CPU, c'est un très bon exemple. 
import numpy as np
#v1 et v1 seront mes 2 vecteurs, ici je fais une simple table de multiplication de1 jusqu'à 10
v1=np.arange(10)+1 #V1== [1,2,..., 9,10], le '+1' s’appliquant à l'intégralité du vecteur grâce au broadcast.
v2=np.arange(10)+1
t=np.empty((len(v1), len(v2))) #t : table vide de 10*10
for i, vv1 in enumerate(v1):
for j, vv2 in enumerate(v2):
t[i,j]=vv1*vv2
print(t)
#[[ 1 2 3 4 5 6 7 8 9 10]
# [ 2 4 6 8 10 12 14 16 18 20]
# ...
# [ 10 20 30 40 50 60 70 80 90 100]]


Voici une version plus “GPU” friendly :



import numpy as np
v1=np.arange(10)+1
v2=np.arange(10)+1
v2p=v2[...,np.newaxis]
#v2p==[[1], [2],..., [9], [10]], v2p est un matrice de 10*1. Cette façon de faire est très "numpyesque".
t=v1*v2p
# magie du broadcast à nouveau: une opération entre un table de dimension (10) et une autre (1,10) produit une sortie (10,10) en répétant virtuellement les entrées pour correspondre à cette dimension de sortie.
print(t)


Pour cette dernière partie, j’ai un peu moins de connaissances, mais a priori, sur un GPU, ça va même plus loin les “classe” travaillent en flux continue (CUDA Dynamic Parallelism). Dans l’analogie, si la 6ième B travaille sur les résultats calculés par la 6ième A, la 6ième A ne va pas attendre d’avoir fini de calculer l’intégralité de leur résultat pour les donner à la 6ième B, mais va les donner au fur et a mesure que c’est calculé. Ca n’attend pas que les entrées soient totalement calculées pour commencer à travailler dessus, ça consomme dès que c’est disponible. Du coup, les GPU sont extrêmement efficace lorsque tu enchaînes plusieurs calculs.