#ifndef MAGMA_S_SERVER_H
#define MAGMA_S_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 s 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_s_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_scopy(magma_mic_scopy_param scopy_param);

void call_sgemm(magma_mic_sgemm_param sgemm_param);

void call_ssymm(magma_mic_ssymm_param ssymm_param);

void call_sgemv(magma_mic_sgemv_param sgemv_param);

void call_ssymv(magma_mic_ssymv_param symv_param);

void call_ssymv2(magma_mic_ssymv2_param symv_param);

void call_strsm(magma_mic_strsm_param strsm_param);

void call_strsv(magma_mic_strsv_param strsv_param);

void call_strmv(magma_mic_strmv_param trmv_param);

void call_strmm(magma_mic_strmm_param strmm_param);

void call_ssyrk(magma_mic_ssyrk_param ssyrk_param);

void call_ssyrk_mmic(magma_mic_ssyrk_mmic_param ssyrk_mmic_param);

void call_ssyr2k(magma_mic_ssyr2k_param ssyr2k_param);

void call_ssyr2k_mmic(magma_mic_ssyr2k_mmic_param ssyr2k_mmic_param);

void call_slarft(magma_mic_slarft_param slarft_param);

void call_slarfb(magma_mic_slarfb_param slarfb_param);

void call_slarfb_gemm(magma_mic_slarfb_gemm_param slarfb_gemm_param);

void call_slaset(magma_mic_slaset_param slaset_param);

void call_stranspose(magma_mic_stranspose_param stranspose_param);

void call_stranspose_mkl(magma_mic_stranspose_param stranspose_param);

void call_slaswp(magma_mic_slaswp_param slaswp_param);

void call_sswap(magma_mic_sswap_param sswap_param);

void call_strsmgemm(magma_mic_strsmgemm_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_S_SERVER_H
