Langage de développement de logiciels de calcul scientifique parallèle?

18

Je souhaite développer un logiciel de calcul scientifique parallèle à partir de zéro. Je veux quelques réflexions sur quelle langue commencer. Le programme consiste à lire / écrire des données dans des fichiers txt et à effectuer des calculs lourds en parallèle, avec de nombreuses factorisations LU et l'utilisation de solveurs linéaires clairsemés. Les solutions candidates auxquelles je pensais sont Fortran 2003/2008 avec OpenMP ou co-array, C ++ avec openmp cilk + ou TBB, python. Toute autre suggestion documentée est la bienvenue! Je connais très bien C, Fortran et Java (dans cet ordre). J'ai fait quelques scripts en python mais des trucs basiques.

Je sais que fortran est très rapide, mais difficile à maintenir et à paralléliser. On dit que le C ++ est lent à moins que vous n'utilisiez des bibliothèques externes, etc. Python que j'aime, mais est-il réaliste d'écrire un logiciel complet à l'échelle industrielle?

Le logiciel doit être capable de gérer de grandes quantités de données et être efficace avec les calculs scientifiques. La performance est essentielle.

Pour le fond, j'ai déjà un logiciel de travail écrit en Fortran. Beaucoup de gens ont été impliqués dans le développement pendant de nombreuses années et le code est vraiment sale. Maintenir et paralléliser le code s'est avéré être un cauchemar et je pense à des alternatives.

Petros

electrique
la source
5
En tant que wonk C ++, je n'appellerais pas Fortran difficile à maintenir. La maintenabilité est liée aux bonnes pratiques pour la plupart, pas au choix de la langue. La lenteur de C ++ est survendue. En outre, je recommanderais que vous augmentiez ce poste pour décrire la taille de vos données et les délais requis. J'ai vu «gros» varier de 9 ou 10 ordres de grandeur selon la personne à qui je parle.
Bill Barth
@BillBarth Le problème avec le code Fortran existant est que trois personnes ont été impliquées en utilisant des pratiques différentes. Je viens d'un milieu C, un gars de F77 et un autre de Matlab. Les données ne sont pas attribuables et dimensionnées pour le plus grand système de taille (j'ai été impliqué récemment). Le code a pu simuler un système avec 72000 équations différentielles et 74000 algébriques sur un horizon temporel de 240 s en 350 s (temps écoulé). J'ai réduit cela à 170 en utilisant OpenMP pour paralléliser. Maintenant, je dois exécuter plusieurs cas en parallèle (à balayer pour le contrôle de sécurité).
electrique
4
@BillBarth est trop modeste pour vendre ses compétences en C ++, mais il est également trop généreux dans sa déclaration selon laquelle la "lenteur de C ++ est survendue". Il y a eu un certain nombre de threads C ++ vs Fortran dans scicomp.stackexchange.com qui ont discuté de cette question et la conclusion générale était qu'il n'est tout simplement pas vrai plus que C ++ n'est plus lent que Fortran dans presque tous les cas. Je pense personnellement qu’aujourd’hui cela pourrait être considéré comme un mythe urbain. Ce qui est tout à fait vrai, c'est que si vous tenez compte de la maintenabilité du code, Fortran ne s'en sort pas très bien aujourd'hui.
Wolfgang Bangerth
2
@BillBarth et d'autres, si vous souhaitez continuer à discuter des mérites généraux de Fortran, C ++ et d'autres langages, veuillez le prendre dans la salle de chat scicomp et @ toute personne que vous souhaitez aborder spécifiquement.
Aron Ahmadia
1
@AronAhmadia: ah, allez, j'ai tellement de choses à dire à Jed ;-) (Jed: une autre fois. Dans notre cas, pas de STL pour les matrices clairsemées, mais beaucoup dans les structures de données de maillage adaptatif.)
Wolfgang Bangerth

Réponses:

19

