GPU

A l’heure actuelle, l’écosystème pour le calcul GPU de Rust est dans l’ensemble moins développé que celui de C++. Il manque notamment encore une solution complète pour écrire la partie GPU (shader) du programme en Rust, même si le prototype rust-gpu est prometteur.

Ce qui est plus mature, en revanche, c’est les bindings vers les bibliothèques graphiques côté hôte.

La plupart des programmes C++ qui font du GPU utilisent directement l’API C bas niveau, qui est verbeuse et piégeuse, à cause de la difficulté d’utiliser des bibliothèques tierces en C++. Mais en Rust, la gestion des dépendances étant un problème bien résolu, on préférera utiliser des couches d’abstractions légères écrites par d’autres personnes.

Ces bindings ne cachent pas la fonctionnalité de l’API, contrairement à l’option plus radicale des moteurs de jeu vidéo (Unreal Engine, Unity…). Ce qu’ils font, c’est d’éliminer toute la partie rébarbative des APIs, liée au fait qu’elles sont spécifiées en C pour des raisons de portabilité :

  • La libération des ressources est automatisée.
  • La gestion des erreurs est basée sur Result et les paniques.
  • Les types manipulés sont plus riches, par exemple on utilise des types énumérés plutôt que des unions ou des structures dont certains membres ont un comportement particulier quand on les met à la valeur spéciale 0.
  • Le système des méthodes centralise la liste des méthodes associées à un type en un seul point de la documentation de la bibliothèque.
  • Et les aspects les plus lourds de l’utilisation (découpage des allocations en sous-allocations, gestion du temps de vie des ressources actuellement utilisées par le GPU, barrières de pipeline…) sont disponibles sous une forme encapsulée plus facile à utiliser, avec possibilité de descendre jusqu’à l’infrastructure sous-jacente via du code unsafe dans les cas rares où on fait des choses trop exigeantes pour l’encapsulation proposée.

A l’heure actuelle, en Rust, je vous recommande deux bibliothèques en particulier :

  • Si vous recherchez une solution mature et bien documentée avec un accès complet aux fonctionnalités du matériel, le support Vulkan de Rust est excellent, avec vulkano comme binding de la vie de tous les jours et ash pour l’accès direct à l’API C sous-jacente. La portabilité entre OS est bonne, mais pas excellente faute de support officiel de Windows et macOS (il faut généralement installer un logiciel tiers pour que ça marche).
  • Si vous privilégiez la portabilité via l’utilisation des APIs graphiques natives de chaque OS, et appréciez une approche plus haut niveau où davantage d’erreurs peuvent être détectées dans le code GPU, en échange de quoi vous êtes prêts à accepter une API moins mature qui couvre moins complètement les fonctionnalités du matériels, alors WebGPU est une autre option à explorer. L’une des implémentations de référence est écrite en Rust, et fournit l’interface haut niveau wgpu qui est l’API graphique la plus utilisée en Rust.

Pour démarrer avec vulkano, qui est la solution que je vous recommanderais actuellement pour le calcul sur GPU hautes performances, je vous conseille le Vulkano Guide qui est le tutoriel officiel du projet. Côté wgpu, l’équivalent est le tutoriel Learn Wgpu, non officiel et moins complet mais qui reste assez bien pour démarrer.

Les deux bibliothèques fournissent également un grand nombre d’exemples d’utilisation plus sophistiquées dans leurs dépôts git respectifs :