// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2021 Erik Schultheis <erik.schultheis@aalto.fi>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.

#ifndef EIGEN_LAPACKE_HELPERS_H
#define EIGEN_LAPACKE_HELPERS_H

#include "./InternalHeaderCheck.h"

#ifdef EIGEN_USE_MKL
#include "mkl_lapacke.h"
#else
#include "lapacke.h"
#endif

namespace Eigen {
namespace internal {
/**
 * \internal
 * \brief Implementation details and helper functions for the lapacke glue code.
 */
namespace lapacke_helpers {

// ---------------------------------------------------------------------------------------------------------------------
//                  Translation from Eigen to Lapacke for types and constants
// ---------------------------------------------------------------------------------------------------------------------

// For complex numbers, the types in Eigen and Lapacke are different, but layout compatible.
template<typename Scalar>
struct translate_type_imp;
template<>
struct translate_type_imp<float> {
    using type = float;
};
template<>
struct translate_type_imp<double> {
    using type = double;
};
template<>
struct translate_type_imp<std::complex<double>> {
    using type = lapack_complex_double;
};
template<>
struct translate_type_imp<std::complex<float>> {
    using type = lapack_complex_float;
};

/// Given an Eigen types, this is defined to be the corresponding, layout-compatible lapack type
template<typename Scalar>
using translated_type = typename translate_type_imp<Scalar>::type;

/// These functions convert their arguments from Eigen to Lapack types
/// This function performs conversion for any of the translations defined above.
template<typename Source, typename Target=translated_type<Source>>
EIGEN_ALWAYS_INLINE auto to_lapack(Source value) { return static_cast<Target>(value); }

/// This function performs conversions for pointer types corresponding to the translations abovce.
/// This is valid because the translations are between layout-compatible types.
template<typename Source, typename Target=translated_type<Source>>
EIGEN_ALWAYS_INLINE auto to_lapack(Source *value) { return reinterpret_cast<Target*>(value); }

/// This function converts the Eigen Index to a lapack index, with possible range checks
/// \sa internal::convert_index
EIGEN_ALWAYS_INLINE lapack_int to_lapack(Index index) {
  return convert_index<lapack_int>(index);
}

/// translates storage order of the given Eigen object to the corresponding lapack constant
template<typename Derived>
EIGEN_ALWAYS_INLINE EIGEN_CONSTEXPR lapack_int lapack_storage_of(const EigenBase<Derived> &) {
  return Derived::IsRowMajor ? LAPACK_ROW_MAJOR : LAPACK_COL_MAJOR;
}

/// translate UpLo type to the corresponding letter code
template<UpLoType mode> char translate_mode;
template<> constexpr char translate_mode<Lower> = 'L';
template<> constexpr char translate_mode<Upper> = 'U';


// ---------------------------------------------------------------------------------------------------------------------
//              Automatic generation of low-level wrappers
// ---------------------------------------------------------------------------------------------------------------------

/*!
 * \internal
 * \brief Helper type to facilitate the wrapping of raw LAPACKE functions for different types into a single, overloaded C++ function.
 * This is achieved in combination with \r EIGEN_MAKE_LAPACKE_WRAPPER
 * \details This implementation works by providing an overloaded call function that just forwards its arguments to the
 * underlying lapack function. Each of these overloads is enabled only if the call is actually well formed.
 * Because these lapack functions take pointers to the underlying scalar type as arguments, even though the actual Scalars
 * would be implicitly convertible, the pointers are not and therefore only a single overload can be valid at the same time.
 * Thus, despite all functions taking fully generic `Args&&... args` as arguments, there is never any ambiguity.
 */
template<typename DoubleFn, typename SingleFn, typename DoubleCpxFn, typename SingleCpxFn>
struct WrappingHelper {
  // The naming of double, single, double complex and single complex is purely for readability
  // and doesn't actually affect the workings of this class. In principle, the arguments can
  // be supplied in any permuted order.
  DoubleFn double_; SingleFn single_; DoubleCpxFn double_cpx_; SingleCpxFn single_cpx_;

  template<typename... Args>
  auto call(Args&&... args) -> decltype(double_(std::forward<Args>(args)...)) {
    return double_(std::forward<Args>(args)...);
  }

  template<typename... Args>
  auto call(Args&&... args) -> decltype(single_(std::forward<Args>(args)...)){
    return single_(std::forward<Args>(args)...);
  }

  template<typename... Args>
  auto call(Args&&... args) -> decltype(double_cpx_(std::forward<Args>(args)...)){
    return double_cpx_(std::forward<Args>(args)...);
  }

  template<typename... Args>
  auto call(Args&&... args) -> decltype(single_cpx_(std::forward<Args>(args)...)){
    return single_cpx_(std::forward<Args>(args)...);
  }
};

/** \internal Helper function that generates a `WrappingHelper` object with the given function pointers and
 * invokes its `call` method, thus selecting one of the overloads.
 * \sa EIGEN_MAKE_LAPACKE_WRAPPER
 */
template<typename DoubleFn, typename SingleFn, typename DoubleCpxFn, typename SingleCpxFn, typename... Args>
EIGEN_ALWAYS_INLINE auto call_wrapper(DoubleFn df, SingleFn sf, DoubleCpxFn dcf, SingleCpxFn scf, Args&&... args) {
  WrappingHelper<DoubleFn, SingleFn, DoubleCpxFn, SingleCpxFn> helper{df, sf, dcf, scf};
  return helper.call(std::forward<Args>(args)...);
}

/**
 * \internal
 * Generates a new function `Function` that dispatches to the corresponding LAPACKE_? prefixed functions.
 * \sa WrappingHelper
 */
#define EIGEN_MAKE_LAPACKE_WRAPPER(FUNCTION) \
template<typename... Args> \
EIGEN_ALWAYS_INLINE auto FUNCTION(Args&&... args) { return call_wrapper(LAPACKE_d##FUNCTION, LAPACKE_s##FUNCTION, LAPACKE_z##FUNCTION, LAPACKE_c##FUNCTION, std::forward<Args>(args)...); }

// Now with this macro and the helper wrappers, we can generate the dispatch for all the lapacke functions that are
// used in Eigen.
// We define these here instead of in the files where they are used because this allows us to #undef the macro again
// right here
EIGEN_MAKE_LAPACKE_WRAPPER(potrf)
EIGEN_MAKE_LAPACKE_WRAPPER(getrf)
EIGEN_MAKE_LAPACKE_WRAPPER(geqrf)

#undef EIGEN_MAKE_LAPACKE_WRAPPER
}
}
}

#endif // EIGEN_LAPACKE_HELPERS_H
