##******************************************************************************
##  Copyright(C) 2008-2013 Intel Corporation. All Rights Reserved.
##  
##  The source code, information  and  material ("Material") contained herein is
##  owned  by Intel Corporation or its suppliers or licensors, and title to such
##  Material remains  with Intel Corporation  or its suppliers or licensors. The
##  Material  contains proprietary information  of  Intel or  its  suppliers and
##  licensors. The  Material is protected by worldwide copyright laws and treaty
##  provisions. No  part  of  the  Material  may  be  used,  copied, reproduced,
##  modified, published, uploaded, posted, transmitted, distributed or disclosed
##  in any way  without Intel's  prior  express written  permission. No  license
##  under  any patent, copyright  or  other intellectual property rights  in the
##  Material  is  granted  to  or  conferred  upon  you,  either  expressly,  by
##  implication, inducement,  estoppel or  otherwise.  Any  license  under  such
##  intellectual  property  rights must  be express  and  approved  by  Intel in
##  writing.
##  
##  *Third Party trademarks are the property of their respective owners.
##  
##  Unless otherwise  agreed  by Intel  in writing, you may not remove  or alter
##  this  notice or  any other notice embedded  in Materials by Intel or Intel's
##  suppliers or licensors in any way.
##
##******************************************************************************
##  Content:
##      Intel(R) Math Kernel Library. Service functions example creation and run
##******************************************************************************

help:
	@echo "MKL Service functions example help."
	@echo ""
	@echo "Usage: make Target [Options...]"
	@echo ""
	@echo "   Target:"
	@echo "       libia32    - statically linked example for processors that use the IA-32 architecture"
	@echo "       soia32     - dynamically linked example for processors that use the IA-32 architecture"
	@echo "       libintel64 - statically linked example for processors that use the Intel(R) 64 architecture"
	@echo "       sointel64  - dynamically linked example for processors that use the Intel(R) 64 architecture"
	@echo "       help       - print this help"
	@echo ""
	@echo "   Options:"
	@echo "       interface={lp64|ilp64}"
	@echo "           programming interface for intel64."
	@echo "           Default: lp64."
	@echo "       threading={parallel|sequential}"
	@echo "           Specifies whether to use MKL in the threaded or sequential mode."
	@echo "           Default: parallel."
	@echo "       compiler={intel|gnu}"
	@echo "           Specifies the compiler used to compile the example."
	@echo "           Default: intel."
	@echo "       MKLROOT=<MKL_directory>"
	@echo "           Specifies the location of Intel MKL libraries used to build this example."
	@echo "           Default: the Intel MKL installation directory."
	@echo ""
	@echo "Usage examples:"
	@echo ""
	@echo "   make libia32"
	@echo "       Link 'servicefuncs' example against parallel static MKL-IA32."
	@echo "   make sointel64 interface=ilp64 threading=sequential"
	@echo "       Link 'servicefuncs' example against sequential dynamic MKL-Intel64"
	@echo "       using ILP64 interface."
	@echo ""
#------------------------------------------------------------------------------

ifndef compiler
compiler=intel
else
ifneq ($(compiler),intel)
ifneq ($(compiler),gnu)
$(warning *** Wrong value compiler=$(compiler))
$(warning *** The correct values for compiler are intel or gnu)
$(error Try >make help)
endif
endif
endif

ifndef interface
interface=lp64
else
ifneq ($(interface),ilp64)
ifneq ($(interface),lp64)
$(warning *** Wrong value interface=$(interface))
$(warning *** The correct values for interface are lp64 or ilp64)
$(error Try >make help)
endif
endif
endif

ifndef threading
threading=parallel
else
ifneq ($(threading),parallel)
ifneq ($(threading),sequential)
$(warning *** Wrong value threading=$(threading))
$(warning *** The correct values for threading are parallel or sequential)
$(error Try >make help)
endif
endif
endif

RES = servicefuncs.res

ifdef _IA

EXT_S=a
EXT_D=so
EXT=$(EXT_$(SD))

S_GRP_S=-Wl,--start-group
E_GRP_S=-Wl,--end-group
S_GRP_D=
E_GRP_D=

RES_EXT_S=lib
RES_EXT_D=so

