soccer jersey forums.silverfrost.com :: View topic - SDBG64 with derived types
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 

SDBG64 with derived types
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> 64-bit
View previous topic :: View next topic  
Author Message
DanRRight



Joined: 10 Mar 2008
Posts: 2867
Location: South Pole, Antarctica

PostPosted: Tue Apr 30, 2024 3:14 pm    Post subject: SDBG64 with derived types Reply with quote

How to see values of derived type variables in SDBG?

Code:
type cell
  real, allocatable, dimension (:) :: var
end type cell
type (cell) species(0:3)


do i=0,3
  n = i + 1
  if(allocated(species(i)%var )) deallocate(species(i)%var)
  allocate (species(i)%var(n))

  species(i)%var = n
enddo

end
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Tue Apr 30, 2024 4:34 pm    Post subject: Reply with quote

Double click on SPECIES in the Variables window.
Then double click on SPECIES(0):TYPE(CELL) in the SPECIES window.
Then double click on var: REAL*4 POINTER ::(1) in the SEPCIES(0) window.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2867
Location: South Pole, Antarctica

PostPosted: Thu May 02, 2024 12:50 pm    Post subject: Reply with quote

Thanks, i was initially confused with "Syntax error" messages and absence of bubble help (like with usual arrays) doing that and thought this option does not work at all
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2867
Location: South Pole, Antarctica

PostPosted: Fri May 03, 2024 12:34 am    Post subject: Reply with quote

10 years ago i tried to use derived types with 32bit FTN95 and failed. Crashes, access violations, irrational behavior....Now i need to allocate variable number of entries in the array (imagine some allocatable 2D array with variable number of elements of each row, every call different) and for that allocation of standard arrays does not work (Standard does not allows that by some reason, that does not work with other compilers too) and hence i need to use derived types again. Why derived types allow that functionality is beyond me.

And i am failing again by multiple reasons. Here is first one. Is anything wrong with this text? It is the same one as above which works, but this time the allocation takes place inside the function in the module not in the main program. It wrongfully tells that array is allocated and then it tries to deallocate it and fails. I compile FTN95 aaa.f95 /link /debug /undef /64 >zzz
Code:
module mod
type cell
  real, allocatable, dimension (:) :: var
end type cell
type (cell) species(0:3)

Contains

integer function fun1 ()
do i=0,3
  n = i + 1
  if ( allocated(species(i)%var )) deallocate(species(i)%var)
  allocate (species(i)%var(n))
  species(i)%var = n
enddo
fun1=2
end function fun1

end module
!==================
Program Prg
use mod
integer, external :: fun2

jj = fun1 ()
jj = fun2 ()

end program
!========================
integer function fun2 ()
use mod
  print*, species(0)%var(2)
fun2=2
end function fun2


Gfortran runs this no problem.

Another example for which i am still preparing a demo, allocates derived type array multiple times and does not ends up with the error despite i do not deallocate this array. But then i change array dimension and it crashes
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


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

PostPosted: Fri May 03, 2024 9:10 am    Post subject: Reply with quote

species(0)%v is allocated just one element species(0)%v(1) so when it comes to the print, species(0)%var(2) is out of range.

species(0:3) should be initialised before testing for ALLOCATED. For example FTN95 allows...

do i = 0,3
nullify(species(i)%var)
end do

but off hand I don't know the "right" way to do this.
Back to top
View user's profile Send private message AIM Address
DanRRight



Joined: 10 Mar 2008
Posts: 2867
Location: South Pole, Antarctica

PostPosted: Fri May 03, 2024 2:14 pm    Post subject: Reply with quote

Looks like nullify could be that missing piece in the puzzle...Thanks Paul
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1897

PostPosted: Fri May 03, 2024 2:56 pm    Post subject: Reply with quote

Dan, your program is almost working. All that you have to do is to make sure that subscript bounds are honored, or, equivalently, allocate arrays with sufficient size.

Here is a fixed-up version:
Code:
module mod
type cell
  real, allocatable, dimension (:) :: var
end type cell
type (cell) species(0:3)

Contains

integer function fun1 ()
do i=0,3
  n = i + 1
  if ( allocated(species(i)%var )) deallocate(species(i)%var)
  allocate (species(i)%var(n))
  print *,'species(',i,') allocated with size ',n
  species(i)%var = n
enddo
fun1=2
end function fun1

end module
!==================
Program Prg
use mod
integer, external :: fun2

jj = fun1 ()
jj = fun2 ()

end program
!========================
integer function fun2 ()
use mod
integer i
  do i = 0,3
     print*, species(i)%var(i+1)
  end do
  fun2=2
