<commit_before>#ifndef __LINALG_H__
#define __LINALG_H__

/** \file linalg.h

    \brief Linear algebra interface

*/

#include <stdint.h>
#include <iostream>
#include <complex>
#include "config.h"
#include "linalg_cpu.h"

template<processing_unit_t> struct blas;

// CPU
template<> struct blas<cpu>
{
    template <typename T>
    static inline void gemm(int transa, int transb, int32_t m, int32_t n, int32_t k, T alpha, T* a, int32_t lda, T* b, int32_t ldb, 
                            T beta, T* c, int32_t ldc);
    
    template <typename T>
    static inline void gemm(int transa, int transb, int32_t m, int32_t n, int32_t k, T* a, int32_t lda, T* b, int32_t ldb, T* c, 
                            int32_t ldc);
    template<typename T>
    static inline void hemm(int side, int uplo, int32_t m, int32_t n, T alpha, T* a, int32_t lda, T* b, int32_t ldb, T beta, T* c, 
                            int32_t ldc);
};

template<> inline void blas<cpu>::gemm<real8>(int transa, int transb, int32_t m, int32_t n, int32_t k, real8 alpha, 
                                              real8* a, int32_t lda, real8* b, int32_t ldb, real8 beta, real8* c, 
                                              int32_t ldc)
{
    const char *trans[] = {"N", "T", "C"};

    FORTRAN(dgemm)(trans[transa], trans[transb], &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc, (int32_t)1, 
                   (int32_t)1);
}

template<> inline void blas<cpu>::gemm<real8>(int transa, int transb, int32_t m, int32_t n, int32_t k, real8* a, int32_t lda, 
                                              real8* b, int32_t ldb, real8* c, int32_t ldc)
{
    gemm(transa, transb, m, n, k, 1.0, a, lda, b, ldb, 0.0, c, ldc);
}

template<> inline void blas<cpu>::gemm<complex16>(int transa, int transb, int32_t m, int32_t n, int32_t k, complex16 alpha, 
                                                  complex16* a, int32_t lda, complex16* b, int32_t ldb, complex16 beta, 
                                                  complex16* c, int32_t ldc)
{
    const char *trans[] = {"N", "T", "C"};

    FORTRAN(zgemm)(trans[transa], trans[transb], &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc, (int32_t)1, 
                   (int32_t)1);
}

template<> inline void blas<cpu>::gemm<complex16>(int transa, int transb, int32_t m, int32_t n, int32_t k, complex16* a, 
                                                    int32_t lda, complex16* b, int32_t ldb, complex16* c, int32_t ldc)
{
    gemm(transa, transb, m, n, k, complex16(1, 0), a, lda, b, ldb, complex16(0, 0), c, ldc);
}

template<> inline void blas<cpu>::hemm<complex16>(int side, int uplo, int32_t m, int32_t n, complex16 alpha, complex16* a, 
                                                  int32_t lda, complex16* b, int32_t ldb, complex16 beta, complex16* c, 
                                                  int32_t ldc)
{
    const char *sidestr[] = {"L", "R"};
    const char *uplostr[] = {"U", "L"};
    FORTRAN(zhemm)(sidestr[side], uplostr[uplo], &m, &n, &alpha, a, &lda, b, &ldb, &beta, c, &ldc, (int32_t)1, (int32_t)1);
}



// GPU
template<> struct blas<gpu>
{
    template <typename T>
    static inline void gemm(int transa, int transb, int32_t m, int32_t n, int32_t k, T* alpha, T* a, int32_t lda, T* b, int32_t ldb, 
                            T* beta, T* c, int32_t ldc);
};

template<> inline void blas<gpu>::gemm<complex16>(int transa, int transb, int32_t m, int32_t n, int32_t k, complex16* alpha, 
                                                  complex16* a, int32_t lda, complex16* b, int32_t ldb, complex16* beta, 
                                                  complex16* c, int32_t ldc)
{
    cublas_zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, lda);
}


template<linalg_t> struct linalg;

template<> struct linalg<lapack>
{
    static int32_t ilaenv(int32_t ispec, const std::string& name, const std::string& opts, int32_t n1, int32_t n2, int32_t n3, 
                       int32_t n4)
    {
        return FORTRAN(ilaenv)(&ispec, name.c_str(), opts.c_str(), &n1, &n2, &n3, &n4, (int32_t)name.length(), 
                               (int32_t)opts.length());
    }
    
    template <typename T> 
    static int gesv(int32_t n, int32_t nrhs, T* a, int32_t lda, T* b, int32_t ldb);

    template <typename T> 
    static int gtsv(int32_t n, int32_t nrhs, T* dl, T* d, T* du, T* b, int32_t ldb);
};

template<> int linalg<lapack>::gesv<real8>(int32_t n, int32_t nrhs, real8* a, int32_t lda, real8* b, int32_t ldb)
{
    int32_t info;
    std::vector<int32_t> ipiv(n);

    FORTRAN(dgesv)(&n, &nrhs, a, &lda, &ipiv[0], b, &ldb, &info);

    return info;
}
<commit_msg>bugfix<commit_after>#ifndef __LINALG_H__
#define __LINALG_H__

/** \file linalg.h

    \brief Linear algebra interface

*/

#include <stdint.h>
#include <iostream>
#include <complex>
#include "config.h"
#include "linalg_cpu.h"

