##******************************************************************************
##                              INTEL CONFIDENTIAL
##  Copyright(C) 2008-2010 Intel Corporation. All Rights Reserved.
##  The source code contained  or  described herein and all documents related to
##  the source code ("Material") are owned by Intel Corporation or its suppliers
##  or licensors.  Title to the  Material remains with  Intel Corporation or its
##  suppliers and licensors. The Material contains trade secrets and proprietary
##  and  confidential  information of  Intel or its suppliers and licensors. The
##  Material  is  protected  by  worldwide  copyright  and trade secret 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, trade secret or other intellectual
##  property right is granted to or conferred upon you by disclosure or delivery
##  of the Materials,  either expressly, by implication, inducement, estoppel or
##  otherwise.  Any  license  under  such  intellectual property  rights must be
##  express and approved by Intel in writing.
##
##******************************************************************************
##  Content:
##      Intel(R) Math Kernel Library. Service functions example creation and run
##******************************************************************************

help:
	@echo "Usage: make {lib32|so32|lib64|so64|libem64t|soem64t}"
	@echo "      [compiler=compiler_name]"
	@echo "      [interface=interface_name]"
	@echo "      [threading=threading_name]"
	@echo ""
	@echo "   compiler_name  - can be gnu or intel. Default value is intel."
	@echo "                    If compiler=gnu then GNU gfortran compiler will be used."
	@echo "                    Note: GNU g77 compiler is not supported."
	@echo ""
	@echo "   interface_name - can be lp64 or ilp64 for em64t and ia64. Default value is lp64."
	@echo ""
	@echo "   threading_name - can be parallel or sequential. Default value is parallel."
#------------------------------------------------------------------------------
#	@echo ""
#	@echo "Usage examples:"
#	@echo ""
#	@echo "make lib32"
#	@echo "   Compile 'servicefuncs' example by Intel(R) C/Fortran compilers,"
#	@echo "   link against parallel static MKL-IA32 using LP64 interface and"
#	@echo "   run 'servicefuncs' example."
#	@echo ""
#	@echo "make soem64t interface=ilp64 threading=sequential"
#	@echo "   Compile 'servicefuncs' example by Intel(R) C/Fortran compilers,"
#	@echo "   link against sequential dynamic MKL-EM64T using ILP64 interface and"
#	@echo "   run 'servicefuncs' example."
#	@echo ""
#	@echo "make so64 compiler=gnu"
#	@echo "   Compile 'servicefuncs' example by GNU C/Fortran compilers (gfortran),"
#	@echo "   link against parallel dynamic MKL-IA64 using LP64 interface and"
#	@echo "   run 'servicefuncs' example."
#	@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

RESC = servicefuncs_c.res
RESF = servicefuncs_f.res

ifndef MKLROOT
MKLROOT=../..
MKL_PATH = "$(subst examples/servicefuncs,lib/$(_IA),$(PWD))"
else
MKL_PATH = "$(MKLROOT)/lib/$(_IA)"
endif

ifeq ($(compiler),gnu)
CC=gcc
FC=gfortran
IFACE_COMP_PART=intel
IFACE_THREADING_PART=intel
else
override CC=icc
override FC=ifort
IFACE_COMP_PART=intel
IFACE_THREADING_PART=intel
endif

ifeq ($(interface),ilp64)
ifeq ($(_IA),32)
$(warning  *** ILP64 interface is not available for MKL-IA32)
$(warning  *** Try >nmake help)
$(error )
endif
IFACE_LIB=$(MKL_PATH)/libmkl_$(IFACE_COMP_PART)_ilp64.$(EXT)
COPTS = -DMKL_ILP64
FOPTS = -i8
ifeq ($(compiler),gnu)
override FC=gfortran
FOPTS=-fdefault-integer-8
endif
else
IFACE_LIB=$(MKL_PATH)/libmkl_$(IFACE_COMP_PART)_lp64.$(EXT)
COPTS =
FOPTS =
endif

