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

passing rank2 array into rank1 dummy

forall
Beginner
1,746 Views
Hi,

the following code accomplishes exactly what I need (dynamic equivalence, with array sizes determined at runtime), with no warnings (on CVF), but I am unsure it is 100% legal, since it involves passing a rank2 array into a dummy argument that is rank1.

!===============
module m
implicit none
contains
subroutine associate1D(a1,np,p1)
implicit none
integer,intent(in)::np
integer,intent(in),target::a1(np)
integer,pointer::p1(:)
p1=>a1(1:np)
endsubroutine associate1D
endmodule m
!-------------
program main
use m
implicit none
integer,parameter::n1=2,n2=3
integer::a2D(n1,n2)
integer,pointer::a1Dp(:)=>null()
! ... various code
call associate1D(a2D,n1*n2,a1Dp)
! ... can now address a2D using single subscript via a1Dp (similar to equivalence,
! but dynamic, with runtime array sizes, eg, if a2D is allocated or automatic or itself
! a dummy explicit-size-array dummy argument)
endprogram main
!===============

I was a bit surprised (and happy) that CVF doesnt complain, although from my understanding of the Fortran argument association mechanism, explicit-shape (and assumed-size) arrays are passed-in using the address of the first element, which would explain why the example works. So is this construction legal? and is there a better way to accomplish this result? thanks in advance as usual.
0 Kudos
6 Replies
Steven_L_Intel1
Employee
1,746 Views

The code is legal-if you are passing an array to an explicit-shape array, the ranks need not match as long as the number of elements in the dummy don't exceed the number of elements in the actual.

0 Kudos
forall
Beginner
1,746 Views
good. However, it seems it is not possible to overload multiple versions (eg, for real and integer arrays "a") of 'associate1D' using generic interfaces, since the compiler cannot resolve the reference to the specific routine (since none of them, by construction, expect a rank2 array). I guess overloading them is not essential.
0 Kudos
Steven_L_Intel1
Employee
1,746 Views
You could always call the "associate" routine with the first element of the array in question - that will match an array of any rank through "sequence association".
0 Kudos
forall
Beginner
1,746 Views
Steve,

any chance you could give an illustration of this? I have tried several ways to overload

subroutine associate1D_i(a1,np,p1)
implicit none
integer,intent(in)::np
integer,intent(in),target::a1(np)
integer,pointer::p1(:)
p1=>a1(1:np)
endsubroutine associate1D_i

and

subroutine associate1D_r(a1,np,p1)
implicit none
integer,intent(in)::np
real,intent(in),target::a1(np)
real,pointer::p1(:)
p1=>a1(1:np)
endsubroutine associate1D_r

onto the same generic name associate1D, but the calls to the generic name are not resolved and I get the compiler message - "there is no matching specific subroutine".

While on this topic, is there any difference at all if I use an assumed-size instead of explicit-size dummy array a1? ie, declare a1(*). I tested it and it works identically, but are there any advantages to doing it? thanks!

dmitri

0 Kudos
Steven_L_Intel1
Employee
1,746 Views

Hmm - doesn't work the way I had envisioned. Perhaps my idea of passing a(1,1) doesn't work for generics - probable. I suppose the alternative is to have two versions of each i and r routine, one for 1D arrays, one for 2D arrays.

Using an adjustable array, a(n), is better than assumed-size, a(*), as you give the optimizer more information about the array bounds, and you can then do whole-array operations with the bound specified where you can't with *, but otherwise they're the same.

0 Kudos
hajek
Beginner
1,746 Views
Associate1D is legal, but using a1Dp afterwards is illegal, as a2D does not have the TARGET attribute. And even if it had, the functionality is compiler-dependent (it is granted for assumed shape and scalars, but not for explicit shape or assumed size)

sec. 12.4.1.2 of the standard says that

If the dummy argument has the TARGET attribute and is an explicit-shape array or is an assumed-size array, and the corresponding actual argument has the TARGET attribute but is not an array section with a vector subscript then
(1) On invocation of the procedure, whether any pointers associated with the actual argument become associated with the corresponding dummy argument is processor dependent and
(2) When execution of the procedure completes, the pointer association status of any pointer that is pointer associated with the dummy argument is processor dependent.

I have recently needed the same (aliasing with different rank) and came to the conclusion that there is no F95-standard way to mimic the reshaping ability of F2003 pointers
(there is a trick to do bounds-remapping, however), save for the EQUIVALENCE statement on static arrays.
However, your code is likely to work with most compilers on machines with linear memory, unless the compiler does a temporary copy on the call of Associate2D
(which it is allowed to).

HTH,
Jaroslav
0 Kudos
Reply