0

I have following subroutine:

subroutine invertCell( a1vec,a2vec,a3vec, rlvec ) !(icluster)
    implicit none
    ! ======= Parameters
    real, dimension (3),  intent(in)  :: a1vec, a2vec, a3vec
    real, dimension (3,3),intent(out) :: rlvec
    ! ... Body ...
end subroutine

When I call it with argument vectors sliced from 3x3 matrix like this

real, dimension (3,3) :: ervec
real, dimension (3,3) :: elvec
...
call invertCell( ervec(1,:),ervec(2,:),ervec(3,:), elvec )

I produces warrnings Fortran runtime warning: An array temporary was created

I can avoid this by making temporary array explicitly:

    real, dimension (3)     :: ervec1,ervec2,ervec3
    ...
    ervec1(:) = ervec(1,:)
    ervec2(:) = ervec(2,:)
    ervec3(:) = ervec(3,:)
    call invertCell( ervec1,ervec2,ervec3, elvec )

But this is some obfuscation I want to avoid.

NOTE: I come from C/C++ background. In C/C++ this would be very easy since arrays are just pointers, so slicing arrays can be always done by pointer arithmetics without copy. I wonder why this is not possible in Fortran.

Prokop Hapala
  • 2,424
  • 2
  • 30
  • 59
  • Can you change the subroutine `invertCell`? – francescalus Sep 02 '22 at 09:15
  • yes, but it should be still general... (it should accept also independnet vectros, not only 3x3 matrix ) – Prokop Hapala Sep 02 '22 at 09:18
  • 3
    The arguments in the subroutine as you have them must be contiguous in memory. Changing them to another form can allow non-contiguous memory, as shown in answer to the linked question. – francescalus Sep 02 '22 at 09:20
  • aha you mean it is transposed; slicing like `call invertCell( ervec(:,1),ervec(:,2),ervec(:,3), elvec )` would be fine ? – Prokop Hapala Sep 02 '22 at 09:21
  • Even with non-contiguous dummy arguments, an array temporary may still be created if the compiler decides that would be better for performance ("copy-in/copy-out"). – francescalus Sep 02 '22 at 09:22
  • 2
    You can pass a contiguous slice to the subroutine to avoid the copy (transposing), or you can make the dummy arguments assumed shape `dimension(:)`. Passing contiguous where possible is likely what you want. – francescalus Sep 02 '22 at 09:24
  • Fortran is not C++ or C, In C if you pass just a pointer, you have to do loads of pointer arithmetic yourself to work on a slice and you must somehow pass the slice information separately. In Fortran you could do the same if you wanted, but modern Fortran can do all that for you if you use assumed shape arrays. – Vladimir F Героям слава Sep 02 '22 at 11:10
  • 1
    Note that in `C` there are no 2D arrays, and slicing 2D arrays is not as trivial as focusing on a contiguous part of memory as with 1D arrays. So the comparison is not fair here. – John Alexiou Sep 02 '22 at 12:24

0 Answers0