Vous êtes sur la page 1sur 26

Programmation

pour le calcul scientifique

UE 2A005 – 2nd semestre 2018-19


Sorbonne Université

Responsable :
Ivan Delbende
Ivan.Delbende@sorbonne-universite.fr

Cours 9a : Les entrées/sorties


Entrée-sortie
● Entrée-Sortie (E/S, Input/Ouput en anglais, I/O) :
transfert d'informations entre la mémoire de
l'ordinateur et l'un de ses périphériques
➢ écran
➢ clavier
➢ système de fichiers (disque dur...)
● Entrée : lecture d'informations du périphérique
vers la mémoire vive
● Sortie : écriture de la mémoire vive vers le
périphérique
● Entrée standard : clavier
● Sortie standard : écran

2
Entrées-sorties standard :
format libre
● En lecture :
READ *, var [, var_2, …, var_n]
➢ Diverses formes possibles suivant le type :
entiers 43 +25 -2
réels 1. 1e-2 -2.4E25
booléens .TRUE. T false
➢ En cas d'erreur (entrée au clavier d'un type incorrect ou
plus fort) : arrêt de l'exécution.
➢ Informations lues séparées par des espaces, des
virgules, ou placées dans des lignes différentes.
➢ Si après l'instruction READ *, i, j, k on entre au clavier
2, ,4 alors i et k vaudront 2 et 4, mais j restera inchangé.
3
Entrées-sorties standard :
format libre
● En écriture :
PRINT *, var [, var_2, …, var_n]

➢ Informations écrites séparées par des espaces


➢ Chaque nouvel appel à PRINT entraîne l'écriture
d'une nouvelle ligne
➢ Il y a parfois des retours à la ligne
supplémentaires si la liste à afficher est longue
➢ En format libre, il y a toujours un caractère
blanc (espace) en début de ligne.

4
E/S dans les fichiers :
Accès séquentiel / direct
● Vocabulaire
➢ Enregistrement : bloc élémentaire de
données traité lors d'une opération de lecture
ou d'écriture
➢ Fichier : suite d'enregistrements
● Il existe deux types de fichiers qui se distinguent
par le mode d'accès
➢ accès séquentiel : accès aux enregistrements
l'un après l'autre, à partir du premier
➢ accès direct : accès direct à n'importe quel
enregistrement (comme dans un tableau)
En 2A005 et dans la suite, on utilisera
toujours l'accès séquentiel (le plus courant).
5
E/S dans les fichiers :
Forme non formatée / formatée
● Forme de l'information dans le fichier
➢ Forme non formatée : l'information est
stockée dans le fichier sous la même forme
qu'elle est stockée en mémoire
 fichier binaire illisible en utilisant un
éditeur de texte (gedit par exemple).
➢ Forme formatée : l'information de la
mémoire est convertie et stockée sous forme
de caractères
 fichier texte (ou ASCII) lisible par un
humain et éditable à l'aide de gedit.
Remarque
➢ Le format libre est une forme formatée.
6
E/S dans les fichiers :
Forme non formatée / formatée
Quand utiliser l'une ou l'autre de ces
formes ?
● Forme formatée (texte ou ASCII) :
➢ Pour les E/S standard (clavier et écran)
➢ Pour les fichiers avec de petites quantités de données
● Forme non formatée (binaire) :
➢ Pour les grandes quantités de données (typiquement
en mécanique les champs de vitesse, de température, de
déformation, ...)
- plus rapide à lire/écrire (pas de conversion en caractères)
- fichiers généralement plus compacts (ex. : -56301 est
représenté sur 4 octets contre 6 octets sous forme ASCII)
- données plus précises pour les réels (pas de perte de
précision lors de la conversion en chaîne de caractères)
➢ Mais parfois perte de compatibilité entre machines 7
(exemple : machine 32 bits  machine 64 bits)
Lire/écrire
dans un fichier texte (1)
● 1ère étape : ouverture du fichier
➢ Sur le disque, le fichier est désigné par son
chemin et son nom (partie UNIX)
➢ Dans le programme F90, le fichier est désigné
par un numéro, le numéro d'unité logique
➢ « Ouvrir » un fichier, c'est attribuer
(temporairement) à un fichier du disque un
numéro d'unité logique
➢ OPEN (UNIT = num, FILE = nom_fichier)
Exemple : on veut lire/écrire dans un fichier
nommé donnees.dat dans le répertoire courant
OPEN (UNIT = 10, FILE = ''donnees.dat'')
8
Lire/écrire
dans un fichier texte (2)
● 2ème étape : lecture/écriture des données
➢ une fois l'ouverture effectuée, on utilise
uniquement le numéro d'unité logique
➢ l'instruction READ *, liste utilisée pour les E/S
standard devient pour les fichiers
READ (UNIT = num, FMT = format) liste
➢ l'instruction PRINT *, liste devient quant à elle
WRITE (UNIT = num, FMT = format) liste
(si  num ou UNIT=num est remplacé par * ⇒ E/S standard). E/S standard).

