GithubHelp home page GithubHelp logo

camfort / camfort Goto Github PK

View Code? Open in Web Editor NEW
121.0 121.0 15.0 15.95 MB

Light-weight verification and transformation tools for Fortran

Home Page: https://camfort.github.io/

License: Other

Haskell 98.53% Yacc 0.82% Shell 0.05% Dockerfile 0.14% Nix 0.46%
automated-refactoring fortran haskell static-analysis verification

camfort's Introduction

CamFort

CamFort is a refactoring and verification tool for scientific Fortran programs. It currently supports Fortran 66, 77, 90, 95 and 2003 (somewhat) with various legacy extensions.

It is a research project developed in the University of Cambridge and University of Kent.

Obtaining

Recommended install method by OS:

  • Windows: prebuilt bundles (includes dependencies) at Releases: download ones beginning camfort-bundle-windows
  • Mac: via Homebrew: brew install camfort/camfort/camfort
  • Linux: prebuilt binaries at Releases. See Wiki: Building for how to install library dependencies for your OS.

We provide prebuilt binaries for Windows, Mac and Linux. For Windows, we also provide archives that bundle the CamFort executable together with all of its dependencies.

CamFort is also available through Homebrew (formula):

brew install camfort/camfort/camfort

An older (~2019) version of CamFort is available on Docker at camfort/camfort.

A new Docker image for developers (still work-in-progress) is available at ghcr.io/camfort/camfort:dev. Suggested invocation is:

  • podman: podman run --volume $(pwd):/host --workdir /host ghcr.io/camfort/camfort:dev <CamFort arguments>

Usage

CamFort is a command-line tool, so invoke it from your favourite shell or command prompt. Detailed usage information is available on the wiki.

Building

