# Wrapping or pipping a compiled fortran code?

**URL:** <https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300>\
**Category:** New to Julia\
**Tags:** fortran\
**Created:** [April 30, 2021, 11:16am UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300 "2021-04-30T11:16:25Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [April 30, 2021, 11:16am UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/1 "2021-04-30T11:16:26Z")

</div>

Hi eveyone.  
A collague gave me a cool little code that I need to call from Julia.  
It is a fortran code and (after compilation) works as a little text based interface.  
It asks for a T and P value and then for another 2 values before printing the values I need.

An example

 ![Screenshot 2021-04-30 at 13.13.22](https://global.discourse-cdn.com/julialang/original/3X/c/4/c47f5e7fa018a749be7bccae93ed272698207f2d.png)

Is there a way to call this code from Julia? Give it inputs and safe the outputs?

Kind regards.

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [April 30, 2021, 11:44am UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/2 "2021-04-30T11:44:38Z")

</div>

I have clean the input and outputs for the code to take:

` echo "1500 65000 5 0 " | ./Perplex_LitMod`

and Just give me the output:

` 8.1736154341023113 4.5757388462334863 3326.6200653859150`

---

<div class="post-metadata">

**Author:** ![Henrique\_Becker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/henrique_becker/32/15443_2.png) [@Henrique\_Becker](https://discourse.julialang.org/u/Henrique_Becker)\
**Post date:** [April 30, 2021, 1:29pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/3 "2021-04-30T13:29:26Z")

</div>

The code is already compiled? It does not have function calls that you can use Julia do access? You have to communicate with it by the text interface?

I mean you can probably pass a `IOBuffer` to a Julia pipeline (like in [this example](https://docs.julialang.org/en/v1/manual/running-external-programs/#Pipelines)) and read the values from the `IOBuffer` but probably would be better if you just called the Fortran code from Julia.

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 30, 2021, 1:53pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/4 "2021-04-30T13:53:56Z")

</div>

This should work:

```julia
readchomp(pipeline(IOBuffer("1500 65000 5 0 "), `./Perplex_LitMod`))

```

Proof of concept:

```julia
julia> readchomp(pipeline(IOBuffer("foo bar baz"), `awk '{print $3 "+" $1 "-" $2}'`))
"baz+foo-bar"

```

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 30, 2021, 1:58pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/5 "2021-04-30T13:58:17Z")

</div>

> [@marianoarnaiz](#):
>
> little code

How little? Converting a fortran code to julia is some times really easy.

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [April 30, 2021, 7:09pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/6 "2021-04-30T19:09:27Z")

</div>

I have the compiled version and the source code.  
It is based on text input, but that can be changed I guess… I really do not understand Fortran HAHAHA

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [April 30, 2021, 7:16pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/7 "2021-04-30T19:16:01Z")

</div>

> [@GunnarFarneback](#):
>
> ```julia
> readchomp(pipeline(IOBuffer("1500 65000 5 0 "), `./Perplex_LitMod`))
> 
> ```

After looking at it… it is a small code that calls somethings I do not understand:

```julia
!gfortran Perplex_LitMod.for SUB* -o Perplex_LitMod -mpc80 -m64 -DD -O2
      
      implicit none
      include 'perplex_parameters.h'
      integer i,idead,ii,j,k,nodes_inv,whocalled,loop1,useless,iki,
     * icounting
      logical meemum, nodata, bulk
      character amount*6 !, yes*1
      integer itri(4),jtri(4),ijpt,ierflag
      double precision ctot, wt(3)
      double precision props,psys,psys1
      common/ cxt22 /props(i8,k5),psys(i8),psys1(i8)
      integer kkp, np, ncpd, ntot
      double precision cp3, ctot3
      common/ cxt15 /cp3(k5,k5),ctot3(k5),kkp(k5),np,ncpd,ntot
      integer iwt
      common/ cst209 /iwt
      double precision atwt
      common/ cst45 /atwt(k0)
      double precision v,tr,pr,r,ps
      common/ cst5 /v(l2),tr,pr,r,ps
      integer ipot,jv,iv
      common / cst24 /ipot,jv(l2),iv(l2)
      character*8 vname,xname
      common/ csta2 /xname(k5),vname(l2)
cccccccccccccccccccccccccccccccccccccccccc
      character pname*14
      common/ cxt21a /pname(k5)

      character*2 trim_name(k5)

      double precision pcomp
      common/ cst324 /pcomp(k5,k5)
ccccccccccccccccccccccccccccccccccccccccccc      
      character*5 cname
      common/ csta4 /cname(k5)

      integer jbulk
      double precision cblk
      common/ cst300 /cblk(k5),jbulk

      double precision a,b
      common/ cst313 /a(k5,k1),b(k5)

      integer icomp,istct,iphct,icp
      common/ cst6 /icomp,istct,iphct,icp

      integer io3,io4,io9
      common / cst41 /io3,io4,io9
c meemum flag used for output routines
c to distunguish meemum from werami
      save meemum
      data meemum/.true./

! REAL(8),ALLOCATABLE:: vs_sys(:),den_sys(:),vp_sys(:),
! * compres_p(:),alpha_p(:)
      REAL(8) vs_sys,den_sys,vp_sys,
     * compres_p,alpha_p
      REAL(8) t_inv,p_inv, t_eq 

!! ...intialize thermodynamic solver (Perple_X solver)
           CALL iniprp

 ! Do
      
! WRITE(*,*)'Input T (C), P (bar)?, Al2O3,FeO'
      READ(*,*) t_inv,p_inv,cblk(2),cblk(3)
      t_inv=t_inv+273.15D0
! WRITE(*,*) 'Input bulk composition (wt%) SiO2,Al2O3,FeO,MgO,CaO '
! READ(*,*) cblk(1:5)
! WRITE(*,*) 'Input bulk composition (wt%) Al2O3,FeO'
! READ(*,*) cblk(2),cblk(3)

      cblk(4)=49.369-4.106*cblk(2)+.343*cblk(2)**2D0
      cblk(5)= -.164+.906*cblk(2)
      cblk(1)=100D0-SUM(cblk(2:5))

      bulk = .true.
      icounting=0
! cblk=0.d0
      ierflag=0

      amount = 'weight'
      
      idead=0

!T in K, P in bar
      if(t_inv<773.1) then
       t_eq=773.1 
      else
       t_eq=t_inv
      endif
      v(jv(1))=t_eq
      v(jv(2))=p_inv 

      IF (bulk) THEN
       if (iwt.eq.1) then
! Convert mass to molar 
          do i = 1, jbulk
           cblk(i) = cblk(i)/atwt(i)
          enddo
        endif
! normalize the composition vector, this 
!is necessary for reasons of stupidity (lpopt0). 
            ctot = 0.d0

            do i = 1, icp
               ctot = ctot + cblk(i)
            enddo

            do i = 1, icp
               b(i) = cblk(i)/ctot
            enddo 
! lpopt does the minimization and outputs
! the results to the print file.
         call lpopt0 (idead)
         IF (idead>0) THEN
          write (*,*) 'Energy Minimization failed at this point'
          do iki=1,jbulk
           write(*,*) 'node cmp T(K) P(bar) '
           write(*,*) ii, cblk(iki)*atwt(iki),v(jv(1)),v(jv(2))
          enddo
          write (*,*) 'I will ignore this point and continue'
          icounting=1+icounting ;idead=0;ierflag=1 ;nodes_inv=useless
       
         ELSE
! compute derivative properties
! v(jv(1))=t_inv
          call getloc (itri,jtri,ijpt,wt,nodata,meemum)
! den_sys(nodes_inv)=psys(10) ! kg m-3
! vs_sys(nodes_inv)=psys(8) ! km s-1
! vp_sys(nodes_inv)=psys(7) ! km s-1
! compres_p(nodes_inv)=psys(14) / 1.0D5 ! (1/Pa)
! alpha_p(nodes_inv)=psys(13) ! (1/K)
          den_sys=psys(10) ! kg m-3
          vs_sys=psys(8) ! km s-1
          vp_sys=psys(7) ! km s-1
          compres_p=psys(14) / 1.0D5 ! (1/Pa)
          alpha_p=psys(13)
         ENDIF

      ENDIF

! WRITE(*,*)'Density (kg/m3)', den_sys
! WRITE(*,*)'Vp (km/s)', vp_sys
! WRITE(*,*)'Vs (km/s)', vs_sys
      WRITE(*,*) vp_sys, vs_sys, den_sys

! WRITE(*,*)'ntot',ntot
! DO i=1,ntot
! WRITE(*,*) 'pname(i)',pname(i)
! WRITE(*,*) ' props(17,i)*props(16,i)/psys(17)*1d2',
! * props(17,i)*props(16,i)/psys(17)*1d2
! write(*,*)'props para la fase',props(:,i) 
! write(*,*) 'pcomp', pcomp(:,i)
! ENDDO
! enddo
      END

```

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [April 30, 2021, 7:18pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/8 "2021-04-30T19:18:35Z")

</div>

Will this be eficient inside a for loop?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 30, 2021, 7:34pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/9 "2021-04-30T19:34:00Z")

</div>

Not in the least. If you want speed you have to call the Fortran code as a library.

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [April 30, 2021, 8:16pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/10 "2021-04-30T20:16:40Z")

</div>

How can I do this?

---

<div class="post-metadata">

**Author:** ![GunnarFarneback](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gunnarfarneback/32/1827_2.png) [@GunnarFarneback](https://discourse.julialang.org/u/GunnarFarneback)\
**Post date:** [April 30, 2021, 8:37pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/11 "2021-04-30T20:37:40Z")

</div>

The principal documentation is here: [Calling C and Fortran Code · The Julia Language](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/)  
But I have never called Fortran code myself and whatever I have known about Fortran is long obsolete.

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [April 30, 2021, 8:57pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/12 "2021-04-30T20:57:15Z")

</div>

I would definitely encourage you to try following those instructions to call your Fortran code as a shared library. There’s a bit of a learning curve to figuring out how to map your Julia data types to the appropriate Fortran-compatible ones, but once you learn it you’ll be able to easily (and efficiently) interoperate between Julia and Fortran.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [April 30, 2021, 9:50pm UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/13 "2021-04-30T21:50:55Z")

</div>

I find those instructions hard to understand, particularly to someone without experience with C.

I have once posted one example here: [Calling a Fortran routine from a library which uses LAPACK - #5 by lmiq](https://discourse.julialang.org/t/calling-a-fortran-routine-from-a-library-which-uses-lapack/49124/5) (but I arrived to succeed in those by finding several examples around, not reading the docs).

To do the same with that code, you need first to convert the program into a subroutine, but the way that is structured doesn’t help.

Probably the first thing to ask is how fast you need that to be. Maybe parsing the output is good enough.

---

<div class="post-metadata">

**Author:** ![marianoarnaiz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marianoarnaiz/32/19377_2.png) [@marianoarnaiz](https://discourse.julialang.org/u/marianoarnaiz)\
**Post date:** [May 1, 2021, 10:29am UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/14 "2021-05-01T10:29:35Z")

</div>

> [@lmiq](#):
>
> Probably the first thing to ask is how fast you need that to be. Maybe parsing the output is good enough.

Hi @lmiq  
Thanks for the link. I will check it.  
I am doing some probabilistic stuff (Monte Carlo Inversion) and this is part of the processing chain. Right now one input-\>output takes about 0.15 s but I need to input 500 times per iteration (say 100 k). So, it is too slow.

Any idea helps 🙂

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [May 1, 2021, 10:36am UTC](https://discourse.julialang.org/t/wrapping-or-pipping-a-compiled-fortran-code/60300/15 "2021-05-01T10:36:00Z")

</div>

But then you are not bounded by the input and output overheard (0.15s is way above that). What takes time is the computation itself. None of the alternatives of interfacing Julia and the Fortran code will solve that.
