La norme Fortran 2003 - PDF by hcw25539

VIEWS: 66 PAGES: 19

									                               La norme Fortran 2003
                                         Lionel Meister
                                    IUSTI, UMR CNRS 6595
                             lionel.meister@polytech.univ-mrs.fr



 e   e
R´sum´
                                                         e
Fortran 2003 introduit un certain nombre de nouveaut´s notamment dans le domaine de la programma-
           e                                  e
tion orient´e objet. Certaines de ces nouveaut´s sont l’aboutissement de concepts apparus avec les normes
Fortran {90|95}.


Allocation dynamique
                          ee       e                   c a               a
L’allocation dynamique a ´t´ compl`tement revue de fa¸on ` ne plus avoir ` recourir aux pointeurs et il est
 e
d´sormais plus souple de passer des tableaux allouables en argument.


                 e
Exceptions arithm´tiques IEEE
Fortran 2003 dispose d’une batterie de fonctions et subroutines accessibles par des modules qui permettent
    e                              e           e              e
de g´rer les exceptions IEEE. Sont ´galement pr´vues des proc´dures pour maˆ  ıtriser les modes d’arrondis.


       e       e
Interop´rabilit´ avec C
            e           a                                         e         e
Accessibles ´galement ` l’aide d’un module, de nombreuses proc´dures et d´finitions de types permettent
                                                                    e              e e
une communication entre Fortran 2003 et C. Les pointeurs, proc´dures, types d´riv´s et tableaux sont
       e
interop´rables entre les deux langages, et dans les sens C->Fortran et Fortran->C.


                    e                   e
Programmation orient´e objet (classes, h´ritage, polymorphisme, etc.)
                                                      e
Fortran 2003 introduit de nouveaux types de donn´es qui permettent d’utiliser la puissance d’un langage
       e                                  e                       e e         e e                  e
orient´ objet : classes, polymorphisme, h´ritage, etc. Les types d´riv´s param´tr´s permettent de d´finir de
   c     e e                       e               e    e         e                 e
fa¸on g´n´rique des types de donn´es qui peuvent ˆtre ´tendus (h´ritage) et regroup´s sous forme de classes.
       e                                     e       a            e e           e           e
Il est ´galement possible d’attacher des proc´dures ` ces types d´riv´s afin de d´finir des m´thodes.


Autres apports
                          e      e                                       e
Extension du jeu de caract`res sp´ciaux, augmentation du nombre de caract`res des noms des variables, du
                                       e
nombre de lignes d’une instruction, acc`s aux variables d’environnement pour une communication avec le
    e
syst`me, etc.



                                                     1
              e
Table des mati`res
1 Introduction                                                                                                       3

2 Allocation dynamique                                                                                               3
   2.1   Passage en argument . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        3
   2.2                                 e e
         Allocation au sein d’un type d´riv´ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        4
   2.3    e
         R´allocation par affectation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        4

                               e
3 Gestion des exceptions arithm´tiques IEEE                                                                          5
   3.1   Modules Fortran 2003 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .           5
   3.2   Fonctions d’interrogation     . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .    5
   3.3   Gestion du mode d’arrondi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .          7
   3.4   Fonction de gestion des exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         7
   3.5   Fonctions de gestion des interruptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         8

         e       e
4 Interop´rabilit´ avec le C                                                                                         8
   4.1        e                 e
         Entit´s de type intrins`que . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        8
   4.2          e       e
         Interop´rabilit´ avec les pointeurs C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     10
   4.3          e       e            e e
         Interop´rabilit´ des types d´riv´s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      10
   4.4   Tableaux C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      11
   4.5          e       e         e
         Interop´rabilit´ des proc´dures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       11
         4.5.1   Appel C depuis Fortran . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        11
         4.5.2   Appel Fortran depuis C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        12

                            e                             e
5 Les nouveaux types de donn´es et la programmation orient´e objet                                                   13
   5.1              e e         e e
         Les types d´riv´s param´tr´s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .        13
   5.2   Constructeurs de structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .       14
   5.3         e ee
         Type d´riv´ ´tendu . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .      14
   5.4   Notion de classe    . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   14
         5.4.1    e
                 D´termination du type par passage en argument . . . . . . . . . . . . . . . . . . . . .             14
         5.4.2    e
                 D´termination du type par pointeur . . . . . . . . . . . . . . . . . . . . . . . . . . . .          15
   5.5       e            e a            e e
         Proc´dures attach´es ` un type d´riv´ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         15
         5.5.1                    e
                 Pointeurs de proc´dure      . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .   15
         5.5.2       e            e
                 Proc´dures attach´es par un nom . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .         16
         5.5.3   L’attribut PASS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .     16
         5.5.4       e            e            e
                 Proc´dures attach´es par un op´rateur . . . . . . . . . . . . . . . . . . . . . . . . . . .         17

    e
