EXECUTANDO PROGRAMAS EM FORTRAN 77

Introdução
Compilação e Linkagem
Debugger
Cronometragem
Referências

Introdução

O compilador Fortran das estações DEC Alpha AXP é o Fortran 77. Estamos com a última versão (3.8) que, a partir da versão (3.5), está aceitando extensões como REAL*16. As variáveis reais em precisão quádrupla (REAL*16), tem 33 dígitos na mantissa e expoente na faixa -4932 a +4932. Existem as correspondentes funções intrínsecas para este tipo de variável (QSQRT, QLOG, QEXP, QSIN, etc.).

Compilação e Linkagem

A compilação e "linkagem" com Fortran é realizada com o comando

     f77 -V -C -check under -check over -o prog.exe prog.f
onde
    -V
    é uma chave opcional que provoca a geração do arquivo prog.l, o qual contem uma listagem do programa com eventuais mensagens de erro de compilação. Use, neste caso, também a chave -cross_reference para uma listagem mais completa, com "cross reference table".
    -C
    é uma chave opcional que faz com que durante a execução os limites das variáveis indexadas sejam sempre verificados.
    -check under
    é uma chave opcional que faz com que mensagens de erro (no máximo duas) sejam dadas ao se detectar underflow em ponto flutuante. Se esta chave não estiver ativada, as variáveis com underflow recebem o valor zero.
    -check over
    é uma chave opcional que causa detecção de overflow de variáveis inteiras.
    -o prog.exe
    dá ao programa executável gerado na compilaçatilde;o o nome prog.exe. Se esta chave não estiver ativada, o nome default para o executável é a.out.
    prog.f
    é o nome do arquivo que contém o programa-fonte a ser compilado. O sufixo pode ser .f, .for ou .FOR.

Uma outra chave opcional é -c, que causa compilação, isto é, geração do arquivo prog.o, sem "link", ou seja, o programa-executável não é efetivamente criado. Outra chave opcional é -g, usada quando se vai examinar a execução do programa com o degugger dbx. Quando se tem certeza que o programa está funcionando corretamente, pode-se usar a opção -fast, retirando -check under, -check over e -C. Com isto o programa será executado mais rapidamente.

Para se executar o programa basta dar o comando (após, é claro, uma compilação bem sucedida):

	prog.exe
Desta forma o programa é executado no modo interativo (foreground). Eventuais erros de execução são reportados na tela. O terminal não pode ser desligado neste modo, sob pena ter sua execução suspensa. Portanto, sua utilidade se resume a programas de execução relativamente curta. Um outro modo de execução é o de "batch" (ou background), onde o desligamento do terminal não causa suspensão na execução. Isto é conseguido com o comando

	prog.exe >>& prog.erro &

onde prog.erro é um arquivo que conterá eventuais mensagens de erro detectados na fase de execução (que são impressos na tela no modo interativo). Quando a execução foi normal ele contém a mensagem FORTRAN STOP e os arquivos de saída estão prontos para serem examinados. Pode-se também usar o arquivo prog.erro como arquivo de saída (comandos write(* , ) que geram saída em tela). O último símbolo & indica para a Alpha que o programa deve ser executado em background.

Para se acompanhar a execução do programa na Alpha pode-se usar os comandos:

	ps gu
ps agu
ps axu | more
que dá informações gerais sobre o sistema. Por exemplo, temos uma saída típica para o comando ps:

USER       PID %CPU %MEM   SZ  RSS TT STAT  TIME COMMAND
fulano     520 11.2 23.715619 6534 08 R N 8662:17 athemp44.exe
root      9467 78.1  0.8  291  202 08 R     0:02 ps axu
root      9468  4.8  0.1   57   32 08 S     0:00 more
root      9432  0.4  0.3  125   63 08 S     0:02 -u (csh)
root        82  0.4  0.0    5    3 ?  S    11:23 /etc/update
root        86  0.1  0.1   31   11 ?  S     2:41 /etc/cron
                  .  .  .
Aqui o programa athemp44.exe, pertencente ao usuário fulano, está sendo executado por 8662 minutos (tempo de CPU), ocupa 11,2% do tempo da CPU e 23,7% da memória.

Para abortar a execução de um programa em modo interativo basta dar o comando

	<ctrl> c
No modo batch é necessário saber o número de identifição do processo (PID) com o comando ps e depois dar kill. Por exemplo, para suspender a execução do programa athemp44.exe, o usuário fulano (ou ainda o superusuário) deve dar o comando

	kill -9 520
Debugger dbx

O "debugger" dbx é usado para se ter mais informações sobre o local onde um erro de execução aconteceu pois, sem isto, o compilador informa apenas que ocorreu um "overflow", por exemplo, sem maiores informações. Para se usar o dbx o programa deve ser compilado novamente com a chave -g. Por exemplo

     f77 -g -C -check under -check over -o prog.exe prog.f