end function fun2
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2587
Location: Sydney

PostPosted: Sat May 04, 2024 6:13 am    Post subject: Reply with quote

I suggest that an enhanced version of the derived type might be more functional, as in the example below
Code:
module mod
type cell
  integer :: n = 0
  real, allocatable, dimension (:) :: var
end type cell
type (cell) species(0:3)

Contains

integer function fun1 ()
do i=0,3
  n = i + 1
  if ( allocated(species(i)%var )) deallocate(species(i)%var)
  allocate (species(i)%var(n))
  print *,'species(',i,') allocated with size ',n
  species(i)%n = n
  species(i)%var = atan (1.0) * n
end do
fun1=2
end function fun1

end module
!==================
Program Prg
use mod
integer, external :: fun2

jj = fun2 ()
jj = fun1 ()
jj = fun2 ()

end program
!========================
integer function fun2 ()
use mod
integer i
  do i = 0,3
     n = species(i)%n
     if ( n > 0) then
       print*, i, n, species(i)%var(n)
     else
       print*, i, n
     end if
  end do
  fun2=2
end function fun2
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2867
Location: South Pole, Antarctica

PostPosted: Sat May 04, 2024 8:50 pm    Post subject: Reply with quote

Let me ask all of you what compiler version do you use because not a single variant mentioned above works with latest version and switches /check or /undef. Some work with latest 9.02 if use nullify. But if i add nullify the variant conflicts with gfortran complaining that this is not a pointer. Without /debug and check the ones above work but what the point to use compiler without major checks ?

Another point is that unfortunately these 2D variants were not the ones which are needed to me. They were oversimplified and what actually needed is 3D or 4D or even more dimensional variants so the derived types will have 3-4 variables with 3-4 dimensions look like this

var1(idim1)%var2(idim2)%var3(idim3,idim4)

And here i fail completely...Both on FTN95 and Gfortran. Even without /debug /check

Hence because the problem could not be compiler-related i have to explain in detail where and how exactly i plan to use derived types. May be i am doing everything wrong from the start.

This is to model relativistic plasma but i will better explain that on similar example from real life. Suppose we investigate 4 species of fish. We divided aquarium on 100 levels of depth installed sensors in each level. On each fish we placed chip which controls them on 12 parameters. And we know exactly how many fish of each species is in each level of aquarium. So

dimension idim1 - idim1 = 4 species of fish
dimension idim2 - Aquarium divided on idim2 levels of depth
dimension idim3 - each fish is tracked by idim3=12 parameters (their temperature, oxygen content in blood, CO2 content etc)
dimension idim4 - tells how many fish of each species is currently in each level of aquarium

When allocating arrays we need to deallocate all the data for each fish, allocate array again based on recent data obtained from the sensors and load this new data. Below we deallocate first, then allocate the data and test if we see on the water surface at least one fish (print) Smile

Code:
!2D sometimes works:                        ftn95 aaa.f95 /64 /link /debug  >z
!2D does not work without nullify:          ftn95 aaa.f95 /64 /link /debug /undef /check  >z
!3D below does not work even with this:     ftn95 aaa.f95 /64 /link /debug  >z
!
!               var1(idim1)%var2(idim2)%var3(idim3,idim4)
!
!
module mod

type v3
  real,  allocatable, dimension(:,:) :: var3  ! idim3 and idim4. This  for just one level of aquarium, controls each fish by 12 parameters
end type v3

type v2
  type(v3), allocatable, dimension (:) :: var2 ! idim2 array contains variable  number of depth of aquarium
end type v2

type (v2) var1(0:3)  ! 4 types of fish will be controlled but generally could be arbitrary

Contains

integer function fun1 ()
do idim1 = 0, 3
   idim2 = 100 
   idim3 = 12
   CALL RANDOM_NUMBER(rand4)
   idim4 = rand4 *1000 + 1

    if ( allocated ( var1(idim1)%var2(idim2)%var3 )) deallocate ( var1(idim1)%var2(idim2)%var3 )
    allocate ( var1(idim1)%var2(idim2)%var3(idim3,idim4) )

    print *,'var1(',idim1,') var2(',idim2,') var3 (', idim3,'x',idim4,')'
    var1(idim1)%var2(1)%var3(1,1) = idim4
 
enddo 
fun1=2

end function fun1

end module mod
!=========================
Program Prg
use mod
integer, external :: fun2

jj = fun1 ()
jj = fun2 ()

        end program
!========================
integer function fun2 ()
use mod
  print*, var1(0)%var2(1)%var3(1,1) ! checking just one fish on the surface
