![forums.silverfrost.com Forum Index](templates/subSilver/images/logo_phpBB.gif) |
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Fri Jul 01, 2016 12:54 pm Post subject: |
|
|
David,
Quote: | SIZOF is nothing to do with SIZE. Arrays don't need to be contiguous in memory so you can't convert between the two even if you know the storage unit size. Consider an array of 1000 elements, then SIZE(a(1:999:2)) is 500 |
This is not ifort. FTN95 would take a copy that is contiguous. I actually wonder if a non-contiguous array complies with the standard. It certainly doesn't conform to my understanding of Fortran and I am sure Eddie would agree on this one. non-contiguous arrays would break a lot of pre F90 codes.
What is the point of making Fortran process SIZE(a(1:999:2)).
I suppose you could try " INQUIRE ( IOLENGTH=len ) a(1:999:2) " but I would expect FTN95 would crash with that.
It will crash with " INQUIRE ( IOLENGTH=len ) a(:) "
As a work around, you have to use " INQUIRE ( IOLENGTH=len ) a(1) ; len = len * SIZE (a(:)) "
John |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sat Jul 09, 2016 3:43 pm Post subject: |
|
|
Non-contiguous arrays (also called array sections) have been in the Standard since Fortran 90.
When such an array is passed to a subroutine with an explicit interface and an assumed-shape dummy argument, FTN95 (like other Fortran compilers) passes a "dope vector" which includes hidden information (start address, stride, size). There is no need for a copy to be made and FTN95 doesn't make one.
When such an array is passed to an external subroutine with an implicit interface (e.g. a F77 subroutine), a copy-in and/or a copy-out must be made. This is handled automatically by FTN95. Existing, F77 codes should therefore not break when a non-contiguous array or array section is passed as an actual argument.
For many F77 subroutines one must pass the array and size information, and it is here where the SIZE intrinsic would be most used. E.g. in subroutine PROCESS below SIZE is used to pass the size of the array to the blas subroutine DSCAL. The compiler needs to do a copy before the call, and a copy after the call.
The compiler doesn't currently support this properly.
Code: |
module foo
contains
subroutine process(a,x)
double precision, intent(in) :: a
double precision, intent(inout) :: x(:) ! <-- this array may be non-contigous
call dscal(size(x), a, x, 1)
end subroutine process
end module foo
|
_________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Sun Jul 10, 2016 12:51 pm Post subject: |
|
|
davidb,
I am not aware of FTN95 using a stride. I tested the example below that I adapted from your example in Plato, using FTN95 /64 and gFortran. It appears to show (me) that FTN95 /64 does not provide a stride while gFortran does. Do you agree ?
The use of stride can create problems for pre F90 memory management approaches, especially when contiguous memory is assumed.
I am relieved that FTN95 provides a copy of the array in this case, although it can provide a performance penalty.
I have previously posted array section examples where FTN95 provides a copy when it did not need to, incurring a severe performance penalty.
John
Code: | module foo
contains
subroutine process(a,x)
double precision, intent(in) :: a
double precision, intent(inout) :: x(:) ! <-- this array may be non-contigous
! call dscal(size(x), a, x, 1)
write (*,*) 'size ', size(x)
write (*,*) 'spacing', loc(x(2)) - loc(x(1))
write (*,*) ' '
end subroutine process
end module foo
program alloctest
use foo
implicit none
real*8 aa(3,7), a
call process ( a, aa(:,1) )
call process ( a, aa(1,:) )
!
end
|
|
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Sun Jul 10, 2016 1:33 pm Post subject: |
|
|
Hi John,
Yes, in this case FTN95 seems to be making a copy in and copy out. As you say this could be inefficient (with big arrays).
The dope vector must still be being passed, otherwise SIZE, UBOUND, and LBOUND would not work, but the dope vector of the copied array will have a stride of 1.
The following compilers avoid the copy.
gfortran
nagfor
lahey
g95
ifort
absoft
pvf
I wonder if this is new behaviour for FTN95. I am sure earlier versions avoided the copy.
Perhaps Paul will comment on this. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7930 Location: Salford, UK
|
Posted: Mon Jul 11, 2016 9:08 am Post subject: |
|
|
In the first call to "process", the array is contiguous and the base address and size of the section are passed. In the second call, the array is not contiguous, and it is copied in and copied out. The base address and size of the copy are passed.
As far as I am aware FTN95 has always worked this way.
Where possible users should avoid passing large non-contiguous array sections.
Also it is worth mentioning in this context that users should always provide an interface (either explicitly or by placing the subprogram in a module) when passing assumed-shape arrays. Otherwise a Fortran compiler may perform a copy-in/copy-out when it is not needed. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Mon Jul 11, 2016 8:32 pm Post subject: |
|
|
Paul,
By your last statement do you mean that you can avoid one of the copy operations when an explicit interface is used. That is:
avoid copy-in when intent(out) is used, and
avoid copy-out when intent(in) is used.
If you mean you can avoid copies altogether this would contradict what you said earlier. _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7930 Location: Salford, UK
|
Posted: Tue Jul 12, 2016 8:27 am Post subject: |
|
|
My recollection is that you can get an unnecessary copy-in and/or and unnecessary copy-out when an interface is omitted. I don't think that this is particularly related to the INTENT attribute.
The important point is that users can forget to provide and an interface when passing assumed-shape arrays and that this can cause problems of one kind or another.
In this context I have used "interface" to mean either (a) a coded INTERFACE/END INTERFACE or (b) a USE of a module subprogram. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7930 Location: Salford, UK
|
Posted: Thu Mar 23, 2017 5:03 pm Post subject: |
|
|
Does anyone object if we change to
1) /SIZE_IOS being an alias for /SIZE32 with only /SIZE_IOS appearing in the documentation,
2) /IOS implying /SIZE_IOS? |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
davidb
Joined: 17 Jul 2009 Posts: 560 Location: UK
|
Posted: Thu Mar 23, 2017 10:58 pm Post subject: |
|
|
You mean /SIZE_ISO and /ISO I believe
These options influence the integer kind returned for the SIZE, UBOUND and LBOUND intrinsic functions.
There are 3 parts to this proposal.
For the 32 bit compiler.
The functions return a value with the same kind as default integer (as they do now).
For the 64 bit compiler enabled with /64
The functions return a 64 bit value by default (as they do now).
The functions return a default integer value when /ISO or /SIZE_ISO is used.
The default integer kind is 32 bits unless /DEF_INT is used to change it.
/SIZE32
/SIZE32 is an alias for /SIZE_ISO.
I would be happy. ![Smile](images/smiles/icon_smile.gif) _________________ Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2556 Location: Sydney
|
Posted: Fri Mar 24, 2017 12:32 am Post subject: |
|
|
Paul,
I would be happy with any approach that provided for an INTEGER*8 response for /64 coding, even the F03 format of SIZE ( a, [,DIM,KIND=n]). The problem is always providing "=n", as values of n= 1,2,3,4,7 or 8 can be a possibility, with =4 being the ambiguous one. =7 is a good non-standard outcome that may get more protests. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7930 Location: Salford, UK
|
Posted: Mon Mar 27, 2017 8:23 am Post subject: |
|
|
The changes outlined above have now been implemented for the next release of FTN95.
1) SIZE, UBOUND and LBOUND can now accept the optional KIND argument.
2) /SIZE32 has become /SIZE_ISO.
3) /ISO now implies /SIZE_ISO.
4) By default SIZE returns a 64 bit value in 64 bit compilations. |
|
Back to top |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|