1

问题

将子例程标记为 时是否有任何并发​​症elemental这个页面似乎暗示了这一点,但没有详细说明它们可能是什么。

注意:我标记了多个 fortran 版本,因为我想知道在开发可移植代码时是否应该注意这些差异。

例子

假设我想编写一个基本子程序来在笛卡尔坐标和极坐标之间进行转换。这可以按如下方式完成:

elemental subroutine calc_xy_from_rt( r, t, x, y )
    real*8, intent(IN)  :: r   ! radius
    real*8, intent(IN)  :: t   ! theta
    real*8, intent(OUT) :: x
    real*8, intent(OUT) :: y
    x = r * cos(t)
    y = r * sin(t)
end subroutine calc_xy_from_rt

因为它是基本的,所以可以在以下上下文中调用它:

program main
    implicit none

    real*8, dimension(1:100) :: r
    real*8, dimension(1:100) :: t
    real*8, dimension(1:100) :: x
    real*8, dimension(1:100) :: y

    ! (Initialize r and t arrays here)

    ! Calculate x and y for each element
    call calc_xy_from_rt( r, t, x, y )   ! gets called 100 times
end program main

我猜这个简单的过程不会有副作用,但我提供了一个例子来使讨论具体化,并提供一个可以扩展以说明可能的副作用的 MWE。

4

1 回答 1

1

基本子程序的明显复杂性是所有虚拟参数都必须是标量。有时人们希望基本操作可以访问共享数组:这不能通过参数发生。

此外,如果一个基本子程序是纯的,它会受到来自该性质的所有限制。

无论是否纯正,基本子程序都受到进一步的限制:

  • 虚拟参数不能是指针或可分配的;
  • 虚拟参数不能是 coarrays;
  • 虚拟参数必须是数据对象。

至于这些限制如何随着时间和实施而变化,几乎不用担心。

在 Fortran 2008 之前,所有基本子程序都是纯子程序,禁止 coarray 虚拟参数是没有意义的。

此外,编译器必须能够检测到违反所述限制的情况,并且我不知道有任何扩展可以放宽它们。

最后,在多年前,当基本过程出现时,存在各种编译器错误。除非拿起在叔叔的车库里发现的机器,否则不必太担心这些。

于 2018-03-21T07:29:57.380 回答