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

"forrtl: severe (151): allocatable array is already allocated" Only Release

hentall_maccuish__ja
New Contributor II
7,091 Views

Hello,

I am getting an error "forrtl: severe (151): allocatable array is already allocated" only in release configuration. This is not called within a loop and  to try and get around this strange issue I am dellocating first but traceback is still throwing an error on the second of these two lines (but only in release not debug):

            if (allocated(xreg2)) deallocate(xreg2)
            allocate(xreg2(regPeriods, dimAboveMed, regPeriods-1+controls))

I'm a bit at a loss to try to trouble shoot this any more. If I deallocate without testing for allocatation first it gives an access violation on the first line and if I comment out the first line it gives an access violation later when I try and use xreg2 (both of which seem like correct errors because I am not allocating xreg anywhere else).

Thanks,   

0 Kudos
1 Solution
Arjen_Markus
Honored Contributor I
6,978 Views

The observation about commenting out these two lines strongly suggests there is a memory problem. Have you tried building the program with various run-time checking options on, such as array bounds checking?

View solution in original post

27 Replies
FortranFan
Honored Contributor II
1,644 Views
@hentall_maccuish__ja wrote:
.. Have I missed some compiler options that would have detected this for me?

 

Did you share here the interface of your subroutine 'doReg'?  I didn't see it in a quick scan of this thread.  If not, if you can post it now it may help with some useful closing discussion here.  Given your findings with the automatic variable 'beta', the interface of 'doReg' ('beta' is the last parameter of this procedure from what you show) might include a key lesson to be learned for you and other interested readers.

Separately, hopefully Intel product stewards are reading this but an unfortunate fact is Intel Inspector has rather limited utility when it comes to Fortran codes, it simply does not take into account much of modern Fortran semantics and it also does not separate out user code from all the processor (compiler+software-hardware platform) stuff making it extremely, extremely difficult for a typical scientific or technical discipline domain expert (an usual Fortran practitioner) to decipher the Inspector reports.  Even a simple Fortran IO (say WRITE) statement can trigger multiple memory related messages in Inspector given how unclean the underlying compiler management of IO instructions appear to be, not to mention some WRITE operations trigger memory leaks also and there is nothing a coder can do about it!

hentall_maccuish__ja
New Contributor II
1,624 Views

Sorry I did but I should have included it in the last post. Here it is:

 

    subroutine doReg(y, x, n, t, k, mask, ols, beta)
    implicit none

    integer, intent(in) :: n, t, k
    real (kind=rk), intent(in) :: y(t, n)
    real (kind=rk), intent(in) :: x(t, n, k)
    logical, intent(in) :: mask(t,n), ols
    real (kind=rk), intent(out) :: beta(k, 1)

.  

0 Kudos
FortranFan
Honored Contributor II
1,553 Views

@hentall_maccuish__ja ,

 

Does the caller 'DIDreg' have an explicit interface available for doReg?  Say, are they all module procedures?

Note the use to explicit-shape arrays [e.g., beta(k,1)] in the subprograms like you show with 'doReg' is as-is fraught with difficulties in modern programs and if the interfaces are implicit, then the problems can compound:

subroutine doReg(y, x, n, t, k, mask, ols, beta)
    implicit none

    integer, intent(in) :: n, t, k
    real (kind=rk), intent(in) :: y(t, n)
    real (kind=rk), intent(in) :: x(t, n, k)
    logical, intent(in) :: mask(t,n), ols
    real (kind=rk), intent(out) :: beta(k, 1)

 

Note if explicit interfaces are available but the use of explicit-shape arrays is continued, then users may have some assistance from the compiler with the run-time option of /check:bounds.  Are you using that?

The safer options per the Fortran language for such array handing scenarios as you show is

  1. Explicit interfaces
  2. Assumed-shape arrays

but this may end up requiring some additional in-code management of calculation data sizes.

 

hentall_maccuish__ja
New Contributor II
1,546 Views

They are all module procedures so I think that is a yes, explicit interfaces are avialable. Yes I used /check:bounds (full list of runtime flag in earlier post) but it did not detect the issue. You seem to think that it should have picked this up, is that right?

An explicit shape array would not have been my choice here, the code for doreg was inherited, but re-writing all completely functional inherited/legacy code just to detect incorrect function calls doesn't really seem a practicable solution.

0 Kudos
andrew_4619
Honored Contributor II
1,544 Views

Do we assume that the allocation of x,y,mask and beta match the sizes of t,n and k?  If so I would declare them as y(:,:) and use size function to get the values of t,k,n is I need them for loops.  Alternatively if you can check that the arrays are big enough for t,k,n passed in if you want to pass them. At least you would then trap bugs.

0 Kudos
hentall_maccuish__ja
New Contributor II
1,541 Views

As I said it is inherited code and I would not have written it like this. I'm not interested in improving doreg. I'm interested in whether there is a better way for me to detect a simple out of bounds error than two days debugging. If you answer is re-write every piece of code I inherit so the interface meets best practice then your answer is, in effect, no you have no better way.

I woul have hoped that the flags I used in debug configuration would have picked up this issue and failling that I would have thought the inspector might have detected it. I was wondeing if there was maybe some setting I missed that would have caught this but so far it seems not.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,508 Views

>> I would still like to know how I could do a better job of catching these errors in the future.

The first steps are: use free form as opposed to fixed form, implicit none, enable compile time diagnostics, especially interface checking and runtime bounds checking. If OpenMP is used, add default(none). This should catch most of the errors. Additional errors can be caught by using the INTENT clause on your arguments to catch inadvertantently modifying variables in the caller and/or not modifying those required to be modified.

Jim Dempsey

0 Kudos
Reply