- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
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.
Link Copied
6 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
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

Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page