|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
DanRRight
Joined: 10 Mar 2008 Posts: 2867 Location: South Pole, Antarctica
|
Posted: Tue Apr 30, 2024 3:14 pm Post subject: SDBG64 with derived types |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8019 Location: Salford, UK
|
Posted: Tue Apr 30, 2024 4:34 pm Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2867 Location: South Pole, Antarctica
|
Posted: Thu May 02, 2024 12:50 pm Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2867 Location: South Pole, Antarctica
|
Posted: Fri May 03, 2024 12:34 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8019 Location: Salford, UK
|
Posted: Fri May 03, 2024 9:10 am Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2867 Location: South Pole, Antarctica
|
Posted: Fri May 03, 2024 2:14 pm Post subject: |
|
|
Looks like nullify could be that missing piece in the puzzle...Thanks Paul |
|
Back to top |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Fri May 03, 2024 2:56 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2587 Location: Sydney
|
Posted: Sat May 04, 2024 6:13 am Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2867 Location: South Pole, Antarctica
|
Posted: Sat May 04, 2024 8:50 pm Post subject: |
|
|
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)
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 |
|
|
mecej4
Joined: 31 Oct 2006 Posts: 1897
|
Posted: Sat May 04, 2024 10:52 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2587 Location: Sydney
|
Posted: Sun May 05, 2024 7:58 am Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2867 Location: South Pole, Antarctica
|
Posted: Sun May 05, 2024 3:29 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2587 Location: Sydney
|
Posted: Sun May 19, 2024 2:36 am Post subject: Re: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2587 Location: Sydney
|
Posted: Sun May 19, 2024 4:30 am Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2587 Location: Sydney
|
Posted: Sun May 19, 2024 5:39 am Post subject: |
|
|
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 |
|
|
|
|
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
|