Laissez-moi essayer de décomposer vos besoins:

  • Maintenabilité
  • Lecture / écriture de données textuelles
  • Interfaces / capacités solides pour les factorisations LU
  • Solveurs linéaires clairsemés
  • Performances et évolutivité aux données volumineuses

À partir de cette liste, je considérerais les langues suivantes:

C, C ++, Fortran, Python, MATLAB, Java

Julia est une nouvelle langue prometteuse, mais la communauté se forme toujours autour d'elle et elle n'a été déployée dans aucun nouveau code majeur.

Lecture / écriture de données textuelles

C'est facile à obtenir dans n'importe quel langage de programmation. Assurez-vous que vous mettez correctement en mémoire tampon et fusionnez votre accès d'E / S, et vous obtiendrez de bonnes performances dans toutes les langues que vous devriez considérer. Évitez les objets de flux en C ++ à moins de savoir comment les utiliser de manière performante.

Interfaces / capacités solides pour les factorisations LU

Si vous effectuez des factorisations LU denses, vous souhaiterez utiliser LAPACK ou ScaLAPACK / Elemental pour une fonctionnalité parallèle. LAPACK et ScaLAPACK sont écrits en Fortran, Elemental est écrit en C ++. Les trois bibliothèques sont performantes et bien prises en charge et documentées. Vous pouvez vous y connecter à partir de n'importe quelle langue que vous devriez considérer.

Solveurs linéaires clairsemés

Les premiers solveurs linéaires clairsemés disponibles gratuitement sont presque tous disponibles via PETSc , écrit en C, qui est bien documenté et pris en charge. Vous pouvez vous connecter à PETSc à partir de n'importe quelle langue que vous devriez considérer.

Performances et évolutivité aux données volumineuses

Les seuls paradigmes de programmation parallèle que vous mentionnez sont basés sur la mémoire partagée, ce qui signifie que vous n'envisagez pas une approche informatique basée sur MPI (passage de messages) et à mémoire distribuée. D'après mon expérience, il est beaucoup plus facile d'écrire du code qui évolue bien au-delà d'une douzaine de cœurs à l'aide d'une solution de mémoire distribuée. Presque tous les «clusters» universitaires sont basés sur MPI de nos jours, les grandes machines à mémoire partagée sont chères et, par conséquent, rares. Vous devriez considérer MPI pour votre approche, mais mes conseils s'appliqueront quel que soit le paradigme de programmation que vous choisissez.

En ce qui concerne les performances sur le nœud, si vous écrivez vous-même des routines numériques, il est plus facile d'obtenir de bonnes performances en série dans Fortran. Si vous avez un peu d'expérience en C, C ++ ou Python, vous pouvez obtenir des performances très comparables (C et C ++ sont morts-même avec Fortran, Python et MATLAB arrivent dans un délai d'environ 25% sans trop d'effort). MATLAB le fait grâce à un compilateur JIT et une très bonne expressivité d'algèbre linéaire. Vous devrez probablement utiliser les noyaux numériques Cython, numpy, numexpr ou incorporés pour obtenir les performances revendiquées de Python. Je ne peux pas commenter les performances de Java, car je ne connais pas très bien le langage, mais je soupçonne qu'il n'est pas loin de Python s'il est écrit par un expert.

Une note sur les interfaces

J'espère que je vous ai convaincu que vous allez pouvoir faire tout ce que vous voulez dans n'importe quel langage de programmation que vous envisagez. Si vous utilisez Java, les interfaces C seront un peu difficiles. Python a une excellente prise en charge des interfaces C et Fortran via ctypes, Cython et f2py. LAPACK est déjà emballé et disponible via scipy. MATLAB possède toutes les fonctionnalités dont vous avez besoin dans ses bibliothèques natives, mais n'est pas facilement évolutif ou particulièrement facile à exécuter sur des clusters. Java peut prendre en charge les interfaces C et Fortran avec le JNI , mais n'est pas communément trouvé sur les clusters et dans les logiciels parallèles pour le calcul scientifique.

