- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Two dimension array with one dimension fixed
I have an allocatable array of vectors. The index range of one of the dimensions is fixed at 3. The other is variable. The array is declared as:
real, pointer :: array( : ,: ) ! or real, allocatable if you wish
When I allocate an array of n vectors I use something like:
allocate(array(3,n))
So far so good.
The allocate in this manner is such that the three components of the vector are in adjacent memory. Supposedly for faster access.
The reason I say supposedly is that when I have optimizations enabled that the compiler cannot be certain as to the size of the extent of the first subscript. i.e. it cannot know it is always 3. The consequence of this is the compiler generates code to look at the in memory descriptor for the allocatable array. This causes unnecessary computations.
I know I can pass the array into a subroutine or function and then use a DIMENSION on the dummy argument. This adds additional overhead and requires I manufacture an additional subroutine.
Is there a way to define an allocatable array with one of the dimensions fixed?
Jim Dempsey
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
TYPE vector INTEGER, DIMENSION(3) :: val END TYPE vector ALLOCATE (vector(n))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That would work for a new program, but for an old program with 100's of source files it will not work.
Reason being it requires changing statements like
dest(1,n) = src(1,n) to dest(n)%vec(1) = src(n)%vec(1)
The editscan be hidden with a #define macro
end type
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Code:
type vector real :: (3) end type vector type(vector), pointer :: foo(:) ... allocate(foo(n)) val =foo(i,j) ! i is 1:3, j is 1:n
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
integer,dimension(:,:),allocatable :: two_d
integer,parameter :: fixed_dimension =
integer :: variable_dimension
variable_dimension =
allocate(two_d(fixed_dimension, variable_dimension))
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
address = ad.base + (( (ad.sub(1)%ub-ad.sub(1)%lb)+1) * (J-ad.sub(2)%lb) + I - ad.sub(1).lb))*ad.esz
ad is the hidden array descriptor
base is the base of the allocated array
sub is a member of ad and is an array of a 2 entry structure containing
lb lower bound
ub upper bound
esz is the element size
base is the base of the allocated array
sub is a member of ad and is an array of a 2 entry structure containing
lb lower bound
ub upper bound
ex extent (ub-lb+1)
esz is the element size
address = ad.base + ((ad.sub(2).ex * (J-ad.sub(2)%lb) + I - ad.sub(1).lb))*4! e.g. 4 for REAL(4)
then it knows everything except for the number of rows (*). The computation then becomes
i.e. contains base-4-12 to account for "I-1", "J-1" (which is *3*4'd)
The new reduced address expression is now
address = ad.base-16 + (3 * J + I)*4! if ad.base containes the actual base
or
address = ad.base + (3 * J + I)*4! if ad.base containes the fudged base
The code necessary to compute the address into the array is greatly simplified.
real :: a
dimension a(3,1:*)
... = .. + a(I,J)
My original post requested if there were a way to declare the constant portions of an allocatable array.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I don't have an answer to your question (I think it's impossible apart from cludges you already discovered yourself). However, have you actually measured the difference in performance between fixed-dimension and unknown-dimension? I think there's a fairly big possibility that we're discussing a strawman here -- modern compilers are known for good handling of assumed-shape arrays, and sometimes they even outperform plain vanilla fixed-size/assumed-size ones. (I wouldn't bet it for pointers though, as more attention must be paid when processing them).
Jugoslav
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have looked at the code and there is a noticeable amount of difference. A few percent. In a computational intensive situation a few percent is significant. In a program that runs 200 hours or more every little bit helps. I can work around the problem using dummy variables or using hacked in inline function/subroutines.
There are two opposing forces in effect here. The object model purest who would like to bury DIMENSION of dummy arguments (i.e. all calls must extract dimension info from the caller) and the pragmatist who is capable of telling the compiler what they want.
In most cases I can get around the problem by using a derived type and then allocate only one dimension. But then this requires what some would consider offensive,A #define statement to convert the double subscripted array references into a single subscripted arraywith member reference.
I do not mind inserting a kludge here and there. I do mind having to edit 100's of working modules and having to re-debug the edits due to the invariable editing mestake here and there.
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