Purpose of kind parameters in derived types

Are your comments aimed at functions/subroutines, derived types, or both?

For derived types you have the parameterized version, which give you the generic kind. I’ve got an example of a PDT for LU factorization of a square matrix available here.

The derived type comes together quite easily:

  type :: lu_workspace(wp,n)
    integer, kind :: wp
    integer, len :: n
    real(wp) :: a(n,n)
    real(wp) :: b(n)
    integer :: ipiv(n)
    logical :: factorized = .false.
  end type

Problems show up when you start adding procedures. In that case you cannot avoid boilerplate (without resorting to preprocessing):

  integer, parameter :: sp = kind(1.0e0)
  integer, parameter :: dp = kind(1.0d0)

  interface factorize
    module procedure factorize_sp
    module procedure factorize_dp
  end interface

contains

  subroutine factorize_sp(this,info)
    use lapack, only: lapack_factorize => sgetrf
    type(lu_workspace(sp,*)), intent(inout) :: this
    integer, intent(out), optional :: info  
    include "lu_pdt.inc"
  end subroutine

  subroutine factorize_dp(this,info)
    use lapack, only: lapack_factorize => dgetrf
    type(lu_workspace(dp,*)), intent(inout) :: this
    integer, intent(out), optional :: info  
    include "lu_pdt.inc"
  end subroutine

I will note that in this usage case, the underlying LAPACK is only available in single and double precision, so declaring them up-front makes sense to me (in a perfect world, we’d also have a generic LAPACK).

I can merely suggest you have a look and participate in the j3-fortran/generics repository.

1 Like