ifeq ($(_IA),32)
   ifeq ($(compiler),intel)
       SPEC_OPT=-xK
#This option is required by Intel(R) 11.0 compiler to produce workable binaries for Pentium(R) III.
#If you don't need it, you can remove this option.
   endif
IFACE_LIB=$(MKL_PATH)/libmkl_$(IFACE_COMP_PART).$(EXT)
COPTS =
FOPTS += -D_IA32
endif

ifeq ($(compiler),gnu)
ifeq ($(FC),gfortran)
else
$(warning ***)
$(warning *** GNU g77 is not supported by this test)
$(warning ***)
$(error Try >make help)
endif

FOPTS+=-fcray-pointer  -x f77-cpp-input
FCOPTS_END = -x none
else
FOPTS+=-fpp
FCOPTS_END =
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$(MKL_PATH) -liomp5
endif

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

MKL_LIBS=$(IFACE_LIB) -Wl,--start-group $(THREADING_LIB) $(CORE_LIB) -Wl,--end-group $(OMP_LIB)

ifeq ($(_IA),32)
RES_DIR=_results/$(compiler)_$(threading)_$(_IA)_$(RES_EXT)$Z
else
RES_DIR=_results/$(compiler)_$(interface)_$(threading)_$(_IA)_$(RES_EXT)$Z
endif

lib32:
	$(MAKE) $(RESC) $(RESF) _IA=32 EXT=a RES_EXT=lib OMP_LIB=$(MKL_PATH)/32/libiomp5.a LABEL=IA32-STATIC
so32:
	$(MAKE) $(RESC) $(RESF) _IA=32 EXT=so RES_EXT=so LABEL=IA32-DYNAMIC
libem64t:
	$(MAKE) $(RESC) $(RESF) _IA=em64t EXT=a RES_EXT=lib OMP_LIB=$(MKL_PATH)/em64t/libiomp5.a LABEL=EM64T-STATIC
soem64t:
	$(MAKE) $(RESC) $(RESF) _IA=em64t EXT=so RES_EXT=so LABEL=EM64T-DYNAMIC
lib64:
	$(MAKE) $(RESC) $(RESF) _IA=64 EXT=a RES_EXT=lib OMP_LIB=$(MKL_PATH)/64/libiomp5.a LABEL=IA64-STATIC
so64:
	$(MAKE) $(RESC) $(RESF) _IA=64 EXT=so RES_EXT=so LABEL=IA64-DYNAMIC

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

vpath %.c source
vpath %.f source

$(RESC): %.res: %.c
	@mkdir -p ./$(RES_DIR)
	@echo ----- Compiling C-$(LABEL)-$(interface)-$(threading) -----
	$(CC) $(SPEC_OPT) $(COPTS) -I$(MKLROOT)/include $< -L$(MKL_PATH) $(MKL_LIBS) -lpthread -lm -o $(RES_DIR)/$*.out
	@echo ----- Execution C-$(LABEL)-$(interface)-$(threading) -----
	export LD_LIBRARY_PATH=$(MKL_PATH):$(LD_LIBRARY_PATH); \
	$(RES_DIR)/$*.out >$(RES_DIR)/$@

$(RESF): %.res: %.f
	@mkdir -p ./$(RES_DIR)
	@echo ----- Compiling FORTRAN-$(LABEL)-$(interface)-$(threading) -----
	$(FC) $(SPEC_OPT) $(FOPTS) -I$(MKLROOT)/include $< $(FCOPTS_END) -L$(MKL_PATH) $(MKL_LIBS) -lpthread -lm -o $(RES_DIR)/$*.out
	@echo ----- Execution FORTRAN-$(LABEL)-$(interface)-$(threading) -----
	export LD_LIBRARY_PATH=$(MKL_PATH):$(LD_LIBRARY_PATH); \
	$(RES_DIR)/$*.out >$(RES_DIR)/$@
#-------------------------------------------------------------------------------
