Le but du projet est de mettre en place une infrastructure simple de calcul parallèle.
1. Organisation
Déroulé : Ce mini projet se déroule sur les séances du 2, du 16 et 23 avril.
Les groupes de projet sont de deux personnes maximum.
2. Préliminaire : Groupe de Processus Simple
2.1. Objectif
Le processus parent va créer un nombre fixe de processus nb
et leur transmettre des tâches à réaliser sous la forme du nom d’un programme python.
A chaque enfant est associé un identifiant entre 1
et nb
.
2.2. Architecture
La communication entre le parent et le groupe de processus est bidirectionnel en utilisant des tubes spécifiques selon l’organisation suivante
- sens parent / enfant
i
: le tubeordre[i]
est écrit par le parent et lu par l’enfanti
- sens enfants / parent : le tube
retour
est écrit par tous les enfants et lu par le parent
Le fonctionnement est le suivant : après création des enfants, chaque
enfant attend sur son tube ordre
une chaine de caractère
"commande"
. Cette commande est exécutée par une méthode os.exec*
(voir la séance prochaine). Lorsque la commande est terminée, l’enfant écrit son `id“ sur le tube retour
.
Après création des enfants, le parent créer une file disponibles
qui contient l’ensemble des nb
identifiants.
Il dépile de sa liste de tâches une commande "cmd"
et dépile un enfant de disponibles
, noté i
. Ensuite il transmet "cmd"
sur ordre[i]
.
Si la liste est vide il attend sur retour
. Le parent ajoute alors cet identifiant dans sa file disponibles
.
2.3. Code Test
Pour commencer on ne va pas mettre en place la méthode exec()
mais "commande"
contiendra un entier. Écrire le code permettant
de mettre en place ce groupe de processus avec comme liste de
commandes 100 entiers aléatoires n
entre 1 et 10. La tâche consistera à
attendre (avec time.sleep
) pendant cmd
secondes.
Quel est le meilleur nb
pour votre station (ou VM) de travail ?
3. Groupe de Processus avec “exec“
3.1. Appel “exec()“
Afin d’exécuter n’importe quel code, l’appel système exec()
va
être utilisé. Comme vu en cours, cela remplace le code exécutable
actuel par un autre code. C’est en particulier la méthode
os.execl()
qui va être utilisée ici.
3.2. Groupe
Modifier le code précédent où chaque ligne contient
commande.py arg1 arg2
afin de
- créer un processus d’identifiant
id
- associer la sortie standard de celui-ci au tube
retour
- paramétrer
os.execl
pour avoir une exécution depython3 commande.py id arg1 arg2
sur chaque enfant - ce programme affiche son résultat, sur sa sortie standard, sous la forme
id: résultat
- le processus parent collecte ces résultats dans une liste
retours-calcul
Tester avec le programme suivant boucles.py
from sys import argv id = argv[1] n = int(argv[2]) longtemps = int(argv[3]) for i in range(n): for j in range(longtemps): pass print(f"{id}: Fini {n} boucles")
Utiliser avec n
entre 1 et 10 et longtemps
à 5 000 000 tours.
Que constatez-vous ?
Quel est le meilleur nb
pour votre station (ou VM) de travail ?
4. Calcul de Pi
Le but de cette section est de calculer les décimales de pi de manière parallèle.
4.1. Formule de Leibniz
Nous allons utiliser la formule de Leibniz.
4.2. Découpage en sommes partielles
Afin d’accélérer le calcul nous allons calculer les sommes partielles de cette série alternée en parallèle.
Écrire un programme calcul.py
qui prend deux paramètres entiers
N1
et N2
et qui calcule la somme partielle de Leibniz de
N1
(inclus) à N2
(non inclus).
4.3. Précisions 1
Comme il s’agit d’une somme alternée, il est simple de majorer
l’erreur pour une somme partielle. Rappeler la formule et écrire une
fonction sommeFromPrecision(decimal)
qui renvoie l’entier
correspondant à la somme partielle qui a une précision de decimal
décimal.
Intégrer ce calcul au programme parent afin de
- calculer un entier en fonction d’une précision demandée en argument
- en fonction du nombre
nb
(de coeurs de votre machine?), découper cette somme partielle ennb
sommes partielles - envoyer le travail demandé aux processus du groupe, qui utilise
calcul.py
- additioner l’ensemble des valeurs reçues et afficher le résultat.
On testera avec une précision de 6, puis 8, enfin de 12 décimales.
4.4. Précisions 2 (facultatif)
La précision des flottants en python est limitée. Il est possible de
travailler en précision arbitraire avec la bibliothèque
mpmath
.
La documentation se trouve [ici
https://mpmath.readthedocs.io/en/stable/]. Il s’agit essentiellement
d’installer cette bibliothèque et de
définir la précision
avec mp.dps = 20
.
Réérire les parties calcul avec cette bibliothèque en utilisant l’objet mpf
.