- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have the following assignment in my code:
INTEGER,DIMENSION(:,:),ALLOCATABLE::factors
:
factors = factors(:,f)
Is this not allowed with automatic de- and reallocation (f2003) on the 2013 compiler?
I get the following error: The shapes of the array expressions do not conform. [FACTORS]
And btw, since in my case f<SIZE(factors,2) will the compiler do this in-place, ie. not by copying the section of factors to a temporary array?
What is the best way if I want to increase the bounds? Is that possible without making an explicit copy to a temporary array in my code?
Link Copied
7 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You have a rank 1 expression on the right hand side. Try using
factors = factors(:,f:f)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:This is true, but doesn't 7.4.1.3 of the Fortran 2003 standard suggest that the original code is acceptable (with /standard-semantics)? 22 If variable is an allocated allocatable variable, it is deallocated if expr is an array of different shape 23 or any of the corresponding length type parameter values of variable and expr differ. If variable is or 24 becomes an unallocated allocatable variable, then it is allocated with each deferred type parameter equal 25 to the corresponding type parameters of expr , with the shape of expr , and with each lower bound equal 26 to the corresponding element of LBOUND(expr ).You have a rank 1 expression on the right hand side. Try using
factors = factors(:,f:f)
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can't change the rank this way.
For example, 7.2.1.2 Intrinsic Assignment (F2008) says (bolding mine)
(3) the variable and the expr shall be conformable unless the variable is an allocatable array that has the same rank as expr and is neither a coarray nor a coindexed object
You can change the extents of each bound, but not the number of bounds.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
"shape" in the above standard refers to the extent of the bound limits of each of the ranks (dimensions).
>>If B is declared as B(2:4, -3:1), then SHAPE (B) has the value (3, 5).
Two arrays that differ in rank also differ in shape.
Two arrays of same rank but different entent of bound limits differ in shape.
real :: A(10,20), B(30,40), C(200), D(-5:4,-10:9)
SHAPE(A) (10,20)
SHAPE(B) (30,40)
SHAPE(C) (200)
SHAPE(D) (10,20)
Shape of A and D the same
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve and Jim. That makes sense because the object would then not match its original declaration in terms of rank if the assignment in the OPs post was allowed.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you all, it was a STUPID mistake by me not to remember the colon before the f...
On the other hand, if I actually wanted the extent of the 2nd dimension to be 1, ie. SIZE(factors,2) == 1, how would I accomplish that using array slicing?
And my questions regarding usage of internal temporaries still remains:
(snip)
And btw, since in my case f
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I understand correctly, Jim's reply gives you SIZE(factors,2) == 1.
"best" implies some sort of judgement about what's best (speed/code clarity, etc). Out of performance sensitive regions I very much tend to go for clarity, and personally I find the array operation syntax clearer than the possible multiline options that may help the compiler avoid a temporary.
(To be honest - I've not bothered to check whether the compiler does generate a temporary with some of these array syntax idioms, but I did have some stack overflow issues a while back that strongly indicate to me that's exactly what was happening with some of my code. Regardless, F2003 is still quite new compiler wise, so things should only get better, and if clear and concise syntax is obvious to me as a source reader as to the intent of a line of code then its probably not too far a step for it to be clear to an optimiser.)
So for chopping - code as presented by Jim. For growing a 1D array, where I know what the new bit is going to be, I simply do "array = [ array, new_bit ]" (being mindful that if array is a derived type with interesting components, then the compiler has been known to generate interesting code). For rank > 1, or when new_bit is yet to be figured out, I use a temporary allocatable and allocate bigger, copy, then swap:
[fortran]
allocate(tmp(size(array,1), size(array,2)+extra))
tmp(:,:size(array,2)) = array
call move_alloc(tmp, array)
[/fortran]
(If the lower bound of array isn't 1 then modifications to the above required.)
But I have been accused of profligacy in the past with respect to things like temporaries, etc. If you do some actual measurements I'd be interested in hearing about them.

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