ifndef MKLROOT
  MKLROOT = ../..
endif
MKL_PATH = $(MKLROOT)/lib/$(_IA)
CMPLR_PATH = $(MKLROOT)/../compiler/lib/$(_IA)

ifeq ($(compiler),gnu)
  override COMPILER = gfortran
  OPTIONS = -fcray-pointer -x f77-cpp-input
  FCOPTS_END = -x none
  IFACE_COMP_PART = gf
  IFACE_THREADING_PART = gnu
else
  override COMPILER = ifort
  OPTIONS = -fpp
  FCOPTS_END =
  IFACE_COMP_PART = intel
  IFACE_THREADING_PART = intel
endif

ifeq ($(_IA),ia32)
  ifeq ($(interface),ilp64)
    $(warning  *** ILP64 interface is not available for MKL-IA32)
    $(error Try >make help)
  endif
  OPTIONS += -m32 # This option tells compiler to generate code for IA-32 architecture.
  ifeq ($(compiler),intel)
      # This option tells the compiler to generate optimized code
      # for Pentium or later processor.
      # If you don't need it, you can remove this option.
    OPTIONS += -mia32
  endif
  OPTIONS += -D_IA32 # This definition is needed for the example itself on IA-32 architecture.
  IFACE_SUFF=
else
  IFACE_SUFF=_$(interface)
endif

RES_DIR=_results/$(compiler)$(IFACE_SUFF)_$(threading)_$(_IA)_$(RES_EXT_$(SD))
IFACE_LIB="$(MKL_PATH)/libmkl_$(IFACE_COMP_PART)$(IFACE_SUFF).$(EXT)"

ifeq ($(interface),ilp64)
  ifeq ($(compiler),gnu)
    OPTIONS += -fdefault-integer-8
  else
    OPTIONS += -i8
  endif
endif

ifeq ($(threading),sequential)
  THREADING_LIB="$(MKL_PATH)/libmkl_sequential.$(EXT)"
  OMP_LIB =
else
  THREADING_LIB="$(MKL_PATH)/libmkl_$(IFACE_THREADING_PART)_thread.$(EXT)"
  OMP_LIB = -L"$(CMPLR_PATH)" -liomp5
endif

CORE_LIB="$(MKL_PATH)/libmkl_core.$(EXT)"

MKL_LIBS_S=$(IFACE_LIB) $(THREADING_LIB) $(CORE_LIB)
MKL_LIBS_D=$(IFACE_LIB) $(THREADING_LIB) $(CORE_LIB)

LABEL = $(compiler)$(IFACE_SUFF)_$(threading)_$(_IA)_$(RES_EXT_$(SD))
endif # ifdef _IA

#-------------------------------------------------------------------------------

ia32: libia32 soia32
intel64: libintel64 sointel64

libia32 lib32:
	@$(MAKE) $(RES) --no-print-directory SD=S _IA=ia32
soia32 so32:
	@$(MAKE) $(RES) --no-print-directory SD=D _IA=ia32
libintel64 libem64t:
	@$(MAKE) $(RES) --no-print-directory SD=S _IA=intel64
sointel64 soem64t:
	@$(MAKE) $(RES) --no-print-directory SD=D _IA=intel64

#-------------------------------------------------------------------------------

vpath %.f source

$(RES): %.res: %.f
	@mkdir -p ./$(RES_DIR)
	@echo ----- Compiling $(LABEL) -----
	$(COMPILER) $(OPTIONS) -I"$(MKLROOT)/include" \
	$< $(FCOPTS_END) \
	$(S_GRP_$(SD)) \
		$(IFACE_LIB) \
		$(THREADING_LIB) \
		$(CORE_LIB) \
	$(E_GRP_$(SD)) \
	$(OMP_LIB) \
	-lpthread -lm -ldl -o $(RES_DIR)/$*.out
	@echo ----- Execution $(LABEL) -----
	export LD_LIBRARY_PATH="$(MKL_PATH)":$(LD_LIBRARY_PATH):$(CMPLR_PATH); \
	$(RES_DIR)/$*.out > $(RES_DIR)/$@

#-------------------------------------------------------------------------------