Exemples
READ (UNIT = 10, FMT = *) n, tab
WRITE (UNIT = 10, FMT = '(100E12.4)') mat(i,:)
9
Lire/écrire
dans un fichier texte (3)
● 3ème étape : fermeture du fichier
➢ finalise l'écriture éventuelle sur le disque (utile
si le programme s’interrompt accidentellement
par la suite)
➢ libère le numéro d'unité logique, qui peut
ensuite être réutilisé, associé au même fichier
ou à un autre
➢ CLOSE (UNIT = num)
Exemples
CLOSE (UNIT = 10)
INTEGER  :: num_u = 10
...
CLOSE (UNIT = num_u)
10
Lire/écrire
dans un fichier texte (4)
● Exemple : lecture de nombres dans un fichier
nombres.dat et écriture de leurs carrés dans un
fichier carres.dat
Problème : le programme ne sait pas combien il y a de
nombres à lire dans le fichier nombres.dat !
PROGRAM carres
IMPLICIT NONE
● Mot-clé
REAL :: r IOSTAT = ios
INTEGER :: ios
➢ en sortie, l'entier
OPEN (UNIT = 10, FILE = "nombres.dat") ios vaut 0 si l'E/S
OPEN (UNIT = 11, FILE = "carres.dat") s'est bien déroulée
DO
READ (UNIT = 10, FMT = *, IOSTAT = ios) r ➢ READ fin de fichier :
IF (ios /= 0) EXIT ios devient <0
WRITE (UNIT = 11, FMT = *) r**2
END DO
➢ Existe aussi pour
CLOSE (UNIT = 10) ; CLOSE (UNIT = 11) les autres fonctions
END PROGRAM carres d'E/S 11
OPEN : syntaxe (plus) générale

● OPEN (UNIT = num, FILE = nom_fichier, &


FORM = type_fichier, & ''formatted'' : fichier texte (défaut)
''unformatted'' : fichier binaire
STATUS = statut_ES, &
ACCESS = type_acces, & ''unknown'' : ouvre quoi qu'il
arrive (défaut)
ACTION = cond_emploi, & ''new'' : crée un nouveau
fichier (erreur sinon)
POSITION = pos, & ''old'' : ouvre un fichier existant
(erreur sinon)
IOSTAT = ios) ''scratch'' : ouvre un fichier tem-
poraire (employé sans FILE=...)

''rewind'' : positionnemt en début ''sequential'' : accès séquentiel


de ficher (défaut) (défaut)
''append'' : en fin de fichier (ajout) ''direct'' : accès direct (plus rare)

''readwrite'' : fichier en lecture et en écriture (défaut)


''read'' : fichier en lecture seule
''write'' : fichier en écriture seule 12
Lire/écrire des données binaires
dans un fichier
● Ouverture du fichier pour des E/S non formatées
OPEN (UNIT = num, FILE = nom_fichier, &
FORM = ''unformatted'')
● Lecture/écriture des données binaires, donc    
sans spécification de format FMT =
READ (UNIT = num) liste
WRITE (UNIT = num) liste
● Fermeture du fichier : CLOSE (UNIT = num)
Exemple
REAL, DIMENSION(512, 512, 256) :: vx, vy, vz, pression = 1.
OPEN (10, FILE = ''vit_pres.dat'', FORM = ''unformatted'')
READ (10) vx, vy, vz ; WRITE (10) pression
CLOSE (10)
13
Les formats (1)
(forme formatée seulement)

