sábado, 21 de setembro de 2019

Como compilar SWAT 2018 rev670 no Gfortran Linux

Instalação do GFortran

Para instalar o GFortran no Ubuntu utilize os comandos:

sudo apt update
sudo apt install gfortran

Modificações do código original

Pode ser necessário alterar os arquivos de código fonte para atendenrem o padrão do fortran. O compilador da intel é mais premissivo quanto ao padrão do arrquivo, enquanto o gfortran é mais chato, requer o código no padrão fixed ou free from, e não lida bem com a mistura dos dois dentro do mesmo arquivo. Os códigos mais recentes do SWAT já tem corrigido essa padronização, mas os antigos podem precisar de bastante modificação.
O SWAT é compilado originalmente com ifortran (intel), e o compilador da intel é mais permissivo que o compilador GFortran para questões de compatibilidade de formato de código antigo (.f) e novo (.f90) . O fortran passou por várias revisões com o tempo, e o código de swat tem arquivos com padrões antigos e novos, as vezes misturados dentro de um mesmo arquivo. O codigo original do SWAT não compila com GFortran, pois ele é mais chato com relação a formatação dos arquivos. Além disso, no SWAT também são utilizadas estruturas que são diferentes das recomendadas pelo padrão fortran, mas que o compilador da intel aceita, pois facilitam o uso da linguangem.
Modificações necessárias para compilar:
  1. Comentar a linha !! include 'modparm.f' no main.f
  2. É necessário alterar o comando "use" em alguns arquivos, para "use parm, except_this_one => tair", onde tair deve ser substituido pelo nome da função do arquivo com erro.
O erro ao compilar caso o comando "use" não seja corrigido é este:
       use parm
         1
Error: ‘regres’ of module ‘parm’, imported at (1), is also the name of the current program unit 
 Os arquivos que precisam ser corrigidos são:

  1. tair.f
  2. layersplit.f
  3. vbl.f
  4. ndenit.f
  5. atri.f
  6. rsedaa.f
  7. regres.h
  8. HQDAV.f90
Para corrigir altere a linha com “use parm” para “use parm, except_this_one => tair”. O nome na exceção deve ser ser o nome da função atual.
Essa modificações devem tornar o código compativel com o GFortran, sem atrapalhar o IFortran. Os os compiladores devem funcionar corretamente.


Arquivo makefile

Foi criado um makefile para facilitar a compilação do sistema. O makefile verifica se o módulo esta disponível e compila, e depois constroi o programa. A versão release e debug estão em diretórios separados. Para compilar executar: make all, make release ou make debug. Make clean limpa os builds antigos e make prep cria os diretórios.
Baixe o arquivo do link disponível no final do post e copie no mesmo diretório do código fonte.


Compilando

Para compilar execute o comando "make all" no diretório do código fonte. Isso vai criar as pastas dos executáveis. O binario está é salvo na pasta /release com o nome swat


Flags do compilador

Aqui é apresentado uma pequena descrição das flags utilizadas no compilador. Voce não precisa entender oque acontece aqui. Elas são apresentadas somente como curiosidade e para ajudar e resolver algum tipo de problema.

Para compilador com sucesso é necessário utilizar algumas flags do compilador. Elas são:
  1. release: -c -O3 -static -ffixed-line-length-none -ffree-line-length-none -std=gnu -ffpe-trap=invalid,zero,overflow -fno-automatic
  2. debug: -c -O0 -static -ffixed-line-length-none -ffree-line-length-none -std=gnu -ffpe-trap=invalid,zero,overflow -fcheck=all -fbacktrace -fno-automatic
Uma breve descrição das flags são:
  1. -O0 ou -O3: nível de otimização do código.
  2. -static: compila bibliotecas estaticamente no código.
  3. -ffixed-line-length-none: informa ao compilador para ler a linha inteira dos arquivos de código que estão no formato fixo. Pode ser necessário retirar essa flag caso o compilador apresente erro ao ler os arquivos.
  4. -ffree-line-length-none: informa ao compilador para ler a linha inteira dos arquivos de código que estão no formato livre. Pode ser necessário retirar essa flag caso o compilador apresente erro ao ler os arquivos.
  5. std=gnu: padrão do fortran utilizado.
  6. -ffpe-trap=invalid,zero,overflow: ativa exceções para capturar erro de overflow, número inválido e divisão por zero. O erro de underflow não é capturado, o número é aproximado para zero.
  7. -fno-automatic: trata variáveis locais como estáticas, ou seja, elas são salvas e mantém o mesmo valor entre as chamadas da função. O fortran inicialmente tratava as variáveis locais como estáticas, mas nas versões mais novas elas não mantém mais o valor entre chamadas. O código swat assume que as variáveis mantém o valor entre as chamadas, por iso precisa dessa flag.
  8. -fcheck=all: verifica por todos erros possíveis durante execução. Pode deixar o programa mais lento. Utilizado somente no debug.
  9. -fbacktrace: faz um rastreamento para a função que gera erro. Utilizado somente no debug.


Sobre os formatos dos arquivos fortran

Os código fontes do fortran seguiam o padrão fixed form (.f), e os mais atuais seguem o free form (.f90). O código do SWAT parece misturar os dois formatos, oque pode gerar erros na compilação com o gfortran.
Os arquivos do SWAT parecem ser todos escritos em fixed form, mas alguns arquivos utilizam a quebra de linha do formato free form. O compilador informa um erro quando isso acontece.
O erro mais comum nos códigos do SWAT é utilizar a extensão .f, e utilizar para quebra de linha o caracter & (que é do padrão .f90). Isso gera um erro. A solução é alterar a extensão do arquivo para .f90, ou corrigir a quebra de linha.
Como regra geral: se o fim da linha tiver um &, a extensão do arquivo deve ser .f90. Se a linha de baixo tiver o & ou outro caracter na coluna 6 então deve ser .f.
Extensão .f → fixed form: primeira cinco colunas em branco. A continuação de linha é incluir algum caracter na coluna 6 da próxima linha. Esse é o primeiro padrão do fortran – F77. F77 le somente até coluna 72 por padrão.
Extensão .f90 → free form: é a versão mais moderna. A continuação de linha é com & no fim a linha atual e no inicio da segunda linha.
É recomendável utilizar .f90.
Alguns arquivos de algumas versões do SWAT tem as duas formas de quebra de linha no mesmo arquivo, oque torna impossível compilar sem corrigir o código para um dos dois padrões definidos.


Link para arquivos

Os arquivos originais do SWAT podem ser obtidos nesse link: https://swat.tamu.edu/software/swat-executables/

Os arquivos já modificados para GFortran e com o arquivo makefile podem ser obtidos no github: https://github.com/JairoRotava/SWAT-2018-GFortran

Vale a pena verificar se os resultados gerados com o binário compilado pelo GFortran é o mesmo que o gerado pelo binário gerado pelo fornecido no site.






Nenhum comentário:

Postar um comentário