Journal Des nouvelles de Fortran

Posté par  (site web personnel) . Licence CC By‑SA.
33
3
mai
2020

Punk is not dead, Fortran non plus. La preuve, avec le présent journal, LinuxFr.org compte désormais en tout et pour tout sept contenus taggés "Fortran" : https://linuxfr.org/tags/fortran/public

Une évolution par les normes

Rappelons que Fortran, qui s'écrivait à l'époque FORTRAN (pour mathematical FORmula TRANslating system), est né chez IBM entre 1954 et 1957 et fait donc partie des tous premiers langages informatiques. Il fait également partie des langages normalisés, ses premières normes datant du milieu des années 60. Depuis trente ans, le modèle est d'alterner révisions majeures et mineures : Fortran 90 et 95, 2003 et 2008, 2018 et 202x. Les normes Fortran sont gérées par le comité international ISO/IEC JTC1/SC22/WG5 et le comité technique américain INCITS PL22.3 (anciennement J3) :

Sur le site du WG5, on trouvera en particulier les brouillons de certaines normes, par exemple celle du Fortran 2008 : https://wg5-fortran.org/f2008.html, ce qui est précieux puisque les normes finales sont des documents à acheter auprès de l'ISO.

Fortran 2003 a apporté en particulier la programmation orientée objet et l'interopérabilité avec les programmes en C. Fortran 2008 apporte des outils natifs pour la parallélisation. Fortran 2018 poursuit l'effort sur l'interopérabilité avec le C et le calcul parallèle.

A noter que l'évolution du langage est pilotée par ces normes, et il faut attendre pas mal d'années avant que l'intégralité d'une norme soit supportée par un compilateur.

De nouveaux compilateurs libres