6 Am´liorations diverses                                                                                             18




                                                          2
    1     Introduction
                                                             e        e        e     e
    Depuis sa standardisation en 1966, Fortran a connu diff´rentes r´visions d´sign´es sous les noms de Fortran
                                                                   e              e           ee
    77, Fortran 90 et Fortran 95 (1978, 1991 et 1997). Seule la r´vision de 1991 ´tait consid´r´e comme majeure
                                               u
    dans l’histoire du langage, dans le sens o` les autres n’apportaient que des corrections ou modifications
               a              e e                            e                           e
    mineures ` la version pr´c´dente. Avec notamment l’av`nement des langages orient´s objet (C++, Java, etc.)
                                                                                     e
    dans le monde de la programmation, il se faisait sentir le besoin d’une nouvelle ´volution de Fortran afin que
                       e                            a           e e
    celui-ci reste comp´titif et ne tombe pas petit ` petit en d´su´tude.
                                    ee       e                                                   ee        e
    C’est le 16 septembre 2004 qu’a ´t´ adopt´e officiellement la norme Fortran 2003 ; l’annonce a ´t´ propag´e
                 e
    par l’interm´diaire notamment du groupe comp.lang.fortran (http://groups-beta.google.com/group/
    comp.lang.fortran/browse frm/thread/d4309629bdacde16/52d6f76186de1799?tvc=1&scrollSave=&&d#
    52d6f76186de1799).
                                                      e
    Les points les plus importants de cette nouvelle r´vision concernent :
    £ l’allocation dynamique des tableaux ;
    £ la prise en compte des exceptions arithm´tique IEEE ;
                                              e
    £ l’interop´rabilit´ avec le C ;
               e       e
    £ les types de donn´es, en particulier pour la programmation orient´e objet ;
                       e                                               e
                                                                          e
    ainsi que d’autres points plus mineurs. L’ensemble de ces points est d´crit dans la suite de ce document.


    2     Allocation dynamique
                                                                                   e                      e
    Apparue avec la norme de Fortran 90, l’allocation dynamique des tableaux pr´sentait jusqu’alors de s´rieuses
                  e                         e
    limitations, n´cessitant l’utilisation d´licate et peu performante de pointeurs (au sens de Fortran). Dans la
                                                       ee        e                                       e
    norme Fortran 2003, l’allocation dynamique a ´t´ repens´e et l’utilisation du pointeur se limitera d´sormais
                                                e
    aux alias dynamiques, pointeurs de proc´dures, etc.


    2.1    Passage en argument
                                                                                                          e
    Il est maintenant possible de passer en argument un tableau avec l’attribut ALLOCATABLE mais non-allou´ et
                             e           e
    de l’allouer dans la proc´dure appel´e. Exemple du programme :
1   program main
2      integer , dimension (: ,:) , allocatable :: tab_i
3      ...
4   ! le tableau tab_i n ’ a ete alloue nulle part
5      call toto ( tab_i )
6      ...
7   end program main

    qui appellerait la subroutine suivante :
1   subroutine toto ( a )
2      integer , dimension (: ,:) , allocatable , intent ( INOUT ) :: a
3      ...
4      allocate ( a (100 ,100))
5      ...
6   end subroutine toto




                                                         3
     2.2                                  e e
            Allocation au sein d’un type d´riv´
               e                                                                  e e
     Il est dor´navant possible d’allouer dynamiquement une composante d’un type d´riv´ :
1    type coord
2       integer :: i , j
3       double precision , dimension (: ,:) , allocatable :: x , y
4    end type coord
5

6    ...
7

8    type ( coord ) :: tab_coord
9    ...
10   imax = tab_coord % i
11   jmax = tab_coord % j
12   allocate ( tab_coord % x ( imax , jmax ) , tab_coord % y ( imax , jmax ))
13   ...


     2.3     e
            R´allocation par affectation
     Supposons que l’on ait un tableau dynamique A et un autre tableau quelconque B, il fallait auparavant
                                            e                                                   a
     s’assurer que les tailles de A et de B ´taient compatibles avant d’affecter le contenu de B ` A :
1    S = size ( B )
2    if ( allocated ( A )) then
3         if ( size ( A )/= S ) deallocate ( A )
4    endif
5    if (. not . allocated ( A )) allocate ( A ( S ))
6    A=B

                                                                   e                                      ee
     Il est convenu maintenant dans Fortran 2003 que l’affectation r´alloue automatiquement la taille de l’´l´ment
                              e e      e
     dynamique ; l’exemple pr´c´dent s’´crit maintenant plus simplement sous la forme :
1    A=B

      u
     o` l’on notera que l’allocation de A est faite directement par l’affectation.
                e         a                   e                ıne           ınes de caract`res dynamiques :
     On pensera ´galement ` la gestion simplifi´e que cela entraˆ pour les chaˆ             e
1    character (:) , allocatable :: nom_dir
2    ...
3    nom_dir = ’../ donnees / ’
4    ...
5    nom_dir = ’../ fichiers_resultats ’

                e          e
     Si on veut ´viter la r´allocation automatique, il suffit d’utiliser les bornes de l’objet. En reprenant l’exemple
       e e
     pr´c´dent avec les tableaux A et B :
