<commit_before>#ifndef MATMUL_H
#define MATMUL_H

#include "Fastor/backend/matmul/matmul_kernels.h"

#ifdef FASTOR_USE_LIBXSMM
#include "Fastor/backend/matmul/libxsmm_backend.h"
#endif

namespace Fastor {



// Forward declare
//-----------------------------------------------------------------------------------------------------------
namespace internal {
template<typename T, size_t M, size_t N>
FASTOR_INLINE
void _matvecmul(const T * FASTOR_RESTRICT a, const T * FASTOR_RESTRICT b, T * FASTOR_RESTRICT out);
} // internal
//-----------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
#ifndef FASTOR_USE_LIBXSMM
template<typename T, size_t M, size_t K, size_t N,
         typename std::enable_if<!(M!=K && M==N && (M==2UL || M==3UL || M==4UL || M==8UL)),bool>::type = 0>
#else
template<typename T, size_t M, size_t K, size_t N,
         typename std::enable_if<
            !(M!=K && M==N && (M==2UL || M==3UL || M==4UL|| M==8UL))
            && is_less_equal<M*N*K/FASTOR_BLAS_SWITCH_MATRIX_SIZE/FASTOR_BLAS_SWITCH_MATRIX_SIZE/FASTOR_BLAS_SWITCH_MATRIX_SIZE,1>::value,
            bool>::type = 0>
#endif
FASTOR_INLINE
void _matmul(const T * FASTOR_RESTRICT a, const T * FASTOR_RESTRICT b, T * FASTOR_RESTRICT out) {

    // Matrix-vector specialisation
    FASTOR_IF_CONSTEXPR (N==1) {
        internal::_matvecmul<T,M,K>(a,b,out);
        return;
    }

    using V = SIMDVector<T,DEFAULT_ABI>;

    // Use specialised kernels
    FASTOR_IF_CONSTEXPR( M<=16UL && (N==V::Size && V::Size!=1)) {
        internal::_matmul_mk_simd_width<T,M,K,N>(a,b,out);
        return;
    }

    FASTOR_IF_CONSTEXPR( M==N && M==K && ((M==12UL || M==24UL) && std::is_same<T,float>::value)) {
        internal::_matmul_mkn_square<T,M,K,N>(a,b,out);
        return;
    }
    FASTOR_IF_CONSTEXPR( M==N && M==K && ((M==33) && std::is_same<T,float>::value)) {
        internal::_matmul_mkn_non_square<T,M,K,N>(a,b,out);
        return;
    }

#ifndef FASTOR_AVX_IMPL
    FASTOR_IF_CONSTEXPR( M*N*K > 27UL ) {
        internal::_matmul_base<T,M,K,N>(a,b,out);
        return;
    }
#else
    // If the remainder is 1, just treat the remainders in scalar mode
    FASTOR_IF_CONSTEXPR( M*N*K > 27UL && N % V::Size <= 1UL) {
        internal::_matmul_base<T,M,K,N>(a,b,out);
        return;
    }
    else FASTOR_IF_CONSTEXPR( M*N*K > 27UL && N % V::Size > 1UL) {
        internal::_matmul_base_masked<T,M,K,N>(a,b,out);
        return;
    }
#endif
    else {
        constexpr int ROUND_ = ROUND_DOWN(N,V::Size);
        for (size_t j=0; j<M; ++j) {
            size_t k=0;
            for (; k<ROUND_; k+=V::Size) {
                V out_row;
                for (size_t i=0; i<K; ++i) {
                    const V brow(&b[i*N+k],false);
                    const V vec_a(a[j*K+i]);
                    out_row = fmadd(vec_a,brow,out_row);
                }
                out_row.store(&out[k+N*j],false);
            }
            for (; k<N; k++) {
                T out_row = 0.;
                for (size_t i=0; i<K; ++i) {
                    out_row += a[j*K+i]*b[i*N+k];
                }
                out[N*j+k] = out_row;
            }
        }
    }
}


#ifdef FASTOR_USE_LIBXSMM
template<typename T, size_t M, size_t K, size_t N,
         typename std::enable_if<
            !(M!=K && M==N && (M==2 || M==3 || M==4))
            && is_greater<M*N*K/FASTOR_BLAS_SWITCH_MATRIX_SIZE/FASTOR_BLAS_SWITCH_MATRIX_SIZE/FASTOR_BLAS_SWITCH_MATRIX_SIZE,1>::value,
            bool>::type = 0>
FASTOR_INLINE
void _matmul(const T * FASTOR_RESTRICT a, const T * FASTOR_RESTRICT b, T * FASTOR_RESTRICT c) {
    blas::matmul_libxsmm<T,M,K,N>(a,b,c);
}
#endif
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
#include "Fastor/backend/matmul/matmul_specialisations_kernels.h"
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------

<commit_msg>Simplify a long enable_if line<commit_after>#ifndef MATMUL_H
#define MATMUL_H

#include "Fastor/backend/matmul/matmul_kernels.h"

#ifdef FASTOR_USE_LIBXSMM
#include "Fastor/backend/matmul/libxsmm_backend.h"
#endif

namespace Fastor {



// Forward declare
//-----------------------------------------------------------------------------------------------------------
namespace internal {
template<typename T, size_t M, size_t N>
FASTOR_INLINE
void _matvecmul(const T * FASTOR_RESTRICT a, const T * FASTOR_RESTRICT b, T * FASTOR_RESTRICT out);
} // internal
//-----------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
#ifndef FASTOR_USE_LIBXSMM
template<typename T, size_t M, size_t K, size_t N,
         typename std::enable_if<!(M!=K && M==N && (M==2UL || M==3UL || M==4UL || M==8UL)),bool>::type = 0>
#else
template<typename T, size_t M, size_t K, size_t N,
         typename std::enable_if<
            !(M!=K && M==N && (M==2UL || M==3UL || M==4UL|| M==8UL))
            && is_less_equal<M*N*K/internal::meta_cube<FASTOR_BLAS_SWITCH_MATRIX_SIZE>::value,1>::value,
            bool>::type = 0>
#endif
FASTOR_INLINE
void _matmul(const T * FASTOR_RESTRICT a, const T * FASTOR_RESTRICT b, T * FASTOR_RESTRICT out) {

    // Matrix-vector specialisation
    FASTOR_IF_CONSTEXPR (N==1) {
        internal::_matvecmul<T,M,K>(a,b,out);
        return;
    }

    using V = SIMDVector<T,DEFAULT_ABI>;

    // Use specialised kernels
    FASTOR_IF_CONSTEXPR( M<=16UL && (N==V::Size && V::Size!=1)) {
        internal::_matmul_mk_simd_width<T,M,K,N>(a,b,out);
        return;
    }

    FASTOR_IF_CONSTEXPR( M==N && M==K && ((M==12UL || M==24UL) && std::is_same<T,float>::value)) {
        internal::_matmul_mkn_square<T,M,K,N>(a,b,out);
        return;
    }
    FASTOR_IF_CONSTEXPR( M==N && M==K && ((M==33) && std::is_same<T,float>::value)) {
        internal::_matmul_mkn_non_square<T,M,K,N>(a,b,out);
        return;
    }

#ifndef FASTOR_AVX_IMPL
    FASTOR_IF_CONSTEXPR( M*N*K > 27UL ) {
        internal::_matmul_base<T,M,K,N>(a,b,out);
        return;
    }
#else
    // If the remainder is 1, just treat the remainders in scalar mode
    FASTOR_IF_CONSTEXPR( M*N*K > 27UL && N % V::Size <= 1UL) {
        internal::_matmul_base<T,M,K,N>(a,b,out);
        return;
    }
    else FASTOR_IF_CONSTEXPR( M*N*K > 27UL && N % V::Size > 1UL) {
        internal::_matmul_base_masked<T,M,K,N>(a,b,out);
        return;
    }
#endif
    else {
        constexpr int ROUND_ = ROUND_DOWN(N,V::Size);
        for (size_t j=0; j<M; ++j) {
            size_t k=0;
            for (; k<ROUND_; k+=V::Size) {
                V out_row;
                for (size_t i=0; i<K; ++i) {
                    const V brow(&b[i*N+k],false);
                    const V vec_a(a[j*K+i]);
                    out_row = fmadd(vec_a,brow,out_row);
                }
                out_row.store(&out[k+N*j],false);
            }
            for (; k<N; k++) {
                T out_row = 0.;
                for (size_t i=0; i<K; ++i) {
                    out_row += a[j*K+i]*b[i*N+k];
                }
                out[N*j+k] = out_row;
            }
        }
    }
}


#ifdef FASTOR_USE_LIBXSMM
template<typename T, size_t M, size_t K, size_t N,
         typename std::enable_if<
            !(M!=K && M==N && (M==2 || M==3 || M==4))
            && is_greater<M*N*K/internal::meta_cube<FASTOR_BLAS_SWITCH_MATRIX_SIZE>::value,1>::value,
            bool>::type = 0>
FASTOR_INLINE
void _matmul(const T * FASTOR_RESTRICT a, const T * FASTOR_RESTRICT b, T * FASTOR_RESTRICT c) {
    blas::matmul_libxsmm<T,M,K,N>(a,b,c);
}
#endif
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------
#include "Fastor/backend/matmul/matmul_specialisations_kernels.h"
//-----------------------------------------------------------------------------------------------------------
//-----------------------------------------------------------------------------------------------------------


{'fraction_non_alphanumeric': 0.3579833747166145, 'fraction_numerical': 0.008636510849616755, 'mean_word_length': 1.2360608254887762, 'pattern_counts': {'":': 0, '<': 59, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2109888', 'n_tokens_mistral': 3037, 'n_tokens_neox': 2913, 'n_words': 490}