sexta-feira, 1 de agosto de 2014

Inteoperabilidade entre as linguagens C e Fortran

É bastante buscado um programa que contenha um código tanto em Fortan quanto em C e na qual uma rotina escrita numa das linguagens seja capaz de chamar outra rotina escrita na outra linguagem. O compilador de Fortran da intel® tem suporte para o padronizado mecanismo do Fortran 2003 que parmite o código em Fortran se cominicar de forma confiável (ou interoperar) com um código em C.
 Como chamar um programa em C a partir de um em fortran e como chamar um programa fortran a partir de um em C, tema de hoje.

Para chamar funções em c a partir de um programa Fortran ou chamar subrotinas em Fortran a partir de C envolve resolver as seguintes problemas:

* 'Case sensitivity' ( uma vez que C é 'case sensitive' porém fortran não é)
* Possivel sublinhado adicional ("_") em nomes de funções em C (o
   sublinhado é adicinado por alguns compiladores em fortran.)
* Possiveis bibliotecas adicionais em Fortran que precisam ser linkadas para
   construir executáveis.
* Subrotinas em fortran são sempre "chamadas por referência" enquanto
   em C podem ser tanto "por referência quando por valor".

No que se segue, especificos exemplos são dados para compiladores intel e compiladores GNU. Se vc está usando outro compilador mudanças podem ser requeridas.

C chamando subrotinas em fortran suboutines

Exemplo de programas em C. Programa principal (c-call-f.c) -- note o sublinhado arrastado
no nome da função for_sub_:
 
#include 
void for_sub_(int *, double *, double *, int *);
int main()
{
int i = 1, ny = 3;
double pi = 3.14159;
double y[] = {1.1, 2.2, 3.3};
// pular uma linha para melhor visualizacao
printf("\n");
printf("_____________________________________________\n");
printf(" C chamando subrotina em fortran, passando\n");
printf(" i = %d, pi = %g\n", i, pi);
printf(" y[] = %g, %g, %g\n", y[0], y[1], y[2]);
printf("_____________________________________________");
//pular uma linha para melhor visualizacao
printf("\n");
for_sub_(&i, &pi, y, &ny);
return 0;
}

Programa exemplo: subrotina em fortran, em "formato livre (free format)" ( f_sub.f)

subroutine FOR_SUB(i, pi, y, ny)
IMPLICIT NONE
integer :: i, ny
double precision :: pi
double precision :: y(ny)
! pular uma linha para melhor visualizacao no terminal
print *, " "
print *, "____________________________________________"
print *, "Esta eh uma subrotina em Fortran..."
print *, "i = ", i, ", pi = ", pi
print *, "y = ", y(1:ny)
print *, "____________________________________________"
! pular uma linha para melhor visualizacao no terminal
print *, " "
end subroutine FOR_SUB

Como compilar:

Usando compiladores Intel icc e ifort

$ icc -c c-call-f.c
$ ifort -free -c f_sub.f
$ icc -o c-call-f-icc  c-call-f.o  f_sub.o -L/u/local/
compilers/intel/fce/current/lib -lifcore -limf
$ ./c-call-f-icc

Usando compiladores GNU gcc e gfortran

$ gcc -c c-call-f.c
$ gfortran -ffree-form -c f_sub.f
$ gcc -o c-call-f-gcc  c-call-f.o f_sub.o  -lgfortran
$ ./c-call-f-gcc 

Fortran chamando funções em C

Exemplo de programa: Programa principal em fortran,
em free format (f-call-c.f):

program f_call_c
IMPLICIT none 
integer :: i = 1, ierr
double precision :: pi = 3.14159 
print *, "______________________________" 
print *, "Fortran chamando C, passando"
print *, "i = ", i, "pi = ", pi
ierr = cfun(i, pi)
print *, "______________________________"
end program f_call_c

Programa exemplo: função em C(cfun_c) -- note que o sublinhado arrastado no nome da
função cfun:
 
#include 
int cfun_(int *ip, double *xp)
{
int i = *ip;
double x = *xp;
printf("\n");
printf("______________________________"); 
printf("Esta eh uma funcao em C...\n");
printf("i = %d, x = %g\n", i, x);
printf("______________________________");
printf("\n"); 
return 0;
}

Como se compilar

Usando compiladores Intel icc and ifort

$ ifort -free -c f-call-c.f $ icc -c cfun.c
$ ifort -o f-call-c-icc f-call-c.o cfun.o $ ./f-call-c-icc

Usando compiladores GNU gcc and gfortran

$ gfortran -ffree-form -c f-call-c.f
$ gcc -c cfun.c
$ gfortran -o f-call-c-gcc f-call-c.o cfun.o
$ ./f-call-c-gcc
 
 
REFERÊNCIAS:
http://hpc.ucla.edu/hoffman2/software/c-fortran-interop.php 
https://gcc.gnu.org/onlinedocs/gfortran/Fortran-Dialect-Options.html
https://software.intel.com/sites/products/documentation/hpc/composerxe/
en-us/2011Update/fortran/win/bldaps_for/common/bldaps_interopc.htm
http://stackoverflow.com/tags/fortran-iso-c-binding/info
http://www.pgroup.com/userforum/viewtopic.php?p=7398&sid=2a05571
a922045c6c4ae26d65bbf9fba
 



Nenhum comentário:

Postar um comentário