new proposal to vector intrinsics

Sa Liu SALIU@de.ibm.com
Mon Jan 14 20:03:00 GMT 2008


Hi,

After some discussion in comp.lang.fortran mailling list 
(http://groups.google.com/group/comp.lang.fortran/browse_thread/thread/6f2b792d34b8e8a8#2f223706bb710fd1), 
we found out that most objections to the vector intrinsic proposal 
(http://gcc.gnu.org/ml/fortran/2007-11/msg00266.html), are about 
introducing the new vector data types and syntax into Fortran language. 
Many suggested us to use rank-1 array representing the vector data 
structure. Thus, we'd like to adopt this idea and define the vector types 
using parameterized derived types.

The type definition will look like this:

type vec_integer (k)
  integer, kind :: k = 4
  integer(k) :: vec (16 / k)
end type

type vec_unsigned (k)
  integer, kind :: k = 4
  integer(k) :: vec (16 / k)
end type

type vec_real (k)
  integer, kind :: k = 4
  real(k) :: vec (16 / k)
end type 

where k stands for kind of scalar data, with default value of 4, and 16 is 
the vector size for this certain target.

Then we could allow the intrinsics to use the derived data types by define 
a list of module procedures, e.g.:

     FUNCTION VEC_ADD_INT(a,b) RESULT(c)
       TYPE(VEC_INTEGER),INTENT(IN) :: a,b
       TYPE(VEC_INTEGER)            :: c
       c%vec = builtin_vec_add_int(a%vec, b%vec)
     END FUNCTION VEC_ADD_INT

     FUNCTION VEC_ADD_FLOAT(a,b) RESULT(c)
       TYPE(VEC_REAL),INTENT(IN) :: a,b
       TYPE(VEC_REAL)            :: c
       c%vec = builtin_vec_add_float(a%vec, b%vec)
     END FUNCTION VEC_ADD_FLOAT

A generic interface groups the overloaded functions:

   interface vec_add
     module procedure vec_add_int, vec_add_float
   end interface

Then we could define a intrinsic module to bind the builtin_* functions 
with their corresponding C functions:

module vec_intrinsics
  implicit none

  interface
    function builtin_vec_add_int(a, b) result(c) bind(c, 
name="__builtin_altivec_vadduwm")
          use, intrinsic :: iso_c_binding
          integer (c_int), intent(in):: a(4), b(4)
          integer(c_int) :: c(4)
    end function builtin_vec_add_int

    function builtin_vec_add_float(a, b) result(c) bind(c, 
name="__builtin_altivec_vaddfp")
          use, intrinsic :: iso_c_binding
          real (c_float), intent(in):: a(4), b(4)
          real(c_float) :: c(4)
    end function builtin_vec_add_float
   end interface
end module vec_intrinsics

In application program, we could then declare vector variables and 
initialize them:

TYPE ( VEC_INTEGER) :: a,b,c
TYPE ( VEC_REAL) :: x,y,z

! initialize
integer(4) :: va_i(4) = (/ 1, 2, 3, 4 /)
integer(4) :: vb_i(4) = (/ 5, 6, 7, 8 /)
equivalence (va_i, a)
equivalence (vb_i, b)

real(4) :: vx_r(4) = (/ 1., 2., 3., 4. /)
real(4) :: vy_r(4) = (/ 5., 6., 7., 8. /)
equivalence (vx_r, x)
equivalence (vy_r, y)

! vec_add_int, bound to __builtin_altivec_vadduwm
c=vec_add(a,b)

! vec_add_float, bound to __builtin_altivec_vaddfp
z=vec_add(x,y)

The rest of the problem is just to make the symbols 
__builtin_altivec_vadduwm and __builtin_altivec_vaddfp recognizable in 
Fortran frontend. These symbols are already known in 
add_builtin_function() in FE, when backend builtins are get initialized. 
We just need to keep them in a namespace, say backend_builtins_ns, in 
order to get them back later when we resolve the builtins. 

With help of preprocessor, this could even be compatible with XLF syntax:

  #define vector(x)  type (vec_ ## x)

which would transform

  vector (integer)  into   type (vec_integer)
  vector (integer (4))  into   type (vec_integer (4))
  vector (real (8))  into  type (vec_real (8)) 

But as far as I know, Gfortran doesn't support parameterized derived 
types. If the above proposal is in the right direction to a possible 
solution, we would like to take over the implementation of parameterized 
derived type.

Thanks!
Sa



More information about the Fortran mailing list