Após a compilação, a execução é feita com o comando

    dbx prog.exe
Aparecem algumas mensagens na tela e em seguida o "prompt"

    (dbx)
Para iniciar a execução use o comando

    run
Note que a execução é sempre no modo interativo, de modo que o dbx não é útil para programas onde o erro só ocorre depois de várias horas de execução. Ao acontecer o erro, aparece na tela a linha onde o mesmo ocorreu.

Além do comando run há outros de bastante utilidade, como:

    dump
    mostra os valores de todas as variáveis no momento da parada na execução;
    print X1,X2
    mostra os valores das variáveis X1 e X2 (note que deve-se usar letras maiúsculas se o mesmo ocorreu no programa-fonte) no momento da parada. O comando print não mostra corretamente variáveis de precisão quádrupla (REAL*16);
    func FUNCAO
    muda o "scope" para a função FUNCAO -- necessário para se examinar variáveis fora da sub-rotina onde ocorreu o erro ou parada. Use $MAIN para mudar o "scope" para o programa-principal, se outro nome não foi dado para ele com o comando PROGRAM. O comando func sem argumento serve para localizar o presente "scope", isto é, para dar informação de onde o programa sofreu interrupção;
    up / down
    mudanca alternativa de "scope" dentro da árvore de chamada de sub-rotinas, para "cima" (em direção ao programa- principal) ou para "baixo" (na direção contrária);
    stop at 120
    serve para forçar parada na linha 120 (p. exemplo). Com isto o usuário pode, se desejar, verificar o valor de certas variáveis naquele ponto da execução. A numeração das linhas é conseguida com o comando list;
    cont
    para dar continuidade à execução, após um stop;
    list FUNCAO
    lista a função FUNCAO como aparece no programa-fonte, com numeração nas linhas. Esta numeração é necessária para o comando "stop at ...". Pressionando as teclas e barra de espaco pode-se movimentar para diante na listagem. Em vez de FUNCAO pode-se dar um número de linha onde a listagem deverá começar, ou dois números de linha separados por uma vírgula. Neste caso, a listagem será feita entre as duas linhas referenciadas;
    delete (numeros de comando, separados por vírgula)
    cancela comandos "stop". O número de comando associado a um certo "stop" é conhecido com o comando "status";
    rerun
    recomeça a execução do programa. O usuário pode ter decidido a colocar comandos "stop" em pontos alternativos, tê-los retirado, etc.
    where
    mostra onde o programa parou.

A saída do dbx se dá com o comando

    quit
Para maiores informações, inclusive outros comandos não listados acima e exemplos de "sessões" em ambiente dbx, consulte o manual "VAX Fortran for ULTRIX Systems User Manual", capítulo 4, disponível na estante da sala de terminais.

Cronometragem

Uma maneira de se saber quanto tempo um programa gasta para ser executado é "vigiando" sua execução com o comando ps, o que não é nada prático. A seqüência abaixo fornece um procedimento automático com a mesma finalidade, fazendo-se chamada da função ETIME dentro do programa Fortran:

  1. Acrescente no cabeçalho do programa a linha seguinte, que tem por finalidade definir as variáveis TIME e TARRAY (array) e a função ETIME como REAL*4:

          REAL ETIME,TIME,TARRAY(2)
    
  2. Acrescente como primeira linha executável o seguinte, que tem por finalidade "disparar" o cronômetro:

          TIME=ETIME(TARRAY)
    
  3. Acrescente antes do STOP o seguinte, que tem por finalidade "travar" o cronômetro e imprimir o tempo na saída 6:

          TIME=ETIME(TARRAY)
          WRITE(6,1009) TIME/60.
    1009  FORMAT(1X,'TEMPO DE EXECUCAO = ',F15.4,' MINUTOS')
    
Se a variável TIME não for dividida por 60 o resultado é dado em segundos. Para tempo em horas, divida por 3600. Para cronometrar o tempo de execução de uma parte do programa (um loop, por exemplo) coloque os dois comandos TIME=ETIME(TARRAY) imediatamente antes e após a seqüência a ser cronometrada.

Referências

Maiores informações podem ser obtidas dos manuais:

1) DEC Fortran - User Manual for DEC OSF/1 and ULTRIX Systems
2) DEC Fortran - Language Reference Manual
3) VAX Fortran for Ultrix Systems - User Manual
4) VAX Fortran for Ultrix Systems - Language Reference Manual
5) ou usando o comando

        man f77
6) ou examinando com more ou view os arquivos

	/usr/lib/cmplrs/fort/decfortran.hlp
	/usr/lib/cmplrs/fort/relnotes