Hello,
I have a few observations/questions about Fortran 95 and in particular
HPF 2.0 concerning array statements with allocatable arrays. Sorry for
the long text, but I think it will be interesting to those using array
features of Fortran.
The array statement I am considering is in a subroutine MULT and has a
very simplified form of:
theta=phi(alpha,:,:)*(phi(beta,:,:)-cshift(phi(beta,:,:),1,1))
where theta and phi are allocatable arrays of (obviously) identical
sizes in the last two dimensions defined in a module that this
subroutine is a part of:
real, dimension(:,:,:), allocatable :: phi
real, dimension(:,:), allocatable :: theta
!hpf$ distribute (block,*,*) :: phi
!hpf$ align (i,j) with phi(i,j,*) :: theta
!hpf$ shadow(0:1,0) :: phi
My HPF compiler (Adaptor 7.0) had problems optimizing the array
assignment (in terms of communication and such) because it complained
about not knowing anything about the global sizes of the allocatables,
i.e. it did not know that somewhere in another subroutine there was a
call:
allocate(phi(N,M,5))
allocate(theta(N,M))
The problem is fixed and very efficient loops are generated if the
arrays are not allocatables:
integer :: N,M
real, dimension(N,M,5) :: phi
real, dimension(N,M) :: theta
(NOTE: N and M should be parameters for the program to run correctly,
say N=M=100).
But this doesn't do me much good since I need allocatable arrays. I am
not sure if this is just Adaptor or general HPF/Fortran 95 behaviour.
I could not figure a way to fix the above problem and help the compiler
figure out that the arrays were globally conformable and it could just
translate the array statement into nested DO's with only shadow
communication and no temporaries. I tried passing the arrays as
arguments (with different dummy names, of course) to the subroutine MULT
and declaring them as:
real, dimension(N,M,5) :: phi_
real, dimension(N,M) :: theta_
but some redundant communication and temporaries were still generated.
I think that according to the HPF 2.0 standard saying:
!hpf$ align (:,:) with psi(:,:) :: theta,phi
instead of:
!hpf$ align (i,j) with psi(i,j) :: theta,phi
should guarantee the compiler that the allocatable arrays have equal
sizes (unfortunately, Adaptor does not allow alignment with : for
allocatables). Am I correct? I am not aware of any such possibility
within Fortran 95, and it seems a useful feature (sort of like
deferred-size arrays, where N and M are not parameters, but just
integers that are assigned values before the routine MULT is called. Is
this an idea that has been looked at? Can pointers maybe help?). Doesn't
the fact that these arrays are used as conformable arrays in an array
statement guarantee this to the compiler?
So I tried another solution. Since all arrays have the same sizes, I put
them in one big array vecs and used my preprocessor to do the
identification (or better use macros):
$macro phi(alpha,range1,range2) vecs(1+alpha,range1,range2)
$define theta vecs(1,:,:)
where vecs is declared as:
real, dimension(:,:,:), allocatable :: vecs
!hpf$ distribute (block,*,*) :: vecs
!hpf$ shadow(1:0,0,0) :: vecs
Althought this is not as stylistically clean, it is a nice solution in
the context of my larger project, since one can use integers
(theta,phi,psi) to identify arrays and only declare a single array vecs,
a convenient feature [NOTE: in the rest of the code, there are other
assignments like this, so that shadows are really needed on both phi and
theta and should be (1:1,0,0)]
Then another problem popped out! Namely, after preprocessing and all,
the final array statement is something like:
vecs(1,:,:)=vecs(1+alpha,:,:)*(vecs(1+beta,:,:)-cshift(vecs(1+beta,:,:),1,1))
and now the same array vecs appears on both sides of the array
statement, so that the compiler generates temporaries and does the
assignment in two steps.
And then it dawned on me that Fortran 95 or HPF do not have a standard
way of letting the compiler know that alpha,beta>0 so that no
temporaries are needed.
Adaptor 7 allows me to add an INDEPENDENT directive to the array
statement:
!hpf$ independent
vecs(1,:,:)=vecs(1+alpha,:,:)*(vecs(1+beta,:,:)-cshift(vecs(1+beta,:,:),1,1))
which fixes the problem and efficient loops are generated.
Why doesn't the HPF 2 standard allow using INDEPENDENTs on array
assignments as well? It seems like a very useful feature, now that I
needed to use it. How about Fortran 95/2000 features in this direction?
I guess some will say that I should simply translate the array
assignment into DO loops my self and stick away from array syntax. This
works, but in that case boundaries have to be handled separately, since
the shadow edges in HPF are not part of the global array, so my DO loops
in global HPF mode can only legally go from 2:N-1 and 2:M-1, not 1:N and
1:M as Adaptor internally translates the above array assignment. Also,
array assignments are nice and easy to work with.
Any comments/ideas would be appreciated,
Aleksandar
--
_____________________________________________
Aleksandar Donev
Physics Department
Michigan State University
East Lansing, MI 48824-1116
E-mail: [log in to unmask]
Work phone: (517) 432-6770
_____________________________________________
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|