Il s'agit de la commande mpy.openmpi qui peut être exécutée dans le fournisseur d'hébergement gratuit OnWorks en utilisant l'un de nos multiples postes de travail en ligne gratuits tels que Ubuntu Online, Fedora Online, l'émulateur en ligne Windows ou l'émulateur en ligne MAC OS
PROGRAMME:
Nom
mpy - Message passant Yorick
SYNOPSIS
mpirun -np mp_size mpy [ -j pfile1.i [ -j pfile2.i [ ... ]]] [ -je fichier1.i [ -je fichier2.i [
... ]]]
mpirun -np mp_size mpy -grouper fichier.i
DESCRIPTION
Yorick est un langage interprété comme Basic ou Lisp, mais beaucoup plus rapide. Voir yorick (1) à
en savoir plus à ce sujet.
MP est une version parallèle de Yorick basé sur l'interface de passage de messages (MPI). Les
la syntaxe exacte pour lancer un travail parallèle dépend de votre environnement MPI. C'est possible
nécessaire de lancer un démon spécial avant d'appeler mirun ou une commande équivalente.
Explications
Le package mpy interface yorick avec la bibliothèque de programmation parallèle MPI. MPI signifie
Interface de transmission de messages ; l'idée est de connecter plusieurs instances de yorick qui
communiquer entre eux via des messages. Mpy peut soit effectuer des opérations simples, hautement parallèles
tâches en tant que programmes interprétés purs, ou il peut démarrer et diriger arbitrairement complexes compilés
packages qui sont libres d'utiliser l'API MPI compilée. L'API interprétée n'est pas destinée
être un wrapper MPI ; au lieu de cela, il est dépouillé au strict minimum.
Il s'agit de la version 2 de mpy (sortie en 2010); il est incompatible avec la version 1 de mpy
(sortie au milieu des années 1990), car la version 1 présentait de nombreux défauts de conception la rendant très
difficile d'écrire des programmes sans conditions de course et impossible à faire évoluer à des millions
de processeurs. Cependant, vous pouvez exécuter la plupart des programmes mpy de la version 1 sous la version 2 en faisant
mp_include,"mpy1.i" avant de mp_include tout fichier définissant une tâche parallèle mpy1 (c'est-à-dire
avant tout fichier contenant un appel à mp_task.)
Utilisation note
L'environnement MPI n'est pas vraiment spécifié par la norme ; les environnements existants sont
très grossiers, et privilégient fortement les jobs batch non interactifs. Le nombre de processus est
corrigé avant que MPI ne commence ; chaque processus a un rang, un nombre de 0 à un de moins que le
nombre de processus. Vous utilisez le rang comme adresse pour envoyer des messages, et le processus
recevoir le message peut sonder pour voir quels rangs lui ont envoyé des messages, et bien sûr
recevoir ces messages.
Un problème majeur dans l'écriture d'un programme de transmission de messages est la gestion des événements ou des messages
arriver dans un ordre imprévu. MPI garantit uniquement qu'une séquence de messages envoyés par
le rang A au rang B arrivera dans l'ordre d'envoi. Il n'y a aucune garantie sur la commande de
arrivée de ces messages relatifs aux messages envoyés à B depuis un troisième rang C. Dans
particulier, supposons que A envoie un message à B, alors A envoie un message à C (ou même échange
plusieurs messages avec C) ce qui fait que C envoie un message à B. Le message de C
peut arriver à B avant le message de A. Un programme MPI qui ne permet pas cela
possibilité a un bogue appelé "condition de course". Les conditions de course peuvent être extrêmement subtiles,
surtout lorsque le nombre de processus est important.
L'interface interprétée de base de mpy se compose de deux variables :
mp_size = nombre de processus
mp_rank = rang de ce processus et quatre fonctions :
mp_send, à, msg; // envoie un message pour classer "à"
msg = mp_recv(de); // recevoir le msg du rang "de"
rangs = mp_probe(bloc); // interroge les expéditeurs des messages en attente
mp_exec, chaîne ; // analyse et exécute la chaîne sur chaque rang
Vous appelez mp_exec au rang 0 pour démarrer une tâche parallèle. Lorsque le programme principal ainsi créé
se termine, tous les rangs autres que le rang 0 retournent à une boucle inactive, en attendant le prochain
mp_exec. Le rang 0 récupère la ligne d'entrée suivante de stdin (c'est-à-dire qu'il attend l'entrée à son
invite dans une session interactive), ou met fin à tous les processus si aucune autre entrée n'est
disponible dans une session batch.
Le package mpy modifie la façon dont yorick gère la directive d'analyseur #include et l'include
et nécessitent des fonctions. A savoir, si une tâche parallèle est en cours d'exécution (c'est-à-dire qu'une fonction a démarré
par mp_exec), tout cela devient des opérations collectives. C'est-à-dire que le rang 0 lit l'ensemble
contenu du fichier et envoie le contenu aux autres processus sous forme de message MPI (comme
mp_exec du contenu du fichier). Chaque processus autre que le rang 0 ne s'exécute que pendant
tâches parallèles; en dehors d'une tâche parallèle lorsque seul le rang 0 est en cours d'exécution (et tous les autres rangs
attendent le prochain mp_exec), la directive #include et les include et require
les fonctions retournent à leur opération sérielle habituelle, n'affectant que le rang 0.
Lorsque mpy démarre, il est en mode parallèle, de sorte que tous les fichiers que yorick inclut lorsqu'il
les démarrages (les fichiers dans Y_SITE/i0) sont inclus en tant qu'opérations collectives. Sans cela
fonctionnalité, chaque processus yorick tenterait d'ouvrir et de lire les fichiers d'inclusion de démarrage,
surcharger le système de fichiers avant que mpy ne démarre. Passer le contenu de ces
fichiers en tant que messages MPI est le seul moyen de garantir qu'il y a suffisamment de bande passante pour chaque
processus pour lire le contenu d'un seul fichier.
Le dernier fichier inclus au démarrage est soit le fichier spécifié dans l'option -batch, soit
le fichier custom.i. Pour éviter les problèmes avec le code dans custom.i qui peut ne pas être sûr pour
exécution parallèle, mpy ne recherche pas custom.i, mais custommp.i à la place. Les
les instructions dans le fichier -batch ou dans custommp.i sont exécutées en mode série sur le rang 0
seul. De même, mpy remplace la fonction process_argv habituelle, de sorte que -i et d'autres
les options de ligne de commande ne sont traitées que sur le rang 0 en mode série. L'intention dans tous ces
cases est de faire en sorte que les fichiers -batch ou custommp.i ou -i include ne s'exécutent que sur le rang 0, comme
si vous les aviez tapés ici de manière interactive. Vous êtes libre d'appeler mp_exec à partir de l'un de ces
pour démarrer des tâches parallèles, mais le fichier lui-même est en série.
Une option de ligne de commande supplémentaire est ajoutée à l'ensemble habituel :
mpy -j unfichier.i
inclut unfichier.i en mode parallèle sur tous les rangs (encore une fois, -i autre.i inclut autre.i uniquement
au rang 0 en mode série). S'il y a plusieurs options -j, les inclusions parallèles se produisent
dans l'ordre de la ligne de commande. Si les options -j et -i sont mélangées, cependant, toutes les inclusions de -j se produisent
avant tout -i inclut.
Comme effet secondaire de la complexité des fonctions d'inclusion dans mpy, la fonction de chargement automatique est
désactivée; si votre code déclenche réellement une inclusion en appelant une fonction chargée automatiquement, mpy
s'arrêtera avec une erreur. Vous devez explicitement charger toutes les fonctions nécessaires pour un parallèle
les tâches utilisant la fonction require s'appellent elles-mêmes à l'intérieur d'une tâche parallèle.
La fonction mp_send peut envoyer n'importe quel tableau yorick numérique (types char, short, int, long,
float, double ou complexe) ou une valeur de chaîne scalaire. Le processus d'envoi du message
via MPI ne préserve que le nombre d'éléments, donc mp_recv ne produit qu'une valeur scalaire ou
un tableau de valeurs 1D, quelle que soit la dimensionnalité transmise à mp_send.
La fonction mp_recv vous oblige à spécifier l'expéditeur du message que vous voulez envoyer
recevoir. Il bloque jusqu'à ce qu'un message arrive réellement de cet expéditeur, mettant en file d'attente tout
les messages d'autres expéditeurs qui peuvent arriver avant. Les messages mis en file d'attente seront
récupéré la commande reçue lorsque vous appelez mp_recv pour l'expéditeur correspondant. Les
la fonction de mise en file d'attente permet d'éviter considérablement plus facilement les types de conditions de concurrence les plus simples
lorsque vous écrivez des programmes parallèles interprétés.
La fonction mp_probe renvoie la liste de tous les expéditeurs de messages en file d'attente (ou nil si
la file d'attente est vide). Appel mp_sonde(0) pour revenir immédiatement, même si la file d'attente est vide.
Appeler mp_sonde(1) à bloquer si la file d'attente est vide, ne retournant que lorsqu'au moins un message
est disponible pour mp_recv. Appel mp_sonde(2) bloquer jusqu'à l'arrivée d'un nouveau message, même si
certains messages sont actuellement disponibles.
La fonction mp_exec utilise une sortance logarithmique - le rang 0 envoie aux processus F, chacun des
qui envoie à F plus, et ainsi de suite, jusqu'à ce que tous les processus aient le message. Une fois un processus
termine toutes ses opérations d'envoi, il analyse et exécute le contenu du message.
L'algorithme de sortance atteint N processus en log à la base F de N étapes. Les processus F
le rang 0 envoie à sont les rangs 1, 2, 3, ..., F. En général, le processus avec le rang r envoie à
rangs r*F+1, r*F+2, ..., r*F+F (quand ceux-ci sont inférieurs à N-1 pour N processus). Cet ensemble
est appelé le « personnel » de rang r. Les rangs avec r>0 reçoivent le message du rang (r-1)/F,
qui est appelé le "patron" de r. L'appel mp_exec interagit avec la file d'attente mp_recv ;
en d'autres termes, les messages d'un rang autre que le boss lors d'un fanout mp_exec seront
mis en file d'attente pour une récupération ultérieure par mp_recv. (Sans cette fonctionnalité, toute tâche parallèle qui
utilisé un modèle de message autre que le fanout logarithmique serait susceptible de course
les conditions.)
Le fanout logarithmique et son équivalent interne sont si utiles que mpy fournit un couple
de fonctions de niveau supérieur qui utilisent le même modèle de sortance que mp_exec :
mp_document, msg ;
total = mp_handin(valeur);
Pour utiliser mp_handout, le rang 0 calcule un msg, puis tous les rangs appellent mp_handout, qui envoie le msg
(une sortie sur tous les rangs autres que 0) partout par le même sortance que mp_exec. Utiliser
mp_handin, chaque processus calcule la valeur, puis appelle mp_handin, qui renvoie la somme de
leur propre valeur et tout leur personnel, de sorte qu'au rang 0 mp_handin renvoie la somme des
valeurs de chaque processus.
Vous pouvez appeler mp_handin en tant que fonction sans argument pour agir en tant que synchronisation ; lorsque
rang 0 continue après un tel appel, vous savez que tous les autres rangs ont atteint ce point.
Toutes les tâches parallèles (tout ce qui a commencé avec mp_exec) doivent se terminer par un appel à mp_handin,
ou une garantie équivalente que tous les processus sont revenus à un état inactif lorsque la tâche
termine au rang 0.
Vous pouvez récupérer ou modifier le paramètre de fanout F à l'aide de la fonction mp_nfan. Le défaut
la valeur est 16, ce qui devrait être raisonnable même pour un très grand nombre de processus.
Une tâche parallèle spéciale est appelée mp_connect, que vous pouvez utiliser pour alimenter interprété
lignes de commande à n'importe quel rang non 0, tandis que tous les autres rangs restent inactifs. Le rang 0 se trouve dans un
boucle en lisant le clavier et en envoyant les lignes au rang "connecté", qui exécute
et renvoie un accusé de réception au rang 0. Vous exécutez la fonction mp_disconnect pour
terminer la tâche parallèle et redescendre au rang 0.
Enfin, une note sur la récupération d'erreur. En cas d'erreur lors d'une tâche parallèle,
mpy tente de quitter gracieusement le mp_exec, de sorte que lorsque le rang 0 revient, tous les autres rangs
sont connus pour être inactifs, prêts pour le prochain mp_exec. Cette procédure sera suspendue pour toujours le cas échéant
l'un des processus est dans une boucle infinie, ou sinon dans un état où il ne sera jamais
appelez mp_send, mp_recv ou mp_probe, car MPI ne fournit aucun moyen d'envoyer un signal qui
interrompt tous les processus. (C'est l'une des façons dont l'environnement MPI est
« brut ».) Le processus de rang 0 conserve le rang du premier processus qui a signalé un
faute, plus un nombre de processus qui se sont mis en faute pour une raison autre que d'être
a envoyé un message qu'un autre rang avait failli. Le premier processus défaillant peut entrer dans dbug
mode via mp_connect ; utilisez mp_disconnect ou dbexit pour revenir en mode série au rang 0.
Options
-j fichier.i inclut le fichier source Yorick fichier.i comme mpy démarre en mode parallèle
à tous les rangs. Ceci est équivalent à la fonction mp_include après mpy
a commencé.
-i fichier.i inclut le fichier source Yorick fichier.i au démarrage de mpy, en mode série.
Cela équivaut à la directive #include après le démarrage de mpy.
-grouper fichier.i inclut le fichier source Yorick fichier.i au démarrage de mpy, en mode série.
Votre fichier de personnalisation custommp.i, le cas échéant, est pas lu, et mpy est
placé en mode batch. Utiliser la commande help sur la fonction batch
(aide, batch) pour en savoir plus sur le mode batch. En mode batch, tous
les erreurs sont fatales ; normalement, mpy arrêtera l'exécution et attendra plus
saisie après une erreur.
Utilisez mpy.openmpi en ligne à l'aide des services onworks.net