2
GEO764 - Programação
avançada em Geofísica
Entrada e saída no Fortran 90
] É extenso em assuntos relativos a E/S.
] Permite um grande número de arquivos conectados a
um programa, tanto para leitura como escrita.
] Um arquivo é conectado por meio de uma unidade
lógica, denotado por um número.
] Cada unidade tem diversas propriedades:
FORTRAN 90: Aula no 9
Miscelânea
mar-07
\
\
\
\
nome: nome do arquivo conectado
ação: se para leitura, escrita, leitura e escrita, etc.
estado: existente, novo, substituir, etc.
método de acesso: seqüencial, direto.
Hédison K. Sato
3
Comando OPEN
Comando OPEN: exemplo
] A sintaxe é:
OPEN([UNIT=]<inteiro>, FILE=<filename>, &
ERR=<label>, STATUS=<status>, ACCESS=<method>,&
ACTION=<mode>,RECL=<int-expr>)
onde
] <filename>
é uma cadeia de caracteres,
] <status> é ’OLD’, ’NEW’, ’REPLACE’, ’SCRATCH’,
’UNKNOWN’
é ’DIRECT’ ou ’SEQUENTIAL’
] <mode> é ’READ’, ’WRITE’ ou ’READWRITE’
] se o acesso é direto, <int-expr> precisa ser dado.
] <method>
4
ou
] OPEN(17, FILE=’output.dat’, ERR=10, &
STATUS=’REPLACE’, ACCESS=’SEQUENTIAL’,&
ACTION=’WRITE’)
] OPEN(14, FILE=’input.dat’, ERR=10, &
STATUS=’OLD’, ACCESS=’DIRECT’,&
ACTION=’READ’,RECL=nlength)
5
Comando READ
6
Comando READ
] Nem todas especificações podem ser simultâneas.
rótulo de um comando executável,
<advance-mode> é ’YES’ ou ’NO’
<num-chars> é o número de caracteres lido,
<int-expr> é o número do registro (p/ acesso direto)
Exemplo:
] <label>
READ([UNIT=]<inteiro>, [FMT=]<format>, &
IOSTAT=<int-variable>, ERR=<label>, &
END=<label>, EOR=<label>, &
ADVANCE=<advance-mode>, REC=<int-expr>, &
SIZE=<num-chars>) <input-list>
]
]
]
]
onde
READ(14,FMT=’(3(F10.7,1X))’,REC=iexp) a,b,c
READ(*,’(A)’,ADVANCE=’NO’,EOR=12,SIZE=nch) str
é um número ou *,
] <format> é uma cadeia de caracteres ou o rótulo de um
FORMAT,
] <int-variable> armazena um código de retorno, zero
significa “sem erro”,
] <unit>
7
Comando WRITE
] Nem todas especificações podem ser simultâneas.
WRITE([UNIT=]<inteiro>, [FMT=]<format>, &
IOSTAT=<int-variable>, ERR=<label>, &
ADVANCE=<advance-mode>, REC=<int-expr>)
&
<output-list>
onde
é um número ou *,
] <format> é uma cadeia de caracteres ou o rótulo de um
FORMAT,
] <int-variable> armazena um código de retorno, zero
significa “sem erro”,
] <unit>
8
Comando WRITE
rótulo de um comando executável,
] <advance-mode> é ’YES’ ou ’NO’
] <int-expr> é o número do registro (p/ acesso direto)
] Exemplo:
] <label>
WRITE(17,FMT=’(I4)’,IOSTAT=istat,ERR=10) IVAL
WRITE(*,’(A)’,ADVANCE=’NO’) ’Yello’
Comando FORMAT
especificação FMT
9
10
Descritores de edição
] Sumário:
w caracteres de dado inteiro
Iw
Fw.d w caracteres de dado real. (d número de decimais)
Ew.dw caracteres de dado real. (d número de decimais)
w caracteres de dado lógico
Lw
w caracteres de dado caracter
A[w ]
nX
pula n caracteres (n espaços)
] Por exemplo:
] FMT= pode especificar tanto o número da linha do
comando FORMAT, uma expressão tipo caracter ou um
* (asterisco).
] O Fortran 90 tem uma rica sintaxe para formatação.
Aqui serão vistos alguns deles.
WRITE(17, FMT=”(2X,2I4,1X,’NOME ’,A7)”) I,J,STR
READ(14,*) x,y
WRITE(*,FMT=10) a,b
10 FORMAT(’vals’, 2(F15.6,2x))
WRITE(*,FMT=’(2X,2(I4,1X),’’name ’’,&
A4,F13.5,1X,E13.5)’) &
77778,3,’ABCDEFGHI’,14.45,14.566666666
imprime
o dado é formatado por meio de descritores de edição.
No exemplo, o seguinte é escrito
11-195 NOME Philip
vals
-1.051330
****
3 name ABCD
14.45000
0.14566E+02
333356.000033
11
Outros comandos de E/S
]
]
]
]
]
CLOSE - desfaz a conexão da unidade do número especificado no
comando.
REWIND - reposiciona o apontador no início do arquivo.
BACKSPACE - o apontador é reposicionado um registro em direção ao início
do arquivo.
ENDFILE - força a gravação de um “end-of-file”.
Esses comandos têm outros especificações tais como o IOSTAT
REWIND(14)
BACKSPACE(UNIT=14)
ENDFILE(17)
CLOSE(UNIT=17,IOSTAT=ival)
12
Procedimentos externos
]
]
]
O Fortran 90 admite o procedimento externo (similar ao velho estilo de
programação do Fortran 77).
Evidentemente, este procedimento não faz parte de um programa ou
módulo, devendo ser denotado como sendo um procedimento externo
(EXTERNAL).
Assim:
\
\
\
\
eles podem ser compilados separadamente,
podem necessitar uma interface explícita para ser fornecida ao programa
usuário,
podem ser utilizados como argumentos (somando-se aos intrínsecos),
devem conter o especificador IMPLICIT NONE.
Sintaxe de subrotina
externa não recursiva
13
14
Subrotina externa: exemplo
]
SUBROUTINE Ext_1(...)
!...
CONTAINS
! Procedimentos internos
SUBROUTINE Int_1(...)
! comandos executáveis
END SUBROUTINE Int_1
...
FUNCTION Int_n(...)
! comandos executáveis
END FUNCTION Int_n
Um procedimento externo pode chamar um outro procedimento externo.
SUBROUTINE sub1(a,b,c)
IMPLICIT NONE
EXTERNAL sum_sq
! declara ou use INTERFACE
REAL :: a,b,c
...; CALL sum_sq(a,b,c,s); ...
END SUBROUTINE sub1
chama
SUBROUTINE sum_sq(aa,bb,cc,ss)
REAL, INTENT(IN) :: aa,bb,cc
REAL, INTENT(OUT):: ss
ss = aa*aa + bb*bb + cc*cc
END SUBROUTINE sum_sq
END SUBROUTINE Ext_1
SUBROUTINE Ext_2(...)
! etc...
END SUBROUTINE Ext_2
Sintaxe de uma função
não recursiva
]
Primeiro modelo:
15
Sintaxe de uma função
não recursiva
]
[<prefixo>] FUNCTION <nome-proc>([<arg-mudos>])
<declaração dos argumentos mudos>
<declaração dos objetos locais>
...
<comandos executáveis, atribuição do resultado>
[CONTAINS
<comandos executáveis, atribuição do resultado>
[CONTAINS
<definições internas ao procedimento>]
END [FUNCTION [<nome-proc>]]
]
Segundo modelo:
FUNCTION <nome-proc>([<arg-mudos>])
<declaração dos argumentos mudos>
<declaração do tipo do resultado>
<declaração dos objetos locais>
...
<definições internas ao procedimento>]
END [FUNCTION [<nome-proc>]]
O <prefixo> especifica o tipo do resultado.
]
O <nome-proc> precisa ser declarado.
16
17
Exemplo de função externa
]
Interfaces de procedimentos
A função é ativada pela sua presença na expressão, no local em que o
resultado é exigido.
É possível prover uma interface explícita para um procedimento externo.
Assim, considerando a seguinte subrotina,
]
]
total = total + maior(a, b, c)
]
18
SUBROUTINE expsum(n,k,x,sum)
USE KIND_VALS: ONLY long
IMPLICIT NONE
INTEGER, INTENT(IN):: n
REAL(long), INTENT(IN) :: k,x
REAL(long), INTENT(OUT):: sum
REAL(long), SAVE:: cool_time
...
END SUBROUTINE expsum
As funções externas devem ser declaradas como EXTERNAL, senão a
INTERFACE deve ser fornecida.
INTEGER, EXTERNAL:: largest
]
A função é descrita como
INTEGER FUNCTION &
maior(i,j,k)
IMPLICIT NONE; INTEGER, &
INTENT(IN):: i,j,k
maior = max(i, j, k)
END FUNCTION maior
FUNCTION maior(i,j,k)
IMPLICIT NONE; INTEGER, &
INTENT(IN):: i,j,k
INTEGER:: maior
maior = max(i, j, k)
END FUNCTION maior
Interfaces de procedimentos
(cont.)
]
A interface propriamente dita é formada com os comandos que aparecem
no intervalo contendo as declarações
INTERFACE
! p/ procedimentos externos
SUBROUTINE expsum(n,k,x,sum)
! interface
USE KIND_VALS: ONLY long
INTEGER, INTENT(IN):: n
! interface
REAL(long), INTENT(IN) :: k,x
! interface
REAL(long), INTENT(OUT):: sum
! interface
END SUBROUTINE expsum
! interface
END INTERFACE
]
As interfaces substituem qualquer comando EXTERNAL e são
desnecessários para os procedimentos internos.
! interface
! interface
! interface
! interface
! interface
19
20
O quê aparece na interface?
]
]
Uma interface contém somente:
\ o cabeçalho SUBROUTINE ou FUNCTION
\ o tipo da função (se não estiver definido no cabeçalho),
\ declaração dos argumentos mudos, incluindo os atributos.
\ o comando END SUBROUTINE ou END FUNCTION
As interfaces somente são necessárias para procedimentos externos e
eliminam a necessidade de qualquer outra forma de declaração para os
procedimentos em questão.
21
Exemplo de interface
]
Interfaces obrigatórias
O programa inclui uma interface explícita
PROGRAM exemplo_de_interface
IMPLICIT NONE
INTERFACE
SUBROUTINE expsum(n,k,x,sum)
INTEGER, INTENT(IN):: n
REAL, INTENT(IN) :: k,x
REAL, INTENT(OUT):: sum
END SUBROUTINE expsum
END INTERFACE
REAL:: sum
...; CALL expnum( 10,0.5,0.1,sum); ...
END PROGRAM exemplo_de_interface
]
As interfaces explícitas permite compilações separadas, otimizações e
verificação dos tipos.
Procedimentos como
argumentos
] Os procedimentos externos usados como argumentos precisam ser
declarados no local da chamada (CALL) como
\ INTRINSIC: para os procedimentos internamente construídos.
INTRINSIC MVBITS
; REAL, INTRINSIC:: ASIN
\ EXTERNAL: para os procedimentos externos ou mudos
22
23
]
Interfaces explícitas são obrigatórias se o procedimento externo tiver
\ argumentos mudos que sejam conjuntos de forma a determinar,
apontadores ou alvos,
\ argumentos opcionais,
\ conjuntos ou apontador como resultado (função),
\ um resultado que tem uma especificação de comprimento LEN=*
herdada (funções caracter).
]
e quando a referência:
\ tem uma palavra-chave como argumento,
\ é uma atribuição definida,
\ é uma chamada para um nome genérico,
\ é uma chamada para um operador definido (função)
Exemplos de procedimentos
como argumentos
PROGRAM main
IMPLICIT NONE
INTRINSIC ASIN
REAL, EXTERNAL:: my_sin
EXTERNAL diffo1
CALL subby(ASIN,my_sin,diffo1,SIN(0.5))
END PROGRAM main
EXTERNAL my_subby ; INTEGER, EXTERNAL:: my_fun
] Se o nome de um procedimento interno é usado em um comando
EXTERNAL, então somente o procedimento externo homônimo é visível no
escopo; o procedimento intrínseco fica indisponível.
] Nos dois casos, o procedimento específico, não o genérico, pode ser usado
como argumento efetivo. Procedimentos internos não podem aparecer
como argumentos.
SUBROUTINE subby(fun1,fun2,sub1,x)
IMPLICIT NONE
REAL, INTENT(IN):: x
REAL, EXTERNAL:: fun1, fun2; EXTERNAL sub1
PRINT *, fun1(x), fun2(x)
CALL sub1(fun2(x),fun1,x)
END SUBROUTINE subby
24
Exemplos de procedimentos
como argumentos (cont.)
25
Comando DATA
SUBROUTINE diffo1(y,f,x)
IMPLICIT NONE ; REAL, INTENT(IN):: x, y
REAL, EXTERNAL:: f
PRINT *, ”Diffo1 = ”, y - f(x)
END SUBROUTINE diffo1
] O comando DATA é bom para iniciar seções de conjuntos de forma
irregular, complicada.
DATA <lista-var-1>/<lista-1-dados>/, &
... <lista-var-n>/<lista-n-dados>/
] O número de constantes em cada <lista-dados> precisa ser igual
ao número de variáveis e elementos de conjuntos da <lista-var>
correspondente. Qualquer objeto iniciado por um comando DATA
tem o atributo SAVE.
REAL FUNCTION my_sin(x)
...
END FUNCTION my_sin
27
Exemplo de comando DATA
]
Como exemplo, considere iniciar um conjunto 100 × 100 com todos os
valores das extremidades iguais a um e o restante, nulo. Este não é um
caso simples a ser feito com outro comando, como é com o DATA:
REAL:: matriz(100,100)
DATA matriz(1, 1:100)/100*1.0/
DATA matriz(100,1:100)/100*1.0/
DATA matriz(2:99,
1)/98*1.0/
DATA matriz(2:99, 100)/98*1.0/
DATA matriz(2:99,2:99)/9604*0.0/
]
A expressão 100*1.0 significa “100 ocorrências de 1.0”, o * é a
especificação de repetição. Neste contexto, não deve ser confundido com a
multiplicação.
26
Comando DATA
laço DO implícito
]
No comando DATA, a <lista-var> pode ser especificada por meio de um
laço DO implícito. Iniciar um matriz com uma constante ao longo da
diagonal e zero nos demais elementos é simples usando este método. A
seção é especificada por um laço genioso que é mais expressivo do que a
sintaxe de conjunto permitem.
REAL:: diag(100,100)
DATA (diag(i,i),i=1,100)
/ 100* 1.0/
DATA ((diag(i,j),diag(j,i), j=i+1,100),i=1,100)&
/9900*0.0/
28
29
Comando GO TO
]
]
]
]
]
]
Comando GOTO: exemplo
É poderoso mas permite desvios indisciplinados.
Pode ser usado para criar desvios para quase todos os locais de uma
unidade de programa.
Pode ser perigoso.
Pode resultar códigos sem estrutura.
Pode ser bastante útil.
A sintaxe básica é:
GOTO <rótulo-numérico>
O rótulo precisa existir e estar no mesmo escopo junto a um comando
executável.
]
]
Usar para tratar situações de exceção em procedimento.
SUBROUTINE sub(ierror)
INTEGER, INTENT(OUT):: ierror
...
ALLOCATE(a(100),STAT=ierror)
IF(ierror>0) THEN
PRINT*, ”Falha na alocação”
RETURN
END IF
...
END SUBROUTINE
]
STOP poderia ter sido usado em lugar do RETURN:
STOP ”sub: falha na alocação”
A mensagem é opcional. Pode ser uma constante inteira com até 5 dígitos.
Considere o seguinte exemplo de uso atroz do GOTO
GOTO 10
! pulo p/ frente
23 CONTINUE
i = i-1
IF(I.EQ.0) GOTO 99
10 PRINT*, ”Linha 10”
69 j = j-1
! “loop”
...
IF(j.NE.0) GOTO 69
GOTO 23
! desvio para trás
99 CONTINUE
]
31
RETURN e STOP
30
Este trecho de código mostra pulos p/ frente, p/ trás e a simulação de um
laço DO. O melhor uso do GOTO é sair de uma estrutura muito embutida,
em situações críticas.
Fortran 95
FORALL
]
Comando e estrutura FORALL
]
]
FORALL (i=1:100,j=2:100) e(i,j)=b(i,j)+f(i,j)
FORALL (i=1:100:3,j=2:100:2,a(i,j)>0)
b(i,j)=c(i,j)+d(i,j)
e(i,j)=b(i,j)+f(i,j)
END FORALL
]
Na estrutura FORALL, além de atribuições, podem ser usados os comandos
e estruturas WHERE e FORALL
Cada comando é executado por completo, em paralelo, antes do seguinte.
]
32
Fortran 95
FORALL (cont.)
]
]
33
34
EFEITO COLATERAL PROIBIDO
O FORALL dispõe uma alternativa eficiente para a construção elemento a
elemento de um conjunto. Permite explicitar elementos de conjuntos,
seções, subcadeias, ou alvos apontados com função dos subscritos dos
elementos.
]
]
FORALL (<lista-de-triplas>[,<máscara-escalar>])
onde cada tripla é
índice=subscrito:subscrito[:passo]
]
O comando considera, como no caso do WHERE, que as operações cálculo
e atribuição são executadas em qualquer ordem sempre com o mesmo
resultado, o que quer dizer, em paralelo.
]
35
EFEITO COLATERAL PROIBIDO
]
A chamada a uma função não deve redefinir o valor de uma
variável que aparece no mesmo comando ou afete o valor de outra
função no mesmo comando.
\ Ex.:
]
Com relação a esta regra, o comando if,
if (expressão lógica) comando
é tratado como equivalente a
if (expressão lógica) then
comando
Fortran 95
PURE
]
d=max(dist(p,q), dist(q,r))
endif
\ O mesmo se aplica para o comando where
]
Esta regra permite que quaisquer expressões, argumentos de um
único procedimento, sejam avaliadas em qualquer ordem.
Para facilitar a compilação otimizada, a regra padrão do Fortran proíbe
dependências a certos efeitos colaterais.
A regra especifica ser desnecessária a avaliação parcial ou total de todos
operandos de uma expressão, se o valor da expressão puder ser
determinada de outra forma.
\ Ex.:
x>y .or. fun(z) ! x, y e z reais e fun uma função lógica
A chamada da função é dispensável se x é maior que y. Desta forma, z
é indeterminado se o seu valor é modificado por fun.
Similarmente, é dispensável a avaliação de subscrito ou subcadeia de um
conjunto de tamanho nulo ou objeto caracter de comprimento nulo
]
]
A palavra PURE, adicionada aos comandos function e subroutine, assegura
que o procedimento não tem efeitos colaterais, ou seja, ficam assegurados
que
\ Não altera qualquer dos argumentos mudos
\ Não altera qualquer parte de uma variável do hospedeiro ou associação
\ Não contém variável local com o atributo save
\ Não realiza operação com um arquivo externo
\ Não contém o comando stop
Ex.:
\ pure function dist(p,q)
Para maiores detalhes, consulte Metcalf e Reid (2000)
36
Fortran 95
ELEMENTAL
]
]
]
]
37
Denomina-se “elemental” os operadores e funções intrínsecas capazes de
serem aplicados a escalares e conjuntos.
Ex.: c=a+b; c=sin(a)
onde a, b e c podem ser conjuntos similares
Estende esta característica para os procedimentos não intrínsecos.
Ex.:
type estat
real :: media, var
end type estat
Fortran 95
ELEMENTAL
]
]
]
]
38
No exemplo anterior, a função tem dois argumentos. Assim, ela é capaz
de operar sobre dados com as seguintes combinações de ordem:
\ 0-0, 0-1, 1-0, 1-1, 0-2, 2-0, 2-2, ..., 0-7, 7-0, 7-7
22 combinações!
\ Se restrito ao Fortran90, teriam que ser escritas 22 versões.
A função elementar tem o atributo “pure” também.
Não é permitido uma função elementar ter o caráter recursivo.
Para maiores detalhes, consulte Metcalf e Reid (2000)
elemental function soma(a,b)
type (estat)
:: soma
type (estat), intent(in):: a, b
soma%media=a%media+b%media
soma%var=a%var+b%var
end function soma
Fortran 95
Miscelânea
]
]
]
O Fortran 95 possui uma função intrínseca NULL para atribuir valor inicial
nulo aos apontadores, em lugar do indefinido.
\ Também tem mecanismos para atribuir valores iniciais aos
componentes dos tipos derivados.
O Fortran 95 permite o uso das funções definidas pelo usuário nas
expressões de especificação, desde que sejam PURE.
Uso da <especificação> no comando END INTERFACE
END INTERFACE <especifição>
39
Fortran 95
Miscelânea
] Características removidas em relação às versões anteriores:
\
\
\
\
\
Comandos ASSIGN e GOTO atribuídos
Comando PAUSE
Variáveis de controle do tipo real no comando DO
Descritor de edição H (para especificação de formato)
Desvio para o ENDIF, de fora do bloco IF
40
41
FIM
] Referências
Metcalf, M. e Reid, John, 2000, Fortran 90/95 explained,
Oxford Univ. Press.
] Fazer os exercícios.
Download

GEO764 - Programação avançada em Geofísica Entrada e saída no