This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: libmvec in gcc to have vector math in fortran
- From: Richard Biener <richard dot guenther at gmail dot com>
- To: Jakub Jelinek <jakub at redhat dot com>
- Cc: szabolcs dot nagy at arm dot com, Janne Blomqvist <blomqvist dot janne at gmail dot com>, nd at arm dot com, GCC Development <gcc at gcc dot gnu dot org>, "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>, sellcey at cavium dot com
- Date: Thu, 14 Jun 2018 12:28:55 +0200
- Subject: Re: libmvec in gcc to have vector math in fortran
- References: <6a8d496b-d830-5eb2-eba3-c2e452d06493@arm.com> <CAO9iq9FvH9Mbmec+tDO5_31vaKiu3p=WGhAXuFFUq8EJEeiQ-g@mail.gmail.com> <80c395e1-9de5-1d9c-35b6-1ccfdfa6a9e5@arm.com> <20180410102954.GB8577@tucnak> <CAFiYyc36_0n2Wn4huhAQO3C+J_ohJhUZqcE2+6m+tkU3m6LvoQ@mail.gmail.com> <20180410130655.GD8577@tucnak>
On Tue, Apr 10, 2018 at 3:07 PM Jakub Jelinek <jakub@redhat.com> wrote:
>
> On Tue, Apr 10, 2018 at 02:55:43PM +0200, Richard Biener wrote:
> > > And the easiest solution is in the Fortran FE based on some flag
> > > (e.g. -mveclibabi=glibc) through a target hook add
> > > __attribute__((__simd__ ("notinbranch")))
> > > to the builtins like __builtin_sin etc. that have them in the
> > > glibc header (x86_64 -m64 and -ffast-math only):
> > >
> > > # undef __DECL_SIMD_cos
> > > # define __DECL_SIMD_cos __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_cosf
> > > # define __DECL_SIMD_cosf __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_sin
> > > # define __DECL_SIMD_sin __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_sinf
> > > # define __DECL_SIMD_sinf __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_sincos
> > > # define __DECL_SIMD_sincos __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_sincosf
> > > # define __DECL_SIMD_sincosf __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_log
> > > # define __DECL_SIMD_log __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_logf
> > > # define __DECL_SIMD_logf __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_exp
> > > # define __DECL_SIMD_exp __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_expf
> > > # define __DECL_SIMD_expf __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_pow
> > > # define __DECL_SIMD_pow __DECL_SIMD_x86_64
> > > # undef __DECL_SIMD_powf
> > > # define __DECL_SIMD_powf __DECL_SIMD_x86_64
> > >
> > > The sincos/sincosf stuff is questionable, because some glibc versions
> > > implement it incorrectly and the simd ("notinbranch") attribute isn't that
> > > useful for it anyway, we'd want to use extra clauses so that it doesn't need
> > > to do scatter stores.
> >
> > I wonder if it is possible for glibc to ship a "module" for fortran instead
> > containing the appropriate declarations and gfortran auto-include that
> > (if present).
>
> Then we'd run into module binary format changing every release, so hard for
> glibc to ship that.
>
> Another thing is how would we express it in the module,
> we could just use OpenMP syntax,
> interface
> function sin(x) bind(C,name="__builtin_sin") result(res)
> import
> !$omp declare simd notinbranch
> real(c_double) :: res
> real(c_double),value :: x
> end function
> end interface
> but we'd need to temporarily enable OpenMP while parsing that module.
As-is the above doesn't work - it doesn't seem to redeclare sin() in a way
that it is 'const', thus dependence analysis rejects calls to it.
I'm playing with the following
subroutine bar (a)
use, intrinsic :: iso_c_binding, only: c_double
interface
pure function sin(x) bind(C,name="sin") result(res)
!$omp declare simd notinbranch
import
real(c_double) :: res
real(c_double),value :: x
end function sin
end interface
real(8) a(100,100)
do I=1,100
do J = 1,100
a(j,i) = sin(a(j,i))
end do
end do
end subroutine bar
'pure' makes it pure but there doesn't seem to be a way to make it const?
Any hint on how to improve the interface above? With
-fopemp -fopenmp-simd -Ofast the loop should be vectorized
(if I got index order correct).
That is, fortran doesn't seem to do anything like "merging" the above
declaration with the existing builtin so the binding above needs to be
complete.
I'm still thinking of exposing libmvec using a include/module that gets
implicitely picked up by gfortran if present.
Richard.
> I see Fortran now supports already
> !GCC$ attributes stdcall, fastcall::test
> Could we support
> !GCC$ attributes simd
> and
> !GCC$ attributes simd('notinbranch')
> too?
>
> Jakub