1    allocate ( A (1:2* S ))
2    ...
3    A (1: S ) = B

        e          e                                                                    e
     empˆchera la r´allocation automatique de A, qui conservera ainsi sa dimension allou´e explicitement.



                                                           4
    3                                  e
          Gestion des exceptions arithm´tiques IEEE
            e          e                       e                                 e
    L’arithm´tique en r´elle flottante est trait´e par le standard IEEE-754 qui sp´cifie cinq exceptions :
             e                               e           e           e      e
        1. op´ration invalide (invalid ) : op´ration math´matique ind´termin´e renvoyant la valeur NaN (not a
           number ) ;
                        e                          e
        2. valeur calcul´e trop grande pour la repr´sentation de la machine (overflow ) ;
                        e                          e
        3. valeur calcul´e trop petite pour la repr´sentation de la machine (underflow ) ;
                         e
        4. division par z´ro (divide by zero) ;
             e                                         e          e
        5. op´ration inexacte (inexact) : valeur calcul´e non repr´sentable.
            e                                                                         e
    Il est d´sormais possible d’utiliser ce standard avec Fortran 2003 afin qu’un ex´cutable rencontrant une de
                            e                                 e
    ces exceptions ne s’arrˆte pas mais utilise une valeur sp´ciale pour la suite du calcul tout en fixant un flag
                                                                                           e       a
    pour avertir l’utilisateur. Un exemple d’utilisation de ce standard est la gestion de m´thodes ` utiliser pour
                    e            e             e                 e
    un calcul donn´ selon les r´sultats donn´s par certaines op´rations.
                             e
    Fortran 2003 supporte ´galement d’autres aspects du standard IEEE-754 tels que le choix du mode d’arrondi
                                    e            e
    ou le test des valeurs particuli`res rencontr´es (comme NaN par exemple).


    3.1     Modules Fortran 2003
                                       e
    Les trois modules concernant l’impl´mentation de Fortran 2003 sont :
        1. IEEE EXCEPTIONS : gestion des exceptions uniquement ;
        2. IEEE ARITHMETIC : gestion de tous les autres aspects de la norme ;
                                          o               e      a
        3. IEEE FEATURES : permet un contrˆle sur les proc´dures ` utiliser.
                                      e                  o                               e
    Pour chacun de ces modules intrins`que, on a un contrˆle possible sur les seules proc´dures auxquelles on
                  e
    veut avoir acc`s. Exemple :
1   USE , INTRINSIC :: IEEE_FEATURES , ONLY : IE EE_INVA LID_FLA G


    3.2     Fonctions d’interrogation
                                                                                               e
    Il s’agit d’un ensemble de fonctions permettant de tester d’une part l’environnement utilis´ pour savoir s’il
    est conforme ` la norme IEEE-754, et, d’autre part, la classe d’une variable (NaN, ∞, etc.).
                   a
                                                      e
    Les fonctions permettant d’interroger la conformit´ de l’environnement sont :
        1. IEEE SUPPORT STANDARD() ;
        2. IEEE SUPPORT DATATYPE() ;
        3. IEEE SUPPORT DENORMAL() ;
        4. IEEE SUPPORT INF() ;
        5. IEEE SUPPORT NAN() ;
        6. IEEE SUPPORT SQRT() ;
                                     e                            e
    En leur fournissant un argument r´el, elles retournent un bool´en qui indique si l’environnement est conforme
    au standard IEEE-754.
              ıtre              e
    Pour connaˆ la classe d’un r´el x, on dispose de cinq fonctions :
        1. IEEE CLASS(x) : quelle est la classe de x ? ;
        2. IEEE IS NAN(x) : est-ce que x est de type NaN ? ;
        3. IEEE IS FINITE(x) : est-ce que x est fini ? ;

                                                           5
                                                  e
       4. IEEE IS NEGATIVE(x) : est-ce que x est n´gatif ? ;
       5. IEEE IS NORMAL(x) : est-ce que x est normal ?
                                                               e
     dont chacune retourne, selon ce qu’elle interroge, un bool´en ou une des constantes suivantes :
       1. IEEE SIGNALING NAN ;
       2. IEEE QUIET NAN ;
       3. IEEE NEGATIVE INF ;
       4. IEEE NEGATIVE NORMAL ;
       5. IEEE NEGATIVE DENORMAL ;
       6. IEEE NEGATIVE ZERO ;
       7. IEEE POSITIVE ZERO ;
       8. IEEE POSITIVE DENORMAL ;
       9. IEEE POSITIVE NORMAL ;
      10. IEEE POSITIVE INF.
     Exemples :
1    use IEEE_ARITHMETIC
2    type ( IEEE_CLASS_TYPE ) :: c
3    real :: x = -1.0
4    if ( I E E E _SU PPORT _DATA TYPE ( x )) then
5       c = IEEE_CLASS ( x )
6    ! C a la classe IEEE_NEGATIVE_ N O R M A L
7    endif

1    use IEEE_ARITHMETIC
2    real :: x = -1.0
3    if ( IEE E_SUPPORT_SQRT ( x )) then
4    ! teste si l ’ environnement est conforme IEEE pour la fonction SQRT
5       if ( IEEE_SUPPORT_NAN ( x )) then
6       ! teste si l ’ environnement est conforme IEEE pour la gestion des exceptions NaN
7           print * , IEEE_IS_NORMAL ( SQRT ( x ))
8           ! renvoie . FALSE . : la racine de x n ’ est pas de type normal
9

10         print * , IEEE_IS_NAN ( SQRT ( x ))
11         ! renvoie . TRUE . : la racine de x est un NaN
12       endif
13   endif

1    use IEEE_ARITHMETIC
2    real :: x = 1.0
3    if ( I E E E _SU PPORT _DATA TYPE ( x )) then
4      print * , IEEE_IS_FINITE ( x )
5      ! renvoie . TRUE . : x est fini
6