Dans le domaine du libre, le compilateur gfortran (GNU Fortran, licence GNU GPL 3) domine depuis pas mal de temps. Il s'agit d'un fork de G95 (qui n'est plus maintenu depuis 2013) qui a été inclus en 2005 dans GCC : https://gcc.gnu.org/wiki/GFortran

Mais depuis quelques années plusieurs challengers utilisant LLVM sont en cours de développement :

Une nouvelle maison

Très récemment, et c'est pourquoi est né ce journal, Fortran s'est offert une nouvelle maison : https://fortran-lang.org/. On y trouvera des nouvelles du langage, un tutoriel pour faire ses débuts en Fortran, une liste de compilateurs libres ou propriétaires, une liste de librairies et de paquets. La communauté y travaille en particulier sur une librairie standard (stdlib) et sur un gestionnaire de paquets pour les applications Fortran : https://github.com/fortran-lang

Crunching numbers forever

Pour paraphraser un des principes de la philosophie UNIX, et en caricaturant, Fortran ne fait qu'une seule chose : calculer vite. Mais il le fait bien. Cela n'est certainement pas pour rien dans sa longévité. Dans la communauté scientifique et technique, quand il faut faire des calculs lourds, que ce soit sur un ordinateur de bureau ou un supercalculateur, Fortran reste un choix pertinent.

logical :: no_future = .false.

do while (.not. no_future)
    print *, "The show must go on..."
end do

end

Quelques références

  • # Performance des compilateurs libres

    Posté par  . Évalué à 9.

    Je m'étais laissé dire (il y a bien des lunes) que les compilateurs proprio avaient atteint un niveau de performance assez dingue sur le code généré.

    Qu'en est-il des compilateurs libres ?

    BeOS le faisait il y a 20 ans !

    • [^] # Re: Performance des compilateurs libres

      Posté par  (site web personnel) . Évalué à 10.

      Voici un benchmark récent de divers compilateurs Fortran :
      https://polyhedron.com/?page_id=175
      qui montre que gfortran ne se débrouille globalement pas plus mal que la plupart des compilateurs commerciaux. Maintenant, c'est compliqué les benchmarks : ça dépend des problèmes mathématiques utilisés, des options choisies pour chaque compilateur, des microprocesseurs sur lesquels ont les utilise (sans parler de clusters de machine), etc.

      Personnellement, j'ai longtemps utilisé les ancêtres d'Intel Fortran, en particulier Compaq Visual Fortran, et depuis une douzaine d'années j'utilise principalement gfortran. J'avais acheté Intel Fortran 2015, mais finalement pour les problèmes qui m'intéressent (basés souvent sur la résolution de gros systèmes d'équations différentielles, sur un bon PC), je me suis rendu compte que suivant les problèmes gfortran pouvait être un peu plus rapide qu'Intel ou le contraire, avec des différences en général inférieures à 10 %. Bon, quand on est à 10 % de différence, c'est peu. Même pour un calcul qui dure 10h, c'est vrai qu'on est content de gagner une heure, mais ça n'est pas non plus déterminant pour le choix d'un compilateur. Les compilateurs commerciaux n'implémentent pas forcément plus vite les nouvelles normes Fortran et finalement si on veut bénéficier des nouveautés, au bout d'un an ou deux il faut ressortir le porte-monnaie.

      A noter que dans les benchmarks, il faut aussi se méfier des versions des compilateurs. Dans le cas de gfortran, sur mon Ubuntu j'ai gfortran-4.8, gfortran-5, gfortran-7, gfortran-8 et gfortran-9 ! J'ai un script python qui me permet de tester sur mon problème chaque version avec différentes options ou groupes d'options (-O3, -Ofast, -march=native, -mtune=native…) et je sais d'expérience que la dernière version n'est pas forcément la plus rapide : parfois oui, parfois non. Le numéro de version mineure a aussi son importance : j'ai en ce moment la 7.5, la 8.4 et la 9.2. Comme leur nom l'indique la 7.5 et la 8.4 ont été plus longuement déboguées. Quand une nouvelle version majeure vient de sortir, par exemple x.0 ou x.1, on peut parfois être déçu. Enfin, on est généralement à des différences de l'ordre de 5 %, parfois 10 %.

      En tout cas, j'attends la sortie de Flang (LLVM 11 ?) car il est toujours bon d'avoir plusieurs compilateurs, d'une part pour choisir le plus rapide, d'autre part parce que ça permet d'améliorer la qualité du code (certains compilateurs vont détecter des petits problèmes que d'autres ne verront pas).

      • [^] # Re: Performance des compilateurs libres

        Posté par  (site web personnel) . Évalué à 3.

        Concernant les performances des compilo, c'est un peu la bouteille à l'encre… En effet, tous les compilateurs Fortran sont en fait des compagnons aux compilateurs C et C++ et ont en commun la libc. (Est-il exagéré dire que gfortran n'est jamais qu'un frontend de la libc ?)

        Il y a quelques années, j'ai été dans l'impossibilité de faire tourner mon moteur de blog sur une machine distante car la glibc avec lequel mon binaire avait été compilé refusait le kernel trop ancien. J'ai alors procédé à une recompilation (en édition de liens statique) sur la distro Alpine Linux sachant que sa libc était "musl". Cet exécutable fonctionnait parfaitement sur ma Gentoo sous glibc et tout aussi bien que sur la machine distante fossilisée. Or, sur ces deux machines, la rapidité d'exécution était absolument surprenante. Évidement, sur un seul job de quelques secondes, il est impossible de conclure. Mais pour un job sur dix heures…

        • [^] # Re: Performance des compilateurs libres

          Posté par  . Évalué à 9.

          Est-il exagéré dire que gfortran n'est jamais qu'un frontend de la libc ?

          Oui, c’est très exagéré. Le Fortran standard propose plein de fonctions (dites « intrinsèques ») qui ne sont pas dans la lib C standard, notamment des fonctions mathématiques et de manipulation de tableaux ou de matrices. Ensuite, un langage, ce n’est pas qu’une liste de fonctions, Fortran propose de nombreuses manières d’accéder aux éléments des tableaux, et d’extraire des sous tableaux (tableaux d’indices, masques, etc) et optimiser tout ça est un travail assez différent pour le compilateur par rapport à compiler du C. Après, tous les exécutables, quel que soit le langage avec lequel ils sont écrits, dépendent des bibliothèques auxquelles ils sont liés, et presque tous les compilateurs lient à la lib C par défaut (car elle est installée sur tous les systèmes). Ça ne fait pas de tous les langages de simples surcouches au C.

          C’est un peu comme si en constatant que ton binaire ne s’exécute pas sur Windows et tu en concluais que Fortran n’est qu’un frontend à Linux. Le programme dépend de l’OS, mais il n’est pas seulement une suite d’appels système.

          • [^] # Re: Performance des compilateurs libres

            Posté par  (site web personnel) . Évalué à 3.

            Je me suis mal exprimé !

            Contrairement à Fortran, le langage C prévoit deux situations : programmation sur machine bare metal ou bien machine dotée d'un système d'exploitation.

            Étant donné que le choix a été fait de tout mettre dans une seule librairie, la libc cumule deux emplois : une extension au langage lui-même et une interface au système d'exploitation.

            Dans le cas de gfortran, on est implicitement dans le cas d'une programmation sous système d'exploitation. (D'un point de vue historique, Fortran a d'abord été implémenté sur une machine bare metal. Par la suite, il y a eu les hyperviseurs puis les OS. Le langage successeur à la programmation algébrique sur machine bare metal fut Forth.)

            Mon propos est que gfortran est l'un des frontends de GCC qui gère plusieurs langages de programmation. Que ce soit du C ou du Fortran, le processus passe toujours par le tronc commun GIMPLE. Le processus GCC passe la main ensuite à la libc quelque soit le (ou les) langage(s) de programmation à l'origine du processus. (Je peux être dans l'erreur mais c'est ainsi que je vois les choses.). De ce qui précède (c'est une boutade !) gfortran est bien en amont à la libc sans laquelle rien n'est possible sous Posix.

            • [^] # Re: Performance des compilateurs libres

              Posté par  . Évalué à 5. Dernière modification le 07 mai 2020 à 09:26.

              Je suis une buse en Fortran, mais ma compréhension du commentaire de Jyes, c'est que ce que tu fais en Fortran, c'est quand même surtout des maths ; et que le gros de la lib de Fortran, elle est spécifique à ton implémentation du compilateur Fortran.

              La libc, c'est effectivement pour les interactions avec le système (allocations mémoire, i/o, …). Mais ça représente quoi sur un programme de résolution d'équation ?

              • [^] # Re: Performance des compilateurs libres

                Posté par  (site web personnel) . Évalué à 2.

                La libc, c'est effectivement pour les interactions avec le système (allocations mémoire, i/o, …). Mais ça représente quoi sur un programme de résolution d'équation ?

                Tout dépend du programme. Si ça joue sur des fonctions trigonométrique, gfortran va employer, entre autres, la bibliothèque libquadmath. Ce qui veut dire que l'on code en Fortran ou en C ça ne change que sur l'ergonomie puisque C l'utilise aussi. (Voir ce commentaire sur les bibliothèques invoquées depuis gfortran.) Si ça joue sur d'autres choses mathématiques qui ne sont pas dans libquadmath, un programme pourra invoquer une bibliothèque spécialisée comme la bien connue blas qui a aussi une déclinaison en C (cblas). Une liste des bibliothèques numériques ici.

                Le compilateur Fortran fera la différence en ce que c'est son cœur de métier contrairement à C. Fortran à une approche algébrique des choses et il fait parfaitement la différence entre un entier négatif, zéro et un entier positif. Fortran, par défaut, compte à partir de un. Le langage C, par défaut, compte à partir de zéro ; il est plutôt orienté sur la logique. Voir aussi ce commentaire.

                Si la tâche s'exécute en quelques secondes sur un seul cœur, on n'est pas dans le domaine du calcul intensif. À la limite, si l'on veut triturer des équations déjà disponibles en bibliothèque, peu importe le langage. Mais si on doit faire chauffer les processeurs pendant plusieurs heures, voire plusieurs jours ou même plusieurs semaines comme ça se voit dans de très grands centre de calcul, on ne peut pas occulter le rôle primordial des systèmes d'exploitation. D'où une influence de la qualité de la libc sur les performance globales.

                Par exemple, 10 % de différence de perf sur un job de 10 heures ça commence à compter au niveau de la facture d'électricité et de l'immobilisation du matériel. Si on est sur une station de travail dont on est le seul utilisateur, on peut s'en ficher puisque l'on fera tourner le soft pendant la nuit. Et puis la consommation d'électricité passera en frais généraux. Mais si on est sur un cluster de plusieurs centaines de nœuds, c'est facturé !

                Je ne peux absolument pas répondre à la question de jusqu'à quel point la libc influence les performances car je ne fais pas de calcul intensif. C'est pourquoi j'aimerais que ceux qui en font livrent leur témoignage. Ce type de témoignage n'est pas évident à trouver car le calcul intensif se pratique soit au profit d'une entreprise (protégée par le secret des affaires ou le secret industriel), soit au profit du monde militaire (protégé par le secret défense) ou des labos publiques où la communication est encadrée.

                À noter, qu'à l'extrême opposé du calcul intensif, les micro-services hébergés dans le Cloud sont facturés au temps de fonctionnement et que la libc musl a une bonne réputation pour les containers (particulièrement avec la distro Alpine Linux qui l'emploie).

                • [^] # Re: Performance des compilateurs libres

                  Posté par  . Évalué à 5.

                  Je ne peux absolument pas répondre à la question de jusqu'à quel point la libc influence les performances car je ne fais pas de calcul intensif. C'est pourquoi j'aimerais que ceux qui en font livrent leur témoignage.

                  Elle n’a strictement aucune influence. Un code de calcul intensif correctement écrit fait peu d’allocations mémoires sur le tas (en gros tout est alloué en début de calcul) et passe beaucoup plus de temps à calculer qu’à lire et écrire des données. Donc, autant avoir une version de BLAS et LAPACK fortement optimisée peut apporter un gain non négligeable pour certaines applications, autant la libc n’a aucune importance. Éventuellement, selon la manière dont le code est écrit, ce sont d’autres propriétés du système d’exploitation qui peuvent impacter les performances, comme le coût des filaments (threads), l’efficacité des communications entre processus ou la bonne gestion du matériel (réseau notamment).

                  • [^] # Re: Performance des compilateurs libres

                    Posté par  (site web personnel) . Évalué à 1.

                    Merci de l'information concernant l'usage de la mémoire qui ne se ferait que très peu sur le tas en calcul intensif alors que j'aurais parié (gros !) sur le contraire !

                    Pour information :
                    Par le plus grand des hasards, hier, au cours d'un dimanche oisif, voulant me documenter sur la nouvelle version 10 de gfortran, j'ai lu la version actualisée de son manuel. À la section 5.5 Thread-safety of the runtime library, voici un extrait qui apporte un peu d'eau à mon moulin :

                    The GNU Fortran runtime library uses various C library functions that depend on the locale, such as strtod and snprintf.

                    En tout cas, ce fils de discussion m'aura été bénéfique en ce qu'il m'a obligé à faire la synthèse d'éléments éparpillés dans ma cervelle ! Et puis ça m'a déjà motivé à me plonger dans la doc en programmation asynchrone avec laquelle nous allons devoir vivre dans le futur.

                    • [^] # Re: Performance des compilateurs libres

                      Posté par  . Évalué à 3. Dernière modification le 11 mai 2020 à 18:23.

                      Merci de l'information concernant l'usage de la mémoire qui ne se ferait que très peu sur le tas en calcul intensif alors que j'aurais parié (gros !) sur le contraire !

                      Attention, peu en nombre d’allocations, mais potentiellement beaucoup de volume alloué ! C’est juste que le temps passé dans les allocations est négligeable par rapport au temps de calcul.

                  • [^] # Re: Performance des compilateurs libres

                    Posté par  (site web personnel) . Évalué à 3.

                    Ca semble rejoindre ce que je montrais dans mon commentaire un peu plus bas :
                    https://linuxfr.org/nodes/120297/comments/1809685

        • [^] # Re: Performance des compilateurs libres

          Posté par  (site web personnel) . Évalué à 7.

          Forcément, sur un système d'exploitation un exécutable c'est :
          - des instructions en langage machine directement exécutées par le processeur,
          - des appels aux fonctions du noyau,
          - des appels aux fonctions des librairies du système.
          Pour tout ce qui concerne l'utilisation du matériel, il faut bien passer par ces fonctions : afficher, lire/écrire sur le disque dur, réserver de la mémoire, etc. Même pour utiliser le microprocesseur, sur un système actuel il faut bien en passer par le scheduler du système. On n'a plus le droit de monopoliser le CPU comme dans les années 80.

          D'ailleurs, comme le C, le Fortran est un langage normalisé dont la norme parle très très peu du matériel : par exemple, dans la norme Fortran 2008, le mot "byte" apparaît 8 fois en 621 pages (essentiellement pour dans la partie interaction avec le C) et le mot "octet" 3 fois. Sur le long terme (~63 ans pour le Fortran, ~50 pour le C), on ne peut pas s'appuyer sur du matériel qui évolue au fil des décennies, ou sur des concepts liés aux systèmes d'exploitation qui évoluent tout autant. Fortran a tourné avant même que le concept de byte se fixe sur 8 bits…

          Donc actuellement, sur un système Linux, un exécutable Fortran fait appel au noyau Linux et à la libc. Mais avant la naissance du C et d'UNIX, il se débrouillait autrement. Et s'il faut tourner sur de nouveaux systèmes sans libc, ça ne changera pas grand chose pour l'utilisateur.

          • [^] # Re: Performance des compilateurs libres

            Posté par  (site web personnel) . Évalué à 3.

            Complètement d'accord ! Voir ma réponse à jves ci-dessus.

            Mon interrogation porte sur l'influence du choix de la la libc (glic vs musl par ex.) sur les performances. J'ai constaté, sur une routine faisant massivement des écritures sur le système de fichier, qu'il y avait une différence humainement perceptible.

            Mon usage de Fortran n'est pas le domaine mathématique mais celui des données. (D'un point de vue historique, avant la banalisation de Basic puis du C, Fortran 77 était couramment employé pour gérer des petites bases de données. Il peut toujours le faire par accès directs aux fichiers. Fortran 77 était réellement un langage bon à tout faire. Il a même existé une norme ISO Fortran temps réel industriel.)

            Sachant que le calcul intensif (ou la programmation orientée objet) fait massivement la trituration de données sur le tas, l'appel système mmap() est forcément de la partie. Je fais la supposition que GCC se sert de la libc pour l'invoquer.

            Dans le cas de mon moteur de blog, je l'ai débuté sous F77 et j'employais des fichiers de manœuvre SCRATCH pour gérer les chaînes de caractères de longueur variable. La modernisation du langage apportée par gfortran m'a permis de transférer dans la mémoire vive mes traitements intermédiaires. Ce qui fait que j'ai beaucoup moins d'entrées-sorties sur disque. Mais ils en reste beaucoup…

            Ce qui m'intéresserait de savoir, par pure curiosité intellectuelle, c'est si le choix de la libc a également une influence sur les performances sur des traitements ne faisant que peu ou pas appel à des I/O sur le système de fichier. Les programmeurs en calcul intensif me semble être les personnes idoines pour satisfaire à ladite curiosité !

            • [^] # Re: Performance des compilateurs libres

              Posté par  (site web personnel) . Évalué à 4.

              Je fais pas de calcul intensif. Ceci dit, je pense que le code fortran compilé ne fait des appels libc que pour les interactions avec le noyau et le système, pas pour les fonctions utilitaires a priori, donc pour du code faisant du calcul intensif, ils ne représentent probablement pas grand chose du code qui est compilé surtout en « des instructions en langage machine directement exécutées par le processeur », pour reprendre le premier point plus haut. Donc peu importe le choix de la libc (glibc, musl, celle d'un des bsd ou autre), la performance ne devrait pas être impactée.

              • [^] # Re: Performance des compilateurs libres

                Posté par  (site web personnel) . Évalué à 3. Dernière modification le 06 mai 2020 à 14:45.

                Je n'ai pas de point de comparaison avec/sans libc.

                Par contre, sans aller jusqu'à désassembler le code, on peut peut-être avoir une idée avec des outils simples. Prenons le programme minimaliste suivant :

                print *, "Hello world!"
                end

                Après compilation avec gfortran :

                $ ldd ./a.out
                        linux-vdso.so.1 (0x00007ffded759000)
                        libgfortran.so.5 => /usr/lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007f73d84f2000)
                        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f73d8301000)
                        libquadmath.so.0 => /usr/lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007f73d82b7000)
                        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f73d8168000)
                        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f73d814e000)
                        /lib64/ld-linux-x86-64.so.2 (0x00007f73d87d8000)

                Avec $ strace ./a.out, j'obtiens entre autres 24 appels mmap() lors de l'initialisation (c'est-à-dire avant l'exécution du print).

                Sur un vrai programme de calcul scientifique, qui ne fait que calculer pendant quelques secondes avec un unique print à la fin, ça a l'air pareil. Après la phase d'initialisation, strace n'affiche plus rien jusqu'à l'affichage final.

              • [^] # Re: Performance des compilateurs libres

                Posté par  (site web personnel) . Évalué à 3.

                Il est difficile de généraliser sur les performances en calcul intensif car le champ des machines va d'une unique station de travail plus ou moins survitaminée à la grappe de centaines de machines pas chères. L'espace mémoire n'est pas forcément continu et les processeurs peuvent être en partie virtualisés par GPU. Certaines configurations auront obligatoirement des I/O au niveau du matériel d’interconnexion ce qui fait qu'un programme faisant des maths pures peut avoir les mêmes contingences qu'une base de données.

                D'autre part, un exécutable peut se fabriquer sous deux formes principales : édition de liens statique ou dynamique.

                Si on lie toutes les bibliothèques avec la routine principale on obtient un gros binaire exécutable autonome. Ça charge lentement mais ça fonctionne ensuite plus vite.

                Si l'on recule l'édition de lien au moment du chargement du programme ET si on active l'option "lazy", la routine principale ne nécessitera que l'édition de lien des seules portions de bibliothèque indispensables au démarrage. Par la suite, d'autres portions de cette bibliothèque seront liées au fur et à mesure des besoins. Ça charge plus vite mais ça fonctionne plus lentement.

                À noter que ces portions d'exécutables sont dispersées sur le système de fichier et que la latence de chargement "à la demande" varie selon la configuration de la variable d'environnement PATH au niveau des répertoires à explorer. Un appel système donné ne sera donc pas activé avec le même vivacité selon le référencement du répertoire de la librairie qui l'actionne. Typiquement, une lib chargera plus vite si elle est en /usr/lib plutôt qu'en /usr/local/lib.

                Dans le cas de musl, on est un peu dans la même démarche qu'a eu BusyBox bien connu du monde de l'embarqué : tout mettre dans le même panier. Dans le duel "glibc" face à "musl", on retrouve la même controverse que celle des micros noyaux face aux noyaux monolithiques.

                Je suppose qu'une configuration matérielle donnée sera plus avantagée par une libc donnée plutôt qu'une autre selon qu'elle soit orientée monotâche ou multitâche. Et, dans le cas de matériels poussés à l'extrême, cette différence doit être encore plus sensible qu'avec la bureautique. Sachant aussi qu'un logiciel de calcul peut être tout aussi bien fonctionner en mode monotâche ou multitâche selon qu'il est parallélisé ou non / distribué ou non.

    • [^] # Re: Performance des compilateurs libres

      Posté par  (site web personnel) . Évalué à 6. Dernière modification le 03 mai 2020 à 22:09.

      Attention, dans le benchmack Polyhedron, il y a deux tableaux : le premier sous Windows, le second sous Linux. A noter que le second semble plus favorable pour gfortran (d'ailleurs en version 7.4 sous Linux, et 8.1 sous Windows…).

    • [^] # Re: Performance des compilateurs libres

      Posté par  . Évalué à 10.

      Mon expérience, c’est que le compilateur Intel produit de binaires parfois plus rapide, mais il est très bogué donc au final quand il donne un binaire significativement plus rapide que Gfortran, ça a plutôt tendance à m’inquiéter car j’ai peur qu’il fasse juste n’importe quoi. De plus il est très lent pour compiler, il plante facilement avec des messages d’erreurs cryptiques et si l’on ajoute à ça un support assez tardif des standards, je trouve finalement Gfortran bien plus confortable à utiliser. En pratique j’utilise Ifort pour chercher les bugs dans mon code que Gfortran ne me remonterait pas et améliorer la portabilité de mon code, mais je passe un certain temps aussi à réécrire du code pourtant valide pour qu’Ifort l’accepte.

      Je n’ai pas encore testé les autres compilateurs, donc je trouve ce journal très bienvenu avec toutes ces informations sur les compilateurs existants et en développement.

  • # Ça fait plaisir un journal sur Fortran

    Posté par  . Évalué à 6.

    Merci pour ce journal. Je ne connaissais pas le site fortran-lang.org, je vais l'explorer.
    Coté compilateur gfortran-10 est disponible.

    Coté parallélisation, est-ce que tu utilises les coArray ? Je n'ai pas encore pris le temps de m'y essayer, mais je me dis que pour un code qu'on doit faire tourner sur plusieurs jeux de données indépendants, c'est peut-être plus commode que OpenMP. As-tu une idée là dessus ?

    • [^] # Re: Ça fait plaisir un journal sur Fortran

      Posté par  (site web personnel) . Évalué à 8.

      Bonsoir,

      le site fortran-lang.org est tout frais, il a été mis en ligne très récemment (avril ?).

      Effectivement, j'ai gfortran-10 dans deux machines virtuelles Fedora 32 et Lubuntu 20.04, mais j'attends de mettre à jour mon Ubuntu 19.10 pour faire des tests de vitesse (j'attends le déconfinement pour faire mes mises à jour…)

      Non, je n'ai pas essayé les coarrays. J'ai juste un code de calcul qui utilise du ray tracing, et qui se parallélise très facilement avec OpenMP (quelques lignes de directives bien choisies) pour utiliser tous les coeurs de mes PC. Mais dans le livre "Numerical Computing with Modern Fortran" de R.J. Hanson et T. Hopkins, il y a trois chapitres sur MPI, Coarrays et OpenMP.

      https://books.google.fr/books/about/Numerical_Computing_with_Modern_Fortran.html?id=Oe4mAgAAQBAJ&redir_esc=y

  • # Pas que le calcul

    Posté par  (site web personnel) . Évalué à 10.

    Pour paraphraser un des principes de la philosophie UNIX, et en caricaturant, Fortran ne fait qu'une seule chose : calculer vite.

    Tout d'abord, merci pour le journal ! Mais je me permets d'apporter la contradiction… (On est quand même sur LinuxFr !)

    Je suis l'auteur de deux des sept contenus taggés en référence : ils faisaient la promotion d'un moteur de blog rédigé en Fortran moderne. De toute évidence, nous ne sommes pas là dans des jobs de calcul intensifs prenant des heures (voire des semaines !) mais sur des traitements de l'ordre de la seconde. Et il n'y a point de maths, juste de la manipulation de chaînes de caractères.

    En effet, depuis Fortran 77, la norme a introduit le type caractère et une capacité de traitement sur les fichiers assez conséquent. Fortran 2003 et 2008 ont considérablement étendu la capacité de traitement des chaînes de caractère avec la gestion de l'unicode, les allocations ET les réallocations dynamiques. Comparé au langage C, jouer avec les lettres en Fortran c'est un délice. (Je suis en train de coder un projet qui impose des routines en C pour des accès Internet et, vraiment, quand on doit se coltiner des concaténations de chaîne en C, c'est grosse galère !)

    Fortran a eu un concurrent autrefois : Basic. Ce qui était alors reproché au vieux Fortran c'était sa concision héritée des cartes perforées. Avec la norme F90-F95, ce langage s'est fortement rapproché de l'ergonomie de Basic. Depuis les années 2000, la programmation orientée objet en a fait un outil vraiment polyvalent.

    Oui, Fortran est fort en maths. Mais pas que… C'est pour tordre le cou à cette idée reçue que j'ai commis un article dans Linux Magazine l'été dernier.

    Accessoirement, J'ai longtemps partagé la croyance ci-près :

    A noter que l'évolution du langage est pilotée par ces normes, et il faut attendre pas mal d'années avant que l'intégralité d'une norme soit supportée par un compilateur.

    Sauf que Cray existe toujours et a un compilateur Fortran prétendument à jour de F2008 et presque entièrement de la dernière norme F2018. Je n'ai pas vérifié si c'était vrai car leur compilo ne tourne que sur leur matériel. (Je n'ose même pas imaginer leurs tarifs…)

    Enfin je profite de l'occasion pour suggérer qu'un codeur, ayant la double compétence en C++ et Fortran, ponde un article comparatif entre ces deux langages tant ils semblent partager les mêmes fonctionnalités. (Je ne sais lequel est le plus puissant des deux mais je suis certain que la facilité d'apprentissage est bien en faveur de l'ancêtre.)

    • [^] # Re: Pas que le calcul

      Posté par  . Évalué à 10.

      un article comparatif entre ces deux langages tant ils semblent partager les mêmes fonctionnalités.

      Les mêmes fonctionnalités, c’est mal connaître les deux langages (enfin, dans la mesure où ils sont tous deux Turing complets, il n’y a rien que fait l’un que ne peut pas faire l’autre, mais leurs usages sont très différents).

      En Fortran pas de template, et (presque) pas de généricité. À l’inverse en C++, il a fallu attendre la version 2017 pour avoir un type tableau de taille fixe qui serve à quelque-chose (std::array), là où Fortran offre plein de fonctions de manipulations de tableaux et possède des types qui permettent de détecter beaucoup d’erreurs à la compilation, et certaines à l’exécution (avec -fcheck=bounds par exemple).

      Fortran est plus simple que C++ et dont plus facile à apprendre, et plus facile à lire par des non-experts, il contient aussi beaucoup moins de pièges (malgré quelques héritages tordus, comme tous les vieux langages). Plus facile à compiler aussi, les modules, intégrés au langage depuis Fortran 90 sont toujours en discussion pour C++ qui n’intègre rien de similaire si ce n’est des palliatifs complexes comme les en-têtes précompilés et autres horreurs.

      Au final, j’aime bien le C++, mais je vois bien à l’usage que j’arrive beaucoup mieux à faire évoluer mon code de calcul scientifique en Fortran que mes autres projets en C++. En Fortran, j’ai un tout petit peu plus de duplication de code due à l’absence de généricité, mais finalement très peu et c’est un prix assez faible à payer pour avoir un code lisible et concis pour le traitement de données en tableaux. C’est aussi beaucoup plus facile de faire travailler des étudiants ou des chercheurs pour une durée déterminée sur un code Fortran. Même mes collègues informaticiens mettent du temps à comprendre le code C++ là où le Fortran se lit presque sans apprentissage (et s’apprend relativement vite pour l’écrire).

      Ce qui manquait cruellement au Fortran c’était une manière propre de s’interfacer avec les autres langages et les dernières versions ont largement comblé ce manque.

      • [^] # Re: Pas que le calcul

        Posté par  . Évalué à 5. Dernière modification le 04 mai 2020 à 10:16.

        Ce qui manquait cruellement au Fortran c’était une manière propre de s’interfacer avec les autres langages et les dernières versions ont largement comblé ce manque.

        f2py, pour faire communiquer Fortran et Numpy (bibliothèque scientifique Python) est génial ! Faut lire la doc pour comprendre comment compiler ça bien, mais après, ça marche tout seul. Et du côté du code Fortran, aucun export C nécessaire.

    • [^] # Re: Pas que le calcul

      Posté par  . Évalué à 8.

      Enfin je profite de l'occasion pour suggérer qu'un codeur, ayant la double compétence en C++ et Fortran, ponde un article comparatif entre ces deux langages tant ils semblent partager les mêmes fonctionnalités. (Je ne sais lequel est le plus puissant des deux mais je suis certain que la facilité d'apprentissage est bien en faveur de l'ancêtre.)

      Juste pour compléter le message de jyes, Fortran a une bibliothèque standard très pauvre. Pas de map ou de vector, pas de fonctions d'aléatoire poussées, pas d'itérateur, et comme le dit jyes, pas de généricité.

      Pour faire du calcul scientifique pur, Fortran est plus simple que C++ ; pour faire des programmes complexes, C++ a plus de fonctionnalités (qui sont absente du C, au passage).

      • [^] # Re: Pas que le calcul

        Posté par  . Évalué à 3.

        Une vraie question : ça sert à quoi un itérateur quand on fait de la parallélisation OpenMP ?

        • [^] # Re: Pas que le calcul

          Posté par  . Évalué à 3.

          Je ne comprends pas bien la question. Un itérateur, ça sert à explorer un conteneur sans avoir à le manipuler directement. En Python, par exemple :

          stock = {"chou":15, "hibou":0, "caillou":584}
          for key,value in stock.items():
             print(key, value)

          Aucun risque d’appeler une clé hors du dictionnaire, ou avec un tableau, un indice hors-limite.

          Grace aux fonctions s'appliquant aux tableaux, mais aussi étant donné l'absence de conteneurs complexes, c'est moins utile en Fortran qu'en C++. C'est sûr.

          Par contre, je ne vois pas le rapport avec OpenMP.

          • [^] # Re: Pas que le calcul

            Posté par  (site web personnel) . Évalué à 2.

            Est-ce qu'il y a une notion d'ordre dans l'itération d'un itérateur Python ? Avec une parallélisation, l'ordre ne serait pas forcément respecté au niveau de l'exécution.

            • [^] # Re: Pas que le calcul

              Posté par  . Évalué à 3.

              Il y a un ordre. Et il peut être important. Ce n'est rien d'autre qu'une boucle un à un sur les éléments d'un objet itérable. On peut l'utiliser de manière parallélisable, si chaque opération est indépendante des autres, ou non. Comme une boucle normale, en somme.

          • [^] # Re: Pas que le calcul

            Posté par  . Évalué à 3.

            De ce que j'ai compris un itérateur ça sert en particulier à masquer à l'utilisateur le mécanisme d'accès à l'élément suivant dans la collection d'objets. Quand on parallélise on a justement besoin de maîtriser cet accès, par exemple pour s'assurer que l'élément suivant est voisin en mémoire pour réduire les occurrences de fautes de page.
            Mais bon, je n'ai peut-être rien compris à ce qu'est un itérateur.

      • [^] # Re: Pas que le calcul

        Posté par  (site web personnel) . Évalué à 5.

        Concernant la généricité, Steve Lionel précise qu'il a été question de travailler dessus pour la future norme 202X, mais que ça a été reporté à la norme suivante 202Y faute de consensus :

        https://stevelionel.com/drfortran/2020/04/25/doctor-fortran-in-forward/

      • [^] # Re: Pas que le calcul

        Posté par  (site web personnel) . Évalué à 2.

        Mille mercis à jyes et Gabbro pour cette comparaison entre Fortran et C++. Ça corrobore ce que je sentais obscurément. Mais je pense que C++ restera encore longtemps dans la course car ce langage semble posséder assez expédients (comme le préprocesseur C) pour être rapidement opérationnel sur du matériel nouveau comme les accélérateurs et autres machines hétérogènes.

        Ces témoignages pourraient conduire à une aimable discussion du vendredi sur le sujet suivant : « Est-il censé de gaver de serpent des générations d'étudiants alors Fortran est une nourriture plus saine et digeste ? ».

        • [^] # Re: Pas que le calcul

          Posté par  . Évalué à 6.

          Et je répondrais tout aussi aimablement que tant que ce n'est pas du Matlab, peut-on raisonnablement se plaindre ?

        • [^] # Re: Pas que le calcul

          Posté par  . Évalué à 6.

          Est-il censé de gaver de serpent des générations d'étudiants alors Fortran est une nourriture plus saine et digeste ?

          Personnellement, je n’aime pas trop Python. Mais je trouve qu’avoir un langage de base avec lequel les élèves apprennent tous les concepts est une bonne idée. Introduction aux langages procéduraux, Python est un bon début. Découverte du paradigme orienté objet, Python permet d’apprendre. Enseignement des méthodes numériques et du calcul scientifique, Python et SciPy sont pleins de bonnes choses. Développement d’interfaces graphiques, Python s’en sort encore très bien. Petits scripts et utilitaires, Python est toujours bon dans ce domaine.

          Au final, malgré tout le mal que je pense de ce langage, même moi je l’utilise pour un certain nombre de traitements (notamment conversions de formats de fichiers et substitut à Octave 1), donc ça me paraît un bon couteau suisse à enseigner aux étudiants.

          Quant à

          Mais je pense que C++ restera encore longtemps dans la course

          J’espère bien ! Le fait que Fortran et C++ aient des atouts différents n’est pas toujours à l’avantage du Fortran. Pour un programme qui fait peu de traitement de données mais manipule des structures complexes, C++ est bien plus indiqué que Fortran. Si Qt s’était basé sur le Fortran, son succès aurait été sûrement beaucoup plus timide !


          1. lui même substitut à Matlab, puisque j’ai toujours évité ce dernier comme la peste. 

    • [^] # Re: Pas que le calcul

      Posté par  (site web personnel) . Évalué à 7.

      C'est intéressant de discuter des chaînes de caractères en Fortran. Personnellement, c'est justement un aspect du langage qui m'a toujours dérangé aux entournures. Probablement parce que les chaînes ont (avaient ?) une longueur fixe, qu'il faut jouer avec Trim(), etc. Ca doit venir de mes années BASIC…

      Mais comme ce n'est pas au cœur de mon usage (en gros les chaînes me servent uniquement à manipuler des noms de fichiers de sortie), j'ai sûrement raté des épisodes, ceux dont tu parles avec Fortran 2003 et 2008. Par exemple, je suis complètement passé à côté de l'Unicode dans Fortran… Je vois aussi que dans Fortran 95, il y avait un module optionnel "Varying length character strings" (ISO/IEC 1539-2 : 2000). Est-ce qu'il a été inclus dans la norme principale ?

      Promis, le jour où je retournerai dans mon bureau (?), je relirai ton article dans GLMF !

      Tiens, je ne savais pas que Cray faisait maintenant partie de HP. Ils n'ont pas fini d'implémenter Fortran 2018 (deffered features), mais je suis incapable de juger de ce que ça représente… Bon, on n'est pas dans la même catégorie, je me contenterai de mon cher gfortran… A noter que dans son blog, Steve Lionel précise qu'un de ses objectifs est de réduire le nombre de nouveautés majeures dans les normes pour laisser le temps aux éditeurs de compilateur d'implémenter les normes (https://stevelionel.com/drfortran/2020/04/25/doctor-fortran-in-forward/). D'ailleurs, il dit bien qu'en 2017 seul le compilateur Cray implémentait intégralement Fortran 2008.

      • [^] # Re: Pas que le calcul

        Posté par  (site web personnel) . Évalué à 4.

        Le module "Varying length character strings" n'est plus d'actualité aujourd'hui depuis que les allocations dynamiques sont devenues possibles.

        Il y a donc deux possibilités pour la déclaration des chaînes de caractères :
        1. À l'ancienne, avec une longueur prédéterminée (option LEN);
        2. Avec l'option ALLOCATABLE pour une longueur variable inconnue à la déclaration.

        Dans les deux cas, il faut procéder à leur initialisation. Cette initialisation doit être précédée du mot clé ALLOCATE pour les chaînes de longueur variable. Et si cette allocation est faite en dehors d'une procédure, ne pas oublier DEALLOCATE (l'équivalent de free() en C) pour les fuites de mémoire. Tout ceci est décrit dans mon article de GLMF de sept 2019 à la page 46.

        Depuis F77, il y a eu d'autres procédures prédéfinies (l'équivalent de la "libc") ajoutées concernant les manipulations sur les chaînes comme ADJUSTL et ADJUSTR qui permettent de justifier à droite ou à gauche une chaîne. À INDEX ont été ajoutés SCAN et VERIFY.

        Du fait des allocations dynamiques, le recours à Valgrind est plus que recommandé. Au passage, il permet de dépister des variables non initialisées qui n'ont pas été dépistées par gfortran. À noter que Valgrind a ses exigences concernant la compilation de la libc. (Il est très possible que Valgrind ne soit pas immédiatement utilisable sur votre distribution.) Et, tant qu'on y est, il y a aussi gdb. Ces deux outils sont contraignants pour la machine hébergeant la chaîne de compilation. Personnellement, je suis sous Gentoo et je suis obligé d'activer l'option [FEATURES="splitdebug"] dans "/etc/portage/make.conf". Ceci fait que tout exécutable de la distro est scindé en deux : l'exécutable strippé étant dans "/usr/bin" et la partie contenant les symboles de débug étant dans "/usr/lib/debug". Mais ceci concerne seulement les sources packagées par la distro ; penser à activer les options de compilation GCC "-Og" et "-ggdb" pour vos propres compilations.

  • # Mes premières lignes de code professionnelles

    Posté par  . Évalué à 7.

    Ah Fortran! Faudrait que je réessaie, mais je risque d'être sacrément dépaysé…

    J'ai fait du Fortran IV pendant deux ans sur DEC PDP-11 : pas de WHILE, des IF sans ELSE et surtout ces fichues colonnes à respecter, héritage des cartes perforées…

    C'était au début des années '90, le matériel et la version du langage étaient déjà obsolètes à l'époque!

    • [^] # Re: Mes premières lignes de code professionnelles

      Posté par  . Évalué à 3.

      Il y a 15 ans (aïe ça fait mal ça), on nous enseignant encore le fortran77 à l'université :(

    • [^] # Re: Mes premières lignes de code professionnelles

      Posté par  . Évalué à 9.

      Salut,

      et surtout ces fichues colonnes à respecter, héritage des cartes perforées

      C'est pas grave, on a évolué : maintenant on fait du python !

      (tout message humoristique planqué serait complètement fortuit)

      :)

      Matricule 23415

      • [^] # Re: Mes premières lignes de code professionnelles

        Posté par  (site web personnel) . Évalué à 3. Dernière modification le 04 mai 2020 à 12:04.

        J'ai trouvé un exo concernant Python et les cartes perforées !
        http://www.france-ioi.org/algo/task.php?idChapter=232&idTask=907

        • [^] # Re: Mes premières lignes de code professionnelles

          Posté par  . Évalué à 1.

          Salut,

          J'ai trouvé un exo concernant Python et les cartes perforées !

          Rigolo :)

          Ça change un peu des exos usuels !

          Je vais tenter ma chance ;)

          Matricule 23415

          • [^] # Re: Mes premières lignes de code professionnelles

            Posté par  . Évalué à 3.

            Salut,

            Il y a sûrement possibilité de compacter et peut-être des bugs, mais en R :

            lines <- readLines("input.carte")
            
            # On s'en fiche un peu, mais on lit quand même
            nbLines <- as.integer(lines[1])
            
            # On vire ce paramètre pas utile des données
            lines <- lines[2:length(lines)] # on aurait pu utiliser nbLines...
            
            # Et on y va !
            parseline <- function(inLine) {
              LETTERS[grep("O", unlist(strsplit(inLine, "")))]
            }
            cat(unlist(lapply(lines, parseline)), sep = "", fill = TRUE)

            Et voilà :)

            Suffit de prendre le bout de script, l'enregistrer dans le fichier cartes.Rscript et faire un fichier texte input.carte puis :

            $ Rscript cartes.Rscript
            LETTRES

            Conclusion, ça m'a rapellé que je ne maîtrise toujours pas lapply :p

            Matricule 23415

            • [^] # Re: Mes premières lignes de code professionnelles

              Posté par  . Évalué à 3.

              Ah bin ouais, c'est devenu un one-liner !

              cat(unlist(lapply(readLines("input.carte")[-c(1)], function(inl) LETTERS[grep("O", unlist(strsplit(inl, "")))])), sep = "", fill = TRUE)

              Matricule 23415

              • [^] # Re: Mes premières lignes de code professionnelles

                Posté par  . Évalué à 8.

                Waow vous utilisez des tellement concis !

                perl -ne'while(/O/g){print chr(97+$-[0])}' < input.carte
                

                :p

                https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                • [^] # Re: Mes premières lignes de code professionnelles

                  Posté par  . Évalué à 1. Dernière modification le 04 mai 2020 à 16:00.

                  Salut :)

                  Ah, chouette !

                  Je me disais bien qu'il y avait moyen de faire plus court :)

                  Par contre, toi, il affiche des minuscules et pas de fin de ligne :p

                  Et prendre sur stdin c'était pas dans les exemples :) Mais bon, ok !

                  Matricule 23415

                  • [^] # Re: Mes premières lignes de code professionnelles

                    Posté par  . Évalué à 4.

                    Si ce n'est que ça :)

                    perl -ne'while(/O/g){print chr(65+$-[0])}' input.carte

                    https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll

                    • [^] # Re: Mes premières lignes de code professionnelles

                      Posté par  . Évalué à 1.

                      Salut,

                      Si ce n'est que ça :)

                      Héhé, oui :)

                      Mais je crois qu'il y a moyen de faire encore plus court en APL par exemple.

                      Sauf que comme je n'en ai jamais fait, faut faire sortir les dinosaures de leur grotte !

                      Merci pour ta participation cependant :)

                      Matricule 23415

                      • [^] # Re: Mes premières lignes de code professionnelles

                        Posté par  (site web personnel) . Évalué à 3. Dernière modification le 06 mai 2020 à 12:14.

                        En J, successeur modernisé d'APL, ça donne :

                            echo u:65+(#~0~:])((27|i.@#@])*'O'=])fread'input.carte'
                        LETTRES
                            perl -ne'while(/O/g){print chr(65+$-[0])}' input.carte
                        LETTRES
                        

                        S'il y a moyen de faire mieux, ça m'étonnerait que ça soit beaucoup plus, donc au final même longeur en caractères, mais surtout c'est beaucoup plus long d'un point de vue sémantique. Les transformations fonctionnelles successives de tableau nous forcent à tout garder en tête avant d'avoir un truc, contrairement au style impératif qui nous permet de gérer les étapes au fur et à mesure comme dans la description intuitive « à chaque fois qu'on tombe sur un 'O', on affiche la lettre correspondant au numéro de colonne ».

                        Le code J, par contre, est moins intuitif à expliquer : on construit un tableau identique à la chaîne de caractères de la carte mais avec des 1 à la place des O et des 0 à la place de tout le reste ('O'=]), ensuite on multiplie ça avec un tableau de même longueur construit avec des indices croissants (fonctions composées i.@#@]) modulo 27 (fonction |) pour les retours à la ligne, puis on sélectionne avec la fonction copy #~ (similaire à filter ici) les cases différentes de 0 (0~:]), qui correspondent aux cases où il y avait un O (faut suivre le fil des transformations !), puis on ajoute 65 pour avoir les numéros des caractères, pour enfin appliquer u: au résultat et obtenir les caractères à partir des numéros.

                        Pour ce genre de trucs, je préfère un langage prévu pour ça comme Perl :-) La charge cognitive du code perl est beaucoup moindre pour quelqu'un qui s'y connait dans les deux langages, je pense (même si je pourrais pas totalement l'assurer vu que je suis pas un expert en J non plus).

                        • [^] # Re: Mes premières lignes de code professionnelles

                          Posté par  . Évalué à 1. Dernière modification le 06 mai 2020 à 12:26.

                          Salut,

                          Merci pour le bout de code en J et les explications :)

                          Matricule 23415

                          • [^] # Re: Mes premières lignes de code professionnelles

                            Posté par  (site web personnel) . Évalué à 2. Dernière modification le 06 mai 2020 à 15:11.

                            Tiens, je viens d'avoir une idée pour améliorer un peu :-)

                                echo u:65+('O'&=#27|i.@#)fread'input.carte'
                            LETTRES
                            

                            Plus court et plus intuitif (mais c'est facile à dire après coup :p), ça fusionne deux étapes : maintenant il reste juste la création d'un tableau de même taille avec les numéro de colonne (27|i.@#) avec sélection via # des cases où il y a un O ('O'&=).

                            Et, en pratique, on peut enlever le “echo” si on écrit ça dans l'interface en ligne de commande et pas dans un script.

                            Bon, faut dire que ça faisait longtemps que je m'amusais pas avec du J ;-)

    • [^] # Re: Mes premières lignes de code professionnelles

      Posté par  (site web personnel) . Évalué à 1.

      C'est sûr !
      Des IF sans ELSE, c'est rude ! Ca sent le GO TO !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.