fun2=2
end function fun2


Last edited by DanRRight on Sat May 04, 2024 11:04 pm; edited 1 time in total
Back to top
View user's profile Send private message
mecej4



Joined: 31 Oct 2006
Posts: 1897

PostPosted: Sat May 04, 2024 10:52 pm    Post subject: Reply with quote

Dan, I used 9.02 without /check or /undef.

FTN95 gives, if I am not mistaken, an incorrect warning:
Code:

WARNING S:\LANG\dan.F90 12:  MOD!SPECIES is not ALLOCATABLE yet is used in an ALLOCATED test
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2587
Location: Sydney

PostPosted: Sun May 05, 2024 7:58 am    Post subject: Reply with quote

To previously test the program, I used PLATO (which was set to Gfortran !)

Now with /64 it crashes, but works with 32-bit

Code:
[FTN95/Win32 Ver. 9.00.0 Copyright (c) Silverfrost Ltd 1993-2023]

[Current options] DEBUG;ERROR_NUMBERS;IMPLICIT_NONE;INTL;LINK;LOGL;

    PROCESSING MODULE  [<MOD> FTN95/Win32 v9.00.0]
0004)   real, allocatable, dimension (:) :: var
WARNING - 1239: ALLOCATABLE components of a derived TYPE are not auotmatically
    deallocated on RETURN from a subprogram
0014)   if ( allocated(species(i)%var )) deallocate (species(i)%var)
WARNING - 1179: MOD!SPECIES is not ALLOCATABLE yet is used in an ALLOCATED
    test
        NO ERRORS, 2 WARNINGS  [<FUN1> FTN95 v9.00.0]
    NO ERRORS  [<MOD> FTN95 v9.00.0]
0031)    integer :: jj
WARNING - 242: Variable JJ has been given a value but never used
    NO ERRORS, 1 WARNING  [<PRG> FTN95 v9.00.0]
    NO ERRORS  [<FUN2> FTN95 v9.00.0]
Creating executable: prg.EXE
 Vern : FTN95 v9.00
 Opts : DEBUG;ECHO_OPTIONS;ERROR_NUMBERS;IMPLICIT_NONE;INTL;LINK;LOGL;
            0           0
            1           0
            2           0
            3           0
 species(           0) allocated with size            1
 species(           1) allocated with size            2
 species(           2) allocated with size            3
 species(           3) allocated with size            4
            0           1    0.785398   
            1           2     1.57080   
            2           3     2.35619   
            3           4     3.14159   

[FTN95/x64 Ver. 9.00.0 Copyright (c) Silverfrost Ltd 1993-2023]

[Current options] 64;DEBUG;ERROR_NUMBERS;IMPLICIT_NONE;INTL;LINK;LOGL;

    PROCESSING MODULE  [<MOD> FTN95/x64 v9.00.0]
0004)   real, allocatable, dimension (:) :: var
WARNING - 1239: ALLOCATABLE components of a derived TYPE are not auotmatically
    deallocated on RETURN from a subprogram
0014)   if ( allocated(species(i)%var )) deallocate (species(i)%var)
WARNING - 1179: MOD!SPECIES is not ALLOCATABLE yet is used in an ALLOCATED
    test
        NO ERRORS, 2 WARNINGS  [<FUN1> FTN95 v9.00.0]
    NO ERRORS  [<MOD> FTN95 v9.00.0]
0031)    integer :: jj
WARNING - 242: Variable JJ has been given a value but never used
    NO ERRORS, 1 WARNING  [<PRG> FTN95 v9.00.0]
    NO ERRORS  [<FUN2> FTN95 v9.00.0]
[SLINK64 v3.10, Copyright (c) Silverfrost Ltd. 2015-2023]
Loading C:\forum\mecej4\lgotemp@.obj
Creating executable file prg.exe
 Vern : FTN95 v9.00
 Opts : 64;DEBUG;ECHO_OPTIONS;ERROR_NUMBERS;IMPLICIT_NONE;INTL;LINK;LOGL;
            0           0
            1           0
            2           0
            3           0

( program crashes )

[FTN95/Win32 Ver. 9.00.0 Copyright (c) Silverfrost Ltd 1993-2023]

[Current options] DEBUG;ERROR_NUMBERS;IMPLICIT_NONE;INTL;LINK;LOGL;

(  this test continues to work with /32 /debug )
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2867
Location: South Pole, Antarctica

PostPosted: Sun May 05, 2024 3:29 pm    Post subject: Reply with quote

So do you find any problems in my setup of a bit more complex 4D derived type in previous post? It does not work at all

