Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Array shape mismatch : workaround?

remkoduursma1
Beginner
1,276 Views
Dear forum,
I apologize if this is a novice question (and it most likely is).
I have a legacy subroutine that looks roughly like this:
subroutine legacy(X)
real x(1:N1, 1:N2, 1:N3)
...
end
A second subroutine calls 'legacy', but I have an array with a different dimension, but I want to use only the first of the Z index. The subroutine looks like this:
subroutine newsub(Y)
real Y(1:N1, 1:N2, 1:N3, 1:Z)
...
! So I figured I could call legacy like this, so that the array actually has the same shape
call legacy(Y(1:N1, 1:N2, 1:N3, 1))
This seems to work OK, but I am afraid of memory leaks. Also, when I set the compiler to the most stringent, I get this error:
error #12028: shape of actual argument 1 in call of "LEGACY" doesn't match the shape of formal argument "X"
Is there a way to fix this problem without having to change the 'legacy' subroutine (because I have reasons not to!).
thanks!
Remko
0 Kudos
3 Replies
Steven_L_Intel1
Employee
1,276 Views
I think you can do it like this:

call legacy(Y(1,1,1))

This gets you "sequence association" for that element and those that follow it, and if I understand you correctly, that's what you want.
0 Kudos
remkoduursma1
Beginner
1,276 Views
I probably was not really clear. I want to be able to make these types of calls:
call legacy(Y(1:N1, 1:N2, 1:N3, 1))
and
call legacy(Y(1:N1, 1:N2, 1:N3, 2))
for the next element of Y,and so on..
The variable Y has the fourth dimension in the subroutine from which I am making the call, but not in subroutine legacy.
thanks,
Remko
0 Kudos
Arjen_Markus
Honored Contributor II
1,276 Views
Assuming your legacy routine is based on the FORTRAN 77 way of dealing with arrays and
"sections" of arrays (the term was not used back then), I would suggest the following:

call legacy(Y(1:N1, 1:N2, 1:N3, 2))

can be done via:

call legacy(y(1,1,1,2) )

as only the last dimension does not start at the lower bound. This means that the
first element of the array that is passed to legacy() is indeed the second part of
the whole array (when split up along this fourth dimension) due to the way Fortran
organises its arrays.

This does presume that the first three dimensions are used over the full range.
In other words, you can not do:

call legacy( y(1:2,1:1, 1:n3, 2) )

in this way (if N1>2, N2>1).

If you want to have that flexilbilty, then use code like:

module legacy_interfacing

contains
subroutine legacy_interface( y )
real, dimension(:,:,:) :: y

call legacy( y )
end subroutine legacy_interface

In this code, the routine legacy_interface takes care of passing the proper section
of the array to legacy() and copying back (if needed) the results in the original
array.

Then:

call legacy_interface( y(1:n1:2,1:n2,1:n3,2) )

would work fine too (albeit that copy-in-copy-out will occur, as the array section is not contiguous).

Regards,

Arjen
0 Kudos
Reply