Google s’intéresse énormément aux différentes plateformes pour effectuer des calculs très intensifs en parallèle, notamment dans le cadre de sa solution libre d’apprentissage profond TensorFlow. La société a développé la bibliothèque StreamExecutor, qui simplifie la gestion des calculs parallèles par rapport aux flux de données, avec une exécution principalement prévue sur des accélérateurs comme des processeurs graphiques (GPU). StreamExecutor se propose comme une couche d’abstraction par rapport à OpenCL et CUDA (les deux technologies prédominantes pour le calcul sur processeurs graphiques), tout en proposant un modèle de traitement des flux similaire à celui de CUDA et une implémentation très proche des meilleures pratiques en C++ moderne. Notamment, cette bibliothèque pourrait être utilisée comme couche de base pour les algorithmes parallèles de la bibliothèque standard de C++17.
L’objectif est en réalité très similaire à celui d’OpenMP, dont les dernières versions permettent de décharger du code sur les accélérateurs. La grande différence est qu’OpenMP est une norme qui a évolué depuis 1997 dans un secteur qui a vu quelques révolutions depuis lors : cette API est très spécialisée et a du mal à bien s’adapter aux accélérateurs actuels. Là où OpenMP génère du code tant pour le processeur principal que l’accélérateur, StreamExecutor ne cherche pas à s’occuper du code qui sera exécuté sur l’accélérateur — le développeur reste responsable de cette partie, afin de l’optimiser au mieux. Grâce à cette différence, StreamExecutor peut ainsi gérer de nouveaux accélérateurs assez facilement.
Google l’a récemment proposé en tant que sous-projet de LLVM, une suite de compilateurs libre. Ainsi, cette bibliothèque pourrait être profondément intégrée au niveau du compilateur, ce qui permettrait une série de tests statiques avant l’exécution de code sur un accélérateur. Notamment, en cas de problème d’arité d’une fonction appelée sur un accélérateur, StreamExecutor détecte le problème et reporte directement une erreur au programmeur (au lieu de ne la détecter que lors d’une tentative d’appel du code concerné).
Les développeurs de LLVM sont relativement partagés concernant cette contribution. Leurs griefs portent principalement sur la concurrence avec liboffload, développée dans le cadre de l’implémentation d’OpenMP pour décharger du code sur des accélérateurs — mais très liée à l’implémentation d’OpenMP. Quand StreamExecutor fonctionne avec des extensions pour CUDA et OpenCL, liboffload peut exécuter du code sur des GPU NVIDIA et des CPU Intel Xeon Phi. En réalité, les deux visent des publics fort différents : liboffload est prévue pour un compilateur, tandis que StreamExecutor se dirige vers tout type d’utilisateur, même si les fonctionnalités se recouvrent. Il n’est cependant pas question à l’heure actuelle d’exploiter cette interface de plus haut niveau pour l’implémentation d’OpenMP.
Source : RFC: Proposing an LLVM subproject for parallelism runtime and support libraries
Voir aussi : la documentation préliminaire de StreamExecutor, TensorFlow.