|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
Kenneth_Smith
Joined: 18 May 2012 Posts: 711 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Apr 28, 2023 12:29 am Post subject: Allocate on assignment + CHARACTER variables + TRANSFER |
|
|
I think there is an issue with the new Fortran 2003 Allocate on assignment for CHARACTER variables, when the array is defined by the result of the TRANSFER intrinsic.
Having never used TRANSFER before this evening it's definitely not a critical issue of me. Just experimenting after getting a little bit further into one of the (now old) text books by Metcalf and Reid.
Code: | program t
implicit none
character(len=1), allocatable :: info(:)
integer :: lengthData
real :: r = 5.0
real :: x = -999.0
!
! This works in FTN95
!
info=['A','B','C'] ! Allocate on assignment works in this case
print*, 'Info = ', info
deallocate(info)
print*
! Now use TRANSFER intrinsic
print*, 'Value of R is ', r ! 1. Print value of R
lengthData = size(transfer(r, info)) ! 2. Find size of required character array
allocate(info(lengthData)) ! 3. Allocate array
info = transfer(r, info) ! 4. Do transfer R to array
print*, 'Size of array ',size(info) ! 5. Print size of array
print*, 'Info string is ',info ! 6. Print array
x = transfer(info,r) ! 7. Do transfer array to X
print*, 'Value of X is ', x ! 8. Print value of X
deallocate(info)
print*
!
! This alternative fails in FTN95 where steps 2, 3 and 4 are done
! in a single line of code
!
x = -999.0
print*, 'Value of R is ', r ! 1. Print value of R
info = transfer(r,info) ! Access violation occurs here ###
print*, 'Size of array ',size(info) ! 5. Print size of array
print*, 'Info string is ',info ! 6. Print array
x = transfer(info,r) ! 7. Do transfer array to X
print*, 'Value of X is ', x ! 8. Print value of X
deallocate(info)
end program t |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8016 Location: Salford, UK
|
Posted: Fri Apr 28, 2023 7:51 am Post subject: |
|
|
Ken
Thanks for the feedback.
This sample code does not produce sensible results when compiled with gFortran or iFort so I am guessing that there is something wrong with it.
I am not that familiar with the TRANSFER function and at first sight I don't understand what is intended. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 711 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Apr 28, 2023 11:46 am Post subject: |
|
|
Thanks Paul,
I have set myself the task of investigating parts of the language which I never used before, and I may be going a bit of course here.
The code should be equivalent to the single line X=R, which is achieved in the first part of the example with FTN95. Basically R is TRANSFERed to the character array INFO, and then TRANSFERed from INFO to X.
The printed output for INFO is meaningless. I cannot figure out how to print the bit pattern for the elements of INFO to the terminal, as in:
Code: | character(len=1) :: a(3) = ['A','B','C']
print'(3B8)', a(1), a(2), a(3)
end
|
Should this not return: 1000001 1000010 1000011 ?
Binary 1000001 = 65 in decimal, IACHAR('A') = 65
Perhaps the use of the B format code to characters is a recent addition to the language, or an extension in gFortran?
PS Sometime later I asked myself another "what happens if" question:
Code: | program p
integer, parameter :: sp = kind(1.0), dp=kind(1.d0)
real(sp) :: rs = 1.0
real(dp) :: rd = 1.d0
complex(sp) :: cs =cmplx(1.0,0.0)
complex(dp) :: cd =cmplx(1.d0,0.d0,kind=dp)
print'(A,B32)' , 'rs',rs
print'(A,B64)' , 'rd',rd
print'(A,2B32)', 'cs',cs
print'(A,2B64)', 'dc',cd
end program p |
This is valid in gFortran. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8016 Location: Salford, UK
|
Posted: Fri Apr 28, 2023 2:39 pm Post subject: |
|
|
Ken
When I see
lengthData = size(transfer(r, info))
I ask what is transfer(r, info)? r is REAL and contains the floating point representation of the single precision 5.0. The result has the same bit pattern as this but with the type changed to that of info. But then info is a 1-dimensional CHARACTER array of unknown length.
Is this meaningful and what its intended? |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 711 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Fri Apr 28, 2023 4:36 pm Post subject: |
|
|
Paul, firstly apologies for taking up your time.
TRANSFER (SOURCE, MOLD [, SIZE])
According to Metcalf:
� �. when SIZE is absent, the result is scalar if MOLD is scalar, and it is of rank one and size just sufficient to hold all of SOURCE if MOLD is array-valued.�
The draft Fortran 95 standard says:
�If MOLD is array valued and SIZE is absent, the result is array valued and of rank one. Its size is as small as possible such that its physical representation is not shorter than that of SOURCE�
I think these two extracts both have the same meaning, and imply that lengthData = size(transfer(r, info)) is a valid Fortran construction.
The form: lengthData = size(transfer(r, info)) also appears in this discussion of a generic linked list module implemented in Fortran 95:
https://jblevins.org/research/generic-list.pdf
In this case MOLD is integer, but the type of MOLD does not matter for the purpose of storing a collection of bits.
However, even with info defined as integer(kind=1), (which is probably more logical and fixes the problem printing the bit pattern), the allocate on assignment still fails.
Code: | program t2
implicit none
integer(kind=1), allocatable :: info(:)
integer :: lengthData,i
real :: r = 5.0
real :: x = -999.0
print*, 'Value of R is ', r ! 1. Print value of R
lengthData = size(transfer(r, info)) ! 2. Find size of required character array
allocate(info(lengthData)) ! 3. Allocate array
info = transfer(r, info) ! 4. Do transfer R to array
print*, 'Size of array ',size(info) ! 5. Print size of array
do i = 1, lengthData ! 6. Print array
print'(B8)', info(i)
end do
x = transfer(info,r) ! 7. Do transfer array to X
print*, 'Value of X is ', x ! 8. Print value of X
deallocate(info)
print*
print*, 'Value of R is ', r ! 1. Print value of R
info = transfer(r,info) ! 2, 3, 4
print*, 'Size of array ',size(info) ! 5. Print size of array
print*, 'Info string (bit pattern) is ' ! 6. Print array
do i = 1, size(info)
print'(B8)', info(i)
end do
x = transfer(info,r) ! 7. Do transfer array to X
print*, 'Value of X is ', x ! 8. Print value of X
deallocate(info)
end program t2 |
Enjoy the weekend and don�t worry about the TRANSFER intrinsic, the dearth of information google finds on this subject tells me its little used. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8016 Location: Salford, UK
|
Posted: Fri Apr 28, 2023 8:21 pm Post subject: |
|
|
Ken
I am beginning to understand what is expected. The C language has sizeof and Fortran 2008 has C_SIZEOF and this could provide a simpler approach. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8016 Location: Salford, UK
|
Posted: Sat Apr 29, 2023 7:56 am Post subject: |
|
|
Here is a sample that illustrates the concept...
Code: | program main
use iso_c_binding
integer,parameter::k=selected_int_kind(2)
integer(k),allocatable::info(:)
integer(k)::v
integer::r = 16+256+1024
isize = c_sizeof(r)/c_sizeof(v)
print*, k, isize
allocate(info(isize))
info = transfer(r, info)
write(*,"(z6)") r
print*, "=============="
do i=isize,1,-1
write(*, "(z6)") info(i)
end do
end program main |
On this basis it might be relatively easy to get FTN95 to do the "allocate on assignment" for the TRANSFER function. |
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 711 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Sun Apr 30, 2023 12:16 pm Post subject: |
|
|
Paul,
Thanks for the sample program, it took me some time to understand the code.
My main concern here was to highlight that the new feature i.e. allocate on assignment failed with TRANSFER.
As there is an easy alternative work around (find the required SIZE and ALLOCATE before TRANSFER), and the probability of another user finding this particular issue must be relatively low, perhaps this fix should be deferred to a low position on the wish list i.e. one for when available time/resources permit. In other words, nice to have but not a priority.
Enjoy what remains of the long bank holiday weekend. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8016 Location: Salford, UK
|
Posted: Tue May 30, 2023 2:06 pm Post subject: |
|
|
FTN95 has now been extended for the next release so that it will handle this "allocate on assignment" (AOA) for the TRANSFER intrinsic.
Note that, by default, FTN95 does not do AOA when the associated variable is explicitly ALLOCATEd (in the current subprogram) prior to the assignment.
This provides some protection against the impact of AOA on existing code.
So the explicit ALLOCATE in the above code will prevent the following AOA. |
|
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
|