7      print * , IEEE_IS_NEGATIVE ( x )
8      ! renvoie . FALSE . : x n ’ est pas negatif
9    ENDIF




                                                          6
     3.3    Gestion du mode d’arrondi
              e                     e                                e
     Deux proc´dures permettent de g´rer le mode d’arrondi que l’on d´sire utiliser lors de calculs :
       1. IEEE GET ROUNDING MODE(round value) ;
       2. IEEE SET ROUNDING MODE(round value).
      u                                                                              e
     o` round value est une constante du type IEEE ROUND TYPE et dont la valeur peut ˆtre une des suivantes :
                                      e             a               e
       1. IEEE NEAREST : arrondit le r´sultat exact ` la valeur repr´sentable la plus proche ;
                                      e             a               e                         e c            e
       2. IEEE TO ZERO : arrondit le r´sultat exact ` la valeur repr´sentable suivante en se d´pla¸ant vers z´ro ;
       3. IEEE UP : arrondit le r´sultat exact a la valeur repr´sentable suivante en se d´pla¸ant vers + ∞ ;
                                 e             `               e                         e c
       4. IEEE DOWN : arrondit le r´sultat exact ` la valeur repr´sentable suivante en se d´pla¸ant vers − ∞ ;
                                   e             a               e                         e c
       5. IEEE OTHER : indique que le mode d’arrondi choisi n’est pas conforme au standard IEEE ;
1    use IEEE_ARITHMETIC
2    type ( IEEE_ROUND_TYPE ) :: round_value
3    call I E E E_G ET _RO UN DIN G_ MO DE ( ROUND_VALUE )
4    if ( ROUND_VALUE == IEEE_OTHER ) then
5      print * , " Attention vous n ’ utilisez pas un mode d ’ arrondi conforme IEEE -754! "
6    endif

1    use IEEE_ARITHMETIC
2    type ( IEEE_ROUND_TYPE ) :: round_value
3    ...
4    if ( I E E E _SU PPORT _DATA TYPE (1.1)) then
5      call I EE E_S ET _RO UN DIN G_ MO DE ( IEEE_NEAREST )
6      print * , IEEE_RINT (1.1)               ! affiche 1.0
7      call I EE E_S ET _RO UN DIN G_ MO DE ( IEEE_UP )
8      print * , IEEE_RINT (1.1)               ! affiche 2.0
9    endif


     3.4    Fonction de gestion des exceptions
                      e
     Il s’agit de proc´dures activant des flags lorsqu’ont lieu des exceptions :
                                                                  e
       1. IEEE GET FLAG(flag, flag value) : retourne le bool´en TRUE dans flag value lorsque le type d’ex-
          ception flag se produit, et FALSE dans le cas inverse ;
                                                                           e                     e
       2. IEEE SET FLAG(flag, flag value) : permet d’activer (TRUE) ou de d´sactiver (FALSE) la d´tection
          d’une exception de type flag.
     Exemples d’utilisation :
1    use IEEE_EXCEPTIONS
2    logical :: flag_value
3    ...
4    call IEEE_GET_FLAG ( IEEE_OVERFLOW , flag_value )
5    if ( flag_value ) then
6      print * , " Probleme d ’ overflow signale . "
7    else
8      print * , " Pas de probleme d ’ overflow signale . "
9    endif
10   ...


                                                           7
     et
1    use IEEE_EXCEPTIONS
2    ...
3    call IEEE_SET_FLAG ( IEEE_OVERFLOW , . true .)
4    ! toutes les erreurs de type IEEE_OVERFLOW seront maintenant signalees


     3.5    Fonctions de gestion des interruptions
                                                                 e
     Il est possible de donner un type de comportement (s’arrˆter ou continuer) en fonction des exceptions
              e              e                           a a
     rencontr´es pendant l’ex´cution d’un programme grˆce ` :
                                                                              e
        1. IEEE GET HALTING MODE(flag, halting) : retourne le mode d’arrˆt pour une exception de type flag
                           a e                                           a
           et met halting ` l’´tat TRUE si cette exception se produit et ` FALSE sinon ;
                                                                         o
        2. IEEE SET HALTING MODE(flag, halting) : permet de contrˆler la continuation (FALSE) ou l’arrˆte
                                    e
           (TRUE) du programme apr`s qu’une exception de type flag se soit produite.
     Exemples :
1    use IEEE_EXCEPTIONS
2    logical halting
3    ...
4    call I E E E_GE T_HAL TING_ MODE ( IEEE_OVERFLOW , halting )
5    ...
6    if ( halting ) then
7      print * , " Le programme s ’ arrete a cause d ’ une erreur d ’ overflow . "
8    endif

     et
1    use IEEE_EXCEPTIONS
2    real :: x
3    ...
4    call I E E E_SE T_HAL TING_ MODE ( IEEE_DIVIDE_BY_ZERO , . false .)
5    x = 1.0 / 0.0
6    ! Le programme continue malgre une erreur de division par zero
7    ...
8    call I E E E_SE T_HAL TING_ MODE ( IEEE_DIVIDE_BY_ZERO , . true .)
9    x = 1.0 / 0.0
10   ! Le programme s ’ arrete a cause d ’ une erreur de division par zero



     4            e       e
           Interop´rabilit´ avec le C
                          e
     Afin de rentre interop´rables Fortran 2003 et C, la nouvelle norme Fortran impose certaines restrictions
               ee                                                                        e
     quant aux ´l´ments manipulables, mais dont les conditions d’utilisation sont facilit´es par l’emploi du module
     ISO C BINDING.


     4.1         e                 e
            Entit´s de type intrins`que
          e                                                      e       e                 e
     Les d´clarations Fortran 2003 des types permettant l’interop´rabilit´ avec C sont list´es dans le tableau
     suivant :
                           e
     Par exemple dans les d´clarations Fortran 2003 suivantes :

                                                           8
Type        Constante               type C
Entier      C INT                   int
            C SHORT                 short int
            C LONG                  long int
            C LONG LONG             long long int
            C SIGNED CHAR           signed char, unsigned char
            C SIZE T                size t
            C INT8 T                int8 t
            C INT16 T               int16 t
            C INT32 T               int32 t
            C INT64 T               int64 t
            C INT LEAST8 T          int least8 t
            C INT LEAST16 T         int least16 t
            C INT LEAST32 T         int least32 t
            C INT LEAST64 T         int least64 t
            C INT FAST8 T           int fast8 t
            C INT FAST16 T          int fast16 t
            C INT FAST32 T          int fast32 t
            C INT FAST64 T          int fast64 t
            C INTMAX T              intmax t
            C INTPTR T              intptr t
 e
R´el        C FLOAT                 float
            C DOUBLE                double
            C LONG DOUBLE           long double
Complexe    C FLOAT COMPLEX         float Complex
            C DOUBLE COMPLEX        double Complex
            C LONG DOUBLE COMPLEX   long double Complex
    e
Bool´en     C BOOL                   Bool
      e
Caract`re   C CHAR                  char




                               9
1   use ISO_C_BINDING
2   ...
3   integer ( kind = C_INT ) :: i
4   real ( kind = C_DOUBLE ) :: x

                                     e                 e
    les variables i et x sont interop´rables avec les d´clarations en C suivantes :
1   int i ;
2   double x ;

                ınes de caract`re, on les d´clarera en Fortran 2003 pour qu’elles soient interop´rables :
    Pour les chaˆ             e            e                                                    e
