7.4 Replicate m4 Macros

The ``replicate'' set of m4 macros is used to replicate a routine so that a version exists for every possible array dimensioning (scalars plus up to seven-dimensioned arrays, the maximum allowed in F90). To use the replicate macros in the CÆSAR Code Package,

Take the following code segment as an example:

module test_replicate
  REPLICATE_INTERFACE([Generic_Routine], [Specific_Routine])
contains

define([REPLICATE_ROUTINE],[
  function Specific_Routine_$1 (R REP_ARGS([var[]i]))
    type(real,$1) :: R
    REP_DECLARE([type(integer)], [var[]i])
    REP_ALLOCATE(R, [var[]i], [status])
    ARRAY_ONLY DEALLOCATE(R)
    SCALAR_ONLY R = 999.
    <other routine contents>
  end function Specific_Routine_$1

])
REPLICATE
end module test_replicate

This code is expanded by Gnu m4 into the following valid F90 code:

module test_replicate
  interface Generic_Routine
    module procedure Specific_Routine_0
    module procedure Specific_Routine_1
    module procedure Specific_Routine_2
    module procedure Specific_Routine_3
    module procedure Specific_Routine_4
    module procedure Specific_Routine_5
    module procedure Specific_Routine_6
    module procedure Specific_Routine_7
  end interface
contains

  function Specific_Routine_0 (R)
    real (kind=KIND(1.0d0)) :: R
    ! DEALLOCATE(R)
    R = 999.
    <other routine contents>
  end function Specific_Routine_0

  function Specific_Routine_1 (R, var1)
    real (kind=KIND(1.0d0)), pointer, dimension(:) :: R
    integer (kind=KIND(1)) :: var1
    ALLOCATE(R(var1), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_1
 
  function Specific_Routine_2 (R, var1, var2)
    real (kind=KIND(1.0d0)), pointer, dimension(:,:) :: R
    integer (kind=KIND(1)) :: var1, var2
    ALLOCATE(R(var1, var2), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_2
 
  function Specific_Routine_3 (R, var1, var2, var3)
    real (kind=KIND(1.0d0)), pointer, dimension(:,:,:) :: R
    integer (kind=KIND(1)) :: var1, var2, var3
    ALLOCATE(R(var1, var2, var3), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_3

  function Specific_Routine_4 (R, var1, var2, var3, var4)
    real (kind=KIND(1.0d0)), pointer, dimension(:,:,:,:) :: R
    integer (kind=KIND(1)) :: var1, var2, var3, var4
    ALLOCATE(R(var1, var2, var3, var4), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_4
 
  function Specific_Routine_5 (R, var1, var2, var3, var4, var5)
    real (kind=KIND(1.0d0)), pointer, dimension(:,:,:,:,:) :: R
    integer (kind=KIND(1)) :: var1, var2, var3, var4, var5
    ALLOCATE(R(var1, var2, var3, var4, var5), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_5

  function Specific_Routine_6 (R, var1, var2, var3, var4, var5, var6)
    real (kind=KIND(1.0d0)), pointer, dimension(:,:,:,:,:,:) :: R
    integer (kind=KIND(1)) :: var1, var2, var3, var4, var5, var6
    ALLOCATE(R(var1, var2, var3, var4, var5, var6), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_6

  function Specific_Routine_7 (R, var1, var2, var3, var4, var5, var6, var7)
    real (kind=KIND(1.0d0)), pointer, dimension(:,:,:,:,:,:,:) :: R
    integer (kind=KIND(1)) :: var1, var2, var3, var4, var5, var6, var7
    ALLOCATE(R(var1, var2, var3, var4, var5, var6, var7), stat=status)
    DEALLOCATE(R)
    ! R = 999.
    <other routine contents>
  end function Specific_Routine_7

end module test_replicate

Note that this set of m4 macros depends on the m4 commands in the settings.m4 file and on the REPLICATE_ROUTINE macro definition.

m4 macros defined in the include/replicate.m4 file:

 ARRAY_ONLY  Used to comment out lines for scalars, but leave them untouched for arrays.
 REPLICATE  Replicates a routine for all array dimensions and scalars.
 REPLICATE_ARRAYS  Replicates a routine for all array dimensions only.
 REPLICATE_INTERFACE  Defines the interface block for the replicated routine.
 REP_ALLOCATE  Used to allocate a replicated variable.
 REP_ARGS  Used to replicate an argument list.
 REP_DECLARE  Used to decalre a replicated variable.
 REP_EXPAND  Used in the REPLICATE_ROUTINE macro to expand to text that varies with the dimensioning (see code listing for input/output details).
 REP_NUMBER  The number of the dimension of the current routine, used internally.
 SCALAR_ONLY  Used to comment out lines for arrays, but leave them untouched for scalars.
 type(vartype,$1)  A useful construction for replicated procedures which is defined by the types macros.

The Replicate m4 Macros code listing contains additional documentation.

Michael L. Hall