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