The reason why I use derived type is that it is impossible to allocate just one dimension of standard array of arbitrary size independent of other dimensions. Before i collected all data in the standard classical array like this

array (idim3,idim4,idim2,idim1)

where as i noted above idim1 was for 4 our different types of "fish" - gold fish, shark, whale and say crab (where last two are not exactly a "fish"). If number of fish of different types is very different (say, we track just one single piece of whale which is rare in the nature) then storing this way becomes inefficient because we allocate for whale same amount of storage as for other fish. Even more inefficient becomes storage when you realize that fish may gather just in some preferable layers of aquarium. If crab gather only on the bottom of it - we need to allocate huge number for idim4 (maximum allowed number of fish for specific layer) and keep that for all other layers and all kinds of fish because allocation of different idim4 for different layers (idim2) and different kinds of fish (idim1) is not allowed - all have to have the same idim4.

As a result if you control 1 billion of fish (particles - electrons, photons, ions and all sorts of compounds) with 12 parameters 4 bytes each you formally need not more than only 12e9*4 = 48 GB of RAM while with array like above you'll need sometimes a Terabyte size of mostly empty sparce array !!!


Last edited by DanRRight on Mon May 20, 2024 9:18 am; edited 1 time in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2587
Location: Sydney

PostPosted: Sun May 19, 2024 2:36 am    Post subject: Re: Reply with quote

DanRRight wrote:

if ( allocated ( var1(idim1)%var2(idim2)%var3 )) deallocate ( var1(idim1)%var2(idim2)%var3 )
allocate ( var1(idim1)%var2(idim2)%var3(idim3,idim4) )

Dan,
I was reviewing this post.
Where is var1(k)%var2(idim2) allocated ?
I think your allocate only allocates var3(idim3,idim4)

You need to go through the tree allocating all var2, then all var3 arrays
I think the following works on Ver 9.00.0
Code:
!2D sometimes works:                        ftn95 aaa.f95 /64 /link /debug  >z
!2D does not work without nullify:          ftn95 aaa.f95 /64 /link /debug /undef /check  >z
!3D below does not work even with this:     ftn95 aaa.f95 /64 /link /debug  >z
!
!               var1(idim1)%var2(idim2)%var3(idim3,idim4)
!
!
module modv3
  integer   :: idim1,idim2,idim3,idim4
  integer*8 :: bytes = 0
  type v3
    integer :: n
    real,  allocatable, dimension(:,:) :: var3  ! idim3 and idim4. This  for just one level of aquarium, controls each fish by 12 parameters
  end type v3

  type v2
    integer :: m
    type(v3), allocatable, dimension (:) :: var2 ! idim2 array contains variable  number of depth of aquarium
  end type v2

  type (v2) var1(0:3)  ! 4 types of fish will be controlled but generally could be arbitrary

Contains

integer function fun1 ()
  real    :: rand4
  integer :: k

  bytes = 0
  do idim1 = 0, 3
     idim2 = 100 + idim1*3
     idim3 = 12
     var1(idim1)%m = idim2
     allocate ( var1(idim1)%var2(idim2) )
     bytes = bytes + idim2*4

    do k = 1,idim2
     
      CALL RANDOM_NUMBER(rand4)
      idim4 = rand4 * 1000. + 1
 
      if ( allocated ( var1(idim1)%var2(k)%var3 )) deallocate ( var1(idim1)%var2(k)%var3 )
      allocate ( var1(idim1)%var2(k)%var3(idim3,idim4) )
 
      write (*,11) 'var1( ',idim1,' )% var2( ',k,' )% var3 (', idim3,' x ',idim4,' )'
   11 format ( a,i0,a,i0,a,i0,a,i0,a)

      var1(idim1)%var2(k)%var3(1,1) = idim4
      var1(idim1)%var2(k)%n         = idim4
      bytes = bytes + 4 + idim3*idim4*4
    end do
  end do
  fun1=2

end function fun1

end module modv3
!=========================
Program Prg
  use modv3
    integer, external :: fun2
    integer :: jj

    jj = fun1 ()
    jj = fun2 ()

    write (*,*) "??"
    read (*,*) jj
end program
!========================
integer function fun2 ()
  use modv3
  integer :: j,k

  do j = 0,3
    idim2 = var1(j)%m
    do k = 1,idim2,4

      print*, var1(j)%m, j,k, var1(j)%var2(k)%n, var1(j)%var2(k)%var3(1,1) ! checking just one fish on the surface
    end do
  end do

  write (*,*) bytes,' bytes allocated'

  fun2=2