1   character ( kind = C_CHAR ) , dimension (*) :: chaine

                  e
    puisque C ne g`re que les CHARACTER de longueur 1, en utilisant les tableaux.


    4.2           e       e
           Interop´rabilit´ avec les pointeurs C
                                                                                          e
    Bien que la notion de pointeur existe dans la norme Fortran 90/95, elle est bien diff´rente de celle de C. Par
    exemple, dans Fortran, on ne peut ni connaˆ                                 e    e
                                                   ıtre ni manipuler l’adresse d´sign´e par un POINTER qui peut
                             e               u
    pointer sur une zone m´moire non contig¨e. On peut voir comme application directe le passage de tableaux
                                                   e                       e
    dynamiques entre les deux langages. Ces diff´rences impliquent la d´finition de certaines contraintes pour
             e       e
    l’interop´rabilit´ entre Fortran 2003 et C.
             e e                 a                             e
    Le type d´riv´ Fortran 2003 ` utiliser pour la compatibilit´ avec tout pointeur C est C PTR. Trois proc´dures
                                                                                                           e
      e
    sp´cifiques aux pointeurs sont disponibles :
      1. C LOC(x) qui retourne l’adresse C de x ;
      2. C F POINTER (CPTR, FPTR [, SHAPE])) qui permet de construire un pointeur Fortran d’une certaine
                a
         forme, ` partir d’un pointeur C ;
      3. C ASSOCIATED(C PTR1 [, C PTR2])) qui permet de de tester si un pointeur C est nul et si deux poin-
         teurs C sont identiques.


    4.3           e       e            e e
           Interop´rabilit´ des types d´riv´s
                     e e               e
    Pour qu’un type d´riv´ soit interop´rable, il faut lui donner l’attribut BIND :
1   type , BIND ( C ) :: coord
2   ...
3   end type coord

    Exemple :
1   use ISO_C_BINDING
2   type , BIND ( C ) :: coord_f
3      integer ( kind = C_INT ) :: i , j
4      real ( kind = C_FLOAT ) :: x , y
5   end type coord_f

               e
    est interop´rable avec :
1   typedef struct {
2      int i , j ;
3      float x , y ;
4   } coord_c

                                                          10
     Il faut noter qu’il n’est pas possible d’utiliser des composantes dynamiques dans des structures de ce type.
     Pour pouvoir en utiliser, on devra passer par des pointeurs C.


     4.4     Tableaux C
                            e
     Les indices sont invers´s entre C et Fortran pour le stockage des tableaux. Ainsi, le tableau Fortran suivant :
1    integer ( kind = C_INT ) :: tab_f (20 , 6:10 , *)

                e
     est interop´rable avec le tableau C :
1    int tab_c [][5][20]


     4.5            e       e         e
             Interop´rabilit´ des proc´dures
                      e                 e           e
     Afin que les proc´dures puissent ˆtre interop´rables, il existe un nouvel attribut VALUE permettant le passage
                                                      e                                                   e
     des arguments muets et qui se fait par l’interm´diaire d’une copie temporaire. Pour qu’une proc´dure Fortran
                 e                                                                    e    e
     soit interop´rable, il faut qu’elle ait une interface explicite et qu’elle soit d´clar´e avec l’attribut BIND, et il
                       e
     est possible de pr´ciser un autre nom dans le code C :
1    function calcul (i ,j , k ) , BIND (C , NAME = ’ computation ’)

                            e            e           e               e
     Pour une fonction, le r´sultat doit ˆtre interop´rable avec le r´sultat du prototype C, et pour une subroutine,
                       e
     le prototype doit ˆtre void.

     4.5.1   Appel C depuis Fortran

     Supposons le prototype de fonction C suivant :
1    int C_L ibrary_Function ( void * sendbuf , int sendcount , int * recvcounts )

     Le module Fortran correspondant est :
1    module ftn_c
2       interface
3          integer ( kind = C_INT ) function c_ li br ar y_f un ct io n &
4                 ( sendbuf , sendcount , recvcounts ) ,           &
5                 BIND (C , NAME = ’ C_Library_Function ’)
6             use ISO_C_BINDING
7             implicit none
8             type ( C_PTR ) , VALUE :: sendbuf
9             integer ( kind = C_INT ) , VALUE :: sendcount
10            type ( C_PTR ) , VALUE :: recvcounts
11         end function c_library_fu nc ti on
12      end interface
13   end module ftn_c

                a
     et l’appel ` la fonction depuis Fortran est :
1    use ISO_C_BINDING
2    use ftn_c
3    ...
4    real ( kind = C_FLOAT ) , target :: send (100)


                                                             11
5    integer ( kind = C_INT ) :: sendcount
6    integer ( kind = C_INT ) , allocatable , target :: recvcounts (:)
7    ...
8    allocate ( recvcounts (100))
9    ...
10   call c _l ibrary_function ( C_LOC ( send ) , sendcount , C_LOC ( recvcounts ))
11   ...


     4.5.2   Appel Fortran depuis C

     Soit le code Fortran suivant :
1    subroutine simulation ( alpha , beta , gamma , delta , arrays ) , BIND ( C )
2       use ISO_C_BINDING
3       implicit none
4       integer ( kind = C_LONG ) , VALUE :: alpha
5       real ( kind = C_DOUBLE ) , intent ( inout ) :: beta
6       integer ( kind = C_LONG ) , intent ( out ) :: gamma
7       real ( kind = C_DOUBLE ) , dimenstion (*) , intent ( in ) :: delta
8       type , BIND ( C ) :: pass
9           integer ( kind = C_INT ) :: lenc , lenf
10          type ( C_PTR ) :: c , f
11      end type pass
12      type ( pass ) , intent ( inout ) :: arrays
13      real ( kind = C_FLOAT ) , allocatable , target , save :: eta (:)
14      real ( kind = C_FLOAT ) , pointer :: c_array (:)
15      ...
16      ! on associe c_array avec un tableau alloue dans C
17      call C_F_POINTER ( arrays %c , c_array , (/ arrays % lenc /))
18      ...
19      ! on alloue le tableau et on le rend accessible a C
20      arrays % lenf = 100
21      allocate ( eta ( arrays % lenf ))
22      arrays % f = C_LOC ( eta )
23      ...

                             e    e
     En C, la structure est d´clar´e par :
1    struct pass { int lenc , lenf ; float *c , * f }

     le prototype de la fonction C est :