(If you want a recent build and don't want to sit through the compilation process, you may wish to instead check the Actions tab and download the relevant build for your system from a recent workflow run.)

This section only covers building briefly. See Wiki: Building for full details.

CamFort supports GHC 8.4 through GHC 8.10, and builds with both Stack and Cabal. We regularly test at least the minimum and maximum supported GHCs. Releases prior to/newer than those may have issues. (We welcome fixes that would let us support a wider range of compilers!)

You will likely need at least 3 GiBs of memory and some patience to build CamFort.

CamFort depends on the following foreign libraries:

  • FLINT >= 2.5
  • LAPACK
  • BLAS
  • Z3 >= 4.5 (executable)

These should be built for your system, but installation method varies. System-specific guides are provided on the wiki. (Alternatively, you could check the GitHub Actions workflows.) On Ubuntu:

apt install libflint-dev liblapack-dev libopenblas-dev z3

Then stack build for Stack, or cabal build for Cabal.

Tab Completion (Bash)

To enable Bash autocompletion for camfort, add the following to your .bashrc or .bash_profile file:

eval "$(camfort --bash-completion-script=$(which camfort))"

Contributing

We appreciate any bugs you encounter and kindly request you to submit it as an issue.

Pull requests are much appreciated, but please contact us first if it is a substantial change. Make sure to run the test suite before you submit.

If you have scientific code that you would like us to analyse, we would be happy to add it to CamFort corpus. This helps us finding useful ways to extend CamFort as well as ensuring it is robust.

Support

For maintainers

See doc/maintainers.md.

camfort's People

Contributors

acr31 avatar astiob avatar dorchard avatar guiltydolphin avatar madgen avatar mrd avatar raehik avatar zbeekman avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

camfort's Issues

Units bug with polymorphic functions calling polymorphic functions

Example:

program squarePoly
  implicit none
  real :: x
  real :: y

  != unit(m) :: a
  real :: a
  != unit(s) :: b
  real :: b

  x = squareP(a)
  y = squareP(b)

  contains

  real function square(x)
    real :: x
    square = x * x
  end function

  real function squareP(x)
    real :: x
    squareP = square(x)
  end function

end program

is marked as inconsistent with the constraint:
constraint #<ParamUse squarepoly_squarep6[1] callId=1> === #<ParamUse squarepoly_square5[1] callId=2>
i.e., the second call to squareP is failing.

Continuation lines in arguments throw the parser off

When I have subroutine arguments over more than one line, commonArg stops working properly.

An example:

subroutine test(a, b, &
                c)

integer :: c1, c2, c3
COMMON /foo/  c1, c2, c3

real :: a, b, c

print *, a, b, c

end subroutine test

would result in

subroutine test(a, b, &
                c),c1,c2,c3

integer :: c1, c2, c3


real :: a, b, c

print *, a, b, c

end subroutine test

I'm using the master, compiled just moments ago.

readOnce not inferred with an if guard

For the following loop we infer stencil (reflexive(dim=1)) :: q:

do i = 1, 10
  if(.true.) q(i) = -q(i)
end do

When the if guard is removed, however, we infer stencil readOnce, (reflexive(dim=1)) :: q:

do i = 1, 10
  q(i) = -q(i)
end do

Wrong inference result on region product

program failing
  integer, dimension(10,10) :: a
  integer :: i, j

  do i = 1, 10
    do j = 1, 10
      a(i,j) = a(i  ,j) + a(i  ,j+1) + a(i  ,j+2) &
             + a(i+1,j) + a(i+1,j+1) + a(i+1,j+2) + a(i,1)
    end do
  end do
end program failing

a above gets a stencil of stencil readOnce, (forward(depth=1, dim=1))*(forward(depth=2, dim=2)) :: a.
We describe * as a stencil of bounded box, but we can't guarantee a(i,1) will always be in the box.

Note that if the assignment is changed to

      a(i,j) = a(i  ,j) + a(i  ,j+1) + a(i  ,j+2) &
             + a(i+1,j) + a(i,1)

We correctly infer stencil readOnce, (forward(depth=1, dim=1)) + (forward(depth=2, dim=2)) :: a. This is correct with respect to our description because we describe + operator as conjunction of both specifications and a(i,1) is a legit access pattern for the former stencil spec.

Stencil specs synth then immediate check fails.

When I run stencils-synth on one of our samples, it produces me the following file. But when I run stencils-check, I get errors like this:

(77:9)-(77:73)  Not well specified.
Specification is:    stencil readOnce, (backward(depth=1, dim=1, irreflexive)) :: a
but at (80:9)-(80:34) the code behaves as
                     stencil readOnce, (backward(depth=1, dim=1, irreflexive)) :: a

program parabolic2
  integer, parameter :: n = 10, m = 20
  real, parameter :: h = 0.1, k = 0.005
  real, dimension (n-1) :: c,d,u,v
  integer:: i,j
  real::pi,pi2,s,r,t

  interface                                                       
  subroutine tri(n,a,d,c,b,x)                               
  integer, intent(in)::n                                    
  real, dimension(:), intent(in):: a,c
  real, dimension(:) :: d,b      
  real, dimension(:), intent(out)::x                        
  end subroutine tri                                        
  end interface

  pi = 4.0*atan(1.0)    
  pi2 = pi*pi 
  s = h*h/k  
  r = 2.0 + s 
  do i = 1,n-1
    d(i) = r  
    c(i) = -1.0 
    != stencil readOnce, (reflexive(dim=1)) :: real
    u(i) = sin(pi*real(i)*h)      
 end do
  print "(//(5(5x,e22.14)))",(u(i),i = 1,n-1)
  do j = 1,m 
   do i = 1,n-1
      d(i) = r
      != stencil readOnce, (reflexive(dim=1)) :: u
      v(i) = s*u(i)     
    end do 
    call tri(n-1,c,d,c,v,v) 
    print*, "print the calculated v(i) where j = ",j
    print "(//(5(5x,e22.14)))",(v(i),i = 1,n-1)
    t = real(j)*k      
    do i = 1,n-1
       != stencil readOnce, (reflexive(dim=1)) :: v
       u(i) = exp(-pi2*t)*sin(pi*real(i)*h) - v(i)       
    end do 
    print*, "This is the difference between true value and v(i) and j =",j
    print "(//(5(5x,e22.14)))",(u(i),i = 1,n-1)
    do i = 1,n-1
       != stencil readOnce, (reflexive(dim=1)) :: v
       u(i) = v(i)       
    end do 
  end do 
end program parabolic2

subroutine tri(n,a,d,c,b,x)                                        
  integer, intent(in)::n                                       
  real, dimension(:), intent(in)::a,c
  real, dimension(:) :: d, b
  real, dimension(:), intent(out):: x                          
  integer ::i                                                  
  real :: xmult                                                
  do i = 2,n                                                   
    xmult = a(i-1)/d(i-1)                                      
    != stencil readOnce, (backward(depth=1, dim=1, irreflexive)) :: a, c
    != stencil readOnce, (backward(depth=1, dim=1)) :: d
    d(i) = d(i) - xmult*c(i-1)                                 
    != stencil readOnce, (backward(depth=1, dim=1, irreflexive)) :: a
    != stencil readOnce, (backward(depth=1, dim=1)) :: b
    != stencil readOnce, (backward(depth=1, dim=1, irreflexive)) :: d
    b(i) = b(i) - xmult*b(i-1)                                 
  end do                                                       
  x(n) = b(n)/d(n)                                             
  do i = n-1,1,-1                                              
    != stencil readOnce, (reflexive(dim=1)) :: b, c, d
    != stencil readOnce, (forward(depth=1, dim=1, irreflexive)) :: x
    x(i) = (b(i) - c(i)*x(i+1))/d(i)                           
  end do                                                       
end subroutine tri

units-synth produces rational power that units-check cannot parse

e.g.

program foo
  != unit X :: x 
  real :: x, y

  y = x ** 2
end program foo

then

$ camfort units-synth foo.f90 foo.f90

Synthesising units for 'foo.f90'
Writing foo.f90

foo.f90:
  3:11 unit x :: x
  3:14 unit x**2.0 :: y

$ camfort units-check foo.f90 foo.f90

Checking units for 'foo.f90'
Error (3:3)-(3:22): Not valid unit syntax at ".0) :: y"
foo.f90: Consistent. 2 variables checked.

We need to output a rational not floating point form.

Allow `*` for unit products

Allow * in addition to whitespace for product of units.

Example:

program mult
  != unit a * b :: x
  integer :: x
end program mult

This doesn't add any complexity to our system and would probably prevents frustration.

Deprecating several functions from Renaming module

extractNameMap, renameAndStrip, underRenaming, and the type NameMap will not be available once we support module use-renaming, therefore they should be phased out.

I have already removed them from the units-of-measure modules.

error compiling camfort

Hello,

I am getting the following error when trying to built camfort on Fedora 21:

[miahw@bengal camfort]$ ghci Main.hs
GHCi, version 7.6.3: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
[ 4 of 19] Compiling Analysis.Annotations ( Analysis/Annotations.hs, interpreted )

Analysis/Annotations.hs:42:47:
Not in scope: type constructor or class `SrcLoc'
Failed, modules loaded: Extensions.UnitsEnvironment, Extensions.UnitsSolve, Analysis.IntermediateReps.
Prelude Extensions.UnitsSolve>

Any help will be greatly appreciated.

cabal install camfort fails

Hi, I just tried to install camfort-0.802 via cabal, and it failed here:

...
[25 of 42] Compiling Camfort.Transformation.CommonBlockElim ( src/Camfort/Transformation/CommonBlockElim.hs, dist/build/Camfort/Transformation/CommonBlockElim.o )

src/Camfort/Transformation/CommonBlockElim.hs:292:31:
    No instance for (Monad ((,) Report)) arising from a use of ‘foldM’
    In the expression:
      foldM
        (\ p (c1, c2)
           -> (coherentCommonsP c1 c2) >>= (\ p' -> return $ p && p'))
        True
        (pairs commons)
    In an equation for ‘allCoherentCommonsP’:
        allCoherentCommonsP commons
          = foldM
              (\ p (c1, c2)
                 -> (coherentCommonsP c1 c2) >>= (\ p' -> return $ p && p'))
              True
              (pairs commons)
Failed to install camfort-0.802
cabal: Error: some packages failed to install:
camfort-0.802 failed during the building phase. The exception was:
ExitFailure 1

I'm using OpenSUSE 13.2 and

$ cabal --version
cabal-install version 1.22.9.0
using version 1.22.8.0 of the Cabal library 

Better documentation, especially the physical units capability

Hi,
I’m very interested in your Fortran refactoring tool, and would love to know more about it. I’ve read the paper and poster posted at http://www.cl.cam.ac.uk/~dao29/camfort/ and understand that this is software is under development, but it looks as though it has the potential to be extremely useful and powerful—even in its current state. Furthermore, I am intrigued by what appears to be consistency checking/validation of physical units. This feature in particular is lacking documentation. I understand that you are probably quite busy, as am I, but a small amount of effort invested in documentation could go a long way, and encourage early adoption of your tool. 👍

Example where units-infer doesn't give a unit where it should (multi-variate polymorphism)

program main
  != unit(A) :: x
  real :: x
  != unit(B) :: y
  real :: y
  real :: z
  z = mult(x,y) + mult(y,x)
end program main

real function mult(x,y)
    real x
    real y
    mult = x * y
end function

gives

poly-example2.f90: ((3,11):(3,11) - (3,11):(3,11)) unit a :: x
poly-example2.f90: ((5,11):(5,11) - (5,11):(5,11)) unit b :: y

but it should also have unit (a b) :: z. Possibly this is that equality on units isn't taking into account commutativity?

Missing file in test suite

Similar to #34, see https://github.com/bergmark/blog/blob/master/2016/package-faq.md for a suggested solution

> /tmp/stackage-build8/camfort-0.900$ runghc -clear-package-db -global-package-db -package-db=/var/stackage/work/builds/nightly/pkgdb Setup configure --enable-tests --package-db=clear --package-db=global --package-db=/var/stackage/work/builds/nightly/pkgdb --libdir=/var/stackage/work/builds/nightly/lib --bindir=/var/stackage/work/builds/nightly/bin --datadir=/var/stackage/work/builds/nightly/share --libexecdir=/var/stackage/work/builds/nightly/libexec --sysconfdir=/var/stackage/work/builds/nightly/etc --docdir=/var/stackage/work/builds/nightly/doc/camfort-0.900 --htmldir=/var/stackage/work/builds/nightly/doc/camfort-0.900 --haddockdir=/var/stackage/work/builds/nightly/doc/camfort-0.900 --flags=
Configuring camfort-0.900...
> /tmp/stackage-build8/camfort-0.900$ runghc -clear-package-db -global-package-db -package-db=/var/stackage/work/builds/nightly/pkgdb Setup build
Building camfort-0.900...
Preprocessing library camfort-0.900...
[ 1 of 30] Compiling Camfort.Helpers.Vec ( src/Camfort/Helpers/Vec.hs, dist/build/Camfort/Helpers/Vec.o )
[ 2 of 30] Compiling Camfort.Helpers  ( src/Camfort/Helpers.hs, dist/build/Camfort/Helpers.o )
[ 3 of 30] Compiling Camfort.Specification.Stencils.Syntax ( src/Camfort/Specification/Stencils/Syntax.hs, dist/build/Camfort/Specification/Stencils/Syntax.o )
[ 4 of 30] Compiling Camfort.Specification.Stencils.Model ( src/Camfort/Specification/Stencils/Model.hs, dist/build/Camfort/Specification/Stencils/Model.o )
[ 5 of 30] Compiling Camfort.Specification.Stencils.InferenceBackend ( src/Camfort/Specification/Stencils/InferenceBackend.hs, dist/build/Camfort/Specification/Stencils/InferenceBackend.o )
[ 6 of 30] Compiling Camfort.Analysis.Simple ( src/Camfort/Analysis/Simple.hs, dist/build/Camfort/Analysis/Simple.o )
[ 7 of 30] Compiling Camfort.Analysis.CommentAnnotator ( src/Camfort/Analysis/CommentAnnotator.hs, dist/build/Camfort/Analysis/CommentAnnotator.o )
[ 8 of 30] Compiling Camfort.Specification.Stencils.Grammar ( dist/build/Camfort/Specification/Stencils/Grammar.hs, dist/build/Camfort/Specification/Stencils/Grammar.o )
[ 9 of 30] Compiling Camfort.Specification.Units.Parser ( dist/build/Camfort/Specification/Units/Parser.hs, dist/build/Camfort/Specification/Units/Parser.o )
[10 of 30] Compiling Camfort.Specification.Units.Environment ( src/Camfort/Specification/Units/Environment.hs, dist/build/Camfort/Specification/Units/Environment.o )
[11 of 30] Compiling Camfort.Analysis.Annotations ( src/Camfort/Analysis/Annotations.hs, dist/build/Camfort/Analysis/Annotations.o )
[12 of 30] Compiling Camfort.Specification.Stencils.Annotation ( src/Camfort/Specification/Stencils/Annotation.hs, dist/build/Camfort/Specification/Stencils/Annotation.o )
[13 of 30] Compiling Camfort.Specification.Stencils.CheckBackend ( src/Camfort/Specification/Stencils/CheckBackend.hs, dist/build/Camfort/Specification/Stencils/CheckBackend.o )
[14 of 30] Compiling Camfort.Specification.Stencils.Synthesis ( src/Camfort/Specification/Stencils/Synthesis.hs, dist/build/Camfort/Specification/Stencils/Synthesis.o )
[15 of 30] Compiling Camfort.Specification.Units.InferenceBackend ( src/Camfort/Specification/Units/InferenceBackend.hs, dist/build/Camfort/Specification/Units/InferenceBackend.o )
[16 of 30] Compiling Camfort.Specification.Units.Monad ( src/Camfort/Specification/Units/Monad.hs, dist/build/Camfort/Specification/Units/Monad.o )
[17 of 30] Compiling Camfort.Specification.Units.InferenceFrontend ( src/Camfort/Specification/Units/InferenceFrontend.hs, dist/build/Camfort/Specification/Units/InferenceFrontend.o )
[18 of 30] Compiling Camfort.Specification.Units.Synthesis ( src/Camfort/Specification/Units/Synthesis.hs, dist/build/Camfort/Specification/Units/Synthesis.o )
[19 of 30] Compiling Camfort.Helpers.Syntax ( src/Camfort/Helpers/Syntax.hs, dist/build/Camfort/Helpers/Syntax.o )
[20 of 30] Compiling Camfort.Transformation.CommonBlockElim ( src/Camfort/Transformation/CommonBlockElim.hs, dist/build/Camfort/Transformation/CommonBlockElim.o )
[21 of 30] Compiling Camfort.Transformation.DeadCode ( src/Camfort/Transformation/DeadCode.hs, dist/build/Camfort/Transformation/DeadCode.o )
[22 of 30] Compiling Camfort.Reprint  ( src/Camfort/Reprint.hs, dist/build/Camfort/Reprint.o )
[23 of 30] Compiling Camfort.Output   ( src/Camfort/Output.hs, dist/build/Camfort/Output.o )
[24 of 30] Compiling Camfort.Transformation.EquivalenceElim ( src/Camfort/Transformation/EquivalenceElim.hs, dist/build/Camfort/Transformation/EquivalenceElim.o )
[25 of 30] Compiling Camfort.Input    ( src/Camfort/Input.hs, dist/build/Camfort/Input.o )
[26 of 30] Compiling Camfort.Specification.Stencils.InferenceFrontend ( src/Camfort/Specification/Stencils/InferenceFrontend.hs, dist/build/Camfort/Specification/Stencils/InferenceFrontend.o )
[27 of 30] Compiling Camfort.Specification.Stencils.CheckFrontend ( src/Camfort/Specification/Stencils/CheckFrontend.hs, dist/build/Camfort/Specification/Stencils/CheckFrontend.o )
[28 of 30] Compiling Camfort.Specification.Stencils ( src/Camfort/Specification/Stencils.hs, dist/build/Camfort/Specification/Stencils.o )
[29 of 30] Compiling Camfort.Specification.Units ( src/Camfort/Specification/Units.hs, dist/build/Camfort/Specification/Units.o )
[30 of 30] Compiling Camfort.Functionality ( src/Camfort/Functionality.hs, dist/build/Camfort/Functionality.o )
Preprocessing executable 'camfort' for camfort-0.900...
[ 1 of 31] Compiling Camfort.Helpers.Vec ( src/Camfort/Helpers/Vec.hs, dist/build/camfort/camfort-tmp/Camfort/Helpers/Vec.o )
[ 2 of 31] Compiling Camfort.Helpers  ( src/Camfort/Helpers.hs, dist/build/camfort/camfort-tmp/Camfort/Helpers.o )
[ 3 of 31] Compiling Camfort.Specification.Stencils.Syntax ( src/Camfort/Specification/Stencils/Syntax.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/Syntax.o )
[ 4 of 31] Compiling Camfort.Specification.Stencils.Model ( src/Camfort/Specification/Stencils/Model.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/Model.o )
[ 5 of 31] Compiling Camfort.Specification.Stencils.InferenceBackend ( src/Camfort/Specification/Stencils/InferenceBackend.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/InferenceBackend.o )
[ 6 of 31] Compiling Camfort.Analysis.Simple ( src/Camfort/Analysis/Simple.hs, dist/build/camfort/camfort-tmp/Camfort/Analysis/Simple.o )
[ 7 of 31] Compiling Camfort.Analysis.CommentAnnotator ( src/Camfort/Analysis/CommentAnnotator.hs, dist/build/camfort/camfort-tmp/Camfort/Analysis/CommentAnnotator.o )
[ 8 of 31] Compiling Camfort.Specification.Stencils.Grammar ( dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/Grammar.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/Grammar.o )
[ 9 of 31] Compiling Camfort.Specification.Units.Parser ( dist/build/camfort/camfort-tmp/Camfort/Specification/Units/Parser.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units/Parser.o )
[10 of 31] Compiling Camfort.Specification.Units.Environment ( src/Camfort/Specification/Units/Environment.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units/Environment.o )
[11 of 31] Compiling Camfort.Analysis.Annotations ( src/Camfort/Analysis/Annotations.hs, dist/build/camfort/camfort-tmp/Camfort/Analysis/Annotations.o )
[12 of 31] Compiling Camfort.Specification.Stencils.Annotation ( src/Camfort/Specification/Stencils/Annotation.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/Annotation.o )
[13 of 31] Compiling Camfort.Specification.Stencils.CheckBackend ( src/Camfort/Specification/Stencils/CheckBackend.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/CheckBackend.o )
[14 of 31] Compiling Camfort.Specification.Stencils.Synthesis ( src/Camfort/Specification/Stencils/Synthesis.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/Synthesis.o )
[15 of 31] Compiling Camfort.Specification.Units.InferenceBackend ( src/Camfort/Specification/Units/InferenceBackend.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units/InferenceBackend.o )
[16 of 31] Compiling Camfort.Specification.Units.Monad ( src/Camfort/Specification/Units/Monad.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units/Monad.o )
[17 of 31] Compiling Camfort.Specification.Units.InferenceFrontend ( src/Camfort/Specification/Units/InferenceFrontend.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units/InferenceFrontend.o )
[18 of 31] Compiling Camfort.Specification.Units.Synthesis ( src/Camfort/Specification/Units/Synthesis.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units/Synthesis.o )
[19 of 31] Compiling Camfort.Helpers.Syntax ( src/Camfort/Helpers/Syntax.hs, dist/build/camfort/camfort-tmp/Camfort/Helpers/Syntax.o )
[20 of 31] Compiling Camfort.Transformation.CommonBlockElim ( src/Camfort/Transformation/CommonBlockElim.hs, dist/build/camfort/camfort-tmp/Camfort/Transformation/CommonBlockElim.o )
[21 of 31] Compiling Camfort.Transformation.DeadCode ( src/Camfort/Transformation/DeadCode.hs, dist/build/camfort/camfort-tmp/Camfort/Transformation/DeadCode.o )
[22 of 31] Compiling Camfort.Reprint  ( src/Camfort/Reprint.hs, dist/build/camfort/camfort-tmp/Camfort/Reprint.o )
[23 of 31] Compiling Camfort.Output   ( src/Camfort/Output.hs, dist/build/camfort/camfort-tmp/Camfort/Output.o )
[24 of 31] Compiling Camfort.Transformation.EquivalenceElim ( src/Camfort/Transformation/EquivalenceElim.hs, dist/build/camfort/camfort-tmp/Camfort/Transformation/EquivalenceElim.o )
[25 of 31] Compiling Camfort.Input    ( src/Camfort/Input.hs, dist/build/camfort/camfort-tmp/Camfort/Input.o )
[26 of 31] Compiling Camfort.Specification.Stencils.InferenceFrontend ( src/Camfort/Specification/Stencils/InferenceFrontend.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/InferenceFrontend.o )
[27 of 31] Compiling Camfort.Specification.Stencils.CheckFrontend ( src/Camfort/Specification/Stencils/CheckFrontend.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils/CheckFrontend.o )
[28 of 31] Compiling Camfort.Specification.Stencils ( src/Camfort/Specification/Stencils.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Stencils.o )
[29 of 31] Compiling Camfort.Specification.Units ( src/Camfort/Specification/Units.hs, dist/build/camfort/camfort-tmp/Camfort/Specification/Units.o )
[30 of 31] Compiling Camfort.Functionality ( src/Camfort/Functionality.hs, dist/build/camfort/camfort-tmp/Camfort/Functionality.o )
[31 of 31] Compiling Main             ( src/Main.hs, dist/build/camfort/camfort-tmp/Main.o )
Linking dist/build/camfort/camfort ...
Preprocessing test suite 'spec' for camfort-0.900...
[ 1 of 10] Compiling Camfort.Transformation.EquivalenceElimSpec ( tests/Camfort/Transformation/EquivalenceElimSpec.hs, dist/build/spec/spec-tmp/Camfort/Transformation/EquivalenceElimSpec.o )
[ 2 of 10] Compiling Camfort.Transformation.CommonSpec ( tests/Camfort/Transformation/CommonSpec.hs, dist/build/spec/spec-tmp/Camfort/Transformation/CommonSpec.o )
[ 3 of 10] Compiling Camfort.Specification.UnitsSpec ( tests/Camfort/Specification/UnitsSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/UnitsSpec.o )
[ 4 of 10] Compiling Camfort.Specification.StencilsSpec ( tests/Camfort/Specification/StencilsSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/StencilsSpec.o )
[ 5 of 10] Compiling Camfort.Specification.Stencils.ModelSpec ( tests/Camfort/Specification/Stencils/ModelSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/Stencils/ModelSpec.o )
[ 6 of 10] Compiling Camfort.Specification.Stencils.GrammarSpec ( tests/Camfort/Specification/Stencils/GrammarSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/Stencils/GrammarSpec.o )
[ 7 of 10] Compiling Camfort.Specification.Stencils.CheckSpec ( tests/Camfort/Specification/Stencils/CheckSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/Stencils/CheckSpec.o )
[ 8 of 10] Compiling Camfort.Helpers.VecSpec ( tests/Camfort/Helpers/VecSpec.hs, dist/build/spec/spec-tmp/Camfort/Helpers/VecSpec.o )
[ 9 of 10] Compiling Camfort.Analysis.CommentAnnotatorSpec ( tests/Camfort/Analysis/CommentAnnotatorSpec.hs, dist/build/spec/spec-tmp/Camfort/Analysis/CommentAnnotatorSpec.o )
[10 of 10] Compiling Main             ( tests/Spec.hs, dist/build/spec/spec-tmp/Main.o )
Linking dist/build/spec/spec ...
> /tmp/stackage-build8/camfort-0.900$ dist/build/spec/spec

spec: tests/Camfort/Transformation/samples/common.expected.f90: openFile: does not exist (No such file or directory)

`units-infer` doesn't stop at inconsistency

(branch: units-new)
For example:

program main
  != unit(A) :: x
  real :: x
  != unit(B) :: y
  real :: y
  x = inc(x)
  y = inc(y)
end program main

real function inc(x) 
    real x  
    inc = x + 1
end function

units-check rightfully calls this inconsistent but units-infer makes both x and y have units b.

Work towards a regression test suite

The following would be a good start for decent software testing in CamFort:

  • Integrate HSpec into the project
  • Lift existing Quickcheck and HUnit tests to HSpec
  • Use corpus and fixman to test over fixtures

units-suggest does not work inside subroutines.

I've just noticed this one, pretty much as it says on the tin. Compare

program square
  implicit none

  real :: x
  real :: a
  
  x = a**2

  end program

units-suggest responds with x. On the other hand:

program square
  implicit none
  call main()
  
contains

  subroutine main()
  real :: x
  real :: a
  x = a**2
  end subroutine

end program

units-suggest says there are 0 variables to annotate.

Equivalence elimination does not deal well with equivalence array elements

program array
  implicit none

  integer :: i
  integer, dimension(5) :: x
  integer, dimension(5) :: y
  equivalence (x(1), y(1))

  do i = 1, 5
     x(i) = i
  end do

  end program

Equivalence elimination does not currently introduce a copy inside the loop. Just the equivalence statement is removed and nothing is added. Instead the result of elimination should be:

program array
  implicit none

  integer :: i
  integer, dimension(5) :: x
  integer, dimension(5) :: y

  do i = 1, 5
     x(i) = i
     if (i .eq. 1) then
      y(1) = x(1)
    end if
  end do

  end program

Select statements not supported

Any select statements would result in a parser error. E.g.:

program test

integer :: i = 42

select case(i)
    case (42)
    print *, "foo"
end select

end program test

I get camfort: select.f90: line 5 column 0: syntax error (from parser). It's actually the number one reason I cannot use camfort for much of my code, because it always stops at these.

I've just noticed the select keyword is commented out in the parser (and so is case), is there a reason for it? I've just double checked and it is still a part of the standard.

Thanks!

Unit specifications on multiple parameter variables breaks

      program param
        implicit none
        != unit(m) :: x, y
        real, parameter :: x = 4, y = 5
        != unit(s) :: t
        real, parameter :: t = 2
        real :: v1, v2
        v1 = x / t
        v2 = y / t
      end program

The synthesised unit specs for this code are weird, and wrong:

        != unit (s) :: x
        != unit (s) :: y
        != unit (s) :: t
        != unit(m) :: x, y
        real, parameter :: x = 4, y = 5
        real, parameter :: t = 2
        != unit (1) :: v1
        != unit (1) :: v2
        real :: v1, v2

If you split the declarations for x and y onto multiple line:

        != unit(m) :: x
        real, parameter :: x = 4
        != unit(m) :: y
        real, parameter y = 5

Then the inference is fine:

        != unit (m) :: x
        real, parameter :: x = 4
        != unit (m) :: y
        != unit (s) :: t
        real, parameter :: y = 5
        real, parameter :: t = 2
        != unit (m / s) :: v1
        != unit (m / s) :: v2
        real :: v1, v2

Double relativisation

Here is something we didn't think of:

program double_relativise
  integer, dimension(10,10) :: a
  integer, dimension(10) :: b
  integer :: i

  do i = 1, 10
    a(i,i+1) = b(i)
  end do
end program double_relativise

We infer a stencil readOnce, (backward(depth=1, dim=1, irreflexive)) :: b for this, but I don't think there is a correct relativisation of this unless we give precedence rules for relativisation. Currently, there is no precedence either meaning a(i,i+1) and a(i+1,i) produce the same stencil annotation.

Can we do better with flows analysis?

For the snippet below, we currently do not infer any specifications, but flows to analysis seems strong enough that we could. Am I missing something or is this just an omission on our part?

program indirect_induction_var
  integer, dimension(10) :: a
  integer :: i, x

  do i = 1, 10
    x = i
    a(i) = b(x)
  end do
end program indirect_induction_var

test suite failure

Probably a data-file/extra-source-file is missing from the cabal file

Preprocessing test suite 'spec' for camfort-0.804...
[ 1 of 10] Compiling Camfort.Transformation.EquivalenceElimSpec ( tests/Camfort/Transformation/EquivalenceElimSpec.hs, dist/build/spec/spec-tmp/Camfort/Transformation/EquivalenceElimSpec.o )
[ 2 of 10] Compiling Camfort.Transformation.CommonSpec ( tests/Camfort/Transformation/CommonSpec.hs, dist/build/spec/spec-tmp/Camfort/Transformation/CommonSpec.o )
[ 3 of 10] Compiling Camfort.Specification.UnitsSpec ( tests/Camfort/Specification/UnitsSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/UnitsSpec.o )
[ 4 of 10] Compiling Camfort.Specification.StencilsSpec ( tests/Camfort/Specification/StencilsSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/StencilsSpec.o )
[ 5 of 10] Compiling Camfort.Specification.Stencils.ModelSpec ( tests/Camfort/Specification/Stencils/ModelSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/Stencils/ModelSpec.o )
[ 6 of 10] Compiling Camfort.Specification.Stencils.GrammarSpec ( tests/Camfort/Specification/Stencils/GrammarSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/Stencils/GrammarSpec.o )
[ 7 of 10] Compiling Camfort.Specification.Stencils.CheckSpec ( tests/Camfort/Specification/Stencils/CheckSpec.hs, dist/build/spec/spec-tmp/Camfort/Specification/Stencils/CheckSpec.o )
[ 8 of 10] Compiling Camfort.Helpers.VecSpec ( tests/Camfort/Helpers/VecSpec.hs, dist/build/spec/spec-tmp/Camfort/Helpers/VecSpec.o )
[ 9 of 10] Compiling Camfort.Analysis.CommentAnnotatorSpec ( tests/Camfort/Analysis/CommentAnnotatorSpec.hs, dist/build/spec/spec-tmp/Camfort/Analysis/CommentAnnotatorSpec.o )
[10 of 10] Compiling Main             ( tests/Spec.hs, dist/build/spec/spec-tmp/Main.o )
Linking dist/build/spec/spec ...
> /tmp/stackage-build8/camfort-0.804$ dist/build/spec/spec
spec: tests/Camfort/Specification/Stencils/example2.f: openBinaryFile: does not exist (No such file or directory)
ubuntu@build0:/opt/stackage-build/stackage/automated$

Releases & Homebrew/Linuxbrew

Once you start publishing releases, and if the project grows enough to pass the "popularity contest metric" (Homebrew calls it notability) I'd be happy to work on submitting a Homebrew formula.

(In the mean time encourage people to star, watch and fork comfort and language-fortran...)

Weaker stencil annotations should be accepted

program stencil_example
  integer, dimension(10) :: a, b
  integer :: i

  do i = 2, 9
    != stencil centered(depth=1, dim=1, irreflexive) :: b
    a(i) = b(i-1) * 2 * b(i+1)**3
  end do
end program stencil_example

Needless to say this should be fine but currently it complains due to absence of readOnce.

New checking mechanism when implemented will solve this.

Stencils with multiple ranges should sometimes get access-pattern specs

e.g. p(:,0) = sum(q(:,1,:))
Investigate further what the correct behaviour is here. This currently gets the specification
stencil readOnce, (reflexive(dim=1))*(reflexive(dim=3)) :: q
But I believe this is an example which is not a true stencil. Instead this should merely be an access pattern:
access readOnce, (reflexive(dim=1))*(reflexive(dim=3)) :: q

Unit aliases need a global check

Named aliases can be given for units, but there is no global check to make sure that there are no repeated name declarations that are defined inconsistently. This needs fixing!

INCLUDE statements not parsed

      program foo
      implicit none
      include 'bar.cmn'
      end  

This is part of Fortran 90 (see p.43 of the standard, ftp://ftp.nag.co.uk/sc22wg5/N001-N1100/N692.pdf)
However, it seems fairly common to use this in Fortran 77 too.... although it is not standard. Perhaps we can allow it in Fortran 77 extended mode?

Inference failure

program failing
  integer, dimension(10,10) :: a
  integer :: i, j

  do i = 1, 10
    do j = 1, 10
      a(i,j) = a(i  ,j) + a(i  ,j+1) + a(i  ,j+2) &
             + a(i+1,j) + a(i+1,j+1) + a(i+1,j+2) + a(i+1,1)
    end do
  end do
end program failing

Snipper above fails on inference with src/Camfort/Analysis/StencilSpecification/Syntax.hs:(232,1)-(243,25): Non-exhaustive patterns in function equalModuloFwdBwd.

Note the error occurs with the addition of final term a(i+1,1) and it doesn't occur if the term has already been observed such as a(i+1,j). It also doesn't occur with a(i,1).

The same error is not limited to terms with absolute indices a(i+1,j+3) also fails. rather than creating a bounded spec.

Inferring empty atLeast approximation

program approximate
  integer, dimension(10) :: a
  integer :: i

  do i = 1, 6
    a(i) = a(i+4)
  end do
end program approximate

stencils-infer gives us this:

Infering stencil specs for 'approximate.f90'

approximate.f90
(6:5)-(6:17)    stencil atLeast, readOnce,  :: a
(6:5)-(6:17)    stencil atMost, readOnce, (forward(depth=4, dim=1)) :: a

Stop exporting camfort as a library

Analyses are too specialised and there is no standard API, so exposing parts of the project outside is misleading.

Core analyses, eg. live variable analysis, will later be moved to a common Fortran language front-end.

Units analysis sensitive to arrays; possible bug

Compare the following two files and the results coming from units-suggest, crit.f90

program critical
  implicit none
  real :: a, b, c, d, e
  e = a + b*c*d
end program

and crit2.f90

program critical2
  implicit none
  integer i = 1
  real, dimension(1) :: a, b, c, d, e
  e(i) = a(i) + b(i)*c(i)*d(i)
end program

units-suggest gives:

$ crit.f90 
Suggesting variables to annotate with unit specifications in 'crit.f90'
crit.f90: 3 variable declarations suggested to be given a specification:
    (3:17)  c
    (3:20)  d
    (3:23)  e

$ crit2.f90 
Suggesting variables to annotate with unit specifications in 'crit2.f90'
crit2.f90: 6 variable declarations suggested to be given a specification:
    (3:11)  i
    (4:25)  a
    (4:28)  b
    (4:31)  c
    (4:34)  d
    (4:37)  e

I believe the second set of critical variables should only differ by i. Or at least, should be some set of size 4, not the above. I suppose this is something to do with how array declarations are handled?

Stop exporting analyse binary

We have shipped analyse CLI tool that we used in stencil spec. evaluation in our releases so when someone installs it with cabal, they get a analyse command line tool.

I don't think this is useful and should go on a different repository. Otherwise, we should at least change it's name to camfort-eval or something.

Compiler error in Traverse.lhs

Sorry I couldn't figure out the following error prompted by ghc

[ 7 of 19] Compiling Traverse ( Traverse.lhs, Traverse.o )

Traverse.lhs:50:58: Not in scope: `strMap'

Traverse.lhs:77:58: Not in scope: `strMap'

Found in TODO from 2015

program square
  implicit none

  real :: a, b
  real, unit(m) :: x
  real, unit(s) :: t

  x = 20.0
  t = 3.0 
  a = sqr(x) 
  b = sqr(t)

  print *, a
  print *, b  

  contains 

  real function sqr(y)
    real y
    real z
    sqr = y * y * z
  end function
end program

What happens to z. Currently it does not get copied! Instead, a temporary column should be generated for it.

Parse errors from 'units'

At the moment, all parse errors in the "units" parser turn into "NotAnnotation". But after parsing a comment with units at the start (after the usually ! + control character setup) we should return ProbablyAnnotation to get better errors (see Stencils/Grammar.y).

getExcludes needs fixing

Right now getExcludes simply extracts all strings from the command line, which doesn't really make sense.

(TODO)

Dataflow analysis for stencil specs sometimes causes exception

For the forpar-dev branch, the command:

camfort stencils-infer samples/stencils/two.f out

fails with:

camfort: src/Camfort/Analysis/StencilSpecification.hs:80:28-53: Irrefutable pattern failed for pattern Just ms

Because of the line:
b(i,j) = a(i,j)

Units spec synthesis erroneous for default values (when unconstrained )

Given program

program unito
  implicit none
  integer :: i = 1
  integer :: j = i + i
  j = j
end program

Running camfort unit on it prodeucs

 != unit (1) :: i
program unito
  implicit none
  integer :: i = 1
 != unit (1) :: j
 != unit (1) :: i
 != unit (1) :: i
  integer :: j = i + i
  j = j
end program

Note the repeated specification of i.

Incorrect normalisation of units

program normal_form
  != unit u1 / (u2 / u3) :: x
  integer x

  != unit u1 / (u2 * u3) :: y
  integer y = 10

  x = y
end program normal_form

This is interpreted as consistent under units-check on new-units branch (CC @mrd). But it throws an error on master.

I think both behaviours are wrong.

Stencil should not be inferred when LHS indicies are all absolute

program absolute_stencil
  integer, dimension(10,20) :: a
  integer :: k

  do k = 1, 10
    a(1,1) = a(k,1)
  end do
end program absolute_stencil

A stencil of stencil readOnce, reflexive(dims=1) is inferred for a. In the case where all LHS indicies are constant, stencil should not be inferred.

README outdated?

It appears that comfort and the language-fortran parser have been moved into the camfort org from @dorchard's personal account, is this true? If so the README needs updating... I could submit a quick PR if that's the case.

Support doxygen notation for specifications

Doxygen picks up comments of the form !< so it won't pick up any specifications in CamFort which start !=. We could easily allow !< or !<= to be used in CamFort (could be a command line option for synthesis commands to tell CamFort which prefix to generate) so that units/stencils/etc. can get into doxygen?

units-suggest gives duplicate information for variables used to give array sizes

program bug36
  implicit none
  integer :: imax
  real    :: a(0:imax)
end program bug36

gives

$ camfort units-suggest bug36.f90 

Suggesting variables to annotate with unit specifications in 'bug36.f90'

bug36.f90: 3 variable declarations suggested to be given a specification:
    (3:14)  imax
    (4:14)  a
    (4:18)  imax

The second imax is spurious.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.