Passing an array to a subroutine that expects a different shape

一笑奈何 提交于 2021-02-02 09:34:30

问题


I have a 1-dimensional work array

real(8), allocatable :: work(:)

which is passed to a subroutine that operates on a 2-dimensional array

pure subroutine f(work, dim1, dim2)
  real(8), intent(out) :: work(dim1, dim2)
  integer, intent(in) :: dim1, dim2
  ...

What is the difference in the following ways of passing the array?

call f(work, dim1, dim2)
call f(work(1), dim1, dim2)

Are they the same in that they just pass the pointer to the first array element or is there some extra overhead with either call? Are there more elegant ways in modern Fortran of passing an array whose shape needs to change, without passing the dimensions explicitly, but without taking a performance hit?

I know the above looks like old Fortran but I've found it faster than declaring a two-dimensional array in the parent subroutine and passing an array section, work(:dim1,:dim2), to f.


回答1:


Both example statements are forms of sequence association. The actual argument specifies a sequence of array elements, that are then associated with the elements of the dummy argument in array element order.

If work (in the calling scope) is allocated to non-zero size and has a lower bound of one, there is unlikely to be a practical difference in implementation.

In both cases, the programmer must ensure that the size of the dummy argument must be less than or equal to the size of the actual argument element sequence.

Using the whole array reference makes it clearer to readers (and perhaps the compiler) that it was the author's intent to pass an array element sequence, potentially including all the elements of the array. It also defends against the actual argument being zero size, or perhaps having a lower bound other than one.

The author's intent is far less clear when a reference to a specific element is used to designate an array element sequence.

In this specific case, because the actual argument is allocatable the compiler knows that the element sequence of the actual argument will be contiguous, and it can arrange for the dummy argument to be associated with the element sequence appropriately. In other cases, say if the actual argument was itself an assumed shape argument without the contiguous attribute, the compiler does not know that the element sequence is contiguous, and it may have to make a copy of the element sequence ahead of the call. This can have material performance impact - it is probably the reason why you found using a non-contiguous rank two array section as an actual argument to be slower.



来源:https://stackoverflow.com/questions/41813114/passing-an-array-to-a-subroutine-that-expects-a-different-shape

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!