template<processing_unit_t> struct blas;

// CPU
template<> struct blas<cpu>
{
    template <typename T>
    static inline void gemm(int transa, int transb, int32_t m, int32_t n, int32_t k, T alpha, T* a, int32_t lda, T* b, int32_t ldb, 
                            T beta, T* c, int32_t ldc);
    
    template <typename T>
    static inline void gemm(int transa, int transb, int32_t m, int32_t n, int32_t k, T* a, int32_t lda, T* b, int32_t ldb, T* c, 
                            int32_t ldc);
    template<typename T>
    static inline void hemm(int side, int uplo, int32_t m, int32_t n, T alpha, T* a, int32_t lda, T* b, int32_t ldb, T beta, T* c, 
                            int32_t ldc);
};

template<> inline void blas<cpu>::gemm<real8>(int transa, int transb, int32_t m, int32_t n, int32_t k, real8 alpha, 
                                              real8* a, int32_t lda, real8* b, int32_t ldb, real8 beta, real8* c, 
                                              int32_t ldc)
{
    const char *trans[] = {"N", "T", "C"};

    FORTRAN(dgemm)(trans[transa], trans[transb], &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc, (int32_t)1, 
                   (int32_t)1);
}

template<> inline void blas<cpu>::gemm<real8>(int transa, int transb, int32_t m, int32_t n, int32_t k, real8* a, int32_t lda, 
                                              real8* b, int32_t ldb, real8* c, int32_t ldc)
{
    gemm(transa, transb, m, n, k, 1.0, a, lda, b, ldb, 0.0, c, ldc);
}

template<> inline void blas<cpu>::gemm<complex16>(int transa, int transb, int32_t m, int32_t n, int32_t k, complex16 alpha, 
                                                  complex16* a, int32_t lda, complex16* b, int32_t ldb, complex16 beta, 
                                                  complex16* c, int32_t ldc)
{
    const char *trans[] = {"N", "T", "C"};

    FORTRAN(zgemm)(trans[transa], trans[transb], &m, &n, &k, &alpha, a, &lda, b, &ldb, &beta, c, &ldc, (int32_t)1, 
                   (int32_t)1);
}

template<> inline void blas<cpu>::gemm<complex16>(int transa, int transb, int32_t m, int32_t n, int32_t k, complex16* a, 
                                                    int32_t lda, complex16* b, int32_t ldb, complex16* c, int32_t ldc)
{
    gemm(transa, transb, m, n, k, complex16(1, 0), a, lda, b, ldb, complex16(0, 0), c, ldc);
}

template<> inline void blas<cpu>::hemm<complex16>(int side, int uplo, int32_t m, int32_t n, complex16 alpha, complex16* a, 
                                                  int32_t lda, complex16* b, int32_t ldb, complex16 beta, complex16* c, 
                                                  int32_t ldc)
{
    const char *sidestr[] = {"L", "R"};
    const char *uplostr[] = {"U", "L"};
    FORTRAN(zhemm)(sidestr[side], uplostr[uplo], &m, &n, &alpha, a, &lda, b, &ldb, &beta, c, &ldc, (int32_t)1, (int32_t)1);
}



// GPU
template<> struct blas<gpu>
{
    template <typename T>
    static inline void gemm(int transa, int transb, int32_t m, int32_t n, int32_t k, T* alpha, T* a, int32_t lda, T* b, int32_t ldb, 
                            T* beta, T* c, int32_t ldc);
};

template<> inline void blas<gpu>::gemm<complex16>(int transa, int transb, int32_t m, int32_t n, int32_t k, complex16* alpha, 
                                                  complex16* a, int32_t lda, complex16* b, int32_t ldb, complex16* beta, 
                                                  complex16* c, int32_t ldc)
{
    cublas_zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc);
}


template<linalg_t> struct linalg;

template<> struct linalg<lapack>
{
    static int32_t ilaenv(int32_t ispec, const std::string& name, const std::string& opts, int32_t n1, int32_t n2, int32_t n3, 
                       int32_t n4)
    {
        return FORTRAN(ilaenv)(&ispec, name.c_str(), opts.c_str(), &n1, &n2, &n3, &n4, (int32_t)name.length(), 
                               (int32_t)opts.length());
    }
    
    template <typename T> 
    static int gesv(int32_t n, int32_t nrhs, T* a, int32_t lda, T* b, int32_t ldb);

    template <typename T> 
    static int gtsv(int32_t n, int32_t nrhs, T* dl, T* d, T* du, T* b, int32_t ldb);
};

template<> int linalg<lapack>::gesv<real8>(int32_t n, int32_t nrhs, real8* a, int32_t lda, real8* b, int32_t ldb)
{
    int32_t info;
    std::vector<int32_t> ipiv(n);

    FORTRAN(dgesv)(&n, &nrhs, a, &lda, &ipiv[0], b, &ldb, &info);

    return info;
}

{'fraction_non_alphanumeric': 0.13625147516360905, 'fraction_numerical': 0.054500590065443624, 'mean_word_length': 2.2244897959183674, 'pattern_counts': {'":': 0, '<': 81, '<?xml version=': 0, '>': 81, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 40, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '449645', 'n_tokens_mistral': 3876, 'n_tokens_neox': 3589, 'n_words': 1042}