Compilation Fortran-显式接口
我对Fortran非常陌生,为了我的研究,我需要让一个怪物模型运行,所以我在学习的过程中不断前进。所以如果我问了一个“愚蠢”的问题,我很抱歉。 我正在尝试编译(MacOSX,从命令行),我已经设法解决了一些问题,但现在我遇到了一些我不确定如何修复的问题。我想我明白了错误背后的想法,但还是不确定如何修复 这个模型非常庞大,所以我只发布我认为相关的代码部分(尽管我可能错了)。我有一个包含多个子例程的文件,它以:Compilation Fortran-显式接口,compilation,fortran,explicit-interface,Compilation,Fortran,Explicit Interface,我对Fortran非常陌生,为了我的研究,我需要让一个怪物模型运行,所以我在学习的过程中不断前进。所以如果我问了一个“愚蠢”的问题,我很抱歉。 我正在尝试编译(MacOSX,从命令行),我已经设法解决了一些问题,但现在我遇到了一些我不确定如何修复的问题。我想我明白了错误背后的想法,但还是不确定如何修复 这个模型非常庞大,所以我只发布我认为相关的代码部分(尽管我可能错了)。我有一个包含多个子例程的文件,它以: !=======================================
!==========================================================================================!
! This subroutine simply updates the budget variables. !
!------------------------------------------------------------------------------------------!
subroutine update_budget(csite,lsl,ipaa,ipaz)
use ed_state_vars, only : sitetype ! ! structure
implicit none
!----- Arguments -----------------------------------------------------------------------!
type(sitetype) , target :: csite
integer , intent(in) :: lsl
integer , intent(in) :: ipaa
integer , intent(in) :: ipaz
!----- Local variables. ----------------------------------------------------------------!
integer :: ipa
!----- External functions. -------------------------------------------------------------!
real , external :: compute_water_storage
real , external :: compute_energy_storage
real , external :: compute_co2_storage
!---------------------------------------------------------------------------------------!
do ipa=ipaa,ipaz
!------------------------------------------------------------------------------------!
! Computing the storage terms for CO2, energy, and water budgets. !
!------------------------------------------------------------------------------------!
csite%co2budget_initialstorage(ipa) = compute_co2_storage(csite,ipa)
csite%wbudget_initialstorage(ipa) = compute_water_storage(csite,lsl,ipa)
csite%ebudget_initialstorage(ipa) = compute_energy_storage(csite,lsl,ipa)
end do
return
end subroutine update_budget
!==========================================================================================!
!==========================================================================================!
我得到的错误消息大致如下:
预算用途f90:20.54:
真实、外部::计算二氧化碳存储
1错误:位于(1)的过程“compute\u co2\u storage”的伪参数“csite”具有一个属性,该属性需要此过程的显式接口 (我有很多,但基本上都是一样的)。现在,看看ed_state_vars.f90(它在子例程中被“使用”),我发现 等-这是一个为另一个500线左右。 因此,为了达到这一点,似乎原始子例程的过程需要一个显式接口,以便能够使用(伪)参数csite。再说一次,我对Fortran是如此陌生,但我真的试图理解它是如何“思考”的。我一直在寻找拥有一个显式接口意味着什么,何时(以及如何!)使用它等等。但我不知道它在我的案例中是如何应用的。我是否应该使用不同的编译器(英特尔?)。有什么提示吗 编辑:因此
csite
在所有过程中都被声明为target
,并且从声明中type(site type)
包含一大堆指针,如site type
中所述。但是sitetype
在所有过程中都正确地使用另一个模块(ed\u state\u vars.f90
)中的d。所以我仍然不明白为什么它会给我显式的接口错误 “显式接口”是指程序(子例程或函数)的接口向编译器声明。这允许编译器检查过程调用和实际过程调用之间的参数一致性。这会发现很多程序员的错误。您可以使用interface
语句编写接口,但有一种简单得多的方法:将过程放入模块中,然后从调用该模块的任何其他实体使用该模块--从主程序或任何本身不在模块中的过程。但是您不必使用同一模块中另一个过程的过程,它们是自动相互知道的
将过程放入模块会自动使编译器了解其接口,并在use
ed时可进行交叉检查。这比编写接口更容易,也不容易出错。对于接口,必须复制过程参数列表。然后,如果您修改了过程,那么您还必须修改调用(当然!)以及接口
使用“高级”参数时,需要显式接口(interface
语句或模块)。否则编译器不知道如何生成正确的调用
如果您有一个过程是使用
ed,您不应该用外部
来描述它。在现代Fortran中,external
的使用非常少——因此,删除external
属性,将所有过程放入一个模块中,使用它们。我遇到了与在mac 10.9上安装ED2时遇到的问题相同的问题。我通过在模块中包含该文件中的所有子例程来修复它,即:
module mymodule
contains
subroutine update_budget(csite,lsl,ipaa,ipaz)
other subroutines ecc.
end module mymodule
对包中的大约10到15个其他文件也必须执行相同的操作。
我已经编译了所有文件并生成了相应的对象文件,但是现在我得到了关于未定义符号的错误。然而,我怀疑这些是独立于修改的,所以如果有人有耐心,这可能是一种至少解决接口问题的方法 您的模块中是否有compute\u water\u storage
和其他函数?我们需要在compute\u co2\u storage()
中查看csite
的声明,因为错误消息引用的是该例程中声明的属性,而不是update\u budget()
中的属性。我怀疑它是声明为可选的
或指针
或类似的东西。感谢所有的反馈@SethMMorton:是的,作为实函数
@Deditos:incompute\u co2\u storage()
,csite
声明与我发布的子例程中的声明相同:type(sitetype),target::csite
@Geraldine是否解决过这个问题?有相同的issue@badgley我想最后可能是我的编译器或MPI或makefile中的某些设置出现了问题。我最终与我所在大学的高性能计算机中心的人员一起工作,他们让它毫无问题地运行……不过,将百万线模型转换为模块可能非常困难。我理解你的意思(很好的解释,谢谢!)。调用的过程是文件中的real function
s,所以我想它们甚至不必声明为external
?或者,由于它们并非都是专门捆绑为一个模块的,所以它们仍然应该?(因为是的,正如@Vladimir所说,这是一个太大的模型,无法将所有内容转换为模块……)。real函数使用另一个文件中的信息(参见我对原始问题的编辑),但它们使用use
(获取sitetype
,用于声明csite
)。
module mymodule
contains
subroutine update_budget(csite,lsl,ipaa,ipaz)
other subroutines ecc.
end module mymodule