Silverfrost Forums

Welcome to our forums

Problem with ALLOCATE and /check

21 Apr 2015 5:42 #16224

I am struggling with use of ALLOCATE with /check and this error is stumping me. I have done a lot of software development lately, using ALLOCATE, to make the program more flexible for problem size and memory size. I have returned to an old program and am trying to check code, so selectively compile some routines with /check, mainly for argument and bounds checking. The following snippet of code uses /check, while most libaray routines use /opt, /debug or no option

      INTEGER*4 MULC, MUM_FEM, L3, L4, L5, L6, L7, Le, P_end, stat
!
      real*8,    allocatable, dimension(:,:) :: EPROP
      real*8,    allocatable, dimension(:,:) :: COPROP
!
!        read and save beam element info
!
         call check_allocate ( 'at entry to BEAM' )
!
         IF (NUM_MAT <= 0) NUM_MAT = 1
         Le = (L6+15*NUME)*4 + (L3+L4+L5+L7+NUME)*8
         call allocate_report (le)
         stat = 0
!
         call check_allocate ( 'about to allocate EPROP' )
!
         ALLOCATE ( EPROP(4,NUM_MAT),   stat=stat ) ; call alloc_test (stat, 'EPROP(4,NUM_MAT)',    4,NUM_MAT)

The resulting report is: Checking if ALLOCATE is working at entry to BEAM Allocate target = 0.989 mb Check of ALLOCATE completed Allocate target = 0.010 mb Checking if ALLOCATE is working about to allocate EPROP Allocate target = 0.989 mb Check of ALLOCATE completed Error allocating EPROP(4,NUM_MAT) : stat = 1 dimensions are 4 1

My called library routines are:

    subroutine alloc_test (stat, array,  n1,n2)
      integer*4 stat, n1,n2
      character *(*) array
!
      if ( stat == 0) return
      write (*,*) 'Error allocating ',array,' : stat =',stat
      write (*,*) 'dimensions are',n1,n2
      stop
    end subroutine alloc_test

    subroutine check_allocate (from)
!
!   This routine allocates a 1mb array to check that ALLOCATE works
!
      character from*(*)
      integer*4 :: n = 360
      real*8, allocatable, dimension(:,:) :: EPROP
      real*8, allocatable, dimension(:,:) :: aa
      integer*4 stat, le, num_mat
!
      write (*,*) 'Checking if ALLOCATE is working ', from
      NUM_MAT = 1
      Le = (n*n + 4*NUM_MAT)*8
      call allocate_report (le)
!
      ALLOCATE ( EPROP(4,NUM_MAT), stat=stat ) ; call alloc_test (stat, 'EPROP(4,NUM_MAT)', 4,NUM_MAT)
      ALLOCATE ( aa(n,n),          stat=stat ) ; call alloc_test (stat, 'aa(n,n)',          n,n)
!
      DEALLOCATE ( aa )
      DEALLOCATE ( EPROP )
      write (*,*) 'Check of ALLOCATE completed'
!
     end subroutine check_allocate

The program is failing trying to allocate an array of 32 bytes, when use of ALLOCATE outside the routine compiled with /check are ok. Is this a known problem ?

I am using FTN95/Win32 Ver. 7.10.0

John

21 Apr 2015 6:37 #16225

I don't know of any problem in this area.

ALLOCATE calls GlobalAlloc except when /CHECK is applied. Otherwise FTN95/salflibc.dll uses its own storage block for all ALLOCATEs and this storage block is created by calling VirltualAlloc.

Does the code that you have posted demonstrate an error that I can reproduce?

21 Apr 2015 6:52 #16226

I have made a small test which reproduces the result. Subroutine beam is compiled with /check Allocate works outside call to routine compiled with /check, or to a routine called from beam, but ALLOCATE does now work in the BEAM subroutine.

The following is a small test example:

https://www.dropbox.com/s/xnawf5zvm59nmtu/Alloc_Test.zip?dl=0 this example uses a large common, but I am surprised by the difference outcome, depending on where 'ALLOCATE' is being called from. do_test.bat is the test batch file ftn95.tce is my result of the run ( oops! do_test will overwrite this file )

32 bytes is an annoyingly small array to fail on !

John

21 Apr 2015 10:58 #16227

