Re: Efficient way to pass different shaped arrays?
- From: glen herrmannsfeldt <gah@xxxxxxxxxxxxxxxx>
- Date: Wed, 28 Jun 2006 16:13:46 -0700
Peter wrote:
I'm attempting to use an array argument of a subroutine for two
different purposes. One, which works fine, has the caller declare an
identical explicit shape array. The other, shown below, has the caller
(A) passing a small number of reals in the same memory space.
Subroutine B knows, via other arguments not shown, which kind of array
argument is being received.
In subroutine A:
REAL, DIMENSION(3) :: array
CALL B(array)
SUBROUTINE B(array)
REAL, DIMENSION(28,0:10001), INTENT(INOUT) :: array
Under CVF6, this worked as expected, but using IVF9, the compiler flags
an error because the extent of 'array' as a dummy argument for B
exceeds the size of the real argument 'array' in A; presumably this is
an error because B could write memory beyond the size of 'array'
declared by the caller.
I am pretty sure passing a one dimensional array to a two dimensional
dummy is allowed, definitely the other way around is allowed.
The standard since F66 would be that the dimensions of the dummy
array (in the called routine) should be variables, either passed as arguments or in COMMON. I believe newer standards allow a subset of
expressions in subscripts.
So, my question is, what is a simple and efficient way to pass in the
3-element array? I don't really want to create a huge 28x10002 array in
the caller, and for efficiency it would be better not to add another
argument (subroutine B gets called many times).
You say that other arguments not shown make the distinction.
Standard back to F66, is if those arguments are the actual array
dimensions, where one should be 1 in the one dimensional case.
I believe since F77 the last subscript of the dummy array can be *,
indicating that the actual value isn't given, but the program is
still required to stay within bounds. In your case, (28,0:*)
should allow an array dimensioned (28), not excessively large.
It might be possible to compute the actual array bounds.
Since Fortran doesn't have a conditional operator, it might be that
you could use a trick I saw once in a discussion about how NOT to
write Fortran code. Consider:
DO 1 I=1,100
DO 1 J=1,100
1 A(I,J)=(I/J)*(J/I)
It seems that someone actually used this to initialize an identity
matrix, with much more multiplication and division than needed.
If multiply and divide are allowed in dummy array dimensions, and I
don't actually know that they are, you might be able to use a similar
trick to compute the appropriate dimensions. The rules for specification expression are complicated enough that I won't go into
more detail. If (28,0:*) doesn't work then I or someone else can figure
out what can actually be done.
-- glen
.
- Follow-Ups:
- Re: Efficient way to pass different shaped arrays?
- From: John Harper
- Re: Efficient way to pass different shaped arrays?
- From: Michael Metcalf
- Re: Efficient way to pass different shaped arrays?
- References:
- Efficient way to pass different shaped arrays?
- From: Peter
- Efficient way to pass different shaped arrays?
- Prev by Date: Re: Efficient way to pass different shaped arrays?
- Next by Date: Re: Efficient way to pass different shaped arrays?
- Previous by thread: Re: Efficient way to pass different shaped arrays?
- Next by thread: Re: Efficient way to pass different shaped arrays?
- Index(es):
Relevant Pages
|