Fortran/fr: Difference between revisions
(Created page with "==Algèbre linéaire numérique") |
(Created page with "À partir de Fortran 90, de nouvelles fonctions sont disponibles pour le traitement des opérations de base : <tt>matmul</tt> et <tt>dot_product</tt> pour les multiplicat...") |
||
Line 12: | Line 12: | ||
==Algèbre linéaire numérique | ==Algèbre linéaire numérique | ||
À partir de Fortran 90, de nouvelles fonctions sont disponibles pour le traitement des opérations de base : <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== | ==Segmentation Faults== |
Revision as of 19:16, 12 June 2017
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.
Segmentation Faults
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:
- 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.
When the argument is an allocatable array, you should replace the following code:
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
by this code:
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
The same principle applies when the argument is a function pointer. Consider, for example, the following code:
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
...
To avoid segmentation faults you should replace the above code by the following:
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
...