1    void simulation ( long alpha , double * beta , long * gamma , double delta [] ,
2                      struct pass * arrays )

     et l’appel de la routine Fortran depuis C est :
1    simulation ( alpha , & beta , & gamma , delta , & arrays );




                                                       12
     5                                    e                             e
                Les nouveaux types de donn´es et la programmation orient´e
                objet
                                                         e                                               e
     Fortran 2003 introduit de nouveaux types de donn´es dont un certain nombre en font un langage orient´
                             e                                                         e
     objet : polymorphisme, h´ritage, etc. Nous allons passer ici en revue ces nouveaut´s.


     5.1                    e e         e e
                 Les types d´riv´s param´tr´s
                                                                       e e                          e
     Il s’agit d’un ajout rendant plus souple l’utilisation des types d´riv´s. Cela consiste en la d´finition de
                           e                                                             e
     deux nouveaux param`tres : le genre (kind ) et la longueur (length) qui sont identifi´s par KIND et LEN. Le
            e                                          a
     param`tre KIND va permettre d’imposer un type ` une valeur et LEN concernera les bornes d’un tableau ou
                               ıne         e
     bien la longueur d’une chaˆ de caract`res.
     Exemple :
1    type coordonnees ( prec ,i , j )
2       ! tout d ’ abord on definit les parametres KIND et LEN dont on a besoin
3       integer , KIND :: prec
4       integer , LEN :: i , j
5

6       ! et on declare ensuite les composantes de l ’ objet
7       integer :: nb_elem = i * j
8       integer :: taille_stockage = nb_elem * prec *8
9       real ( kind = prec ) , dimension (i , j ) :: x , y
10   end type coordonnees

                                                          e   e                        e           e
     Ainsi, dans cet exemple, on voit que l’entier prec d´clar´ comme KIND permet de pr´ciser la pr´cision des
                                                      e   e
     composantes x et y et que les entiers i et j d´clar´s comme LEN permettent de fixer les bornes de x et
                                                    e             e
     y. D’autre part, nous voyons que ces param`tres sont utilis´s dans cet exemple pour calculer le nombre
     d’´l´ments et la taille m´moire utilis´e pour chaque composante1 .
       ee                     e            e
                                    e e
     Pour l’utilisation de ce type d´riv´, on peut donner des valeurs explicites :
1    ! les composantes x et y de coord1 seront
2    ! + des tableaux 10 X10 de reels simple precision
3    type ( coordonnees (4 ,10 ,10)) :: coord1
4

5    ! les composantes x et y de coord2 seront
6    ! + des tableaux 16 X101 de reels double precision
7    type ( coordonnees (8 ,5:20 ,0:100)) :: coord2

                               e
     ou bien utiliser le caract`re : pour un objet allouable :
1    type ( coordonnees (4 ,: ,10)) , allocatable :: coord3
2    ...
3    ! dans l ’ allocation , le caractere ’* ’ signifie que la valeur est
4    ! + supposee connue par ailleurs
5    allocate ( coord3 (* ,30 ,*))

                  ıtre                   e                      e
     On peut connaˆ les valeurs des param`tres en utilisant la mˆme syntaxe que pour une composante :
1    print * , coord1 % prec , coord1 %i , coord2 % j

         1 ce                    e e
                qui n’a aucun int´rˆt autre que didactique !


                                                               13
     5.2     Constructeurs de structures
     Il est possible d’utiliser les noms des composantes d’une structure pour initialiser des sous-types. En reprenant
                   e e                         e
     l’exemple pr´c´dent, il est possible d’´crire :
1    coord4 = coordonnees ( prec =8 , i =10 , j =10) ( x =0.0 , y =1.0)

           e                                                                               e
     qui d´clarera coord4 comme un sous-type de coordonnees dont les composantes sont des r´els double
       e                        e a                 a
     pr´cision et sont initialis´es ` 0.0 pour x et ` 1.0 pour y.


     5.3           e ee
             Type d´riv´ ´tendu
                                                        e                                     e
     L’utilisation de l’argument extensible lors de la d´finition d’un type permet ensuite de r´utiliser ce type
     en y ajoutant de nouvelles composantes. Exemple :
1    type , extensible :: point2d
2       real :: x , y
3    end type point2d
4

5    type , extends ( point2d ) :: point3d
6        real :: z
7    end type point3d
8    ...
9    type ( point2d ) :: p2d
10   type ( point3d ) :: p3d


     5.4     Notion de classe
                                  e e                e e e                    a
     On peut regrouper un type d´riv´ et les types d´riv´s ´tendus construits ` partir de lui dans une classe, que
           e                                                         e e
     l’on d´clare en tant que CLASS. Ainsi, en reprenant l’exemple pr´c´dent :
1    CLASS ( point2d ) :: point

                                                                          e
     point sera selon le contexte du type point2d ou bien point3d. La d´termination du type peut se faire en
                                                                     e
     fonction de la nature d’un argument d’appel ou bien par l’interm´diaire d’un pointeur.

     5.4.1    e
             D´termination du type par passage en argument

              e                                            e e      e              a         e       a a
     On peut ´tablir un comportement en fonction du type h´rit´ pass´ en argument ` une proc´dure grˆce ` la
                        o                                      e e        e                e
     structure de contrˆle SELECT TYPE. Continuons l’exemple pr´c´dent en ´crivant une proc´dure de calcul de
     la distance entre deux points :
1    subroutine distance ( p1 , p2 )
2       CLASS ( point2d ) :: p1 , p2
3       real :: distance
4       SELECT TYPE ( p1 )
5          ! si le type de p1 est point2d :
6          TYPE IS ( point2d )
7               distance = sqrt (( p2 %x - p1 % x )**2+( p2 %y - p1 % y )**2)
8          ! si le type de p1 est point3d :
9          TYPE IS ( point3d )
10              distance = sqrt (( p2 %x - p1 % x )**2+( p2 %y - p1 % y )**2+( p2 %z - p1 % z )**2)


                                                            14
