Automate Cellulaire sur NetGen
Transcription
Automate Cellulaire sur NetGen
Automate Cellulaire sur NetGen Thibault Failler 2 juillet 2010 Résumé NetGen permet de développer des réseaux réguliers et irréguliers en systèmes concurrents, exprimés actuellement en syntaxe Occam et Cuda. Ces systèmes peuvent ensuite être compilés et exécutés en parallèle sur des multi-coeurs ou des accèlérateurs graphique tels que ceux de Nvidia. Dans ce travail nous avons cherché à spécifier les automates celullaires du jeu de la vie de Conway, afin de vérifier l’apport des abstractions de NetGen, et de ses générateurs de codes dans le cas d’architectures régulières. D’autres domaines peuvent bénéficier d’approches similaires, par exemple, les algorithmes génétiques, les réseaux de neurones, etc ... 1 Description Il est possible de simuler un automate cellulaire sur CUDA en utilisant l’abstraction de NetGen. En effet l’architecture parallèle gérée par CUDA correspond parfaitement aux besoins des automates cellulaires. Chaque cellule exécutée en parallèle change son état suivant les cellules auxquelles elle est reliée. Les cellules sont disposées sur une grille de taille et de connectivitée variable. Cette note montre comment simuler le jeu de la vie. La connectivité est ici fixe : chaque cellule est reliée à tous ses voisins proche c’est à dire de 3 (pour les bords) à 8 connexions. 2 Principes Un grand nombre d’automates cellulaires sont spécifiés à l’aide de syntaxes spécifiques, telles que .lif ou .mcl[1]. Il est avantageux d’utiliser ces syntaxes pour entrer les problèmes dans NetGen. Le logiciel étant écrit en Smalltalk80, sa structure repose natutrellement sur des classes. La classe Mcell permet de lire ces fichiers standard en ce qui concercne le jeu de la vie, afin de récuperer l’état initial d’un automate cellulaire ainsi que les règles associées. 2.1 Mcell : un lecteur pour fichiers .lif et .mcl La première étape se situe au niveau du parser. Il permet de lire un fichier texte au format .lif ou .mcl pour en récupérer des données tel que la hauteur et la largeur du réseau (données calculé dans le cas des fichiers .lif) définissant la taille de l’automate ainsi que les règles et l’état initial. Une grille est ensuite crée pour représenter l’état de chaque cellule du réseau à un moment donné. On obtient un objet de la classe Mcell contenant toutes les informations nécessaires dans ses variables d’instance. Ces informations servent à générer une image en Smalltalk pour visualiser l’automate et aussi faciliter les transmitions de l’ensemble du réseau entre le programme de calcul et smalltalk. 1 Figure 1 – Interface graphique de Mcell 2.2 Connectivité de l’automate cellulaire La plupart des automates cellulaires ont une connectivité logique qui permet d’être représentés par une série de vecteurs de connexions relatives. La classe ConnectivityModel permet de créer cette connectivité grâce aux informations du réseau (c’est à dire la taille, hauteur et largeur) et d’une série de vecteurs représentant les connexions par rapport à une cellule. Chaque cellule est représentée par une coordonnée définissant sa position dans l’automate. Un tableau contient l’ensemble des cellules connectées à la cellule courrante. Un affichage graphique est disponible pour représenter le réseau et les cellules reliées entre elles (figure 2). Le model est ensuite envoyé à la classe CudaBuilder qui va permettre de générer une série de canaux sur le modèle synchrone conforme à NetGen[2]. Pour le jeu de la vie il a été possible d’utiliser 3 approches différentes pour la gestion des connexions entre les cellules : manuelle : La définition se fait dans la fonction parallèle avec un algorithme prédéfinis. Ce qui spécifie le réseau le rendant rapide mais moin flexible. NetGen : Les canaux de communications sont générés par NetGen, le réseau de communication est donc générique et adaptable pour différent type d’automate cellulaire mais la génération est lente dû à l’approche graphique de la génération. automatique : Les connexions entre chaque cellule sont générées grâce à la classe ConnectivityModel (permettant de créer des automates cellulaires 2D et leur connectivité) avec une connectivitée fixe correspondant au jeu de la vie. 2.3 Couplages entre NetGen et l’exécution CUDA Pour exécuter l’automate cellulaire en parallèle sur Cuda, le programme doit être capable de communiquer avec Smalltalk pour récupérer l’état initial du réseau puis de transférer le résultat d’une étape vers Smalltalk. Une fois les canaux générés, les informations (c’est à dire les règles, l’initialisation, et la taille) doivent être transférées au programme CUDA. Le transfert peut s’effectuer à l’aide de fichiers, pipes ou d’une librairie. En premier lieu, le programme CUDA lit la hauteur et la largeur pour pouvoir allouer les sructures de données qui 2 Figure 2 – Représentation d’un automate cellulaire pour le jeu de la vie de 10x10 cellules vont contenir l’automate cellulaire. Les données sont ensuite initialisées. Voici une description du comportement suivant la communication : par fichier : Dans le cas de la communication à l’aide de fichiers. Smalltalk génère un fichier qui va contenir les données d’initialisation. Puis cuda va écrire le résultat d’une étape dans un autre fichier qui sera lu par Smalltalk pour afficher le résultat. Le programme cuda est réexécuté entièrement à chaque étape (figure 3). NetGen Visualworks NetGen CUDA fichier Figure 3 – Communication par fichiers par pipe : Dans le cas des pipes, Smalltalk lance le programme cuda qui lis les informations via stdin et écris dans stdout. Ces descripteurs de fichiers sont récupérés par Smalltalk et permettent donc les transactions de données. Smalltalk envoie dabord les données d’initialisation puis la données ’1’ pour effectuer une étape ou ’0’ pour quitter le programme cuda (figure 5). par librairie partagée : Une librairie est crée pour exécuter le réseau. La librairie est chargée dans smalltalk qui utilise les différentes fonctions pour exécuter l’automate cellulaire (figure ??). par threads sur librairie partagée : La gestion des données Smalltalk et l’exécution Cuda sont séparés en threads. Ce qui permet de calculer une nouvelle étape 3 stdout VisualWorks Cuda stdin Figure 4 – Communication par pipes VisualWorks Appels Cuda Functions et variables de fonctions Figure 5 – Communication par librairie pendant que la précédente est en cours de traitement et donc d’accélérer les performances. Cuda exécute un pas puis attend que Smalltalk lise la donnée. Une fois cette donnée lu, Cuda exécute un autre pas pendant que Smalltalk traite les données pour générer l’image (figure 6). Thread VisualWorks Thread Cuda wait read signal Step signal wait gen Figure 6 – Communication par librairie et séparation en thread Lors de l’ouverture d’un nouveau réseau, les canaux de communications sont regénérés et le programme CUDA recompilé. 3 Mesures de temps pour la génération constructive Différence de vitesse entre la génération exhaustive (NetGen) et constructive (ConnectivityModel) des connexions sur différents réseaux de cellules. Le temps de compilation du programme Cuda n’est pas pris en compte : 4 Mesure de temps pour les différents modules Le tableau récapitule les mesures de temps pour Cuda seul (GPU) puis Cuda avec copie des données sur l’hôte (GPU+CPU) puis le traitement Smalltalk(GPU+CPU+VW, 4 méthode/dimension exhaustive constructive 70x22 821 ms 98 ms 52x52 2138 ms 162 ms 60x102 11578 ms 374 ms 168x260 508168 ms 4056 ms Table 1 – Comparaison des temps des méthodes de génération par examen exhaustif des connexion, et par construction algorithmique d’un réseau régulier VW étant le temps smalltalk seul). Un comparatif peut être fait entre la gestion par librairie(GPU+CPU+VW) et par pipe(PIPE). Les valeurs sont en microseconds sur une boucle de 100 itérations. GPU GPU+CPU GPU+CPU+VW PIPE(avec VM) ONLY VM 10x8 3474 us 4365 us 44134 us 43293 us 39769 us 70x22 4460 us 5343 us 658498 us 738325 us 653155 us 60x102 11808 us 13710 us 3155951 us 3442299 us 3142241 us 168x260 84581 us 93373 us 24954014 us 26649479 us 24860641 us Table 2 – Comparaison entre les différents blocs de calcul compilation réseau réseau+compilation 10x8 1315 ms 7 ms 1322 ms 70x22 2626 ms 125 ms 2751 ms 60x102 2740 ms 359 ms 3099 ms 168x260 19363 ms 8408 ms 27771 ms Table 3 – Temps de compilation et de génération totale du réseau 5 Librairie CUDA Pour utiliser la librairie dynamique CUDA (pour passer les informations via des fonctions plus rapidement que des pipes) il faut renommer les fonctions par leur equivalent en CUDA (en effet les fonctions ont des noms differents une fois compiler via nvcc). La librairie contient des variables global contenant l’état courant de l’automate cellulaire c’est à dire les règles et les données à l’étape courrante. Références [1] http ://psoup.math.wisc.edu/mcell/ca files formats.html. [2] Thibault Failler et B. Pottier. Netgen : un générateur de code pour cuda, principes, implémentation et performances. 5