● Le format libre désigné par « * » est très pratique


➢ pour programmer vite
➢ en écriture pour des messages courts, du debuggage...
➢ en lecture quand on ne connaît pas le format des données
(qu'elles soient saisies au clavier ou issues d'un fichier)
● Pas toujours adapté et dépendant du compilateur !
Exemple : affichage d'un tableau d'entiers
INTEGER, DIMENSION (5, 5) :: tab ; INTEGER :: i, j
DO i = 1, 5 ; DO j = 1, 5 ; tab (i, j) = (i - j)**3 ; END DO ; END DO
DO i = 1, 5 ; PRINT *, tab (i, :) ; END DO

avec g95 : avec gfortran :

14
Les formats (2)
● Spécifier un format, c'est décider comment une
valeur doit être traduite en chaîne de caractères
Exemple : ici on veut 5 entiers (I) sur 4 caractères
DO i = 1, 5 ; PRINT ''(5I4)'', tab(i, :) ; END DO

avec g95 comme avec gfortran :

● Prévoir de la place additionnelle (au moins un


caractère de plus que l'extension maximale, pour
séparer les valeurs)
● Si le format est inadapté, des **** remplacent les
valeurs dans la sortie... 15
Les formats (3)
● Les principaux descripteurs (voir Delannoy annexe D)
Descripteur Type Représentation Ex. w = 13, d = 4
Iw [.m] entier décimale

B/O/Zw [.m] entier binaire / octale / hexadécimale

Fw.d réel flottante -14500.5000


