forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Size and 64 bits
Goto page Previous  1, 2
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1772
Location: Sydney

PostPosted: Fri Jul 01, 2016 12:54 pm    Post subject: Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 524
Location: UK

PostPosted: Sat Jul 09, 2016 3:43 pm    Post subject: Reply with quote

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
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1772
Location: Sydney

PostPosted: Sun Jul 10, 2016 12:51 pm    Post subject: Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 524
Location: UK

PostPosted: Sun Jul 10, 2016 1:33 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4915
Location: Salford, UK

PostPosted: Mon Jul 11, 2016 9:08 am    Post subject: Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 524
Location: UK

PostPosted: Mon Jul 11, 2016 8:32 pm    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4915
Location: Salford, UK

PostPosted: Tue Jul 12, 2016 8:27 am    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4915
Location: Salford, UK

PostPosted: Thu Mar 23, 2017 5:03 pm    Post subject: Reply with quote

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
View user's profile Send private message
davidb



Joined: 17 Jul 2009
Posts: 524
Location: UK

PostPosted: Thu Mar 23, 2017 10:58 pm    Post subject: Reply with quote

You mean /SIZE_ISO and /ISO I believe Wink

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
_________________
Programmer in: Fortran 77/95/2003/2008, C, C++ (& OpenMP), java, Python, Perl
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 1772
Location: Sydney

PostPosted: Fri Mar 24, 2017 12:32 am    Post subject: Reply with quote

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
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 4915
Location: Salford, UK

PostPosted: Mon Mar 27, 2017 8:23 am    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Goto page Previous  1, 2
Page 2 of 2

 
Jump to:  
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