#ifndef MAGMA_D_SERVER_H
#define MAGMA_D_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 d Fri Nov 22 14:21:23 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_d_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_dcopy(magma_mic_dcopy_param dcopy_param);

void call_dgemm(magma_mic_dgemm_param dgemm_param);

void call_dsymm(magma_mic_dsymm_param dsymm_param);

void call_dgemv(magma_mic_dgemv_param dgemv_param);

void call_dsymv(magma_mic_dsymv_param symv_param);

void call_dsymv2(magma_mic_dsymv2_param symv_param);

void call_dtrsm(magma_mic_dtrsm_param dtrsm_param);

void call_dtrsv(magma_mic_dtrsv_param dtrsv_param);

void call_dtrmv(magma_mic_dtrmv_param trmv_param);

void call_dtrmm(magma_mic_dtrmm_param dtrmm_param);

void call_dsyrk(magma_mic_dsyrk_param dsyrk_param);

void call_dsyrk_mmic(magma_mic_dsyrk_mmic_param dsyrk_mmic_param);

void call_dsyr2k(magma_mic_dsyr2k_param dsyr2k_param);

void call_dsyr2k_mmic(magma_mic_dsyr2k_mmic_param dsyr2k_mmic_param);

void call_dlarft(magma_mic_dlarft_param dlarft_param);

void call_dlarfb(magma_mic_dlarfb_param dlarfb_param);

void call_dlarfb_gemm(magma_mic_dlarfb_gemm_param dlarfb_gemm_param);

void call_dlaset(magma_mic_dlaset_param dlaset_param);

void call_dtranspose(magma_mic_dtranspose_param dtranspose_param);

void call_dtranspose_mkl(magma_mic_dtranspose_param dtranspose_param);

void call_dlaswp(magma_mic_dlaswp_param dlaswp_param);

void call_dswap(magma_mic_dswap_param dswap_param);

void call_dtrsmgemm(magma_mic_dtrsmgemm_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_D_SERVER_H
