/* -----------------------------------------------------------------
 * Programmer: Cody J. Balos @ LLNL
 * -----------------------------------------------------------------
 * SUNDIALS Copyright Start
 * Copyright (c) 2025-2026, Lawrence Livermore National Security,
 * University of Maryland Baltimore County, and the SUNDIALS contributors.
 * Copyright (c) 2013-2025, Lawrence Livermore National Security
 * and Southern Methodist University.
 * Copyright (c) 2002-2013, Lawrence Livermore National Security.
 * All rights reserved.
 *
 * See the top-level LICENSE and NOTICE files for details.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 * SUNDIALS Copyright End
 * -----------------------------------------------------------------*/

#ifndef _SUNDIALS_LAPACK_H
#define _SUNDIALS_LAPACK_H

#include <sundials/sundials_types.h>

#ifdef __cplusplus /* wrapper to enable C++ usage */
extern "C" {
#endif

/* Define LAPACK name-mangling macros. Depending on the inferred scheme, one of
 * the following six macros will be defined:
 *
 * #define SUNDIALS_LAPACK_FUNC(name,NAME) name
 * #define SUNDIALS_LAPACK_FUNC(name,NAME) name ## _
 * #define SUNDIALS_LAPACK_FUNC(name,NAME) name ## __
 * #define SUNDIALS_LAPACK_FUNC(name,NAME) NAME
 * #define SUNDIALS_LAPACK_FUNC(name,NAME) NAME ## _
 * #define SUNDIALS_LAPACK_FUNC(name,NAME) NAME ## __
 */
#define SUNDIALS_LAPACK_FUNC(name,NAME) name ## _

/* Define LAPACK name-mangling macro for C identifiers
 * which contain underscores.
 */
#define SUNDIALS_LAPACK_FUNC_(name,NAME) name ## _

/*
 * ==================================================================
 * Blas and Lapack functions
 * ==================================================================
 */

#if defined(SUNDIALS_LAPACK_FUNC)

#define dgbtrf_f77 SUNDIALS_LAPACK_FUNC(dgbtrf, DGBTRF)
#define dgbtrs_f77 SUNDIALS_LAPACK_FUNC(dgbtrs, DGBTRS)
#define dgetrf_f77 SUNDIALS_LAPACK_FUNC(dgetrf, DGETRF)
#define dgetrs_f77 SUNDIALS_LAPACK_FUNC(dgetrs, DGETRS)
#define dgeev_f77  SUNDIALS_LAPACK_FUNC(dgeev, DGEEV)

#define sgbtrf_f77 SUNDIALS_LAPACK_FUNC(sgbtrf, SGBTRF)
#define sgbtrs_f77 SUNDIALS_LAPACK_FUNC(sgbtrs, SGBTRS)
#define sgetrf_f77 SUNDIALS_LAPACK_FUNC(sgetrf, SGETRF)
#define sgetrs_f77 SUNDIALS_LAPACK_FUNC(sgetrs, SGETRS)
#define sgeev_f77  SUNDIALS_LAPACK_FUNC(sgeev, SGEEV)

#else

#define dgbtrf_f77 dgbtrf_
#define dgbtrs_f77 dgbtrs_
#define dgetrf_f77 dgetrf_
#define dgetrs_f77 dgetrs_
#define dgeev_f77  dgeev_

#define sgbtrf_f77 sgbtrf_
#define sgbtrs_f77 sgbtrs_
#define sgetrf_f77 sgetrf_
#define sgetrs_f77 sgetrs_
#define sgeev_f77  sgeev_

#endif

/* LAPACK */

extern void dgbtrf_f77(const sunindextype* m, const sunindextype* n,
                       const sunindextype* kl, const sunindextype* ku,
                       double* ab, sunindextype* ldab, sunindextype* ipiv,
                       sunindextype* info);

extern void dgbtrs_f77(const char* trans, const sunindextype* n,
                       const sunindextype* kl, const sunindextype* ku,
                       const sunindextype* nrhs, double* ab,
                       const sunindextype* ldab, sunindextype* ipiv, double* b,
                       const sunindextype* ldb, sunindextype* info);

extern void dgetrf_f77(const sunindextype* m, const sunindextype* n, double* a,
                       sunindextype* lda, sunindextype* ipiv, sunindextype* info);

extern void dgetrs_f77(const char* trans, const sunindextype* n,
                       const sunindextype* nrhs, double* a,
                       const sunindextype* lda, sunindextype* ipiv, double* b,
                       const sunindextype* ldb, sunindextype* info);

extern void dgeev_f77(const char* jobvl, const char* jobvr, const sunindextype* n,
                      double* a, const sunindextype* lda, double* wr, double* wi,
                      double* vl, const sunindextype* ldvl, double* vr,
                      const sunindextype* ldvr, double* work,
                      const sunindextype* lwork, sunindextype* info);

extern void sgbtrf_f77(const sunindextype* m, const sunindextype* n,
                       const sunindextype* kl, const sunindextype* ku,
                       float* ab, sunindextype* ldab, sunindextype* ipiv,
                       sunindextype* info);

extern void sgbtrs_f77(const char* trans, const sunindextype* n,
                       const sunindextype* kl, const sunindextype* ku,
                       const sunindextype* nrhs, float* ab,
                       const sunindextype* ldab, sunindextype* ipiv, float* b,
                       const sunindextype* ldb, sunindextype* info);

extern void sgetrf_f77(const sunindextype* m, const sunindextype* n, float* a,
                       sunindextype* lda, sunindextype* ipiv, sunindextype* info);

extern void sgetrs_f77(const char* trans, const sunindextype* n,
                       const sunindextype* nrhs, float* a,
                       const sunindextype* lda, sunindextype* ipiv, float* b,
                       const sunindextype* ldb, sunindextype* info);

extern void sgeev_f77(const char* jobvl, const char* jobvr, const sunindextype* n,
                      float* a, const sunindextype* lda, float* wr, float* wi,
                      float* vl, const sunindextype* ldvl, float* vr,
                      const sunindextype* ldvr, float* work,
                      const sunindextype* lwork, sunindextype* info);

#ifdef __cplusplus
}
#endif

#endif
