[patch, fortran, RFC] Inline matmul(transpose(a),b)

Thomas Koenig tkoenig@netcologne.de
Mon May 15 22:14:00 GMT 2017


Hello world,

the attached patch, just an RFC so far, implements inlining
for matmul(transpose(a),b).

This implements

      c = 0
      do i=1, size(a,2)
         do j=1, size(b,2)
            do k=1, size(a,1)
               c(i,j) = c(i,j) + a(k,i) * b(k,j)
            end do
         end do
      end do

which is at least capable of being vectorized with recent trunk
and which shows an improvement over the library version:

$ cat bench0.f90
program main
   implicit none
   integer, parameter :: n = 30, m=40, cnt=20
   real(kind=8), dimension(cnt,n) :: a
   real(kind=8), dimension(cnt,m) :: b
   real(kind=8), dimension(n,m) :: c
   integer :: i, j, k
   real(kind=8) :: s
   integer :: rep = 100000
   integer :: irep
   integer, parameter :: nmin = min(n, m, cnt)

   call random_number(a)
   call random_number(b)

   s = 0.
   do irep=1,rep

      do i=1,nmin
        a(i,i) = (a(i,i) + 1.)*0.5  ! Just to confuse the optimizer
      end do

      c = matmul(transpose(a),b)
      s = s + sum(c)
   end do
   print *,s
end program main
$ gfortran -Ofast -finline-matmul-limit=0 bench0.f90 && time ./a.out
    622153335.54627311

real    0m2,896s
user    0m2,888s
sys     0m0,008s
$ gfortran -Ofast  bench0.f90 && time ./a.out
    642240828.34605432

real    0m1,378s
user    0m1,376s
sys     0m0,000s

So, is this the right way to go, or should I try some other version of
ordering the DO loops?  I seem to remember that we talked about
using some kind of vector temporary, but I am not sure how this was
done, or if it would bring large improvements for really small matrix
sizes.

Regards

	Thomas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p1.diff
Type: text/x-patch
Size: 5247 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/fortran/attachments/20170515/6e6ea2c3/attachment.bin>


More information about the Fortran mailing list