end function fun2


I'm not sure how much storage this requires ? (there is overhead for each allocatable components)


Last edited by JohnCampbell on Sun May 19, 2024 4:58 am; edited 1 time in total
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2587
Location: Sydney

PostPosted: Sun May 19, 2024 4:30 am    Post subject: Reply with quote

Dan,

I have not used multi-level derrived types with allocatable components before.
It certainly gives versatility of the data structure.

The de-allocate code in the example above is very under-done !
If you have allocatable components that need to be de-allocated then all their allocatable components must also be specifically deallocated first.

I left off the test
if ( allocated ( var1(idim1)%var2 ) ) ...
The required code would have to deallocate any %var3 allocated to %var2
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2587
Location: Sydney

PostPosted: Sun May 19, 2024 5:39 am    Post subject: Reply with quote

I have expanded to a smaller example to show deallocate of allocatable components, which appears to work.

Code:
!  ftn95 /64 /debug /link
!
!               var1(idim1)%var2(idim2)%var3(idim3,idim4)
!
!
module modv3
  integer   :: idim1,idim2,idim3,idim4
  integer*8 :: bytes = 0

  type v2
    integer :: n
    real,  allocatable, dimension(:,:) :: var3
  end type v2

  type v1
    integer :: m
    type(v2), allocatable, dimension (:) :: var2
  end type v1

  type (v1) var1(0:3)  ! 4 types of fish

Contains

  integer function fun1 ()
   real    :: rand4
   integer :: k

    write (*,10)
 10 format (/' regenerating data structure')
    bytes = 0
    do idim1 = 0, 3
       idim2 = 10 + idim1*3  ! was 100
       idim3 = 12
       if ( allocated ( var1(idim1)%var2 )) call deallocate_var2 ( idim1 )
       var1(idim1)%m = idim2
       allocate ( var1(idim1)%var2(idim2) )
       bytes = bytes + idim2*4

      do k = 1,idim2
       
        CALL RANDOM_NUMBER(rand4)
        idim4 = rand4 * 1000. + 1

        if ( allocated ( var1(idim1)%var2(k)%var3 )) then
          deallocate ( var1(idim1)%var2(k)%var3 )
          write (*,*) 'unexpected deallocate var1(idim1)%var2(k)%var3'
        end if
        allocate ( var1(idim1)%var2(k)%var3(idim3,idim4) )

        write (*,11) 'var1( ',idim1,' )% var2( ',k,' )% var3 (', idim3,' x ',idim4,' )'
     11 format ( a,i0,a,i0,a,i0,a,i0,a)

        var1(idim1)%var2(k)%n         = idim4
        var1(idim1)%var2(k)%var3(1,1) = idim4
        bytes = bytes + 4 + idim3*idim4*4
      end do
    end do

    fun1=2
  end function fun1

  subroutine deallocate_var2 ( j )
   integer :: j,lj,k, nd

    if ( allocated ( var1(j)%var2 ) ) then
      nd = 0
      lj = var1(j)%m
      do k = 1,lj
        if ( .not. allocated ( var1(j)%var2(k)%var3 )) cycle
        deallocate ( var1(j)%var2(k)%var3 )
        nd = nd+1
      end do
      deallocate ( var1(j)%var2 )
      nd = nd+1
      write (*,fmt='(a,i0,a,i0,a,i0)') '( var1( ',j,' )%var2( ',lj,' ) DEALLOCATED ',nd
    end if
  end subroutine deallocate_var2

end module modv3
!=========================
Program Prg
  use modv3
    integer, external :: fun2
    integer :: jj

    jj = fun1 ()
    jj = fun1 ()
    jj = fun2 ()

    write (*,*) "??"
    read (*,*) jj
end program
!========================
integer function fun2 ()
  use modv3
  integer :: j,lj,k

    do j = 0,3
      lj = var1(j)%m
      do k = 1,lj,4
        print*, var1(j)%m, j,k, var1(j)%var2(k)%n, var1(j)%var2(k)%var3(1,1) ! checking just one fish on the surface
      end do
    end do

    write (*,11) bytes,' bytes allocated'
 11 format (B'zzz,zzz,zzz,zz#',a)

    fun2=2
end function fun2

Paul, the following warning appears false.
[FTN95/x64 Ver. 9.00.0 Copyright (c) Silverfrost Ltd 1993-2023]
0036) if ( allocated ( var1(idim1)%var2 )) call deallocate_var2 ( idim1 )
WARNING - 1179: MODV3!VAR1 is not ALLOCATABLE yet is used in an ALLOCATED test
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> 64-bit 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