#ifndef MAGMA_C_SERVER_H
#define MAGMA_C_SERVER_H

/*
 *   -- micMAGMA (version 0.1) --
 *      Univ. of Tennessee, Knoxville
 *      Univ. of California, Berkeley
 *      Univ. of Colorado, Denver
 *      April 2012
 *
 *   @author Azzam Haidar
 *   @author Khairul Kabir 
 *
 *   @generated c Fri Nov 22 14:21:24 2013
 */

#include <mkl.h>

#include <mkl_trans.h>
#include <scif.h>
#include <fcntl.h>
#include <offload.h>

#if 0
#ifdef __MIC__
#define _M512_TYPED
#include <lmmintrin.h>
#endif
#endif
//#include <immintrin.h>

#include "magma.h"
#include "magma_c_bindings.h"

// Flops formula
#define MICFMULS_GEMM(m, n, k) ((m) * (n) * (k))
#define MICFADDS_GEMM(m, n, k) ((m) * (n) * (k))
#define MICFMULS_SYMM(side, m, n) (((side) == MagmaLeft) ? MICFMULS_GEMM(m, m, n) : MICFMULS_GEMM(m, n, n))
#define MICFADDS_SYMM(side, m, n) (((side) == MagmaLeft) ? MICFADDS_GEMM(m, m, n) : MICFADDS_GEMM(m, n, n))
#define MICFMULS_GEMV(m, n)   ((m) * (n))
#define MICFADDS_GEMV(m, n)   ((m) * (n))
#define MICFMULS_TRMM_L(m, n) (0.5 * (n) * (m) * ((m)+1))
#define MICFADDS_TRMM_L(m, n) (0.5 * (n) * (m) * ((m)-1))
#define MICFMULS_TRMM_R(m, n) (0.5 * (m) * (n) * ((n)+1))
#define MICFADDS_TRMM_R(m, n) (0.5 * (m) * (n) * ((n)-1))
#define MICFMULS_TRSM_L(m, n) (0.5 * (n) * (m) * ((m)+1))
#define MICFADDS_TRSM_L(m, n) (0.5 * (n) * (m) * ((m)-1))
#define MICFMULS_TRSM_R(m, n) (0.5 * (m) * (n) * ((n)+1))
#define MICFADDS_TRSM_R(m, n) (0.5 * (m) * (n) * ((n)-1))
#define MICFMULS_SYRK(k, n) (0.5 * (k) * (n) * ((n)+1))
#define MICFADDS_SYRK(k, n) (0.5 * (k) * (n) * ((n)+1))
#define MICFMULS_SYR2K(k, n) ((k) * (n) * (n)        )
#define MICFADDS_SYR2K(k, n) ((k) * (n) * (n) + (n)  )

#define MICFLOPS_GEMM(m, n, k) (MICFMULS_GEMM(m, n, k) + MICFADDS_GEMM(m, n, k))
#define MICFLOPS_SYMM(side, m, n) (MICFMULS_SYMM(side, m, n) + MICFADDS_SYMM(side, m, n))
#define MICFLOPS_GEMV(m, n)    (MICFMULS_GEMV(m, n) + MICFADDS_GEMV(m, n))
#define MICFLOPS_TRSM_L(m, n)  (MICFMULS_TRSM_L(m, n) + MICFADDS_TRSM_L(m, n))
#define MICFLOPS_TRSM_R(m, n)  (MICFMULS_TRSM_R(m, n) + MICFADDS_TRSM_R(m, n))

#define MICFLOPS_SYRK(k, n)    (MICFMULS_SYRK(k, n) + MICFADDS_SYRK(k, n))
#define MICFLOPS_SYR2K(k, n)   (MICFMULS_SYR2K(k, n) + MICFADDS_SYR2K(k, n))

void call_ccopy(magma_mic_ccopy_param ccopy_param);

void call_cgemm(magma_mic_cgemm_param cgemm_param);

void call_chemm(magma_mic_chemm_param chemm_param);

void call_cgemv(magma_mic_cgemv_param cgemv_param);

void call_chemv(magma_mic_chemv_param hemv_param);

void call_csymv2(magma_mic_csymv2_param symv_param);

void call_ctrsm(magma_mic_ctrsm_param ctrsm_param);

void call_ctrsv(magma_mic_ctrsv_param ctrsv_param);

void call_ctrmv(magma_mic_ctrmv_param trmv_param);

void call_ctrmm(magma_mic_ctrmm_param ctrmm_param);

void call_cherk(magma_mic_cherk_param cherk_param);

void call_cherk_mmic(magma_mic_cherk_mmic_param cherk_mmic_param);

void call_cher2k(magma_mic_cher2k_param cher2k_param);

void call_cher2k_mmic(magma_mic_cher2k_mmic_param cher2k_mmic_param);

void call_clarft(magma_mic_clarft_param clarft_param);

void call_clarfb(magma_mic_clarfb_param clarfb_param);

void call_clarfb_gemm(magma_mic_clarfb_gemm_param clarfb_gemm_param);

void call_claset(magma_mic_claset_param claset_param);

void call_ctranspose(magma_mic_ctranspose_param ctranspose_param);

void call_ctranspose_mkl(magma_mic_ctranspose_param ctranspose_param);

void call_claswp(magma_mic_claswp_param claswp_param);

void call_cswap(magma_mic_cswap_param cswap_param);

void call_ctrsmgemm(magma_mic_ctrsmgemm_param trsmgemm_param);

#define SREG_WIDTH 16
#define DREG_WIDTH 8

#define _MM512_LOAD_PPS _mm512_load_ps
#define _MM512_LOAD_PPD _mm512_load_pd

#define _MM512_STORE_PPS _mm512_store_ps
#define _MM512_STORE_PPD _mm512_store_pd

#define _MM512_I32LOEXTSCATTER_PPS _mm512_i32extscatter_ps
#define _MM512_I32LOEXTSCATTER_PPD _mm512_i32loextscatter_pd

#define __M512S __m512
#define __M512D __m512d
#endif // MAGMA_C_SERVER_H
