The Pure-Fortran project now has a program xarray.py that transforms code with loops to use array operations when possible. For example,
program xloop
implicit none
integer :: i, nseed
integer, allocatable :: seed(:)
integer, parameter :: n = 5
real :: x(n), sum_positive, xmin, xmax, xmean
xmean = 0.5
! set seed
call random_seed(size=nseed)
allocate(seed(nseed))
do i=1,nseed
seed(i) = i * 10**6
end do
call random_seed(put=seed)
deallocate(seed)
! set x to de-meaned random uniform
do i=1,n
call random_number(x(i))
x(i) = x(i) - xmean
end do
! compute minval, maxval
do i=1,n
if (i >= 2) then
xmin = min(x(i), xmin)
xmax = max(x(i), xmax)
else
xmin = x(i)
xmax = x(i)
end if
end do
! print x
do i=1,n
print "(i2,f7.3)", i, x(i)
end do
! compute sum of positive values
sum_positive = 0.0
do i=1,n
if (x(i) > 0) sum_positive = sum_positive + x(i)
end do
print*,sum_positive
print*,xmin,xmax
end program xloop
is transformed (including the positioning of comments) to
program xloop
implicit none
integer :: i, nseed
integer, parameter :: n = 5
real :: x(n)
! set seed
call random_seed(size=nseed)
call random_seed(put=[(i * 10**6, i=1,nseed)])
! set x to de-meaned random uniform
call random_number(x)
x = x - 0.5
! print x
print "(i2,f7.3)", (i, x(i), i=1,n)
! compute sum of positive values
print*,sum(x, mask = x > 0)
! compute minval, maxval
print*,minval(x),maxval(x)
end program xloop
by the command python xarray.py xloop.f90 --out temp.f90 --run-diff --inline which gave output
5 array-operation replacement candidate(s).
xloop.f90:11-13 constructor_fill_loop program xloop
xloop.f90:17-20 random_number_fill_elementwise program xloop
xloop.f90:22-30 reduction_minmax_value_pair program xloop
xloop.f90:32-34 io_loop_implied_do program xloop
xloop.f90:36-39 reduction_masked_sum program xloop
Fixed xloop.f90: replaced 5 block(s), wrote temp.f90
removed redundant allocate-before-assignment: 1
--fix summary: files changed 1, replaced 5, allocates removed 1
Build (original): gfortran xloop.f90 -o xloop_orig.exe
Build (original): PASS
Run (original): xloop_orig.exe
Run (original): PASS
1 0.382
2 0.034
3 0.011
4 0.080
5 -0.343
0.507028103
-0.343274832 0.381796479
Build (transformed): gfortran temp.f90 -o temp.exe
Build (transformed): PASS
Run (transformed): temp.exe
Run (transformed): PASS
1 0.382
2 0.034
3 0.011
4 0.080
5 -0.343
0.507028103
-0.343274832 0.381796479
Run diff: MATCH
The --inline option tells it to write code that when possible uses expressions directly instead of saving them in variables. I created it by giving Codex examples of loop-based code I would like it to transform. After it could do that I tested xarray.py with code from John Burkardt, Lapack, and other sources to find bugs. There is a --concurrent option to use do concurrent when possible. It will improve as it is tested against more code, so please try it and report issues.