Fortran/fr: Difference between revisions

From Alliance Doc
Jump to navigation Jump to search
(Created page with "Fortran est un langage compilé disponible sur les ordinateurs de Calcul Canada où sont installés les compilateurs <tt>gfortran</tt> et <tt>ifort</tt>. En général, les lan...")
No edit summary
 
(17 intermediate revisions by 2 users not shown)
Line 3: Line 3:
Fortran est un langage compilé disponible sur les ordinateurs de Calcul Canada où sont installés les compilateurs <tt>gfortran</tt> et <tt>ifort</tt>. En général, les langages compilés offrent une meilleure performance; nous vous encourageons donc à écrire vos programmes en Fortran, C ou C++.
Fortran est un langage compilé disponible sur les ordinateurs de Calcul Canada où sont installés les compilateurs <tt>gfortran</tt> et <tt>ifort</tt>. En général, les langages compilés offrent une meilleure performance; nous vous encourageons donc à écrire vos programmes en Fortran, C ou C++.


==Useful Compiler Options==
== Options utiles de compilation ==


Most contemporary Fortran compilers have a variety of options that can be very helpful during the debugging phase of code development.
La plupart des compilateurs Fortran modernes offrent des options utiles pour le débogage.  
* <tt>-fcheck=all</tt> for the gfortran compiler and <tt>-check</tt> for the ifort compiler check array bounds and alert for disassociated pointers and uninitialized variables;
* <tt>-fcheck=all</tt> pour le compilateur gfortran et <tt>-check</tt> pour le compilateur ifort vérifient les limites des tableaux et signalent les pointeurs sans cible et les variables non initialisées;
* <tt>-fpe0</tt> (ifort) causes the application to halt for floating point exceptions such as division by zero or the square root of a negative, instead of simply generating a NaN and letting the application run;  
* <tt>-fpe0</tt> (ifort) interrompt l'application dans des cas de virgule flottante (division par zéro ou racine carrée d'un nombre négatif) plutôt que de simplement générer NaN (''not a number'') et laisser l'application se poursuivre;
* during testing, you should use <tt>-O0</tt> to disable optimizations and <tt>-g</tt> to add debugging symbols.     
* pendant les tests, utilisez <tt>-O0</tt> pour désactiver les optimisations et <tt>-g</tt> pour ajouter les symboles de débogage.     


==Numerical Linear Algebra==
==Algèbre linéaire numérique==


Note that modern versions of Fortran, i.e. from Fortran 90 on, include built-in functions to handle basic linear algebra operations like multiplication involving matrices and vectors (<tt>matmul</tt> and <tt>dot_product</tt>) and tranposition of matrices (<tt>transpose</tt>). You should use these or the system-provided BLAS/LAPACK libraries and never attempt to write your own methods for such operations, except as an educational exercise. The BLAS matrix-matrix multiplication routine can be up to 100 times faster than a naive implementation involving three nested loops.     
À partir de Fortran 90, de nouvelles fonctions sont disponibles pour le traitement des opérations de base&nbsp;: <tt>matmul</tt> et <tt>dot_product</tt> pour les multiplications avec matrices et vecteurs; <tt>transpose</tt> pour la transposition de matrices. Utilisez toujours ces fonctions ou les librairies BLAS/LAPACK fournies et n'essayez jamais de créer vos propres méthodes, à moins que ce ne soit pour des motifs d'apprentissage. La routine BLAS pour la multiplication de matrices peut s'avérer 100 fois plus rapide que l'algorithme primaire avec trois boucles imbriquées.     


==Segmentation Faults==
==Erreurs de segmentation==


An error that is frequently seen with a Fortran program comes from interface problems. These problems surface if a pointer, a dynamically allocated array or even a function pointer is passed as an argument to a subroutine. There are no compile-time problems, but when the program is ran you see for example the following message:
Une erreur fréquemment observée avec un exécutable Fortran provient de problèmes d'interface. Ces problèmes surviennent lorsque l'on transmet comme argument d'une sous-routine un pointeur, un tableau alloué dynamiquement ou encore un pointeur de fonctions. À la compilation il n'y a pas de problème, cependant à l'exécution vous obtiendrez par exemple le message suivant&nbsp;:
; '''forrtl: severe (174): SIGSEGV, segmentation fault occurred'''
; '''forrtl: severe (174): SIGSEGV, segmentation fault occurred'''
To correct this problem, you should ensure that the interface of the subroutine is explicitly defined. This can be done in Fortran using the INTERFACE command. Then the compiler can construct the interface and the segmentation faults are fixed.
Pour corriger le problème, il faut s'assurer que l'interface de la sous-routine est définie explicitement. Ceci peut se faire en Fortran avec la commande INTERFACE. Ainsi, le compilateur arrivera à construire l'interface et les erreurs de segmentation seront réglées.