11      END SELECT
12   end subroutine distance

                                                            e                                e e
     On voit qu’il est ainsi possible de construire des proc´dures dont le comportement est g´n´rique. Il est possible
       e      e            e e
     d’ˆtre mˆme plus g´n´rique que l’exemple ci-dessus puisqu’il existe dans la structure SELECT TYPE des
                           e                                 e
     branchements par d´faut lorsque les tests explicites ´chouent (TYPE DEFAULT, CLASS IS, CLASS DEFAULT).

     5.4.2    e
             D´termination du type par pointeur

                                                                        a a
     En utilisant les pointeurs on peut allouer dynamiquement le type grˆce ` l’instruction ALLOCATE :
1    ! Definition des types
2    TYPE ( point2d ) , target :: p2d
3    TYPE ( point3d ) , target :: p3d
4    CLASS ( point2d ) , pointer :: point1 , point2
5    point1 = > p2d
6    point2 = > p3d
7    allocate ( point1 )
8    allocate ( point2 )
9    allocate ( TYPE ( point3d ) :: point3 )

                                   e
     Dans cet exemple, on a ainsi d´fini que :
     £ point1 est de type point2d ;
     £ point2 est de type point3d ;
     £ point3 est de type point3d.


     5.5         e            e a            e e
             Proc´dures attach´es ` un type d´riv´
     5.5.1                    e
             Pointeurs de proc´dure

                          e                    e                               e
     Un pointeur peut d´signer maintenant ´galement un pointeur de proc´dure. Exemple d’un pointeur de
         e                        ea                    e
     proc´dure p qui est initialis´ ` null et qui a la mˆme interface que proc :
1    PROCEDURE ( proc ) , POINTER :: p = > null ()

                         e                          e
     Il est possible de d´clarer un pointeur de proc´dure sans l’assigner :
1    PROCEDURE () , POINTER :: p

               e          e           a                                          e
     Il pourra ˆtre associ´ plus tard ` une subroutine ou une fonction de la mani`re suivante :
1    p = > proc

                                       e            a                                         e         e
     L’utilisation de pointeurs de proc´dure permet ` Fortran 2003 d’introduire la notion de m´thode, li´e
                      a          e e
     dynamiquement ` un type d´riv´ :
1    type coordonnees ( prec ,i , j )
2       integer , KIND :: prec
3       integer , LEN :: i , j
4       integer :: nb_elem = i * j
5       integer :: taille_stockage = nb_elem * prec *8
6       real ( kind = precision ) , dimension (i , j ) :: x , y
7       PROCEDURE () , POINTER :: calcul


                                                            15
8    end type coordonnees
9    ...
10   type ( coordonnees ( prec =8 , i =20 , j =30)) :: coord5
11   ...
12   calcul = > operation1
13   ! l ’ instruction suivante utilisera la subroutine operation1
14   call coord5 % calcul (...
15   ...
16   calcul = > operation2
17   ! l ’ instruction suivante utilisera maintenant la subroutine operation2
18   call coord5 % calcul (...


     5.5.2       e            e
             Proc´dures attach´es par un nom

                                                                                      e             e e
     On vient de voir que les pointeurs de structure permettent d’associer des m´thodes aux types d´riv´s.
                                              e        e                  e                     c
     Cependant, si on associe toujours la mˆme proc´dure par l’interm´diaire du pointeur, une fa¸on moins
                                       e e
     lourde est de l’attacher au type d´riv´ par son nom. La syntaxe est la suivante :
1    type coordonnees ( prec ,i , j )
2       integer , KIND :: prec
3       integer , LEN :: i , j
4       integer :: nb_elem = i * j
5       integer :: taille_stockage = nb_elem * prec *8
6       real ( kind = precision ) , dimension (i , j ) :: x , y
7       contains
8          procedure :: operation1
9          procedure :: calcul = > operation2
10   end type coordonnees

                                                                                              e e
     qui attache operation1 avec son nom et operation2 avec le nom calcul, au type d´riv´ coordonnees. Les
          e              e              c            e      e     e
     proc´dures attach´es de cette fa¸on doivent ˆtre d´clar´es en module ou bien avec une interface explicite. En
                                                                        e        e e              e           e
     utilisant l’attribut GENERIC, il est ainsi possible d’utiliser le mˆme nom g´n´rique pour diff´rentes proc´dures :
1    type mon_type
2       ... ! declaration des composantes du type
3       contains
4          GENERIC :: calcul = > calc1 , calc2 , calc3
5    end mon_type

             e                                      e     e     a
     les proc´dures calc1, calc2 et calc3 seront diff´renci´es grˆce leur interface.

     5.5.3   L’attribut PASS

                               e     a          e e                               e e                           e
     Lorsqu’on attache une proc´dure ` un type d´riv´, l’objet utilisant le type d´riv´ est automatiquement pass´
     en argument. Exemple, supposons la subroutine ma procedure suivante :
1    subroutine ma_procedure (a ,b , c )
2       ...
3    end subroutine ma_procedure

                              e e
     et attachons la au type d´riv´ mon type



                                                            16
1    type mon_type
2       ... ! declaration des composantes du type
3       contains
4          procedure :: ma_procedure
5    end mon_type

     a l’appel, on aura :
1    type ( mon_type ) :: obj
2    real :: x , y
3    ...
4    call obj % ma_procedure (x , y ) ! equivalent a call ma_procedure ( obj ,x , y )

               e                                                         c
     On peut sp´cifier l’obligation de passer l’objet en argument de la fa¸on suivante :
1    type mon_type
2       ... ! declaration des composantes du type
3       contains
4          procedure , NOPASS :: ma_procedure
5    end mon_type

     qui demande alors de passer explicitement l’argument :
