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

Check if allocatable array on the LHS is reallocated?

mSSM_B_
Beginner
1,871 Views

I have recently stumbled over the handling of standard semantics in ifort, specifally how allocatable arrays are dealt with. In particular, the following description of realloc_lhs in ifort's manpage raised some questions:
 

assume realloc_lhs
                                Tells  the compiler that when the left-hand side of an assignment is an allocatable object,
                                it should be reallocated to the shape of the right-hand side of the assignment before the
                                assignment occurs. This is the Fortran 2003 definition. This feature may cause extra
                                overhead at run time.

Now my questions is: what happens if the LHS is already allocated and has the same shame as the RHS? Will it be reallocated anyways? Is there a way to check this? See the following MWE:

program mytest
    implicit none

    integer, dimension(:), allocatable :: a1, a2
    integer :: arrsize
    integer :: i

    arrsize = 10

    allocate(a1(arrsize))
    allocate(a2(arrsize))

    a2 = [ (i=1, arrsize) ]

    ! Is a1 reallocated here?
    a1 = a2

    ! This ensures non-reallocation, but fixes the arrays' ranks
    a1(:) = a2(:)

end program mytest

In principle I could of course use the second way of assining a2 to a1. However, I'd prefer using “a1 = a2”, since that notation allows for arbitrary rank arrays, while the second option fixes my arrays' ranks.

0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,871 Views

If the array has the same shape, it is not reallocated. I don't know of a foolproof way to detect reallocation. You could take the address of the LHS before and after and see if they're the same. If they're not, reallocation occurred. If they are, then reallocation probably didn't occur but if the same size got reallocated it might have the same address.

Be aware, though, that you can't change the rank of an array through intrinsic assignment. You seem to be assuming that this can be done.

View solution in original post

0 Kudos
12 Replies
Steven_L_Intel1
Employee
1,872 Views

If the array has the same shape, it is not reallocated. I don't know of a foolproof way to detect reallocation. You could take the address of the LHS before and after and see if they're the same. If they're not, reallocation occurred. If they are, then reallocation probably didn't occur but if the same size got reallocated it might have the same address.

Be aware, though, that you can't change the rank of an array through intrinsic assignment. You seem to be assuming that this can be done.

0 Kudos
mSSM_B_
Beginner
1,871 Views

Thanks for the clarification. I should indeed have a look at the memory addresses (I guess there is a chance that the address before and after a potential reallocation might coincide, but I suppose the odds are negligible).

Thank you also for the comment on the array ranks. I just noticed that my MWE doesn't exactly reflect my use case. My arrays are actually defined and allocated in a module, and then use-d by my subroutines. Their ranks and shapes match up by definition, s.t. the above example would look rather like below (making it more obvious why I am interested in not fixing ranks):

subroutine my_modifying_routine

    use my_array_module, only: a1, a2

    a1 = a2

end my_modifying_routine

 

0 Kudos
Steven_L_Intel1
Employee
1,871 Views

I would just use the regular assignment and not worry about it - with -standard-semantics enabled.

0 Kudos
Izaak_Beekman
New Contributor II
1,871 Views

Only the ‘(:)’ on the LHS of assignment is needed to prevent reallocation, FYI, if you want to guarantee no reallocation, and as you noted, you must be careful about the rank when using it.

0 Kudos
Steven_L_Intel1
Employee
1,871 Views

Well, no, you don't have to be careful about the rank, as the compiler will let you know if those don't match. You DO have to be careful about the shape.

0 Kudos
Izaak_Beekman
New Contributor II
1,871 Views

Yes, I just mean, make sure you have the correct number of colons… but as you point out, the compiler will alert you at compile time.

0 Kudos
FortranFan
Honored Contributor III
1,871 Views

Steve Lionel (Intel) wrote:

If the array has the same shape, it is not reallocated. I don't know of a foolproof way to detect reallocation. You could take the address of the LHS before and after and see if they're the same. If they're not, reallocation occurred. If they are, then reallocation probably didn't occur but if the same size got reallocated it might have the same address.

Be aware, though, that you can't change the rank of an array through intrinsic assignment. You seem to be assuming that this can be done.

Steve,

Is it possible to add a run-time debugging option, similar to -check:arg_temp_created (call it say -check:reallocation), that can allow users to test for this while debugging their code?  If Intel team can come up with some option along such lines for such checking, it will be really useful.  So basically I'm suggesting if the run-time environment along with ifort can do what you suggested, "take the address of the LHS before and after and see if they're the same. If they're not, reallocation occurred", and alert the user accordingly.