Maintenabilité

Une grande partie de cela va se résumer à une saveur personnelle, mais le consensus général sur la maintenabilité est que vous voulez minimiser le nombre de lignes de code dans votre logiciel, écrire du code modulaire avec des interfaces bien définies, et pour les logiciels de calcul, fournir des tests qui vérifient l'exactitude et la fonctionnalité de l'implémentation.

Recommandation

J'ai personnellement eu beaucoup de chance avec Python et je le recommande pour de nombreux projets de calcul. Je pense que vous devriez le considérer sérieusement pour votre projet. Python et MATLAB sont probablement les langages les plus expressifs disponibles pour le calcul scientifique. Vous pouvez facilement interfacer Python avec n'importe quel autre langage de programmation, vous pouvez utiliser f2py pour encapsuler votre implémentation Fortran actuelle et réécrire morceau par morceau les parties que vous souhaitez en Python tout en vérifiant que vous maintenez la fonctionnalité. Pour le moment, je recommanderais une combinaison de l'implémentation officielle de Python 2.7 avec scipy . Vous pouvez commencer très facilement avec cette pile à partir de la distribution Enthought Python disponible gratuitement .

Vous pouvez également effectuer la plupart de ces opérations en C, C ++ ou Fortran. Le C et le C ++ sont des langages très attrayants pour les développeurs professionnels avec beaucoup d'expérience, mais ils tripotent fréquemment les nouveaux développeurs et ne sont probablement pas en ce sens une bonne idée pour un code plus académique. Fortran et MATLAB sont populaires en calcul académique, mais sont faibles au niveau des structures de données avancées et de l'expressivité qu'offre Python (pensez à un objet dict Python, par exemple).

Questions connexes:

