forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Shape of deallocated array
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Thu Apr 20, 2023 1:42 am    Post subject: Shape of deallocated array Reply with quote

In the following program, FTN95 remembers the shape of the allocatable array after it is deallocated. In other compilers the call to Shape generates a run-time error.

Code:
Program p
  Integer, Dimension(:), Allocatable :: i
  Allocate (i(2))
  Deallocate (i)
  Print*, Shape(i), Allocated(i)
End Program p

In my larger programme I am getting inconsistent behaviour when it is rerun with exactly the same inputs. I am wondering whether this problem is somehow related. Occasionally it seems that FTN95 returns an error when trying to reallocate this memory (I am using IOSTAT=, which returns 1), although I can confirm that allocated (i) is false before the call.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Thu Apr 20, 2023 7:11 am    Post subject: Reply with quote

Simon

I am not sure if I can provide any assistance on this issue but some details might depend on whether or not it is 64 or 32 bits, CHECK or not CHECK.
Back to top
View user's profile Send private message AIM Address
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Thu Apr 20, 2023 7:33 am    Post subject: Reply with quote

Hi Paul,

I seem to get the same output ("2 F") regardless of which compiler options I use.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Thu Apr 20, 2023 12:44 pm    Post subject: Reply with quote

Simon

I don't see how the problem could relate to the shape of an array after deallocate. FTN95 will allocate memory for a pointer to the allocated block and presumably for the returned shape. The pointer will be reset to NULL on deallocate but I guess that the shape won't be reset.

An IOSTAT value of 1 means that the resulting call to HeapAlloc has failed which in turn means that that there is insufficient memory or that the heap is corrupted. There is also the possibility that the requested size of the block of memory has got corrupted.

I presume that you have run tests using /CHECKMATE.
Back to top
View user's profile Send private message AIM Address
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Thu Apr 20, 2023 4:12 pm    Post subject: Reply with quote

Indeed, I have tried CHECKMATE. But forgetting about the larger programme for now, is Shape not returning an incorrect result even in the simple example? Size also returns 2 after i is deallocated.
Back to top
View user's profile Send private message
Kenneth_Smith



Joined: 18 May 2012
Posts: 697
Location: Hamilton, Lanarkshire, Scotland.

PostPosted: Fri Apr 21, 2023 1:44 am    Post subject: Reply with quote

The 2008 (draft) standard explicitly states that the argument of both SHAPE and SIZE must not be an unallocated allocatable variable. So what a complier should or should not return in this case is not clearly defined.
Back to top
View user's profile Send private message Visit poster's website
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Fri Apr 21, 2023 7:44 am    Post subject: Reply with quote

What FTN95 actually does after DEALLOCATE can be discovered by using /EXPLIST on the command line and decyphering the resultant listing but I don't think that it will have any bearing on the current problem.

Add some code locally to get the shape so that you can see how it relates to the registers and associated memory allocation.
Back to top
View user's profile Send private message AIM Address
mecej4



Joined: 31 Oct 2006
Posts: 1885

PostPosted: Fri Apr 21, 2023 1:44 pm    Post subject: Reply with quote

Line 5 of the short program in the first post has two function invocations in the output list, one of which is legal and the other is not. If we separate the two, as in
Code:
Program p
  Integer, Dimension(:), Allocatable :: i
  Allocate (i(2))
  Deallocate (i)
  Print*, Shape(i)      ! not legal, since i is not currently allocated
  Print *, Allocated(i) ! legal
End Program p

it is easier to discuss what the program may be expected to do, when it is compiled with and without /check.

When /check has not been used, the use of Shape(i) when the variable I is currently not allocated is incorrect, the program behaviour is undefined and it can do anything.

I think that when /check has been used the modified program should be able to detect the reference to Shape with an argument that is currently not allocated, issue an appropriate message, and abort execution. FTN95 currently does not do this, and a fix may be worth considering.

For this program, after compiling and linking with Lahey Fortran with the -Hx option, the program terminates with the output:
Code:
jwe0324i-w line 5 Allocatable array (i) is not allocated.
 error occurs at _MAIN__  line 5 loc 004010ce offset 000000ce
 _MAIN__      at loc 00401000 called from o.s.
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Sat Apr 29, 2023 4:37 pm    Post subject: Reply with quote

Many thanks to everyone's inputs. It has been helpful to know not to expect shape to "work" (if that is the correct word) when its argument is deallocated.

I don't know whether this is a closely related problem, but in trying to trace the memory issues I referred to before, I encountered the following issue:
Code:

print *, shape(b),shape(a)
b(:,:) = a(:,:,1)
print *, shape(b)

a and b are both allocated, and in one example where this problem happens I get the following output:
Code:

35 36 35 36 1
1 36

I will see if I can create a small example of code to reproduce this problem ...
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Apr 30, 2023 12:44 pm    Post subject: Reply with quote

If "b" is deallocated, then I would expect shape(b) is undefined for values and also possibly for rank ?

