- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
1) Is it legal to create arrays using components of derived types, eg,
arr(:)=var(:)%comp
assuming arr and comp are of the same type and their dimensions match.
2) Can they be used as targets of pointer association, eg
p=>var(:)%comp
3) Can they be passed to subroutines expecting array arguments, eg,
call sub(arr=var(:)%comp)
It appears that both IVF and CVF function correctly in simple cases (eg, see below), but I have a large program where this could be a problem and so wanted to check that these usages (especially 2 and 3) are indeed legal.
thanks in advance,
dmitri
!***************************
module m
implicit none
type t
real::r
endtype t
contains
!---
subroutine test(argR)
real,intent(in)::argR(:)
integer::i
do i=1,size(argR)
write(*,*)argR(i)
enddo
endsubroutine test
!---
endmodule m
!*****************************
subroutine sample_subroutine()
use m,only:t,test
implicit none
integer,parameter::n=2
type(t),target::var(n)
real,pointer::p(:)
! does 'var(:)%r' constitute a valid array?
var(:)%r=(/1.0,2.0/) ! is this assignment valid?
p=>var(:)%r ! is this pointer statement legal?
call test(argR=var(:)%r) ! is this call legal?
call test(argR=p)
endsubroutine sample_subroutine
!******************************
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I would recommend not using the (:) in expressions as it can sometimes inhibit optimizations, but I understand if you want to use it to make clear it's an array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Your example is inadequate for testing. To make a better test try
type t
sequence
real(8)::r
integer(4) :: i
endtype t
This way the array of t's is not equivilent to the array of t%r (i.e. the group of r's are not in adjecent memory. And the additional member of t is not a multiple of the size of r.
It is unknown to me as to if the compiler creates a temporary array or if it creates a descriptor with stride when passing var(:)%r as an argument Looking at the dissassembly window would tell you which method was used. Creating an array descriptor with stride would be useful when calling a Fortran subroutine. To get the descriptor passed you would have to declare an interface with the dummy argument declared with (:). For calling a C/C++ you might want the compiler to construct a temporary array as C++ subroutines tend to not examine the Fortran descriptor.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tracked down my problem to the following reduced case, which crushes with stack overflow (but doesnt work properly otherwise either). Strangely enough in a more complex code this results in the string becoming blank, rather than causing stack-problems when passing it.
Now I am wondering whether using arrays of components of derived types is a good idea even if it is legal, since it seems to require the creation of temp storage whenever the derived type contains components of different memory lengths (in which case it would be impossible to create a compact descriptor with strides?) - is this a fair statement?
!******************************************************************
module m
implicit none
contains
!----------------------------------------------------
subroutine sub1(vname)
implicit none
! dummies
character(*),intent(in)::vname(:)
call sub2(vname,n=size(vname))
endsubroutine sub1
!----------------------------------------------------
subroutine sub2(item,n)
implicit none
integer,intent(in) :: n
character(*),intent(in) :: item(n) ! this line crashes the code (explicit-shape array)
!character(*),intent(in) :: item(:) ! this line works
write(10,'(a)')"'"//item//"'" ! this statement fails
endsubroutine sub2
!----------------------------------------------------
endmodule m
!*****************************************************************
subroutine sample_subroutine()
use m
implicit none
type var1_type
character(10)::name
real::v ! removing this component makes the code work always (aligned type)
endtype var1_type
integer,parameter::n=2
character(10)::vname(n)
type(var1_type)::var(n)
vname=(/"x1","x2"/)
var(:)%name=vname
call sub1(vname=vname) ! this works fine
call sub1(vname=var%name) ! this causes stack-overflow
endsubroutine sample_subroutine
!******************************************************************
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Please report the bug to Intel Premier Support.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Steve,
>> I don't understand your comment about strides
The strides may or may not work, depending on how strides are internallyimplemented (number of items or number of bytes)
Consider
type t
sequence
real(8)::r
integer(4) :: i
endtype t
type(t) :: Tarray(100)
Tarray(1) would start a memory block of
real(8)
integer(4)
real(8)
integer(4)
real(8)
integer(4)
... 97 more times
In the above, each element of the array is 12 bytes (with external representation of stride implicitly being 1 element)
If the internal representation of Stride is in bytes then each 8-byte real would be positioned at 12-byte intervals. Although the 12 byte stride cannot be specified at the source code level, it can very well be specified in the descriptor. Therefore, a descriptor could be constructed for Tarray(:)%r and passed to a subrouting taking real(8) :: r(:) without requiring a copy to/from temp array.
As an alternate technique, the element size could be specified as being 12 bytes (and stride of 1 element).
r need not be at the base of the structure since the base address of the 1st r can be used in lieu of the base address of the first t.
Does this make sense to you?
Jim Dempsey

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