|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Fri Jan 26, 2024 4:47 pm Post subject: |
|
|
Ken
It fails for me so I have added it to the list. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Fri Jan 26, 2024 6:39 pm Post subject: |
|
|
This runs correctly:
Code: | real, allocatable :: a(:)
integer n, i
n = 10
a = [ (real(i),i=1,n) ]
print*, allocated(a)
print*, a
end |
|
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Sat Jan 27, 2024 9:02 am Post subject: |
|
|
FTN95 has been fixed for the next release so that this will work...
Code: | real, allocatable :: a(:)
integer n, i
n = 10
a = [ (i,i=1,n) ]
print*, allocated(a)
end |
|
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 709 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Sat Jan 27, 2024 9:51 am Post subject: |
|
|
Thanks Paul, I think that will fix John's issue. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Sat Jan 27, 2024 2:17 pm Post subject: |
|
|
Thanks Paul for finding the source of the error. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Sun Jan 28, 2024 10:03 am Post subject: |
|
|
Expanding on my "Saturday devilry" and including a variant of Ken's suggestion of MOVE_ALLOC, the following code example does not compile with updated FTN95 Ver 9.00.
Code: | subroutine auto_alloc ( a, nn ) ! using auto-allocate
! extend vector A by nn using auto-allocate
real, allocatable, intent(inout) :: a(:)
integer, intent(in) :: nn
real, allocatable :: extra(:)
real, allocatable :: copy(:)
integer na
! allocate ( extra(nn) )
extra = [ (0.0, i=1,nn) ]
if ( allocated (a) ) then
na = size(a)
call move_alloc ( a, copy )
a = [ copy, extra ]
else
na = 0
a = extra
end if
write (*,fmt='(a,i0,a,i0)') 'Auto-Extend A from ',na,' to ',na+nn
end subroutine auto_alloc |
But using " a = [ a, extra ]" does compile.
Would the use of MOVE_ALLOC be a more conservative approach, when available ? |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Sun Jan 28, 2024 11:12 am Post subject: |
|
|
John
At the moment the FTN95 implementation of MOVE_ALLOC does not allow for this construction. Hopefully it can be fixed fairly soon. |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 8011 Location: Salford, UK
|
Posted: Tue Jan 30, 2024 4:54 pm Post subject: |
|
|
This failure with MOVE_ALLOC has now been fixed for the next release of FTN95. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Wed Jan 31, 2024 1:25 am Post subject: |
|
|
Thanks Paul and Ken for this thread.
The following are 3 alternatives for extending a vector size by nn, using either:
* FTN95+ but no auto allocate
* using auto allocate, but making a copy first
* using auto allocate, allowing compiler to manage copy
I am not sure which is best. If hidden in a library, the first is the most conservative approach ?
Code: | program extend
use iso_fortran_env
implicit none
real, allocatable :: a(:)
integer i
write (*,*) compiler_version ()
do i = 1, 5
select case ( mod(i,3) )
case (0)
call extend_alloc_auto ( a, 5000 )
case (1)
call extend_alloc_move ( a, 500 )
case (2)
call extend_alloc_no_auto ( a, 500 )
end select
print*, size(a), a(size(a))
end do
contains
subroutine extend_alloc_no_auto ( a, nn ) ! with no auto-allocate
! extend vector A by nn without auto-allocate
real, allocatable, intent(inout) :: a(:)
integer, intent(in) :: nn
real, allocatable :: copy(:)
integer na
if ( allocated (a) ) then
na = size(a)
allocate ( copy(na) )
copy = a
deallocate ( a )
allocate ( a(na+nn) )
a(1:na) = copy
a(na+1:) = 0
deallocate ( copy )
else
allocate ( a(nn) )
a = 0
end if
write (*,*) 'extend_alloc_no_auto', size(a)
end subroutine extend_alloc_no_auto
subroutine extend_alloc_move ( a, nn ) ! using move_alloc
! extend vector A by nn using auto-allocate
integer, intent(in) :: nn
real, allocatable, intent(inout) :: a(:)
real, allocatable :: extra(:)
real, allocatable :: copy(:)
! allocate ( extra(nn) )
extra = [ (0.0, i=1,nn) ]
if ( allocated (a) ) then
call move_alloc ( a, copy )
a = [ copy, extra ]
else
a = extra
end if
write (*,*) 'extend_alloc_move', size(a)
end subroutine extend_alloc_move
subroutine extend_alloc_auto ( a, nn ) ! using auto-allocate
! extend vector A by nn using auto-allocate
real, allocatable, intent(inout) :: a(:)
integer, intent(in) :: nn
real, allocatable :: extra(:)
real, allocatable :: copy(:)
extra = [ (0.0, i=1,nn) ]
if ( allocated (a) ) then
a = [ a, extra ]
else
a = extra
end if
write (*,*) 'extend_alloc_auto', size(a)
end subroutine extend_alloc_auto
end program extend |
|
|
Back to top |
|
|
Kenneth_Smith
Joined: 18 May 2012 Posts: 709 Location: Hamilton, Lanarkshire, Scotland.
|
Posted: Wed Jan 31, 2024 1:54 pm Post subject: |
|
|
John,
It gets interesting if the lower bound of the source array is not 1. Hopefully this example illustrates this particular devilry.
Code: | real, allocatable :: a(:), b(:), c(:), d(:)
allocate(a(-10:-8))
! Assign some data so checkmate does not complain
a = [1,2,3]
print*, lbound(a) ! -10
! No array constructor
b = a
print*, lbound(b) ! -10
! With array constructor []
c = [a]
print*, lbound(c) ! 1
! With move_alloc
call move_alloc(a,d)
print*, lbound(d) ! -10
end |
|
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2580 Location: Sydney
|
Posted: Fri Feb 02, 2024 3:27 am Post subject: |
|
|
Hi Ken,
Thanks for highlighting an added complexity of changing the lower bound of an allocatable array !
Not something I want to address ( as I find Fortran's support of non-default lower bounds to be unfriendly )
John |
|
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
|