Aron Ahmadia
la source
1
Une réponse très bien documentée, tout compris. Sous Fortran, j'utilise beaucoup de Lapack. Je vais jeter un œil à python et essayer d'envelopper mon code Fortran pour commencer et passer lentement à Python. La seule chose qui me fait peur, c'est le temps supplémentaire de 25% que je pourrais avoir. Mais s'il vient avec l'avantage d'un code plus expressif et d'une meilleure gestion de l'informatique parallèle, je vais y aller. J'ai mentionné la mémoire partagée uniquement parce que le logiciel fonctionne actuellement de manière interactive (modifiez les données et réexécutez) sur les ordinateurs à mémoire partagée de 2,4,8,24,48 cœurs des chercheurs de l'Uni sous Windows et Linux.
electrique
3
Je ne sais pas comment vous pouvez réclamer 25% de frais généraux pour les noyaux numériques écrits en Python. Les noyaux numériques en Python pur sont souvent 100 fois plus lents que C. Numpy et numexpr peuvent faire un travail décent avec certaines expressions, mais cela n'écrit guère de nouveaux noyaux numériques en Python. Cython peut rendre certaines choses rapides, mais généralement pas à moins de 25% de C. Python est un bon langage de "collage", mais je pense qu'Aron le sur-vend comme solution générale pour les tâches sensibles aux performances.
Jed Brown
Les E / S sont le point faible de Fortran, car Fortran nécessite beaucoup de structure en E / S. Mon expérience de seconde main de parler avec des collègues de mon laboratoire qui travaillent avec Cython correspond à ce que Jed dit à propos de Cython; au moins l'un d'eux écrit un C réglé à la main pour remplacer le Cython pour les tâches exigeantes en performances, puis je pense que les performances de Python appelant le code C résultant sont plus proches de la revendication d'Aron. De plus, si vous voulez mentionner PETSc et Python, vous pourriez aussi bien mentionner petsc4py. La dernière fois que j'ai vu (c'était il y a quelques années), il n'y avait pas de bonnes interfaces MPI pour Java. Cela a-t-il changé?
Geoff Oxberry
@GeoffOxberry: Les liaisons Java MPI existent mais n'ont pas été mises à jour depuis près d'une décennie. Je considère leur statut douteux. Fortran dispose de nombreuses options d'E / S qui peuvent être réalisées très rapidement. Je recommanderais d'explorer Parallel HDF5 (et HDF5, en général). Si les E / S sont vraiment dominantes (plus de 50% du temps d'exécution), des mesures plus sérieuses pourraient être de mise, mais sinon, la qualité et la portabilité et l'interface de type HDF en valent probablement la peine.
Bill Barth
@BillBarth: Je vais devoir vérifier cela. Mon commentaire sur Fortran I / O vient du point de vue de quelqu'un qui m'a recommandé d'écrire un analyseur de fichier d'entrée dans Fortran. C'est possible, en imposant beaucoup de structure, mais je n'ai tout simplement pas vu d'analyseur d'expressions régulières regex ou de bibliothèques d'analyseurs XML à Fortran (pour donner quelques exemples). Il y a une bonne raison à cela: nous sommes les seuls à utiliser Fortran. Nous pensons peut-être à différents cas d'utilisation.
Geoff Oxberry
2

En plus de la réponse très complète d'Aron, j'examinerais les différents fils de discussion sur scicomp.stackexchange qui traitaient de la question de savoir quel langage de programmation prendre - à la fois en ce qui concerne la vitesse des programmes ainsi que la question de la facilité ou de la difficulté il s'agit d'écrire et de maintenir des logiciels dans ces langues.

Cela dit, en plus de ce qui y est écrit, permettez-moi de faire quelques observations:

(i) Vous incluez le co-réseau Fortran dans votre liste. À ma connaissance, le nombre de compilateurs qui le prennent en charge est très faible - et le mien, en fait, est nul. Le compilateur Fortran le plus largement disponible est GNU gfortran, et bien que les sources de développement actuelles analysent un sous-ensemble de co-tableaux, je pense qu'il n'en prend en charge aucun (c'est-à-dire qu'il accepte la syntaxe mais n'implémente aucune sémantique) . Il s'agit bien sûr d'une observation générale sur les nouvelles normes Fortran: que le décalage avec lequel les compilateurs prennent réellement en charge les nouvelles normes est mesuré sur plusieurs années - les compilateurs n'ont implémenté Fortran 2003 que dans les deux dernières années et ne prennent en charge que Fortran 2008 partiellement. Cela ne devrait pas vous empêcher d'utiliser tout cela si vous avez un compilateur qui prend en charge ce que vous utilisez,

(ii) La même chose est certainement vraie avec C ++ / Cilk +: Oui, Intel développe cela sur une branche de GCC mais il n'est disponible dans aucune des versions de GCC et ne le sera probablement pas pendant un certain temps. Vous pouvez vous attendre à ce qu'il prenne encore 2-3 ans au moins jusqu'à ce que vous trouviez Cilk + avec les versions GCC installées sur des machines Linux typiques.

(iii) C ++ / TBB est une autre histoire: le TBB existe depuis un certain temps, a une interface très stable et est compilable avec la plupart des compilateurs C ++ qui existent depuis plusieurs années (sur Linux ainsi que sur Windows) . Nous l'utilisons en deal.II depuis plusieurs années déjà avec de bons résultats. Il y a aussi un très bon livre là-dessus.

(iv) J'ai ma propre opinion sur OpenMP, à savoir que c'est une solution à la recherche d'un problème. Cela fonctionne bien pour paralléliser les boucles internes, ce qui pourrait être intéressant si vous avez des structures de données très régulières. Mais c'est rarement ce que vous voulez faire si vous avez besoin de paralléliser quelque chose - parce que ce que vous voulez vraiment faire est de paralléliser les boucles externes . Et pour cela, des solutions telles que le TBB sont de bien meilleures solutions car elles utilisent les mécanismes du langage de programmation plutôt que d'essayer de décrire ce qui se passe en dehors du langage (via #pragmas) et de telle manière que vous n'avez pas accès aux poignées de threads , indicateurs d'état des résultats, etc., à partir de votre programme.

(v) Si vous êtes expérimental, vous pouvez également jeter un œil aux nouveaux langages de programmation conçus pour la programmation parallèle et, en particulier, pour des tâches comme celles que vous décrivez. Il y en a essentiellement deux que j'examinerais: X10 et Chapel . J'ai vu de bons tutoriels sur Chapel, et cela semble bien conçu, bien que les deux soient bien sûr aujourd'hui des solutions insulaires.

Wolfgang Bangerth
la source
Pour mémoire, Intel affirme avoir un Fortran co-array parallélisé (mémoire distribuée) intégré dans leurs compilateurs actuels. Nous étudions la question au TACC, mais je n'ai rien à signaler pour l'instant. Cray a également une implémentation dans leur compilateur, mais elle n'est disponible que sur un petit nombre entier de machines à travers le monde. Je ne pense pas que quiconque implémente la norme Fortran 2008 complète en ce qui concerne les co-tableaux, mais il y a plus qu'un support naissant dans quelques compilateurs. Cilk + est, bien sûr, également disponible avec les compilateurs Intel, mais être dépendant n'est probablement pas encore sage.
Bill Barth
La norme Fortran 2008 n'a été approuvée qu'à la fin de 2010, il faudra donc quelques années avant que le CAF ne soit largement disponible. G95 avait en fait une implémentation (non gratuite) mais n'est plus développé (le développeur avait rejoint PathScale).
stali
La majeure partie du g95 s'est finalement retrouvée dans le gfortran, mais il se peut que les FAC n'en fassent pas partie.
Wolfgang Bangerth
Je crois que le compilateur Intel fournit un bon support de co-array. Ils l'ont construit en utilisant mpiexec. Ce ne sera pas mon premier choix. La bonne chose est que la même implémentation peut fonctionner sur la mémoire partagée et distribuée (j'ai effectué quelques tests). Avec les processeurs à mémoire partagée opteron atteignant 60 cœurs à des prix vraiment raisonnables, je veux voir mes options de mémoire partagée en premier.
electrique
2

En général, si vous êtes vraiment sérieux au sujet de ce projet de logiciel, je suggérerais une réécriture complète dans la langue avec laquelle vous vous sentez le plus à l'aise. Il semble que vous fassiez le travail seul et que vous obtiendrez donc les meilleurs résultats dans la langue avec laquelle vous vous sentez le plus à l'aise.

Plus précisément, cependant, en ce qui concerne le parallélisme, je vous encourage à essayer de penser un peu en dehors de la boîte. OpenMP a ses points forts, mais est coincé dans un état d'esprit de prendre un code séquentiel et un parallélisme claquant ici et là. Il en va de même, en substance, pour Intels TBB.

Cilk est définitivement un pas dans la bonne direction, c'est-à-dire qu'il vous oblige à repenser votre problème / solution dans une configuration intrinsèquement parallèle. Ce que je n'aime pas, cependant, c'est que c'est encore une autre langue . De plus, comme il ne peut que déduire grossièrement les relations entre les tâches parallèles, le planificateur peut être assez conservateur et peut ne pas bien évoluer pour certains problèmes.

La bonne nouvelle est, cependant, que, encore une fois, si vous êtes sérieux au sujet de votre implémentation, vous pouvez faire ce que fait Cilk, par exemple réécrire votre problème sous la forme d'un ensemble de tâches interdépendantes et les répartir sur un certain nombre de processeurs / cœurs, vous-même en utilisant pthreads ou en utilisant abusivement OpenMP pour générer des processus. Un bon exemple de la façon dont cela peut être fait est le planificateur QUARK utilisé dans la bibliothèque PLASMA . Une belle comparaison de ses performances par rapport à Cilk est donnée ici .

Pedro
la source
Je vais regarder les liens proposés. Le papier de comparaison est très joli! Merci! J'ai pensé à pthreads mais je veux que le programme soit multi-plateforme. D'après ce que je sais, les pthreads ont des problèmes sous Windows (faux?).
electrique
@ p3tris: Le "p" dans pthreads est pour POSIX, il est donc à peu près aussi portable que possible. Il existe des implémentations Windows conformes telles que pthreads-win32ou dans le cygwinprojet.
Pedro
Basé sur stackoverflow.com/q/2797690/801468, je vois qu'il y a beaucoup de choses à trier pour l'utiliser. Étant donné que je ne suis pas programmeur, je préfère m'en tenir à quelque chose de plus testé.
electrique
2

Il y a eu peu de discussions sur le coarray fortran dans les commentaires ci-dessus. À l'heure actuelle, et à ma connaissance limitée, le support de coarray dans les compilateurs est à peu près comme suit:

  • Cray a un compilateur qui prend en charge au moins les fonctionnalités de base de coarray. Je l'ai utilisé pour écrire du code qui était destiné à être "éducatif", mais je dirais que vous pouvez écrire du vrai code dans forar transar. La syntaxe et les concepts sont généralement beaucoup plus simples que MPI, mais comme toujours, il existe des pièges lotsa et les pièges sont différents de MPI.
  • Intel fortran a une prise en charge de coarray intégrée à sa bibliothèque MPI. Soi-disant, cela limite leurs performances de pointe théoriques, mais je n'ai vu aucune mesure.
  • Gfortran prend en charge les coarrays, mais uniquement pour une seule image (ou un seul rang, en langage MPI). Par conséquent, aucune véritable parallélisation n'est disponible tant que gfortran 4.8 ou 4.9 n'est pas sorti.

En général, je serais prudent si vous démarrez un code basé sur Coarray. La syntaxe est simple et beaucoup plus pratique que Fortran / C / C ++ avec MPI, mais elle n'est tout simplement pas aussi complète. Par exemple, MPI prend en charge de nombreuses opérations de réduction, etc., ce qui pourrait être très pratique pour vous. Cela dépendrait vraiment de votre besoin de beaucoup de communication. Si vous voulez un exemple, faites-le moi savoir et je peux vous en fournir quelques-uns, si je peux déterrer les fichiers.

pletnes
la source
Oui, plus d'informations sur l'état de préparation de Fortar Fortran pour ce type de problème seraient certainement utiles. Bienvenue sur scicomp!
Aron Ahmadia
1

Jetez un œil à Spark, c'est un framework distribué pour les calculs en mémoire qui tire parti de la programmation fonctionnelle. La structure d'un programme dans Spark est très différente par rapport à MPI, fondamentalement, vous écrivez un code comme pour un seul ordinateur, qui est automatiquement distribué en tant que fonctions aux données situées en mémoire. Il prend en charge Scala, Java et Python.

Régression logistique (scala):

//load data to distributed memory
val points = spark.textFile(...).map(parsePoint).cache()
var w = Vector.random(D) // current separating plane
for (i <- 1 to ITERATIONS) {
  val gradient = points.map(p =>
    (1 / (1 + exp(-p.y*(w dot p.x))) - 1) * p.y * p.x
  ).reduce(_ + _)
  w -= gradient
}
println("Final separating plane: " + w)

Il existe une extension appelée MLib (bibliothèque d'apprentissage automatique) qui utilise une bibliothèque Fortran pour certains calculs de bas niveau (pour Python, je suppose que numpy est utilisé). Donc, l'idée est simple, concentrez-vous sur votre algorithme et laissez les optimisations à des niveaux inférieurs (ordre de traitement, distribution des données, etc.).

Tombart
la source