<commit_before>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <blas.hpp>

#ifdef USE_MKL
#include <mkl_cblas.h>
#endif

#include <Array.hpp>
#include <Param.hpp>
#include <cast.hpp>
#include <common/blas_headers.hpp>
#include <common/complex.hpp>
#include <common/err_common.hpp>
#include <common/half.hpp>
#include <copy.hpp>
#include <kernel/dot.hpp>
#include <platform.hpp>
#include <types.hpp>

#include <af/defines.h>
#include <af/dim4.hpp>
#include <af/traits.hpp>

#include <algorithm>
#include <type_traits>
#include <vector>

using af::dtype_traits;
using common::half;
using common::is_complex;
using std::add_const;
using std::add_pointer;
using std::conditional;
using std::enable_if;
using std::is_floating_point;
using std::remove_const;
using std::vector;

namespace cpu {

// clang-format off
// Some implementations of BLAS require void* for complex pointers while others
// use float*/double*
//
// Sample cgemm API
// OpenBLAS
// void cblas_cgemm(OPENBLAS_CONST enum CBLAS_ORDER Order,
//                  OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA,
//                  OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB,
//                  OPENBLAS_CONST blasint M,
//                  OPENBLAS_CONST blasint N,
//                  OPENBLAS_CONST blasint K,
//                  OPENBLAS_CONST float *alpha, OPENBLAS_CONST float *A,
//                  OPENBLAS_CONST blasint lda,
//                  OPENBLAS_CONST float *B, OPENBLAS_CONST blasint ldb,
//                  OPENBLAS_CONST float *beta,
//                  float *C, OPENBLAS_CONST blasint ldc);
//
// MKL
// void cblas_cgemm(const  CBLAS_LAYOUT Layout,
//                  const CBLAS_TRANSPOSE TransA, const  CBLAS_TRANSPOSE TransB,
//                  const MKL_INT M, const MKL_INT N, const MKL_INT K,
//                  const void *alpha, const void *A, const MKL_INT lda,
//                  const void *B, const MKL_INT ldb, const void *beta,
//                  void *C, const MKL_INT ldc);
// void cblas_cgemm_batch(const  CBLAS_LAYOUT Layout,
//                        const CBLAS_TRANSPOSE* TransA,
//                        const CBLAS_TRANSPOSE* TransB,
//                        const MKL_INT* M, const MKL_INT* N, const MKL_INT* K,
//                        const void *alpha, const void **A, const MKL_INT* lda,
//                        const void **B, const MKL_INT* ldb, const void *beta,
//                        void **C, const MKL_INT* ldc,
//                        const MKL_INT group_count, const MKL_INT* group_size);
//
// atlas cblas
// void cblas_cgemm(const enum CBLAS_ORDER Order,
//                  const enum CBLAS_TRANSPOSE TransA,
//                  const enum CBLAS_TRANSPOSE TransB,
//                  const int M, const int N, const int K,
//                  const void *alpha, const void *A, const int lda,
//                  const void *B, const int ldb, const void *beta,
//                  void *C, const int ldc);
//
// LAPACKE
// void cblas_cgemm(const enum CBLAS_ORDER Order,
//                  const enum CBLAS_TRANSPOSE TransA,
//                  const enum CBLAS_TRANSPOSE TransB,
//                  const int M, const int N, const int K,
//                  const void *alpha, const void *A, const int lda,
//                  const void *B, const int ldb, const void *beta,
//                  void *C, const int ldc);
// clang-format on

template<typename T>
struct blas_base {
    using type =
        typename conditional<is_complex<T>::value && cplx_void_ptr, void,
                             typename dtype_traits<T>::base_type>::type;
};

template<typename T>
using cptr_type =
    typename conditional<is_complex<T>::value,
                         const typename blas_base<T>::type *, const T *>::type;
template<typename T>
using ptr_type = typename conditional<is_complex<T>::value,
                                      typename blas_base<T>::type *, T *>::type;

template<typename T, bool batched = false>
struct scale_type {
    const T val;
    scale_type(const T* val_ptr)
        : val(*val_ptr){}
    using api_type = const typename conditional<is_complex<T>::value,
                                                const typename blas_base<T>::type *,
                                                const typename conditional<batched,  const T*, const T>::type>::type;

