Templates Fortran中任何类型数组的过程 Base: < /强>我想编写一个程序,对任何输入数组类型进行操作:整数、实数(4)、实数(8)< /代码>等。我在StAcExcel上读取的唯一思想是模仿C++模板,使用泛化和预处理的通用过程,包括复制代码。
但在搜索流行I/O软件的API时,我在手册中发现:Templates Fortran中任何类型数组的过程 Base: < /强>我想编写一个程序,对任何输入数组类型进行操作:整数、实数(4)、实数(8)< /代码>等。我在StAcExcel上读取的唯一思想是模仿C++模板,使用泛化和预处理的通用过程,包括复制代码。,templates,fortran,overriding,Templates,Fortran,Overriding,但在搜索流行I/O软件的API时,我在手册中发现: function nf90_put_var(ncid, varid, values, start, count, stride, map) integer, intent(in) :: ncid, varid any valid type, scalar or array of any rank, intent(in) :: values ... 对于传递给值的每个秩的每种数组类型,它都能正常工作 问题:他们无法预测任
function nf90_put_var(ncid, varid, values, start, count, stride, map)
integer, intent(in) :: ncid, varid
any valid type, scalar or array of any rank, intent(in) :: values
...
对于传递给值的每个秩的每种数组类型,它都能正常工作
问题:他们无法预测任何排名,因此无法为每个案例制作明确的模板。如何构建相同的友好界面?这与MPI过程的情况相同。关键是(至少在Fortran 2008及更早版本中)使用例程的隐式接口。在这种情况下,不会进行参数检查,您可以传递任何您想要的内容。如果过程是外部的,那么就有隐式接口。这与MPI过程的情况相同。关键是(至少在Fortran 2008及更早版本中)使用例程的隐式接口。在这种情况下,不会进行参数检查,您可以传递任何您想要的内容。如果过程是外部的,则具有隐式接口
例如:
subroutine store(A,count,sizeof)
use iso_fortran_env, only: int8
integer, intent(in) :: count, sizeof
integer(int8) :: A(count*sizeof)
integer :: u
!here you can treat A just as an array of count*sizeof bytes
open(newunit=u,file=out.bin,access=stream)
write(u) A
close(u)
end subroutine
program p
real :: A(5,6)
call store(A, size(A), storage_size(A(1,1))/8)
end program
当您需要显式接口时,您可以(未经测试)执行以下操作(许多编译器不支持,Fortran 2008除外):
或者使用一些编译器支持的指令:
!GCC$ attributes no_arg_check::A
!DEC$ attributes no_arg_check::A
这将禁用对参数的检查。补充Vladimir答案的最后一部分:mpi_f08
模块使用以下不可移植部分定义了大多数例程,这似乎适合大多数编译器(但很可能不是所有编译器):
(根据您的需要调整变量名。)至少在Fortran 2008及更高版本中是这样——不要告诉我您已经有了更现代的编译器!不支持,但有些编译器支持以下TS中的选定功能(与C的进一步互操作性)。啊!谢谢,这是一个有用的更新,我会看看我的编译器是怎么做的。你能扩展你的例子并添加调用这个sub的程序吗,例如,只编写输入数组。我想不出如何正确地编码。谢谢。还有两个问题:1)这是否意味着我可以将这个字节数组直接传递给MPI子例程?2) 如何在类过程中使用此技巧?(想法是重写其中一个类方法)
!GCC$ attributes no_arg_check::A
!DEC$ attributes no_arg_check::A
!DEC$ ATTRIBUTES NO_ARG_CHECK :: sendbuf, recvbuf
!GCC$ ATTRIBUTES NO_ARG_CHECK :: sendbuf, recvbuf
!$PRAGMA IGNORE_TKR sendbuf, recvbuf
!DIR$ IGNORE_TKR sendbuf, recvbuf
!IBM* IGNORE_TKR sendbuf, recvbuf