Ew.d réel exponentielle : mantisse Î[0,1[ -0.1450E+05
ENw.d réel ingénieur : exposant mult. de 3 - 14.5005E+03
ESw.d réel scientifique : mantisse Î[1,10[ -1.4500E+04
Gw.d réel flottante ou exp. suivant valeur -0.1450E+05
Lw booléen
A[w] caractère / s'adapte automatiquement à la
chaîne longueur de la var. si w est omis

w : nombre total de caractères (tout compte : E + - . )


d : nombre de caractères après le séparateur décimal
16
m (sortie) : nombre minimal de chiffres à écrire (défaut = 1)
Les formats (4)
● Possibilité d'insérer un intitulé ou des espaces (nX)
x = 2. ; y = -1.1 ; PRINT '(''coord :'', X, F6.3, X, F6.3)', x, y
donne
● Possibilité de répéter ou de mettre en facteur :
'(5I3)' éq. à '(I3, I3, I3, I3, I3)'
'(4(I3, X), I3)' éq. à '(I3, X, I3, X, I3, X, I3, X, I3)'
● S'il y a plus de descripteurs dans le format que
d'éléments dans la liste, ceux qui sont en trop sont
abandonnés. Utile pour les tableaux par exemple :
WRITE (*, '(1000E12.4)') mat(i,:)  ! mat a moins de 1000 colonnes
● S'il y en a moins, le format est ré-utilisé avec un
changement de ligne (ou d'enregistrement)
→ DANGEREUX EN LECTURE : A EVITER. 17
Mot-clé « ADVANCE = 'no' »
(forme formatée seulement)
● Ce mot-clé évite le retour à la ligne (ou le
changement d'enregistrement pour un fichier) à
l'issue d'une instruction READ ou WRITE
➢ En lecture : le READ suivant ne se fera pas sur la ligne
suivante (ou enregistrement suivant), mais au caractère
suivant de la même ligne
➢ En écriture : le WRITE suivant n'écrira pas sur la ligne
suivante (ou à l'enregistrement suivant), mais à la suite
sur la même ligne (impossible avec PRINT)
Exemple
WRITE (*, FMT = '(A, X)', ADVANCE = 'no') ''Exemple d'ecriture''
WRITE (*, FMT = '(A)') ''avec ADVANCE = 'no'.''

donne

18
Programmation
pour le calcul scientifique

UE 2A005 – 2nd semestre 2018-19


Sorbonne Université

Responsable :
Ivan Delbende
Ivan.Delbende@sorbonne-universite.fr

Cours 9b : Modularité
Structure d'un module

MODULE nom_module
[ USE nom_autre_module ]
Visibles dans ce module et
dans les unités utilisatrices
de ce module
IMPLICIT NONE
  [ ! Définitions de types ]
  [ ! Déclarations de constantes / (de
variables) ] 
Il est conseillé de se limiter
à des déclarations de
[ CONTAINS constantes (PARAMETER),
et de déclarer les variables
  ! Procédures ] dans les procédures ou
dans le programme
END MODULE nom_module principal.
2
Module et fichiers

● Le module peut être placé :

➢ soit dans le même fichier que l'unité


utilisatrice : le module doit alors apparaître
avant l'unité utilisatrice dans le fichier ;

➢ soit dans un fichier différent du fichier


contenant l'unité utilisatrice
Dans ce cas, c'est au moment de la compilation
qu'il faut respecter l'ordre (cf. plus loin).

3
Exemple
Fichier unique
programme.f90
MODULE lecture ● Le module est
IMPLICIT NONE
placé AVANT le
CONTAINS
INTEGER FUNCTION lire_entier(maximum) programme
INTEGER, INTENT(IN) :: maximum principal
DO
READ *, lire_entier
IF (lire_entier <= maximum) EXIT ● La compilation
END DO se fait de la
END FUNCTION lire_entier manière
END MODULE lecture
habituelle
PROGRAM exemple_lecture g95 -o prog
USE lecture programme.f90
IMPLICIT NONE
INTEGER :: n
n = lire_entier(100); PRINT *, "n = ", n
4
END PROGRAM exemple_lecture
Exemple
Module dans un fichier séparé

lecture_entier.f90 main.f90
MODULE lecture
IMPLICIT NONE PROGRAM exemple_lecture
CONTAINS USE lecture
INTEGER FUNCTION lire_entier(maximum) IMPLICIT NONE
INTEGER, INTENT(IN) :: maximum INTEGER :: n
DO
READ *, lire_entier n = lire_entier(100);
IF (lire_entier <= maximum) EXIT PRINT *, "n = ", n
END DO END PROGRAM exemple_lecture
END FUNCTION lire_entier
END MODULE lecture

5
Compilation séparée

● Comment compiler un programme FORTRAN 90


réparti sur plusieurs fichiers sources ?
➢ On a un (et un seul) programme principal sur
l'ensemble des fichiers à compiler (ici dans main.f90).
➢ compilation séparée en 2 étapes :
1) compilation de chaque fichier source .f90 :
g95 -c lecture_entier.f90 lecture_entier.o
g95 -c main.f90 lecture.mod
main.o
* pour chaque fichier source .f90
se crée un fichier objet .o (binaire illisible)
* pour chaque module se crée un fichier .mod (fichier texte)
2) édition de liens : on rassemble les fichiers objets .o (et
seulement eux) pour créer l'exécutable final (ici prog)

g95 -o prog lecture_entier.o main.o


6
Compilation séparée

● Dans quel ordre effectuer la compilation


séparée ?
➢ Il faut respecter les dépendances entre modules (elle
repose sur la génération des fichiers .mod) :
- on compile d'abord les modules qui n'utilisent aucun autre
module,
- puis les modules qui utilisent des modules déjà compilés,
- et ainsi de suite pour finir par la compilation du programme
principal.
● L'exécutable est généré grâce à l'édition de liens.
● On peut faire les deux étapes en une commande :
g95 -o prog lecture_entier.f90 main.f90

mais il faut respecter les dépendances des


modules dans l'ordre des fichiers .f90. 7
Compilation : suppléments

● Quelques options utiles pour compiler


➢ Option pour forcer le stockage des réels sur 8 octets
plutôt que 4 (simple → double précision) : double précision) :
g95 -r8 ...
gfortran -fdefault-real-8 ...
ifort -r8 ...

➢ Option pour vérifier les dépassement de tableau à


l'exécution (à utiliser en particulier quand le message
d'erreur 'Segmentation fault' apparaît à l'exécution) :

g95 -fbounds-check ...


gfortran -fcheck=bounds ...
ifort -CB ...

(cf. memento FORTRAN 90)


8

Vous aimerez peut-être aussi