anchor.diff:  
             ! Query or JIT-generate a function; return zero if it does not exist,
             ! or if JIT is not supported (single-precision).
  -          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_sdispatch(               &
  -     &    m, n, k, alpha, beta, lda, ldb, ldc, flags, prefetch) BIND(C)
  -            IMPORT :: C_FUNPTR, C_FLOAT, C_INT
  -            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k
  -            REAL(C_FLOAT),  INTENT(IN), VALUE :: alpha, beta
  -            INTEGER(C_INT), INTENT(IN), VALUE :: lda, ldb, ldc
  -            INTEGER(C_INT), INTENT(IN), VALUE :: flags, prefetch
  +          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_sdispatch0(              &
  +     &    m, n, k, lda, ldb, ldc, flags)                                &
  +     &    BIND(C, NAME="libxsmm_sdispatch")
  +            IMPORT :: C_FUNPTR, C_INT
  +            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k, lda, ldb, ldc
  +            INTEGER(C_INT), INTENT(IN), VALUE :: flags
             END FUNCTION
             ! Query or JIT-generate a function; return zero if it does not exist,
             ! or if JIT is not supported (double-precision).
  -          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_ddispatch(               &
  -     &    m, n, k, alpha, beta, lda, ldb, ldc, flags, prefetch) BIND(C)
  +          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_ddispatch0(              &
  +     &    m, n, k, lda, ldb, ldc, flags)                                &
  +     &    BIND(C, NAME="libxsmm_ddispatch")
  +            IMPORT :: C_FUNPTR, C_INT
  +            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k, lda, ldb, ldc
  +            INTEGER(C_INT), INTENT(IN), VALUE :: flags
  +          END FUNCTION
  +
  +          ! Query or JIT-generate a function; return zero if it does not exist,
  +          ! or if JIT is not supported (single-precision).
  +          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_sdispatch1(              &
  +     &    m, n, k, lda, ldb, ldc, flags, prefetch) BIND(C)
  +            IMPORT :: C_FUNPTR, C_INT
  +            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k, lda, ldb, ldc
  +            INTEGER(C_INT), INTENT(IN), VALUE :: flags, prefetch
  +          END FUNCTION
  +          ! Query or JIT-generate a function; return zero if it does not exist,
  +          ! or if JIT is not supported (double-precision).
  +          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_ddispatch1(              &
  +     &    m, n, k, lda, ldb, ldc, flags, prefetch) BIND(C)
  +            IMPORT :: C_FUNPTR, C_INT
  +            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k, lda, ldb, ldc
  +            INTEGER(C_INT), INTENT(IN), VALUE :: flags, prefetch
  +          END FUNCTION
  +
  +          ! Query or JIT-generate a function; return zero if it does not exist,
  +          ! or if JIT is not supported (single-precision).
  +          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_sdispatch2(              &
  +     &    m, n, k, lda, ldb, ldc, flags, prefetch, alpha, beta) BIND(C)
  +            IMPORT :: C_FUNPTR, C_FLOAT, C_INT
  +            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k, lda, ldb, ldc
  +            INTEGER(C_INT), INTENT(IN), VALUE :: flags, prefetch
  +            REAL(C_FLOAT),  INTENT(IN), VALUE :: alpha, beta
  +          END FUNCTION
  +          ! Query or JIT-generate a function; return zero if it does not exist,
  +          ! or if JIT is not supported (double-precision).
  +          TYPE(C_FUNPTR) PURE FUNCTION libxsmm_ddispatch2(              &
  +     &    m, n, k, lda, ldb, ldc, flags, prefetch, alpha, beta) BIND(C)
               IMPORT :: C_FUNPTR, C_DOUBLE, C_INT
  -            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k
  +            INTEGER(C_INT), INTENT(IN), VALUE :: m, n, k, lda, ldb, ldc
  +            INTEGER(C_INT), INTENT(IN), VALUE :: flags, prefetch
               REAL(C_DOUBLE), INTENT(IN), VALUE :: alpha, beta
  -            INTEGER(C_INT), INTENT(IN), VALUE :: lda, ldb, ldc
  -            INTEGER(C_INT), INTENT(IN), VALUE :: flags, prefetch
             END FUNCTION
   
             ! Non-pure function returning the current clock tick
  