    api_type getScale() const;
};

template<typename T, bool batched>
typename scale_type<T, batched>::api_type scale_type<T, batched>::getScale() const {
    return val;
}

#define INSTANTIATE_BATCHED(TYPE)                                                    \
template<>                                                                           \
typename scale_type<TYPE, true>::api_type scale_type<TYPE, true>::getScale() const { \
    return &val;                                                                     \
}

INSTANTIATE_BATCHED(float);
INSTANTIATE_BATCHED(double);
#undef INSTANTIATE_BATCHED

#define INSTANTIATE_COMPLEX(TYPE, BATCHED)                                        \
template<>                                                                        \
scale_type<TYPE, BATCHED>::api_type scale_type<TYPE, BATCHED>::getScale() const { \
    return reinterpret_cast<const blas_base<TYPE>::type * const>(&val);           \
}

INSTANTIATE_COMPLEX(cfloat, true);
INSTANTIATE_COMPLEX(cfloat, false);
INSTANTIATE_COMPLEX(cdouble, true);<commit_msg>move function definition of scale_type struct<commit_after>/*******************************************************
 * Copyright (c) 2014, ArrayFire
 * All rights reserved.
 *
 * This file is distributed under 3-clause BSD license.
 * The complete license agreement can be obtained at:
 * http://arrayfire.com/licenses/BSD-3-Clause
 ********************************************************/

#include <blas.hpp>

#ifdef USE_MKL
#include <mkl_cblas.h>
#endif

#include <Array.hpp>
#include <Param.hpp>
#include <cast.hpp>
#include <common/blas_headers.hpp>
#include <common/complex.hpp>
#include <common/err_common.hpp>
#include <common/half.hpp>
#include <copy.hpp>
#include <kernel/dot.hpp>
#include <platform.hpp>
#include <types.hpp>

#include <af/defines.h>
#include <af/dim4.hpp>
#include <af/traits.hpp>

#include <algorithm>
#include <type_traits>
#include <vector>

using af::dtype_traits;
using common::half;
using common::is_complex;
using std::add_const;
using std::add_pointer;
using std::conditional;
using std::enable_if;
using std::is_floating_point;
using std::remove_const;
using std::vector;

namespace cpu {

// clang-format off
// Some implementations of BLAS require void* for complex pointers while others
// use float*/double*
//
// Sample cgemm API
// OpenBLAS
// void cblas_cgemm(OPENBLAS_CONST enum CBLAS_ORDER Order,
//                  OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA,
//                  OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB,
//                  OPENBLAS_CONST blasint M,
//                  OPENBLAS_CONST blasint N,
//                  OPENBLAS_CONST blasint K,
//                  OPENBLAS_CONST float *alpha, OPENBLAS_CONST float *A,
//                  OPENBLAS_CONST blasint lda,
//                  OPENBLAS_CONST float *B, OPENBLAS_CONST blasint ldb,
//                  OPENBLAS_CONST float *beta,
//                  float *C, OPENBLAS_CONST blasint ldc);
//
// MKL
// void cblas_cgemm(const  CBLAS_LAYOUT Layout,
//                  const CBLAS_TRANSPOSE TransA, const  CBLAS_TRANSPOSE TransB,
//                  const MKL_INT M, const MKL_INT N, const MKL_INT K,
//                  const void *alpha, const void *A, const MKL_INT lda,
//                  const void *B, const MKL_INT ldb, const void *beta,
//                  void *C, const MKL_INT ldc);
// void cblas_cgemm_batch(const  CBLAS_LAYOUT Layout,
//                        const CBLAS_TRANSPOSE* TransA,
//                        const CBLAS_TRANSPOSE* TransB,
//                        const MKL_INT* M, const MKL_INT* N, const MKL_INT* K,
//                        const void *alpha, const void **A, const MKL_INT* lda,
//                        const void **B, const MKL_INT* ldb, const void *beta,
//                        void **C, const MKL_INT* ldc,
//                        const MKL_INT group_count, const MKL_INT* group_size);
//
// atlas cblas
// void cblas_cgemm(const enum CBLAS_ORDER Order,
//                  const enum CBLAS_TRANSPOSE TransA,
//                  const enum CBLAS_TRANSPOSE TransB,
//                  const int M, const int N, const int K,
//                  const void *alpha, const void *A, const int lda,
//                  const void *B, const int ldb, const void *beta,
//                  void *C, const int ldc);
//
// LAPACKE
// void cblas_cgemm(const enum CBLAS_ORDER Order,
//                  const enum CBLAS_TRANSPOSE TransA,
//                  const enum CBLAS_TRANSPOSE TransB,
//                  const int M, const int N, const int K,
//                  const void *alpha, const void *A, const int lda,
//                  const void *B, const int ldb, const void *beta,
//                  void *C, const int ldc);
// clang-format on

template<typename T>
struct blas_base {
    using type =
        typename conditional<is_complex<T>::value && cplx_void_ptr, void,
                             typename dtype_traits<T>::base_type>::type;
};

template<typename T>
using cptr_type =
    typename conditional<is_complex<T>::value,
                         const typename blas_base<T>::type *, const T *>::type;
template<typename T>
using ptr_type = typename conditional<is_complex<T>::value,
                                      typename blas_base<T>::type *, T *>::type;

template<typename T, bool batched = false>
struct scale_type {
    const T val;
    scale_type(const T* val_ptr)
        : val(*val_ptr){}
    using api_type = const typename conditional<is_complex<T>::value,
                                                const typename blas_base<T>::type *,
                                                const typename conditional<batched,  const T*, const T>::type>::type;

    api_type getScale() const {
		return val;
	}
};


#define INSTANTIATE_BATCHED(TYPE)                                                    \
template<>                                                                           \
typename scale_type<TYPE, true>::api_type scale_type<TYPE, true>::getScale() const { \
    return &val;                                                                     \
}

INSTANTIATE_BATCHED(float);
INSTANTIATE_BATCHED(double);
#undef INSTANTIATE_BATCHED

#define INSTANTIATE_COMPLEX(TYPE, BATCHED)                                        \
template<>                                                                        \
scale_type<TYPE, BATCHED>::api_type scale_type<TYPE, BATCHED>::getScale() const { \
    return reinterpret_cast<const blas_base<TYPE>::type * const>(&val);           \
}

INSTANTIATE_COMPLEX(cfloat, true);
INSTANTIATE_COMPLEX(cfloat, false);
INSTANTIATE_COMPLEX(cdouble, true);
{'fraction_non_alphanumeric': 0.11975199291408326, 'fraction_numerical': 0.0012400354295837024, 'mean_word_length': 1.9909933774834436, 'pattern_counts': {'":': 0, '<': 94, '<?xml version=': 0, '>': 94, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 32, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7626009', 'n_tokens_mistral': 3468, 'n_tokens_neox': 3281, 'n_words': 894}