I have downloaded the archive and logged this for investigation.

In the mean time is it possible to do the ALLOCATE in a separate subroutine that does not have /CHECK? applied. Then you will be getting the memory directly via GlobalAlloc.

Another possibility is to use GET_STORAGE@ instead of ALLOCATE because GET_STORAGE@ looks like it will call GlobalAlloc even when /CHECK is applied.

21 Apr 2015 12:10 #16228

Paul,

Thanks for looking at this. At present, FTN95 does not allow an allocatable array to be allocated in another routine, unless the array is in a module. I think it may be easier to change the way I am using /check than move these arrays to global allocatable arrays. This has many other implications in the program's development.

It is good to know the reason for the error.

John

21 Apr 2015 1:54 #16229

John, using allocatable arrays as arguments to subprograms was not a feature that was provided in Fortran 95. This feature was defined in a technical report (TR-15581) from the ISO committee and became part of Fortran 2003, although some compiler vendors implemented TR-15581 in their Fortran 95 compilers. See https://forums.silverfrost.com/Forum/Topic/2608 .

Adding this capability would greatly enhance the usefulness of FTN95, since many codes use this feature of the language. For example, the package Galahad-2 uses it.

Update, 22 July 2015: The output from your example does not contain 'Error allocating EPROP(4,NUM_MAT)' when one uses FTN95 7.20.

23 Jul 2015 12:44 #16634

mecej4,

I have today downloaded the test from dropbox and it now runs on Ver 7.10.0 I also found the original .exe on disk and it now runs without error. Back in April, it failed on every run. Previously the error did not occur on every run of the bigger program, so I may give it another go. I am not sure what this shows !!

Dan, this is not a huge program (40k lines, 500 routines), but it does use large arrays.

The only change has been the regular Microsoft updates to Win 7. I should install FTN95 Ver 7.2. Updates are not going well at the moment ! I've recently installed 2 versions of gFortran 5.1.0, both of which do not work.

John

23 Jul 2015 5:59 #16637

John

If it helps, I think that I could add a new item to /INHIBIT_CHECK. The extra item would disable the checking code around an ALLOCATE statement.

23 Jul 2015 8:03 #16638

Paul,

Thanks for the offer. Based on recent posts, it would be good to have ALLOC in the option name; such as /INHIBIT_ALLOC_CHECK.

You posted earlier

ALLOCATE calls GlobalAlloc except when /CHECK is applied. Otherwise FTN95/salflibc.dll uses its own storage block for all ALLOCATEs and this storage block is created by calling VirltualAlloc.

Based on this I thought if ALLOCATE could use GlobalAlloc when /CHECK is applied, this may remove the problem. Is this a possible approach ? /GLOBAL_ALLOC could be a possible option, if it does not cause problems for SDBG.

The main reason I try to use /check is to check the argument lists and then subscripts in range.

Given I can't reproduce the error today, I wonder what is causing the problem.

As a supplementary question: For a multi-dimension array, does /check check each subscript is in range, or only if the memory address is within the array memory limits. ie real*8 A(3,3) I = 7 J = 1 aa = A(I,J)

Would this be out of bounds or as it is effectively A(1,3) be ok ? I find my more common error is when I or J = 0

John

23 Jul 2015 11:13 #16640

Quoted from JohnCampbell mecej4,

Updates are not going well at the moment ! I've recently installed 2 versions of gFortran 5.1.0, both of which do not work.

For production work you should be using 4.9 or lower. Anything higher is 'experimental' -- useful for trying out new language features that do not exist in the 'stable' version, but likely to be buggy, as you found.

23 Jul 2015 2:01 #16641

John

I would use /INHIBIT_CHECK <value> initially because it would be experimental and may not do the trick.

25 Jul 2015 3:14 #16645

Paul,

Thanks for the offer. Can you provide a beta test and I will see what happens ?

The direct failure I am getting is that ALLOCATE appears to run out of available memory. (Which is not being released by DEALLOCATE when /CHECK is used ?)

John

7 Jun 2016 7:46 #17561

John

Sorry for the delay but, now that I look into implementing your request, it seems like the facility that you need is already available.

Please try using /CHECK with /INHIBIT_CHECK 4 to see if this gives the desired behaviour.

Please login to reply.