how to write wrapper for 'allocate'

后端 未结 2 1477
天命终不由人
天命终不由人 2020-12-01 08:50

I am trying to write a wrapper for \'allocate\' function, i.e. function which receives an array and dimensions, allocates memory and returns allocated array. The most import

相关标签:
2条回答
  • 2020-12-01 09:10

    This can be done via a generic interface block. You have to create procedures for each rank that you want to handle, e.g., memory_1d, memory_2d, ... memory_4d. (Obviously a lot of cut & pasting.) Then you write a generic interface block that gives all of these procedures the alternative name memory as a generic procedure name. When you call memory, the compiler distinguishes which memory_Xd should be called based on the rank of the argument. The same for your freem functions.

    This is how intrinsic functions such as sin have long worked -- you can call sin with a real arguments of various previsions, or with a complex argument, and the compiler figures out with actual sin function to call. In really old FORTRAN you had to use different names for the different sin functions. Now modern Fortran you can setup the same thing with your own routines.

    Edit: adding a code example demonstrating the method & syntax:

    module double_array_mod
    
       implicit none
    
       interface double_array
          module procedure double_vector
          module procedure double_array_2D
       end interface double_array
    
       private  ! hides items not listed on public statement 
       public :: double_array
    
    contains
    
       subroutine double_vector (vector)
          integer, dimension (:), intent (inout) :: vector
          vector = 2 * vector
       end subroutine double_vector
    
       subroutine double_array_2D (array)
          integer, dimension (:,:), intent (inout) :: array
          array = 2 * array
       end subroutine double_array_2D
    
    end module double_array_mod
    
    
    program demo_user_generic
    
       use double_array_mod
    
       implicit none
    
       integer, dimension (2) :: A = [1, 2]
       integer, dimension (2,2) :: B = reshape ( [11, 12, 13, 14], [2,2] )
       integer :: i
    
       write (*, '( / "vector before:", / 2(2X, I3) )' )  A
       call double_array (A)
       write (*, '( / "vector after:", / 2(2X, I3) )' )  A
    
       write (*, '( / "2D array before:" )' )
       do i=1, 2
          write (*, '( 2(2X, I3) )' )  B (i, :)
       end do
       call double_array (B)
       write (*, '( / "2D array after:" )' )
       do i=1, 2
          write (*, '( 2(2X, I3) )' )  B (i, :)
       end do   
    
       stop
    end program demo_user_generic
    
    0 讨论(0)
  • 2020-12-01 09:14

    subroutine memory(array, length) has as it first dummy parameter 1-dimensional array (real(8), allocatable, intent(out), dimension(:) :: array).

    Calling this subroutine from your main program with 3-dimensional array foo (real(8), allocatable, dimension(:,:,:) :: foo) is error obviously. And this is what compiler actually said.

    If you really need such subroutines write one pair memory/freem subroutines for each array of different dimension - one subroutines pair for 1-dimensional array, another for 2-dimensional array, etc.

    By the way, memory subroutines will be different in general because in order to allocate n-dimensional array you need to pass n extents to above-mentioned subroutine.

    0 讨论(0)
提交回复
热议问题