基础:我想编写一个程序,对任何输入数组类型进行一些操作:integer, real(4), real(8)
等。我在StackOverflow上读到的唯一想法是模仿C ++模板,使用用于覆盖复制代码的覆盖和预处理器的通用过程。
但是在搜索流行的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
...
它确实适用于每个排名的每个数组类型,并传递给values
。
问题他们无法预测任何排名,因此他们无法为每个案例制作明确的模板。我如何建立相同的友好界面?
答案 0 :(得分:0)
这与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之外的许多编译器支持):
subroutine typebound(self, A, count, sizeof)
class(my_class) :: self
TYPE(*),DIMENSION(..) :: A
integer, intent(in) :: count, sizeof
!subroutine
call store(A, count, sizeof)
或使用一些编译器支持的指令:
!GCC$ attributes no_arg_check::A
!DEC$ attributes no_arg_check::A
这会禁用对参数的检查。
答案 1 :(得分:0)
补充弗拉基米尔答案的最后一部分:mpi_f08
模块定义了大多数具有以下不可移植部分的例程,这似乎适合大多数编译器(但很可能不是全部):
!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
(根据您的需要调整变量名称。)