Food for thought,

0 Kudos
Steven_L_Intel1
Employee
1,871 Views

We are generally reluctant to add diagnostics for features that are integral to the language, especially as in this case you're going to get correct results. What would be the purpose in such an option? There are many applications that depend on the now-standard behavior - so many so nowadays that we are considering making -assume realloc_lhs the default in a future release, the way some other compilers have recently done.

0 Kudos
IanH
Honored Contributor III
1,871 Views

FortranFan wrote:

Quote:

Steve Lionel (Intel) wrote:

 

If the array has the same shape, it is not reallocated. I don't know of a foolproof way to detect reallocation. You could take the address of the LHS before and after and see if they're the same. If they're not, reallocation occurred. If they are, then reallocation probably didn't occur but if the same size got reallocated it might have the same address.

Be aware, though, that you can't change the rank of an array through intrinsic assignment. You seem to be assuming that this can be done.

 

 

Steve,

Is it possible to add a run-time debugging option, similar to -check:arg_temp_created (call it say -check:reallocation), that can allow users to test for this while debugging their code?  If Intel team can come up with some option along such lines for such checking, it will be really useful.  So basically I'm suggesting if the run-time environment along with ifort can do what you suggested, "take the address of the LHS before and after and see if they're the same. If they're not, reallocation occurred", and alert the user accordingly.

 

What's the use case?

For non-polymorphic objects with no deferred length parameters you can do it yourself with `IF (ANY(SHAPE(lhs) /= SHAPE(rhs))) PRINT "('Reallocation!')"` or similar. 

Runtime diagnostics for shape mismatches in assignments where the left hand side isn't allocatable strikes me as far more useful.

0 Kudos
FortranFan
Honored Contributor III
1,871 Views

Steve Lionel (Intel) wrote:

We are generally reluctant to add diagnostics for features that are integral to the language, especially as in this case you're going to get correct results. What would be the purpose in such an option? There are many applications that depend on the now-standard behavior - so many so nowadays that we are considering making -assume realloc_lhs the default in a future release, the way some other compilers have recently done.

Steve,

Can you please explain the value of -check arg_temp_created?  Is there any value to it beyond being "informative" when temporary storage is created before procedure calls.  Does this feature have relevance to any wrong/right results?  The way we use it, it simply allows us to focus our attention on situations where temporary storage is involved during procedure invocations.  So if the temporary storage is not intentional (an aspect some other coder might have overlooked during development), the team can investigate code redesign to avoid it.  Quite handy, since it is part of ifort. 

Now when working with arrays, we do see situations where unintentional and costly reallocations are taking place in compute-intensive code (e.g., in an utility used by a solver that is invoked frequently in some simulation) because of coder oversight (yes, the allocatable attribute does get abused at times).  Perhaps VTune Amplifier can point out situations, but it is a separate tool often out of reach.  Hence I was thinking a built-in check in ifort will be handy.

0 Kudos
FortranFan
Honored Contributor III
1,870 Views

IanH wrote:

Quote:

FortranFan wrote:

 

Steve,

Is it possible to add a run-time debugging option, similar to -check:arg_temp_created (call it say -check:reallocation), that can allow users to test for this while debugging their code?  ...

 

What's the use case?

For non-polymorphic objects with no deferred length parameters you can do it yourself with `IF (ANY(SHAPE(lhs) /= SHAPE(rhs))) PRINT "('Reallocation!')"` or similar. 

..

The use case is quick and easy diagnostics of unintentional reallocations in assignments.  We did have a situation where a utility in a solver was chewing up more compute time than necessary due to reallocations of some of the work areas as the problem space considered by the solver was changing.  The overall team would sooner or later catch such scenarios during performance evaluation of the simulator, but it could be sooner if ifort had a handy option to alert the user.  

0 Kudos
Steven_L_Intel1
Employee
1,871 Views

-check arg_temp_created applies to argument passing where the compiler has to do copy-in/copy-out because of a mismatch in assumptions, generally related to noncontiguous arrays being passed to contiguous arrays. The copying can be a serious performance issue.

In the assignment case, you're already doing a copy - the issue is merely one of reallocation which isn't all that expensive and tends to be constant time.

0 Kudos
Reply