我正在设计一个与hdf5 Fortran库一起使用的模块。该模块包含子程序,用于从文件读取和写入不同类型和形状的数组。
e.g。我希望能够调用writeToHDF5(文件路径,数组),无论数组的形状和类型是什么。我意识到必须使用接口来实现不同类型的接口。然而,我想知道是否有可能具有假定的阵列形状。
e.g。
如果定义了数组,例如
integer(kind=4), dimension(*),intent(in) :: array
并传递了一个二维数组。有没有办法做到这一点,而不为数组的每个形状创建单独的子程序?
答案 0 :(得分:4)
正如Vladimir F所说,Fortran 2015增加了“假设等级” - 这个 有用的Fortran-Fortran(它是MPI为Fortran绑定请求的),但是当你收到这样的数组时,没有其他并发症,你不能直接做很多事情。有几个编译器已经支持这个,但很少(如果有的话)支持新添加的SELECT RANK结构,这使得它更有用。
但是,您可以使用C_LOC和C_F_POINTER将假定等级的虚拟“强制转换”为指向您喜欢的任何等级数组的指针,这样就有可能。
标准(甚至回到Fortran 90)确实可以帮到你。如果你写:call writeToHDF5(filepath, array(1,1))
(假设数组在这里是排名2),被调用过程的显式接口可以通过“序列关联”的魔力指定伪参数的任何排名。但是有一些限制 - 特别是不允许将数组假定为形状或POINTER。
答案 1 :(得分:0)
我知道这个问题来得晚,但对于未来的读者来说 - 答案实际上是肯定的。 这是读取具有任何给定形状的单个整数数据集的过程的简单示例。使用单个例程从HDF5读取所需的输入,该例程不需要任何特殊规范,并且对于整数,实数,字符串等是相同的。 我在“0-D”阵列(大小为(/ 1 /)),1-D,2-D,3-D和4-D阵列上进行了测试。 在所有情况下,都可以正确检索数据。 (注意:我删除了一些关于Errorflag的检查,因为它们对于示例并不重要)
subroutine ReadSingleDataset_int(FileName,DataName,DataType,Data_dims,Errorflag,InputArray)
implicit none
character(len=*), intent(in) :: FileName,DataName
integer(HID_T), intent(in) :: DataType
integer(hsize_t), dimension(:), intent(in) :: Data_dims
logical, intent(out) :: ErrorFlag
integer, dimension(*), intent(inout) :: InputArray
integer :: hdferr
integer(HID_T) :: file_id,dset_id
ErrorFlag=.FALSE.
IF (.NOT.HDF5_initialized) THEN
CALL h5open_f(hdferr)
HDF5_initialized=.TRUE.
ENDIF
call h5fopen_f(trim(FileName),H5F_ACC_RDONLY_F, file_id, hdferr)
call h5dopen_f(file_id,trim(DataName),dset_id,hdferr)
call h5dread_f(dset_id,DataType,InputArray,Data_dims,hdferr)
call h5dclose_f(dset_id,hdferr)
call h5fclose_f(file_id,hdferr)
end subroutine ReadSingleDataset_int
我现在对此的主要兴趣是 - 是否可以用以下行中的泛型替换特定类型/类(整数/实数/等'):
class(*), dimension(*), intent(inout) :: InputArray
因为我有几个这样的例程(对于int,real,string),它们只在输入类型/类的规范中有所不同。如果这种限制也可以减轻,那将更加优雅。
(只是指出问题 - h5dread_f
不接受缓冲区参数,在我的情况下为InputArray
,是无限多态的