在Fortran中正确实现显式接口 [英] Correct implementation of an explicit interface in Fortran

查看:248
本文介绍了在Fortran中正确实现显式接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Fortran的显式接口中苦苦挣扎.

I am struggling with explicit interfaces in Fortran.

在一个实例中,当我尝试使用假定形状的数组作为函数或子例程(即过程)的伪参数时,编译器已要求我编写一个显式接口:的显式接口...假定形状参数.例如,它在子例程中看起来像 REAL,INTENT(IN OUT):: dummy_array(:).数组声明中的(:)表示编译器负责将有关数组形状的信息传递给子例程.这很方便,但这也意味着编译器必须知道在编译调用或对该过程的引用时要执行此操作.仅从 CALL (或引用)来看,这是不明显的,因此编译器必须具有有关该过程的伪参数的信息,因此需要显式接口.

In one instance, the compiler has requested that I write an explicit interface when I attempt to use an assumed-shape array as a dummy argument for a function or subroutine (i.e., procedure): Explicit interface required for ... assumed-shape argument. For example, this would appear like REAL, INTENT(IN OUT) :: dummy_array(:) in a subroutine. The (:) in the declaration of the array means that the compiler takes care of passing information about the shape of the array to the subroutine. That's handy, but it also means that the compiler must know to do this when compiling the call or reference to the procedure. This is not evident from the CALL (or reference) alone, so the compiler must have information about the procedure's dummy arguments, hence the need for a explicit interface.

据我了解,有三种方法可以在Fortran中实现显式接口:

From what I understand, there are three methods for implementing an explicit interface in Fortran:

  1. 使用一个 MODULE 对该程序进行 CONTAINS .这往往是推荐的方法.
  2. 将过程 internal 设置为调用它的对象.这就像在主程序的 END 语句之前放置 CONTAINS 语句一样.然后,我的过程的整个代码将放在这两个语句之间.
  3. 为该过程编写一个 INTERFACE .我想大多数人都默认使用此方法,但是它往往是最少推荐的方法,因为这可能会比较费力.
  1. Use a MODULE that CONTAINS the procedure. This tends to be the recommended approach.
  2. Make the procedure internal to whatever calls it. This would be like putting a CONTAINS statement right before the END statement of my main program. The entire code of my procedure would then be placed between these two statements.
  3. Write an INTERFACE for the procedure. I guess most folks default to this, but it tends to be the least recommended approach as it can be a bit laborious.

这使我想到了当前的问题:在另一个实例中,编译器给出了...可分配参数所需的 Explicit接口.以下是上述方法1的相关部分:

This brings me to my current problem: In another instance, the compiler gives Explicit interface required for ... allocatable argument. Here are the relevant parts following method 1 above:

MODULE My_Module
  CONTAINS
    SUBROUTINE Clean(my_array_sizes, my_arrays, my_arrays_clean)
      USE Shared, ONLY : dp
      IMPLICIT NONE
      ...
      REAL(dp), INTENT(OUT), ALLOCATABLE, ASYNCHRONOUS :: my_arrays_clean(:)
      ...
      ALLOCATE(my_arrays_clean(non_zero)) !new array of correct size
      my_arrays_clean = temp(1:non_zero) !transfer values
    END SUBROUTINE Clean
END MODULE My_Module

问题似乎出在虚拟数组 my_arrays_clean 上.这是电话:

The problem seems to be with the dummy array my_arrays_clean. Here's the call:

  CALL Clean(my_array_size, probability, probability_clean) !remove empty values from array

probability_clean 的声明:

  REAL(dp), DIMENSION(:), ALLOCATABLE, ASYNCHRONOUS :: probability, probability_clean !store Photon(E_i, depth) values

一切似乎都很好,直到我尝试使用 gfortran -g -std = f2008 -Wall -Wextra -O2 -fall-intrinsics -fopenmp 进行编译:对"clean_"的未定义引用.我不知道怎么了当然,我可以解决这个问题来完成我需要的工作,但我真的很想了解执行此操作的正确方法.

All seems well until I try to compile with gfortran -g -std=f2008 -Wall -Wextra -O2 -fall-intrinsics -fopenmp: undefined reference to 'clean_'. I have no idea what's wrong. Of course I can work around this problem to accomplish what I need, but I'd really like to understand the proper way to do this.

推荐答案

当我们谈论一个显式(或隐式)接口时,我们不是在谈论过程本身的属性.一个过程具有一个接口,但这不是完全相同的概念.如下所示,获取模块和子例程.

When we talk about an explicit (or implicit) interface, we aren't talking about a property of the procedure itself. A procedure has an interface, but this is not entirely the same concept. Take the module and subroutine as below.

module mod
contains
  subroutine sub
  end subroutine
end module

子例程 sub 具有一个接口,包括这样的信息,即它是一个名为 sub 的子例程,没有伪参数.问题中感兴趣的子例程具有其自己的对应接口.

The subroutine sub has an interface, including such information as it being a subroutine called sub with no dummy arguments. The subroutine of interest from the question has its own corresponding interface.

显式接口"代之以关于在引用过程的点上已知的有关过程接口的信息.看

The "explicit interface" instead is about what information is known about the procedure's interface at the point at which the procedure is referenced. Look at

call sub
end

并与

use mod, only : sub
call sub
end

在第一种情况下,在不使用模块 mod 的情况下,编译器甚至无法将 sub 视为模块内的子例程. sub 这里是带有隐式接口的外部过程(而不是模块中的那个).在第二个中, sub use关联的

In the first case, without using the module mod the compiler can't even see sub as being the subroutine within the module. sub here is an external procedure with implicit interface (and not the one in the module). In the second, sub is use associated; not only does the compiler now see the module subroutine but it sees the interface (which is now explicit).

同样,内部过程(使用 contains 语句的项目2)在其宿主中始终具有显式接口:

Likewise, an internal procedure (item 2. using the contains statement) always has an explicit interface in its host:

  call sub
contains
  subroutine sub
  end subroutine
end program

第三,带有接口块:

subroutine sub
end subroutine

  interface
    subroutine sub
    end subroutine
  end interface

  call sub
end program

结论:可访问模块过程始终具有可用的显式接口,但是必须首先使用 use 语句使它们可访问.内部过程始终可以在主机中使用始终带有显式接口的方式进行访问.接口块提供了一个显式接口,但同样,接口块本身必须位于过程引用所在的位置.

In conclusion: accessible module procedures always have an explicit interface available, but they must first be made accessible with a use statement. Internal procedures are always accessible in the host, always with an explicit interface. Interface blocks provide an explicit interface, but again the interface block itself must be around where the procedure reference is made.

这篇关于在Fortran中正确实现显式接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