1    call obj % ma_procedure ( obj ,x , y )

                       e           c       e                      a
     On peut en fait sp´cifier de fa¸on syst´matique les arguments ` passer ou pas. Exemple :
1    type mon_type
2       ... ! declaration des composantes du type
3       contains
4          procedure , PASS ( b ) , NOPASS ( obj , c ) :: ma_procedure
5    end mon_type

                                                          a
     permet de ne pas passer explicitement b, mais oblige ` passer les autres arguments :
1    call obj % ma_procedure ( obj , y )


     5.5.4       e            e            e
             Proc´dures attach´es par un op´rateur

                        e              e
     Cela permet la surd´finition des op´rateurs :
1    type matrice ( prec ,m , n )
2       integer , kind :: prec
3       integer , len :: m , n
4       real ( kind = prec ) :: element (m , n )
5       contains
6          ! ce sont des surdefinitions d ’ operateurs faites par des subroutines :
7          ! + ex : - plus1 additionne terme a terme les termes d ’ une matrice
8          !+         - plus2 ajoute un reel a tous les termes d ’ une matrice
9          !+         - egale1 assigne dans une matrice
10         !+         - egale2 somme chaque ligne d ’ une matrice et assigne le resultat
11         ! ++         dans l ’ element d ’ un vecteur
12         ! + etc .
13         GENERIC :: OPERATOR (+) = > plus1 , plus2
14         GENERIC :: ASSIGNMENT (=) = > egale1 , egale2

                                                         17
15   end type
16   ...
17   type ( matrice ( prec =4 , m =20 , n =20)) :: a ,b , c
18   real , dimension (20) :: v
19   real :: r =2.0
20   ...
21   a = b + c ! utilise plus1 et egale1
22   a = a + r ! utilise plus2 et egale1
23   v = a + b ! utilise plus1 et egale2



     6      e
          Am´liorations diverses
           e      e
     Caract`res sp´ciaux et internationaux
                                                                       e
     Fortran 2003 supporte la norme ISO-10646 concernant les caract`res internationaux permettant par exemple
     de porter sur toute plateforme les chaˆ                e                                                  e
                                              ınes de caract`re avec des accents, ou bien d’utiliser des caract`res
     sp´ciaux tels que : { } [ ] @ \ / , etc.
       e


     Noms de variables – Nombres de lignes
                                                a          e                                       a
     Les noms des variables peuvent avoir jusqu’` 63 caract`res et les instructions continues jusqu` 256 lignes.


        e
     Acc`s aux variables d’environnement
     L’utilisation de variables d’environnement est maintenant possible grˆce au module ISO FORTRAN ENV et
                                                                          a
                       ıtre                    e            e
     permet de connaˆ les valeurs de diff´rents param`tres reliant un programme Fortran et l’environnement
                              e
     dans lequel il est execut´. Il s’agit des constantes suivantes :
     £ INPUT UNIT, OUTPUT UNIT et ERROR UNIT : correspondent aux num´ros d’unit´ par d´faut identifi´s par
                                                                         e           e e           e
                e                                                          e
       le caract`re * dans les commandes READ, WRITE et pour les erreurs d’´critures ;
     £ IOSTAT END et IOSTAT EOR : correspondent aux valeurs par d´faut donn´es ` la variable IOSTAT lorsqu’une
                                                                 e         e a
       fin de lecture anormale se produit ;
     £ NUMERIC STORAGE SIZE, CHARACTER STORAGE SIZE, FILE STORAGE SIZE : correspondent aux tailles en bits
                 e     e                  e                e
       d’une donn´e num´rique, d’un caract`re et d’une unit´ de stockage.
                       e                            e
     En outre, les proc´dures suivantes sont intrins`ques dans la norme Fortran 2003 :
     £ COMMAND ARGUMENT COUNT() : fonction qui retourne le nombre d’arguments de la ligne de commande ;
     £ GET COMMAND([COMMAND,LENGTH,STATUS]) : subroutine qui retourne la commande enti`re ayant lanc´ le
                                                                                      e             e
       programme dans COMMAND ;
     £ GET COMMAND ARGUMENT(NUMBER[,VALUE,LENGTH,STATUS] : subroutine qui retourne l’argument num´ro
                                                                                                 e
       NUMBER de la commande dans VALUE :
     £ GET ENVIRONMENT VARIABLE(NAME,[VALUE,LENGTH,STATUS,TRIM NAME]) : subroutine qui retourne dans
                                                        e e
       VALUE la valeur de la variable d’environnement sp´cifi´e dans NAME, comme par exemple $HOME.


     L’attribut VOLATILE
                                a            e         e                    e
     L’attribut VOLATILE permet ` un objet d’ˆtre modifi´ en dehors de l’unit´ de programme, par exemple par
                                          e
     un autre programme tournant en parall`le.

                                                          18
 ee
R´f´rences
 [1] Information technology – programming languages – Fortran – part I : Base language. Technical Report
     ISO/IEC IS 1539-1 :2004 (E), ANSI, 2004.
 [2] Fortran 2003 accepted as standard : http://developers.slashdot.org/article.pl?sid=04/09/17/
     0550212&tid=156&tid=162&tid=8.
 [3] Sneak Peek at Fortran 2003 for quantitative analysts http://www.fenews.com/fen35/where num
     matters/where num matters.html.
 [4] P. Corde and H. Delouis. Les apports de fortran 2003 (http://www.idris.fr/data/cours/lang/
     fortran/f200x/Fortran 200x.pdf). Technical report, IDRIS, 2004-10-26.
 [5] B. Pichon. Des documents sur la norme : http://www.obs-nice.fr/pichon/.
 [6] J. Reid. The new features of Fortran 2003. Technical report.
 [7] J. Reid. The future of Fortran. Computing in science & Engineering, July/August 2003.
 [8] http://www.fortran.com/fortran/fcd announce.html.
 [9] Fortran 90, 95 and 2003 home page : http://www.kcl.ac.uk/kis/support/cit/fortran/f90home.
     html.
[10] Fortran Standards Technical Committee : http://www.nag.co.uk/sc22wg5/.




                                                   19

								
To top