##******************************************************************************
##                              INTEL CONFIDENTIAL
##  Copyright(C) 2005-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 LAPACK95 examples creation and run
##******************************************************************************

help:
	@echo "Usage: make {lib32|so32|lib64|so64|libem64t|soem64t} [function=name]"
	@echo "[compiler=compiler_name] [interface=interface_name] [threading=threading_name]"
	@echo "[parallel=parallel_name] [omp=omp_name] [gnu_path=gnu_lib_path]"
	@echo "[F95ROOT=<f95_root_path>] [MKLROOT=<MKL_root_path>]"
	@echo "name           - function name. Please see lapack95.lst file."
	@echo "compiler_name  - can be gnu or intel. Default value is intel."
	@echo "                 Intel (R) Fortran Compiler as default."
	@echo "                 If compiler=gnu then GNU gfortran compiler will be used."
	@echo "                 Note: GNU g77 compiler is not supported."
	@echo "interface_name - can be lp64 or ilp64 for em64t and ia64. Default value is lp64."
	@echo "threading_name - can be parallel or sequential. Default value is parallel."
	@echo "parallel_name  - can be intel or gnu. Default value is intel."
	@echo "omp_name       - can be guide or iomp5 if parallel=intel or"
	@echo "                 can be iomp5 or gomp if parallel=gnu."
	@echo "                 Default value is iomp5."
	@echo "gnu_lib_path   - If you are using gnu threading layer, specify path to GNU libraries,"
	@echo "                 such as libgomp and libgfortran, with gnu_path variable."
	@echo "                 Default value is /usr/lib."
	@echo "f95_root_path  - Path to lapack95 library and .mod files that are built on user side."
	@echo "                 Mandatory if compiler is not intel. To build library and .mod files,"
	@echo "                 go to the directory <MKLROOT>/interfaces/lapack95 and run:"
	@echo "                 make <target> [options] FC=<f95compiler> INSTALL_DIR=<f95_root_path>"
	@echo "                 See description of the FC and INSTALL_DIR in the interface makefile."
	@echo "MKL_root_path  - Locate MKL libraries relative to <MKL_root_path>."
	@echo "                 Default value: ../.., unless defined in environment."

##------------------------------------------------------------------------------
## examples of using:
##
## make lib32 function=geevx   - build  by  Intel(R) Fortran Compiler  (as default)
##                               and run DGEBRD example for 32-bit applications,
##                               static linking
##
## make lib64 compiler=gnu F95ROOT=f95_root_path
##                             - build by gfortran GNU  Fortran  compiler  and  run  all
##                               examples of MKL for Intel(R) Itanium(R) processor family
##                               applications, static linking
##
## make  so64                    - build by Intel(R) Fortran Compiler (as default) and
##                               run all examples of MKL for Intel(R) Itanium(R) processor
##                               family applications, dynamic linking
##------------------------------------------------------------------------------

include lapack95.lst

ifndef function
   function = $(SRC_F90)
endif

ifneq ($(compiler),gnu)
   override compiler=intel
endif

ifneq ($(interface),ilp64)
   override interface=lp64
endif

ifneq ($(threading),sequential)
   override threading=parallel
endif

ifneq ($(parallel),gnu)
   override parallel=intel
endif

ifeq ($(parallel),gnu)
   ifneq ($(omp),gomp)
   override omp=iomp5
   endif
else
   ifneq ($(omp),guide)
   override omp=iomp5
   endif
endif

ifndef $(gnu_path)
   gnu_path=/usr/lib
endif

RES = $(addsuffix .res ,$(function))
ifndef MKLROOT
MKLROOT=../..
MKL_PATH = "$(subst examples/lapack95,lib/$(_IA),$(PWD))"
else
MKL_PATH = "$(MKLROOT)/lib/$(_IA)"
endif

ifeq ($(interface),ilp64)
   IFACE_LIB=$(MKL_PATH)/libmkl_$(IFACE_COMP_PART)_ilp64.$(EXT)
   FOPTS = -i8
   ifeq ($(compiler),gnu)
      override FC=gfortran
      FOPTS=-fdefault-integer-8
   endif
else
   IFACE_LIB=$(MKL_PATH)/libmkl_$(IFACE_COMP_PART)_lp64.$(EXT)
   FOPTS =
endif

ifeq ($(compiler),gnu)
   FC=gfortran
   ifeq ($(FC),gfortran)
      IFACE_COMP_PART=gf
   else
      IFACE_COMP_PART=intel
   endif
else
   override FC=ifort
   IFACE_COMP_PART=intel
endif

ifeq ($(parallel),gnu)
   IFACE_THREADING_PART=gnu
   GFORTRAN_LIB=-L$(gnu_path) -lgfortran
else
   IFACE_THREADING_PART=intel
   GFORTRAN_LIB=
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)
   FOPTS =
endif

ifeq ($(threading),sequential)
   THREADING_LIB=$(MKL_PATH)/libmkl_sequential.$(EXT)
   OMP_LIB =
   GFORTRAN_LIB=
else
   THREADING_LIB=$(MKL_PATH)/libmkl_$(IFACE_THREADING_PART)_thread.$(EXT)
   ifeq ($(omp),gomp)
      OMP_LIB = -L$(gnu_path) -l$(omp)
   else
      OMP_LIB = -L$(MKL_PATH) -l$(omp)
   endif
endif

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

ifeq ($(EXT),so)
   MKL_LAPACKLIB=$(MKL_PATH)/libmkl_lapack.$(EXT)
else
   MKL_LAPACKLIB=
endif

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

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

ifndef F95ROOT
   F95ROOT = $(MKLROOT)
   ifneq ($(compiler),intel)
     $(error F95ROOT is mandatory parameter for $(compiler))
   endif
endif

ifeq ($(_IA),32)
   MODPATH=$(F95ROOT)/include/$(_IA)
   LIB95=$(F95ROOT)/lib/$(_IA)/libmkl_lapack95.a
else
   MODPATH=$(F95ROOT)/include/$(_IA)/$(interface)
   LIB95=$(F95ROOT)/lib/$(_IA)/libmkl_lapack95_$(interface).a
endif

lib32:
	$(MAKE) $(RES) EXT=a _IA=32 PLATF=ia32 RES_EXT=lib
so32:
	$(MAKE) $(RES) EXT=so _IA=32 PLATF=ia32 RES_EXT=so
libem64t:
	$(MAKE) $(RES) EXT=a _IA=em64t PLATF=em64t RES_EXT=lib
soem64t:
	$(MAKE) $(RES) EXT=so _IA=em64t PLATF=em64t RES_EXT=so
lib64:
	$(MAKE) $(RES) EXT=a _IA=64 PLATF=ipf RES_EXT=lib
so64:
	$(MAKE) $(RES) EXT=so _IA=64 PLATF=ipf RES_EXT=so

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

vpath %.f90 source

$(RES): %.res: %.f90
	mkdir -p ./$(RES_DIR)
	export LD_LIBRARY_PATH=$(MKL_PATH):$(LD_LIBRARY_PATH):$(gnu_path); $(FC) $(SPEC_OPT) $(FOPTS) -I $(MODPATH) -w $< $(LIB95) $(MKL_LIBS) -lpthread $(GFORTRAN_LIB) -o $(RES_DIR)/$*.out
	export LD_LIBRARY_PATH=$(MKL_PATH):$(LD_LIBRARY_PATH):$(gnu_path); $(RES_DIR)/$*.out <data/$*.d >$(RES_DIR)/$@
#-------------------------------------------------------------------------------
