Passing size as argument VS assuming shape in Fortran procedures
Asked Answered
E

1

10

I'm trying to decide which one of these two options would be the best:

subroutine sqtrace( Msize, Matrix, Value )
  integer, intent(in)  :: Msize
  real*8,  intent(in)  :: Matrix(Msize, Msize)
  real*8,  intent(out) :: Value

  [instructions...]

end subroutine sqtrace

VS

subroutine sqtrace( Matrix, Value )
  real*8,  intent(in)  :: Matrix(:,:)
  real*8,  intent(out) :: Value

  if ( size(Matrix,1) /= size(Matrix,2) ) then
    [error case instructions]
  end if

  [instructions...]

end subroutine sqtrace

I understand that when you compile with warnings, the first case should automatically check at compile time if calls to sqtrace comply with the size indicated. However, I don't know if the compiler can perform those checks when the given arguments are allocatable, for example (more so if such allocation depends on other things that are determined at runtime). The second one requires an explicit interface and has more code (the checks), but would seem to catch more errors.

Which are the advantages/disadvantages of using each and in which cases should one go with one over the other?

Equinox answered 20/12, 2017 at 20:19 Comment(8)
Probably treated before, maybe from different viewpoint. It.may bring differences in speed with assumed shape, contiguous is recommended where appropriate.Jack
Asking for a "preferred way" may lead to people choosing to close as opinion based. Perhaps you could rephrase to clearly ask about specific aspects? (Note that explicit shape and assumed shape are more than just a little different.)Papacy
@VladimirF Ok, I'll consider it for next time. I used f90 tag because I thought assumed shape was not present in f70. Anyways, why do you say it is not f90 conforming? what is wrong?Equinox
@Papacy would it be better to frame it as "When would I want to use one VS the other?". I can't really get any more specific because I'm actually asking what are the consequences/limitations of using one or the other.Equinox
"I understand that when you compile with warnings, the first case should automatically check at compile time if calls to sqtrace comply with the size indicated." Perhaps, if you use modules it might happen with the right compiler. Often no check will be done. The size at the callsite might not be known at compile-time anyway. The explicit size arguments are from the old days when no checks were done on arguments most of the time.Jack
I feel that if I wanted to give a good answer on the difference between the two forms it would take many paragraphs. That may say more about my limited answering skills than the question, though.Papacy
@Papacy nah, it is a broad question indeed. The thing is I find myself constantly switching my programming from one way to the other without a clear conviction. And I feel that I'm lacking some kind of knowledge to help develop my criteria of how to use this, but it is not clear what exactly that knowledge is.Equinox
My opinion there would need to be a real compelling reason to force the calling routine to pass a superfluous size argument. I cant see any.Relate
P
17

First, some terminology. Consider the dummy arguments declared as

real :: a(n)                ! An explicit shape array
real :: b(:)                ! An assumed shape array
real, allocatable :: c(:)   ! A deferred shape array (allocatable)
real, pointer :: d(:)       ! A deferred shape array (pointer)
real :: e(*)                ! An assumed size array
real :: f(..)               ! An assumed rank array/scalar

I won't answer in terms of which is better in a given situation, but will simply detail some of the important characteristics leaving choice, where there is one, to the programmer. Crudely (and incorrectly), many view explicit shape arrays as "Fortran 77" and assumed and deferred shape arrays as "Fortran 90+".

Assumed size and assumed rank arguments are beyond the scope of this question and answer.


Shape:

  • the shape of an explicit shape array follows its declaration;
  • the shape of an assumed shape array dummy argument is that of the actual argument;
  • the shape of a deferred shape dummy argument may be undefined, becoming defined in the procedure, or that of the actual argument.

Contiguousness:

  • an explicit shape array is simply contiguous;
  • an assumed shape array dummy argument's contiguousness relates to that of the associated actual argument;
  • a deferred shape dummy argument may be that of the actual argument, or depending on the procedure's execution.

Restrictions on actual argument:

  • an actual argument associated with an explicit shape array must have at least as many elements as the dummy argument;
  • an actual argument associated with an assumed shape array must not itself be assumed size;
  • an actual argument associated with an assumed or deferred shape array must be of the same rank as the dummy argument.

Interfaces in the calling scope:

  • if a dummy argument is of assumed or deferred shape, the referencing scope must have accessible an explicit interface for the procedure.

Consider real a(6). This may be an actual argument to the dummies

real b(3)
real c(2,3)
real d(:)   ! With an explicit interface available

a(1::2) may be associated with b but as b is contiguous copy-in/copy-out will be involved. Copy-in/copy-out needn't be involved when associated with d, but it may be.

There are plenty of other aspects, but hopefully this is an initial high-level introduction.

Papacy answered 22/12, 2017 at 16:50 Comment(3)
Thank you for the overview! It seems these were compiled by you, but do you happen to know if there is any source material where they explicitly go into the details of the difference between different type of arrays and situations in which one would use one or the other? All books on fortran I read usually just introduce them separately and there is not a clear listing of these differences. If I wanted to go further than an introduction, where should I look for it?Equinox
The Fortran standard documents are actually quite readable as such things go, once you have a reasonable understanding of the concepts. There's little cross-referencing in places, but one can quickly become familiar. Alternatively, if people continue asking good questions here, I'd suggest following them.Papacy
@Eular, there could be a performance difference, but one would expect that this would be comparable to the general overhead of procedure references. The main real performance difference would be in the contiguity aspects: explicit shape dummy arguments are always contiguous (which may have involve a temporary copy being made).Papacy

© 2022 - 2024 — McMap. All rights reserved.