positive.code:      &    LIBXSMM_PREFETCH_AL2BL2_VIA_C_AHEAD = IOR(                    &
       &        LIBXSMM_PREFETCH_BL2_VIA_C, LIBXSMM_PREFETCH_AL2_AHEAD)
  
          ! Structure providing the actual/extended arguments of an SGEMM call.
          TYPE, BIND(C) :: LIBXSMM_SGEMM_XARGS
            ! The Alpha and Beta arguments.
            REAL(C_FLOAT) :: alpha, beta
            ! The prefetch arguments.
            TYPE(C_PTR) :: pa, pb, pc
          END TYPE
          ! Constructs an actual/extended argument set for an SGEMM call.
          INTERFACE LIBXSMM_SGEMM_XARGS_INTERFACE
            MODULE PROCEDURE LIBXSMM_SGEMM_XARGS_CTOR
          END INTERFACE
  
          ! Structure providing the actual/extended arguments of a DGEMM call.
          TYPE, BIND(C) :: LIBXSMM_DGEMM_XARGS
            ! The Alpha and Beta arguments.
            REAL(C_DOUBLE) :: alpha, beta
            ! The prefetch arguments.
            TYPE(C_PTR) :: pa, pb, pc
          END TYPE
          ! Constructs an actual/extended argument set for an SGEMM call.
          INTERFACE LIBXSMM_DGEMM_XARGS_INTERFACE
            MODULE PROCEDURE LIBXSMM_DGEMM_XARGS_CTOR
          END INTERFACE
  
          ! Overloaded dispatch/JIT routines (single/double precision).
          INTERFACE libxsmm_dispatch
            MODULE PROCEDURE sdispatch, ddispatch, xdispatch
          END INTERFACE
  
          ! Overloaded BLAS routines (single/double precision).
          INTERFACE libxsmm_blasmm
            MODULE PROCEDURE libxsmm_sblasmm, libxsmm_dblasmm
          END INTERFACE
  
          ! Overloaded auto-dispatch routines (single/double precision).
          INTERFACE libxsmm_mm
            MODULE PROCEDURE libxsmm_smm, libxsmm_dmm
          END INTERFACE
  
          ! Type of a function generated for a specific M, N, K, and Alpha, Beta.
          ABSTRACT INTERFACE
            PURE SUBROUTINE LIBXSMM_SMM_FUNCTION(a, b, c, xargs) BIND(C)
              IMPORT :: C_FLOAT, LIBXSMM_SGEMM_XARGS
              REAL(C_FLOAT), INTENT(IN) :: a(*), b(*)
              REAL(C_FLOAT), INTENT(INOUT) :: c(*)
              TYPE(LIBXSMM_SGEMM_XARGS), INTENT(IN) :: xargs
            END SUBROUTINE
            PURE SUBROUTINE LIBXSMM_DMM_FUNCTION(a, b, c, xargs) BIND(C)
              IMPORT :: C_DOUBLE, LIBXSMM_DGEMM_XARGS
              REAL(C_DOUBLE), INTENT(IN) :: a(*), b(*)
              REAL(C_DOUBLE), INTENT(INOUT) :: c(*)
              TYPE(LIBXSMM_DGEMM_XARGS), INTENT(IN) :: xargs
            END SUBROUTINE
          END INTERFACE
  
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: sgemm, dgemm
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_init, libxsmm_sdispatch, libxsmm_ddispatch
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_timer_tick, libxsmm_timer_duration
          INTERFACE
            SUBROUTINE sgemm(                                             &
  
negative.code:         END INTERFACE$MNK_INTERFACE_LIST
  
        CONTAINS
          TYPE(LIBXSMM_SMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_smm_function_mnk(m, n, k, flags)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_sdispatch0(m, n, k, 0, 0, 0,                     &
       &      MERGE(0, flags, .NOT.PRESENT(flags)))
            CALL C_F_PROCPOINTER(fn, libxsmm_smm_function_mnk%smm0)
          END FUNCTION
          TYPE(LIBXSMM_DMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_dmm_function_mnk(m, n, k, flags)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_ddispatch0(m, n, k, 0, 0, 0,                     &
       &      MERGE(0, flags, .NOT.PRESENT(flags)))
            CALL C_F_PROCPOINTER(fn, libxsmm_dmm_function_mnk%dmm0)
          END FUNCTION
  
          TYPE(LIBXSMM_SMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_smm_function_ldx(                              &
       &  m, n, k, lda, ldb, ldc, flags)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: lda, ldb, ldc
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_sdispatch0(m, n, k, lda, ldb, ldc,               &
       &      MERGE(0, flags, .NOT.PRESENT(flags)))
            CALL C_F_PROCPOINTER(fn, libxsmm_smm_function_ldx%smm0)
          END FUNCTION
          TYPE(LIBXSMM_DMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_dmm_function_ldx(                              &
       &  m, n, k, lda, ldb, ldc, flags)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: lda, ldb, ldc
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_ddispatch0(m, n, k, lda, ldb, ldc,               &
       &      MERGE(0, flags, .NOT.PRESENT(flags)))
            CALL C_F_PROCPOINTER(fn, libxsmm_dmm_function_ldx%dmm0)
          END FUNCTION
  
          TYPE(LIBXSMM_SMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_smm_function_prf(m, n, k, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_sdispatch1(m, n, k, 0, 0, 0, flags, prefetch)
            CALL C_F_PROCPOINTER(fn, libxsmm_smm_function_prf%smm1)
          END FUNCTION
          TYPE(LIBXSMM_DMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_dmm_function_prf(m, n, k, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_ddispatch1(m, n, k, 0, 0, 0, flags, prefetch)
            CALL C_F_PROCPOINTER(fn, libxsmm_dmm_function_prf%dmm1)
          END FUNCTION
  
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_smm_function_ldf
          TYPE(LIBXSMM_SMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_smm_function_ldf(                              &
       &  m, n, k, lda, ldb, ldc, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: lda, ldb, ldc
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_sdispatch1(m, n, k, lda, ldb, ldc,               &
       &      flags, prefetch)
            CALL C_F_PROCPOINTER(fn, libxsmm_smm_function_ldf%smm1)
          END FUNCTION
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_dmm_function_ldf
          TYPE(LIBXSMM_DMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_dmm_function_ldf(                              &
       &  m, n, k, lda, ldb, ldc, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: lda, ldb, ldc
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_ddispatch1(m, n, k, lda, ldb, ldc,               &
       &      flags, prefetch)
            CALL C_F_PROCPOINTER(fn, libxsmm_dmm_function_ldf%dmm1)
          END FUNCTION
  
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_smm_function_abf
          TYPE(LIBXSMM_SMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_smm_function_abf(                              &
       &  m, n, k, alpha, beta, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            REAL(LIBXSMM_FLS_KIND), INTENT(IN) :: alpha, beta
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_sdispatch2(m, n, k, 0, 0, 0,                     &
       &      MERGE(0, flags, .NOT.PRESENT(flags)),                       &
       &      MERGE(0, prefetch, .NOT.PRESENT(prefetch)),                 &
       &      alpha, beta)
            CALL C_F_PROCPOINTER(fn, libxsmm_smm_function_abf%smm2)
          END FUNCTION
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_dmm_function_abf
          TYPE(LIBXSMM_DMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_dmm_function_abf(                              &
       &  m, n, k, alpha, beta, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            REAL(LIBXSMM_FLD_KIND), INTENT(IN) :: alpha, beta
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_ddispatch2(m, n, k, 0, 0, 0,                     &
       &      MERGE(0, flags, .NOT.PRESENT(flags)),                       &
       &      MERGE(0, prefetch, .NOT.PRESENT(prefetch)),                 &
       &      alpha, beta)
            CALL C_F_PROCPOINTER(fn, libxsmm_dmm_function_abf%dmm2)
          END FUNCTION
  
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_smm_function_all
          TYPE(LIBXSMM_SMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_smm_function_all(                              &
       &  m, n, k, lda, ldb, ldc, alpha, beta, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: lda, ldb, ldc
            REAL(LIBXSMM_FLS_KIND), INTENT(IN) :: alpha, beta
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_sdispatch2(m, n, k, lda, ldb, ldc,               &
       &      MERGE(0, flags, .NOT.PRESENT(flags)),                       &
       &      MERGE(0, prefetch, .NOT.PRESENT(prefetch)),                 &
       &      alpha, beta)
            CALL C_F_PROCPOINTER(fn, libxsmm_smm_function_all%smm2)
          END FUNCTION
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_dmm_function_all
          TYPE(LIBXSMM_DMM_FUNCTION)                                      &
       &  FUNCTION libxsmm_dmm_function_all(                              &
       &  m, n, k, lda, ldb, ldc, alpha, beta, flags, prefetch)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: m, n, k
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: lda, ldb, ldc
            REAL(LIBXSMM_FLD_KIND), INTENT(IN) :: alpha, beta
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: flags
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN), OPTIONAL :: prefetch
            TYPE(C_FUNPTR) :: fn
            fn = libxsmm_ddispatch2(m, n, k, lda, ldb, ldc,               &
       &      MERGE(0, flags, .NOT.PRESENT(flags)),                       &
       &      MERGE(0, prefetch, .NOT.PRESENT(prefetch)),                 &
       &      alpha, beta)
            CALL C_F_PROCPOINTER(fn, libxsmm_dmm_function_all%dmm2)
          END FUNCTION
          
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_savailable
          LOGICAL PURE FUNCTION libxsmm_savailable(function)
            TYPE(LIBXSMM_SMM_FUNCTION), INTENT(IN) :: function
            libxsmm_savailable =                                          &
       &      ASSOCIATED(function%smm0).OR.                               &
       &      ASSOCIATED(function%smm1).OR.                               &
       &      ASSOCIATED(function%smm2)
          END FUNCTION
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_davailable
          LOGICAL PURE FUNCTION libxsmm_davailable(function)
            TYPE(LIBXSMM_DMM_FUNCTION), INTENT(IN) :: function
            libxsmm_davailable =                                          &
       &      ASSOCIATED(function%dmm0).OR.                               &
       &      ASSOCIATED(function%dmm1).OR.                               &
       &      ASSOCIATED(function%dmm2)
          END FUNCTION
  
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_align_value
          INTEGER(LIBXSMM_INT_KIND) PURE FUNCTION libxsmm_align_value(    &
       &    n, typesize, alignment)
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: n, typesize
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: alignment
            libxsmm_align_value = (((n * typesize + alignment - 1) /      &
       &      alignment) * alignment) / typesize
          END FUNCTION
  
          ! Non-dispatched matrix multiplication using BLAS (single-precision).
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_sblasmm
          SUBROUTINE libxsmm_sblasmm(flags, m, n, k, a, b, c, alpha, beta)
            INTEGER(LIBXSMM_INT_KIND), PARAMETER :: T = LIBXSMM_FLS_KIND
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, m, n, k
            REAL(T), INTENT(IN) :: a(:,:), b(:,:)
            REAL(T), INTENT(INOUT) :: c(:,:)
            REAL(T), INTENT(IN), OPTIONAL :: alpha, beta
            IF (0.NE.LIBXSMM_COL_MAJOR) THEN
              CALL sgemm(                                                 &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_A, flags)),         &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_B, flags)),         &
       &        m, n, k,                                                  &
       &        MERGE(REAL(LIBXSMM_ALPHA, T), alpha, .NOT.PRESENT(alpha)),&
       &        a, MAX(SIZE(a, 1), m), b, MAX(SIZE(b, 1), k),             &
       &        MERGE(REAL(LIBXSMM_BETA, T), beta, .NOT.PRESENT(beta)),   &
       &        c, MAX(SIZE(c, 1), m))
            ELSE
              CALL sgemm(                                                 &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_A, flags)),         &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_B, flags)),         &
       &        n, m, k,                                                  &
       &        MERGE(REAL(LIBXSMM_ALPHA, T), alpha, .NOT.PRESENT(alpha)),&
       &        b, MAX(SIZE(b, 2), n), a, MAX(SIZE(a, 2), k),             &
       &        MERGE(REAL(LIBXSMM_BETA, T), beta, .NOT.PRESENT(beta)),   &
       &        c, MAX(SIZE(c, 1), n))
            ENDIF
          END SUBROUTINE
  
          ! Non-dispatched matrix multiplication using BLAS (double-precision).
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_dblasmm
          SUBROUTINE libxsmm_dblasmm(flags, m, n, k, a, b, c, alpha, beta)
            INTEGER(LIBXSMM_INT_KIND), PARAMETER :: T = LIBXSMM_FLD_KIND
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, m, n, k
            REAL(T), INTENT(IN) :: a(:,:), b(:,:)
            REAL(T), INTENT(INOUT) :: c(:,:)
            REAL(T), INTENT(IN), OPTIONAL :: alpha, beta
            IF (0.NE.LIBXSMM_COL_MAJOR) THEN
              CALL dgemm(                                                 &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_A, flags)),         &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_B, flags)),         &
       &        m, n, k,                                                  &
       &        MERGE(REAL(LIBXSMM_ALPHA, T), alpha, .NOT.PRESENT(alpha)),&
       &        a, MAX(SIZE(a, 1), m), b, MAX(SIZE(b, 1), k),             &
       &        MERGE(REAL(LIBXSMM_BETA, T), beta, .NOT.PRESENT(beta)),   &
       &        c, MAX(SIZE(c, 1), m))
            ELSE
              CALL dgemm(                                                 &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_A, flags)),         &
       &        MERGE('N', 'T',                                           &
       &            0.EQ.IAND(LIBXSMM_GEMM_FLAG_TRANS_B, flags)),         &
       &        n, m, k,                                                  &
       &        MERGE(REAL(LIBXSMM_ALPHA, T), alpha, .NOT.PRESENT(alpha)),&
       &        b, MAX(SIZE(b, 2), n), a, MAX(SIZE(a, 2), k),             &
       &        MERGE(REAL(LIBXSMM_BETA, T), beta, .NOT.PRESENT(beta)),   &
       &        c, MAX(SIZE(c, 1), n))
            ENDIF
          END SUBROUTINE
  
          ! Dispatched matrix multiplication (single-precision).
          !DIR$ ATTRIBUTES OFFLOAD:MIC :: libxsmm_smm
          SUBROUTINE libxsmm_smm(
       &  flags, m, n, k, a, b, c, pa, pb, pc, alpha, beta)
            INTEGER(LIBXSMM_INT_KIND), PARAMETER :: T = LIBXSMM_FLS_KIND
            INTEGER(LIBXSMM_INT_KIND), INTENT(IN) :: flags, m, n, k
            REAL(T), INTENT(IN) :: a(:,:), b(:,:)
            REAL(T), INTENT(INOUT) :: c(:,:)
            REAL(T), INTENT(IN), OPTIONAL :: pa(*), pb(*), pc(*)
            REAL(T), INTENT(IN), OPTIONAL :: alpha, beta
            TYPE(LIBXSMM_SMM_FUNCTION) :: xmm
            INTEGER(LIBXSMM_INT_KIND) :: mn
            IF (LIBXSMM_MAX_MNK.GE.(m * n * k)) THEN
              IF (.NOT.(PRESENT(pa).OR.PRESENT(pb).OR.PRESENT(pc))) THEN
                xmm = libxsmm_sdispatch(m, n, k, flags)
                IF (libxsmm_savailable(xmm)) THEN
                  !CALL libxsmm_call(xmm, a, b, c)
                ELSE
                  CALL libxsmm_sblasmm(                                   &
       &            flags, m, n, k, a, b, c, alpha, beta)
                ENDIF
              ELSE IF (.NOT.(PRESENT(alpha).OR.PRESENT(beta))) THEN
                xmm = libxsmm_sdispatch(m, n, k, flags,                   &
       &          LIBXSMM_PREFETCH)
                IF (libxsmm_savailable(xmm)) THEN
                  !CALL libxsmm_call(xmm, a, b, c, pa, pb, pc)
                ELSE
                  CALL libxsmm_sblasmm(                                   &
       &            flags, m, n, k, a, b, c, alpha, beta)
                ENDIF
              ELSE
                xmm = libxsmm_sdispatch(m, n, k, alpha, beta, flags,      &
       &          LIBXSMM_PREFETCH)
                IF (libxsmm_savailable(xmm)) THEN
                  !CALL libxsmm_call(xmm, a, b, c, pa, pb, pc, alpha, beta)
                ELSE
                  CALL libxsmm_sblasmm(                                   &
       &            flags, m, n, k, a, b, c, alpha, beta)
                ENDIF
              ENDIF
            ELSE
              CALL libxsmm_sblasmm(flags, m, n, k, a, b, c, alpha, beta)
            ENDIF
          END SUBROUTINE
  
          !!!!!!!!!!!!!!
        END MODULE
  