For "b(:,:) = a(:,:,1)" I am not sure if auto-allocate applies, although the following code example does not show this for both FTN95 and Gfortran.

I am unsure when auto-allocate does apply so I try to avoid this syntax.

Does the following code example help ?
It does not reproduce your post result

Code:
! test of auto allocate
integer, allocatable :: a(:,:,:)
integer, allocatable :: b(:,:)
integer :: i,j,k

allocate ( a(4,7,3) )
allocate ( b(4,6) )

do k = 1,3
  do j = 1,7
    do i = 1,4
      a(i,j,k) = i+j+k
    end do
  end do
end do

  do j = 1,6
    do i = 1,4
      b(i,j) = i+j+4
    end do
  end do

print *, 'a', shape(a), size(a)
print *, 'b', shape(b), size(b)

b(:,:) = a(:,:,1)    !  not sure what happens here

print *, 'b', shape(b), size(b)
do j = 1,6
  write (*,*) j,b(:,j)
end do

end
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Sun Apr 30, 2023 8:06 pm    Post subject: Reply with quote

That would be interesting - if b were already allocated but got resized at the "not sure what happens here" line, that could result in some very difficult to track problems.
Back to top
View user's profile Send private message
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Mon May 01, 2023 6:08 pm    Post subject: Reply with quote

Here is an attempt to isolate the problem with the shape of an array being reassigned.
Code:
Module m1
   Implicit None
   Real, Dimension(:,:),   Allocatable, Public  :: b
   Real, Dimension(:,:,:), Allocatable, Public  :: a
End Module m1


Module m2
!
Contains
!
 Subroutine s1 ( )
   Use m1,           Only: a, b
!
   Call s2 ( )
   a = 1.0
   Print *, shape(a)
   Print *, shape(b)
   b(:,:) = a(:,:,1)
   Print *, shape(b)
!
   Return
 End Subroutine s1
!
!
 Subroutine s2 ( )
   Use m1, Only: a, b
!
   Allocate ( a(35,30,1) )
   Allocate ( b(35,30) )
!
   Return
 End Subroutine s2
End Module m2


It seems that the modules and main program may each need to be in a separate file:

Code:
Program p
   Use m2, Only: s1

   Call s1 ()
End Program p


But I am not entirely sure, because I do not get consistent results. If I keep everything in separate files, recompile and run, I get different outcomes. So far I have had the following outcomes:

1. A run-time crash after the second print statement
2. The program completes with no crash but the third print returns 1 30
3. The third print returns 1 30 but a run-time error is issued

... but now that I have submitted this example, if I compile and run from a command prompt, it seems to work ok! But building it within a Plato project creates the error. I really hope somebody at Silverfrost can reproduce and diagnose the error. I can try to forward a simple package containing the relevant files and settings if that would be helpful.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue May 02, 2023 11:39 am    Post subject: Reply with quote

This appears to expose a bug in FTN95. A work-around is to have just one USE statement in module m2. Note that statements like "b(:,:) = a(:,:,1)" might be very expensive. There could be a lot of work going on to evaluate the addresses for each copy.

Code:
Module m1
   Implicit None
   Real, Dimension(:,:),   Allocatable, Public  :: b
   Real, Dimension(:,:,:), Allocatable, Public  :: a
End Module m1


Module m2
Use m1, Only: a, b
!
Contains
!
 Subroutine s1 ( )
!
   Call s2 ( )
   a = 1.0
   Print *, shape(a)
   Print *, shape(b)
   b(:,:) = a(:,:,1)
   Print *, shape(b)
!
   Return
 End Subroutine s1
!
!
 Subroutine s2 ( )
!
   Allocate ( a(35,30,1) )
   Allocate ( b(35,30) )
!
   Return
 End Subroutine s2
End Module m2

program maim
use m2
call s1()
end program maim
Back to top
View user's profile Send private message AIM Address
simon



Joined: 05 Jul 2006
Posts: 268

PostPosted: Tue May 02, 2023 2:30 pm    Post subject: Reply with quote

Thanks Paul. I'm relieved you were able to isolate the bug. It has taken a great deal of work to locate the problem and then produce the small example.

Are you able to be more generic about what we should avoid until this problem is resolved? I am concerned that this problem may be occurring elsewhere in my program undetected. Should we be avoiding a USE statement in more than one subroutine or function within a module, and if so, is that only for arrays? For arrays of more than one dimension? Only for arrays that are assigned values?

What would you suggest in place of the expensive line? Simply removing the brackets on the left? A DO CONCURRENT? I had programmed this section in that way specifically because I thought it permitted the most efficient code.
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue May 02, 2023 7:50 pm    Post subject: Reply with quote

Simon

I need to investigate this issue before I can give a clear reply. At the moment I am not sure that this exposes a bug in FTN95.

Since sub1 and sub2 share the same arrays A and B, it seems natural to me to USE (i.e. load) the module just once in the header rather than separately in each subprogram.

At the moment I am guessing that FTN95 is producing separate instances of A and B when when USE appears in both subroutines and that this is probably wrong according to the Standard.
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group