anchor.diff:          INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
        &    LIBXSMM_ALIGNMENT = $ALIGNMENT
           INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
  -     &    LIBXSMM_ALIGNED_STORES = $ALIGNED_STORES
  -        INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
  -     &    LIBXSMM_ALIGNED_LOADS = $ALIGNED_LOADS
  -        INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
  -     &    LIBXSMM_ALIGNED_MAX = $ALIGNED_MAX
  -        INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
        &    LIBXSMM_PREFETCH = $PREFETCH
           INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
        &    LIBXSMM_ROW_MAJOR = $ROW_MAJOR
  
positive.code:      &    LIBXSMM_GEMM_FLAG_TRANS_B = 2,                                &
       &    LIBXSMM_GEMM_FLAG_ALIGN_A = 4,                                &
       &    LIBXSMM_GEMM_FLAG_ALIGN_C = 8
  
          ! Flag representing the GEMM performed by the simplified interface.
          INTEGER(LIBXSMM_INT_KIND), PARAMETER ::                         &
       &    LIBXSMM_GEMM_FLAG_DEFAULT = IOR(                              &
       &        MERGE(LIBXSMM_GEMM_FLAG_ALIGN_A, 0,                       &
       &          1.LT.LIBXSMM_ALIGNED_LOADS),                            &
       &        MERGE(LIBXSMM_GEMM_FLAG_ALIGN_C, 0,                       &
       &          1.LT.LIBXSMM_ALIGNED_STORES))
  
          ! Enumeration of the available prefetch strategies which can be IORed.
          !   LIBXSMM_PREFETCH_NONE:      No prefetching and no prefetch fn. signature.
  
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
  