• Applications of the storage_size function?

    From Beliavsky@21:1/5 to All on Wed Feb 16 06:09:02 2022
    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say

    storage_size (a [, kind ] ) returns the size, in bits, that would be taken in memory by an array element with the dynamic type and type parameters (Section 15.3.2) of a.
    The argument a may be of any type or rank (including a scalar). It is permitted to be an undefined pointer unless it is polymorphic, and is permitted to be a disassociated pointer or unallocated allocatable unless it has a deferred type parameter or is
    unlimited polymorphic. The return type is integer with the specified kind, or default kind if kind is not present.

    I wrote a small program to demonstrate its use at https://github.com/Beliavsky/FortranTip/blob/main/storage_size.f90 , also pasted below. Why was the storage_size function added, and what are its practical applications?

    program test_storage_size
    ! test the storage_size function of Fortran 2008
    use iso_fortran_env, only: int64
    implicit none
    intrinsic :: storage_size
    type :: date_ymd
    integer :: year, month, day
    end type date_ymd
    integer, parameter :: dp = kind(1.0d0)
    logical :: tf
    character(len=1) :: s
    character(len=10) :: string
    integer :: i
    integer(kind=int64) :: i64
    real :: x
    real(kind=dp) :: x_dp
    real(kind=dp), dimension(3) :: xvec_dp
    complex :: z
    type(date_ymd) :: date
    write (*,"(a30,a15)") "entity","storage_size"
    write (*,"(a30,i15)") "integer",storage_size(i), &
    "int64",storage_size(i64),"real",storage_size(x), &
    "real(kind=dp)",storage_size(x_dp), &
    "real(kind=dp), dimension(3)",storage_size(xvec_dp), &
    "complex",storage_size(z), &
    "logical",storage_size(tf), &
    "character(len=1)",storage_size(s), &
    "character(len=10)",storage_size(string), &
    "date_ymd",storage_size(date)
    end program test_storage_size
    ! Output:
    ! entity storage_size
    ! integer 32
    ! int64 64
    ! real 32
    ! real(kind=dp) 64
    ! real(kind=dp), dimension(3) 64
    ! complex 64
    ! logical 32
    ! character(len=1) 8
    ! character(len=10) 80
    ! date_ymd 96

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Klimowicz@21:1/5 to Beliavsky on Wed Feb 16 08:10:21 2022
    Beliavsky <beliavsky@aol.com> writes:

    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say

    ... Why was the storage_size function added, and what are its practical applications?

    Near as I can tell digging through the old J3 Fortran papers, it was
    introduced in paper 04-120.txt at meeting 167 (link https://j3-fortran.org/doc/year/04/04-120.txt).

    There are a number of other papers where storage_size is refined or
    mentioned. bu I did not dig deeply into them.

    Here is the text of the 04-120.txt rationale:
    Rationale: Storage size in bits is a low level concept which ordinarily
    I would prefer to leave unspecified in standard Fortran. However,
    there are programmers who need to write extremely portable programs
    that depend on the exact sizes of data items. F03
    already specifies that a programmer has access to the sizes
    of the standard-specified storage units. This proposal
    extends the programmer's access to size information
    to the case of derived types and intrinsic types not required
    to be supported (a seconmd integer kind or a third real kind,
    for example).

    Following the arguments made for the storage size constants
    in ISO_FORTRAN_ENV, the size is specified in bits to enable
    detection of unusual hardware or of unusual software conventions.

    STORAGE_SIZE results should be available during compilation
    to enable array extents to be declared, etc.

    STORAGE_SIZE should reside in ISO_FORTRAN_ENV because that's
    where the constants are, and it seems to be
    an environment-oriented inquiry.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Gary Scott@21:1/5 to Beliavsky on Wed Feb 16 11:14:45 2022
    On 2/16/2022 10:41 AM, Beliavsky wrote:
    On Wednesday, February 16, 2022 at 11:10:28 AM UTC-5, g...@pobox.com wrote:
    Beliavsky <beli...@aol.com> writes:

    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say >>>
    ... Why was the storage_size function added, and what are its practical applications?

    Near as I can tell digging through the old J3 Fortran papers, it was
    introduced in paper 04-120.txt at meeting 167 (link
    https://j3-fortran.org/doc/year/04/04-120.txt).

    There are a number of other papers where storage_size is refined or
    mentioned. bu I did not dig deeply into them.

    Here is the text of the 04-120.txt rationale:
    Rationale: Storage size in bits is a low level concept which ordinarily
    I would prefer to leave unspecified in standard Fortran. However,
    there are programmers who need to write extremely portable programs
    that depend on the exact sizes of data items. F03
    already specifies that a programmer has access to the sizes
    of the standard-specified storage units. This proposal
    extends the programmer's access to size information
    to the case of derived types and intrinsic types not required
    to be supported (a seconmd integer kind or a third real kind,
    for example).

    Following the arguments made for the storage size constants
    in ISO_FORTRAN_ENV, the size is specified in bits to enable
    detection of unusual hardware or of unusual software conventions.

    STORAGE_SIZE results should be available during compilation
    to enable array extents to be declared, etc.

    STORAGE_SIZE should reside in ISO_FORTRAN_ENV because that's
    where the constants are, and it seems to be
    an environment-oriented inquiry.

    Helpful, thanks. Maybe storage_size is useful when calling C? I'm
    aware of the ISO_C_BINDING module.
    Its useful for any number of bit manipulation tasks that you want to
    make semi-portable.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Beliavsky@21:1/5 to g...@pobox.com on Wed Feb 16 08:41:45 2022
    On Wednesday, February 16, 2022 at 11:10:28 AM UTC-5, g...@pobox.com wrote:
    Beliavsky <beli...@aol.com> writes:

    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say

    ... Why was the storage_size function added, and what are its practical applications?

    Near as I can tell digging through the old J3 Fortran papers, it was introduced in paper 04-120.txt at meeting 167 (link https://j3-fortran.org/doc/year/04/04-120.txt).

    There are a number of other papers where storage_size is refined or mentioned. bu I did not dig deeply into them.

    Here is the text of the 04-120.txt rationale:
    Rationale: Storage size in bits is a low level concept which ordinarily
    I would prefer to leave unspecified in standard Fortran. However,
    there are programmers who need to write extremely portable programs
    that depend on the exact sizes of data items. F03
    already specifies that a programmer has access to the sizes
    of the standard-specified storage units. This proposal
    extends the programmer's access to size information
    to the case of derived types and intrinsic types not required
    to be supported (a seconmd integer kind or a third real kind,
    for example).

    Following the arguments made for the storage size constants
    in ISO_FORTRAN_ENV, the size is specified in bits to enable
    detection of unusual hardware or of unusual software conventions.

    STORAGE_SIZE results should be available during compilation
    to enable array extents to be declared, etc.

    STORAGE_SIZE should reside in ISO_FORTRAN_ENV because that's
    where the constants are, and it seems to be
    an environment-oriented inquiry.

    Helpful, thanks. Maybe storage_size is useful when calling C? I'm
    aware of the ISO_C_BINDING module.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From David Duffy@21:1/5 to Gary Scott on Thu Feb 17 02:48:09 2022
    Gary Scott <garylscott@sbcglobal.net> wrote:
    On 2/16/2022 10:41 AM, Beliavsky wrote:
    On Wednesday, February 16, 2022 at 11:10:28 AM UTC-5, g...@pobox.com wrote: >>> Beliavsky <beli...@aol.com> writes:

    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say >>>>
    ... Why was the storage_size function added, and what are its practical applications?

    Helpful, thanks. Maybe storage_size is useful when calling C? I'm
    aware of the ISO_C_BINDING module.
    Its useful for any number of bit manipulation tasks that you want to
    make semi-portable.

    I find it very useful just to output to the user how much memory that
    last successful big matrix allocation used up (esp in the case of a
    later crash).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JCampbell@21:1/5 to Beliavsky on Sat Feb 19 23:55:29 2022
    On Thursday, February 17, 2022 at 1:09:05 AM UTC+11, Beliavsky wrote:
    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say

    storage_size (a [, kind ] ) returns the size, in bits, that would be taken in memory by an array element with the dynamic type and type parameters (Section 15.3.2) of a.
    The argument a may be of any type or rank (including a scalar). It is permitted to be an undefined pointer unless it is polymorphic, and is permitted to be a disassociated pointer or unallocated allocatable unless it has a deferred type parameter or is
    unlimited polymorphic. The return type is integer with the specified kind, or default kind if kind is not present.

    I have struggled with the use of STORAGE_SIZE, especially when trying to document the storage size of a derived type that contains allocatable array components, especially when trying to report the size of an array of the derived type. It can be
    difficult to identify the actual memory storage/usage of this structure, which would be preferred in bytes. SIZE and SIZE_OF are also available but exclude derived type data structures.

    This problem arose when trying to document the memory usage growth of an Allocatable derived type array where each derived type included 1d and 2d allocatable arrays.
    Allocatable components also store their allocated status and size.
    As David Duffy identified, "esp in the case of a later crash"

    eg Documenting the memory usage of structure "element_array_records" as it grows (and may need to be extended)
    module ELEM_DATA_BASE
    TYPE elem_data_record
    ...
    TYPE elem_array_record ! set in elcomp
    integer*4, allocatable :: ln(:) ! (ni) element parameters
    integer*4, allocatable :: lm(:) ! (nd) element equation map
    real*8, allocatable :: sd(:) ! S(nd,nd) !symmetric stiffness matrix sd( nt )
    real*8, allocatable :: xm(:) ! (nd) element mass matrix
    real*8, allocatable :: st(:,:) ! (ns,nd) element stress matrix
    real*8, allocatable :: P(:,:) ! (nd,ilg) element load group matrix
    real*8, allocatable :: tt(:,:) ! (ns,ilg) element stress correction matrix
    !
    END TYPE elem_array_record
    !
    type (elem_array_record), allocatable :: elem_array_records(:) ! (max_elem_records)
    !
    end module ELEM_DATA_BASE

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to JCampbell on Sun Feb 20 08:46:11 2022
    JCampbell <campbelljohnd01@gmail.com> schrieb:
    On Thursday, February 17, 2022 at 1:09:05 AM UTC+11, Beliavsky wrote:
    Fortran 2008 introduced the storage_size function. Metcalf/Reid/Cohen say

    storage_size (a [, kind ] ) returns the size, in bits, that would be taken in memory by an array element with the dynamic type and type parameters (Section 15.3.2) of a.
    The argument a may be of any type or rank (including a scalar). It is permitted to be an undefined pointer unless it is polymorphic, and is permitted to be a disassociated pointer or unallocated allocatable unless it has a deferred type parameter or
    is unlimited polymorphic. The return type is integer with the specified kind, or default kind if kind is not present.

    I have struggled with the use of STORAGE_SIZE, especially when
    trying to document the storage size of a derived type that contains allocatable array components, especially when trying to report
    the size of an array of the derived type. It can be difficult to
    identify the actual memory storage/usage of this structure, which
    would be preferred in bytes. SIZE and SIZE_OF are also available
    but exclude derived type data structures.

    This problem arose when trying to document the memory usage
    growth of an Allocatable derived type array where each derived
    type included 1d and 2d allocatable arrays.


    Allocatable components also store their allocated status and size.
    As David Duffy identified, "esp in the case of a later crash"

    eg Documenting the memory usage of structure
    "element_array_records" as it grows (and may need to be extended)

    module ELEM_DATA_BASE
    TYPE elem_data_record
    ...
    TYPE elem_array_record ! set in elcomp
    integer*4, allocatable :: ln(:) ! (ni) element parameters

    [...]

    What about something like

    program main
    implicit none
    integer, parameter :: ip = selected_int_kind(15)
    type foo
    real, dimension(:), allocatable :: a
    real, dimension(:,:), allocatable :: b
    end type foo
    type(foo), allocatable, dimension(:) :: x
    allocate (x(2))
    allocate (x(1)%a(1234))
    print *,foo_size(x)
    contains
    integer(kind=ip) function foo_size(arr) result(res)
    type(foo), dimension(:), intent(in) :: arr
    integer(kind=ip) :: sz
    integer(kind=ip) :: i
    sz = size(arr)
    res = sz * storage_size(arr)
    do i=1,sz
    if (allocated(arr(i)%a)) &
    res = res + storage_size(arr(i)%a(1)) * size(arr(i)%a)
    if (allocated(arr(i)%b)) &
    res = res + storage_size(arr(i)%b(1,1)) * size(arr(i)%a)
    end do
    end function foo_size
    end program main

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Thomas Koenig@21:1/5 to Thomas Koenig on Sun Feb 20 08:48:36 2022
    Thomas Koenig <tkoenig@netcologne.de> schrieb:

    What about something like

    program main
    implicit none
    integer, parameter :: ip = selected_int_kind(15)
    type foo
    real, dimension(:), allocatable :: a
    real, dimension(:,:), allocatable :: b
    end type foo
    type(foo), allocatable, dimension(:) :: x
    allocate (x(2))
    allocate (x(1)%a(1234))
    print *,foo_size(x)
    contains
    integer(kind=ip) function foo_size(arr) result(res)
    type(foo), dimension(:), intent(in) :: arr
    integer(kind=ip) :: sz
    integer(kind=ip) :: i
    sz = size(arr)
    res = sz * storage_size(arr)
    do i=1,sz
    if (allocated(arr(i)%a)) &
    res = res + storage_size(arr(i)%a(1)) * size(arr(i)%a)
    if (allocated(arr(i)%b)) &
    res = res + storage_size(arr(i)%b(1,1)) * size(arr(i)%a)
    ^^^^^^^

    which should be size(arr(i)%b), of course.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From JCampbell@21:1/5 to Thomas Koenig on Sun Feb 20 05:14:06 2022
    On Sunday, February 20, 2022 at 7:48:39 PM UTC+11, Thomas Koenig wrote:
    Thomas Koenig <tko...@netcologne.de> schrieb:
    What about something like

    Two points:
    1) It would be good if SIZE(x), SIZE_OF(x) or STORAGE_SIZE (x) could at least report FOO_SIZE (x), ie accept derived types as an argument, and
    2) I would like to "identify the actual memory storage/usage of this structure".
    Could STORAGE_SIZE (x) be adapted to this to report the full usage ?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)