When the argument is an allocatable array, you should replace the following code:
Dans le cas où l'argument est un tableau allouable, il s'agit de remplacer le code suivant
{{
{{
File
File
Line 42: Line 42:
end
end
}}
}}
by this code:
par le code
{{
{{
File
File
Line 72: Line 72:
end
end
}}
}}
The same principle applies when the argument is a function pointer. Consider, for example, the following code:  
Le principe est le même dans le cas où l'argument est un pointeur de fonction. Considérons, par exemple, le code suivant&nbsp;:  
{{
{{
File
File
Line 109: Line 109:
...
...
}}
}}
To avoid segmentation faults you should replace the above code by the following:
Pour ne pas obtenir d'erreur de segmentation, il faut remplacer le code précédent par ce qui suit&nbsp;:
{{
{{
File
File

Latest revision as of 21:25, 5 March 2019

Other languages:

Fortran est un langage compilé disponible sur les ordinateurs de Calcul Canada où sont installés les compilateurs gfortran et ifort. En général, les langages compilés offrent une meilleure performance; nous vous encourageons donc à écrire vos programmes en Fortran, C ou C++.

Options utiles de compilation

La plupart des compilateurs Fortran modernes offrent des options utiles pour le débogage.

  • -fcheck=all pour le compilateur gfortran et -check pour le compilateur ifort vérifient les limites des tableaux et signalent les pointeurs sans cible et les variables non initialisées;
  • -fpe0 (ifort) interrompt l'application dans des cas de virgule flottante (division par zéro ou racine carrée d'un nombre négatif) plutôt que de simplement générer NaN (not a number) et laisser l'application se poursuivre;
  • pendant les tests, utilisez -O0 pour désactiver les optimisations et -g pour ajouter les symboles de débogage.

Algèbre linéaire numérique

À partir de Fortran 90, de nouvelles fonctions sont disponibles pour le traitement des opérations de base : matmul et dot_product pour les multiplications avec matrices et vecteurs; transpose pour la transposition de matrices. Utilisez toujours ces fonctions ou les librairies BLAS/LAPACK fournies et n'essayez jamais de créer vos propres méthodes, à moins que ce ne soit pour des motifs d'apprentissage. La routine BLAS pour la multiplication de matrices peut s'avérer 100 fois plus rapide que l'algorithme primaire avec trois boucles imbriquées.

Erreurs de segmentation

Une erreur fréquemment observée avec un exécutable Fortran provient de problèmes d'interface. Ces problèmes surviennent lorsque l'on transmet comme argument d'une sous-routine un pointeur, un tableau alloué dynamiquement ou encore un pointeur de fonctions. À la compilation il n'y a pas de problème, cependant à l'exécution vous obtiendrez par exemple le message suivant :

forrtl: severe (174): SIGSEGV, segmentation fault occurred

Pour corriger le problème, il faut s'assurer que l'interface de la sous-routine est définie explicitement. Ceci peut se faire en Fortran avec la commande INTERFACE. Ainsi, le compilateur arrivera à construire l'interface et les erreurs de segmentation seront réglées.


Dans le cas où l'argument est un tableau allouable, il s'agit de remplacer le code suivant

File : error_allocate.f90

Program Eigenvalue
implicit none

integer                       :: ierr
integer                       :: ntot
real, dimension(:,:), pointer :: matrix

read(5,*) ntot
ierr = genmat( ntot, matrix )

call Compute_Eigenvalue( ntot, matrix )

deallocate( matrix )
end


par le code

File : interface_allocate.f90

Program Eigenvalue
implicit none

integer                       :: ierr
integer                       :: ntot
real, dimension(:,:), pointer :: matrix

interface
    function genmat( ntot, matrix )
    implicit none
    integer                       :: genmat
    integer, intent(in)           :: ntot
    real, dimension(:,:), pointer :: matrix
    end function genmat
end interface

read(5,*) ntot
ierr = genmat( ntot, matrix )

call Compute_Eigenvalue( ntot, matrix )

deallocate( matrix )
end


Le principe est le même dans le cas où l'argument est un pointeur de fonction. Considérons, par exemple, le code suivant :

File : error_=pointer.f90

Program AreaUnderTheCurve
implicit none

real,parameter :: boundInf = 0.
real,parameter :: boundSup = 1.
real           :: area
real, external :: computeIntegral
real, external :: FunctionToIntegrate

area = computeIntegral( FunctionToIntegrate, boundInf, boundSup )

end

function FunctionToIntegrate( x )
implicit none

real             :: FunctionToIntegrate
real, intent(in) :: x

FunctionToIntegrate = x

end function FunctionToIntegrate

function computeIntegral( func, boundInf, boundSup )
implicit none

real, external   :: func
real, intent(in) :: boundInf, boundSup

...


Pour ne pas obtenir d'erreur de segmentation, il faut remplacer le code précédent par ce qui suit :

File : interface_pointer.f90

Program Eigenvalue
implicit none

real,parameter :: boundInf = 0.
real,parameter :: boundSup = 1.
real           :: area
real, external :: computeIntegral

interface
    function FunctionToIntegrate( x )
    implicit none
    real             :: FunctionToIntegrate
    real, intent(in) :: x
    end function FunctionToIntegrate
end interface

area = computeIntegral( FunctionToIntegrate, boundInf, boundSup )

end


function FunctionToIntegrate( x )
implicit none

real             :: FunctionToIntegrate
real, intent(in) :: x

FunctionToIntegrate = x

end function FunctionToIntegrate


function computeIntegral( func, boundInf, boundSup )
implicit none

real, intent(in) :: boundInf, boundSup

interface
    function func( x )
    implicit none
    real             :: func
    real, intent(in) :: x
    end function func
end interface

...