##*****************************************************************************
## Copyright(C) 2006-2014 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:
##      Makefile for MKL FFTW3X CDFT wrapper library.
##      This library allows using MKL CDFT routines through MPI FFTW interface.
##*****************************************************************************

help:
	@echo "Usage: make libia32|libintel64|libmic"
	@echo "            [mpi=intelmpi|mpich|mpich2|openmpi]"
	@echo "            [compiler=intel|gnu]"
	@echo "            [interface=lp64|ilp64]"
	@echo "            [mpidir=path]"
	@echo
	@echo "Targets:"
	@echo "   libia32     - for IA-32 architecture"
	@echo "   libintel64  - for Intel(R) 64 architecture"
	@echo "   libmic      - for Intel(R) MIC architecture"
	@echo
	@echo "mpi=intelmpi   - using Intel(R) MPI, default"
	@echo "mpi=mpich      - using MPICH"
	@echo "mpi=mpich2     - using MPICH2"
	@echo "mpi=openmpi    - using OpenMPI"
	@echo "compiler=intel - using Intel(R) C Compiler, default"
	@echo "compiler=gnu   - using GNU C compiler"
	@echo
	@echo "interface=lp64 - using 32-bit integers (only for Intel(R) 64), default"
	@echo "interface=ilp64- using 64-bit integers (only for Intel(R) 64)"
	@echo "mpidir=path    - path to MPI installation directory. MPI scripts are taken"
	@echo "   from <mpidir>/bin or <mpidir>/<arch>/bin for IntelMPI and Intel(R) 64."
	@echo "   If this directory is in PATH you can omit mpidir parameter."
	@echo "   When using MPICH, make sure that MPICH was compiled by the same compiler"
	@echo "   as used to build examples."
	@echo
	@echo "Additional macros:"
	@echo "   MKLROOT - path to MKL root, default is ../.."
	@echo
	@echo "   INSTALL_DIR - location where MKL FFTW3X CDFT wrap library will be installed"
	@echo "                 Default is <MKLROOT>/lib/<arch>"
	@echo
	@echo "   INSTALL_LIBNAME"
	@echo "               - name of MKL FFTW3X CDFT wrap library will be installed"
	@echo "                 Default is libfftw3x_cdft.a"
	@echo
	@echo "   TARGET_ARCH=<flags>"
	@echo "               - defines additional compiler flags"
	@echo "                 Refer to the compiler documentation about CPU specific flags."
	@echo "                 Some compilers may need these flags to enable optimizations"
	@echo "                 for modern CPUs"
	@echo
	@echo "Set environment variables LD_LIBRARY_PATH and etc. properly before testing."
##---------------------------------------------------------------------------------
## examples of using:
##
## make libintel64
##      - compile using Intel(R) MPI Library, Intel(R) C Compiler
##        and build library for
##        Intel(R) 64 based applications
##
## make libia32 mpi=mpich mpidir=/opt/mpich compiler=gnu
##      - compile using MPICH from /opt/mpich, GNU C compiler
##        and build library for 32-bit applications
##----------------------------------------------------------------------------------

include fftw3x_cdft.lst

## Please use the command line parameters to override the values below
MKLROOT = ../..

ifndef mpi
    mpi = intelmpi
else
    ifeq (,$(findstring $(mpi),intelmpi mpich mpich2 openmpi))
        $(error "Set mpi to one of: intelmpi mpich mpich2 openmpi")
    endif
endif

ifndef compiler
    compiler = intel
else
    ifeq (,$(findstring $(compiler),intel gnu))
        $(error "Set compiler to one of: intel gnu")
    endif
endif

ifeq ($(interface),ilp64)
    ILP_OPTS = -DMKL_ILP64
    ILP_EXT  = _ilp64
else
    ILP_OPTS =
    ILP_EXT  = _lp64
endif

ifndef INSTALL_DIR 
INSTALL_DIR = $(MKLROOT)/lib/$(_IA)
obj_path = ./obj_$(_IA)$(ILP_EXT)
else
obj_path = $(INSTALL_DIR)/obj_$(_IA)$(ILP_EXT)
endif

ifeq ($(mpi),intelmpi)
    ifeq ($(compiler),intel)
        CS = mpiicc
    endif
    ifeq ($(compiler),gnu)
        CS = mpicc
    endif
    ifdef mpidir
        _CS = $(mpidir)/$(_IA)/bin/$(CS)
    else
        _CS = $(CS)
    endif
endif

ifeq ($(mpi),mpich)
    ifeq ($(compiler),intel)
        CS = mpicc -cc=icc
    endif
    ifeq ($(compiler),gnu)
        CS = mpicc -cc=gcc
    endif
    ifdef mpidir
        _CS = $(mpidir)/bin/$(CS)
    else
        _CS = $(CS)
    endif
endif

ifeq ($(mpi),mpich2)
    ifeq ($(compiler),intel)
        CS = mpicc -cc=icc
    endif
    ifeq ($(compiler),gnu)
        CS = mpicc -cc=gcc
    endif
    ifdef mpidir
        _CS = $(mpidir)/bin/$(CS)
    else
        _CS = $(CS)
    endif
endif

ifeq ($(mpi),openmpi)
    ifeq ($(compiler),intel)
        CS = mpicc -cc=icc -DUSING_OPEN_MPI
    endif
    ifeq ($(compiler),gnu)
        CS = mpicc -cc=gcc -DUSING_OPEN_MPI
    endif
    ifdef mpidir
        _CS = $(mpidir)/bin/$(CS)
    else
        _CS = $(CS)
    endif
endif

ifdef INSTALL_LIBNAME
    WRAPLIB_FFTW3X_CDFT = $(INSTALL_LIBNAME).a
else
    WRAPLIB_FFTW3X_CDFT = libfftw3x_cdft$(ILP_EXT).a
endif

.PHONY: libia32 lib32 libintel64 libem64t libmic

libia32 lib32:
	$(MAKE) clean mkobjdir wraplib ILP_EXT= _IA=ia32

libintel64 libem64t:
	$(MAKE) clean mkobjdir wraplib ILP_EXT=$(ILP_EXT) _IA=intel64

libmic:
	$(MAKE) clean mkobjdir wraplib ILP_EXT=$(ILP_EXT) _IA=mic

##---------------------------------------------------------------------------------
## Nested makefile
##---------------------------------------------------------------------------------

ifdef _IA
    objs    = $(addsuffix .o ,$(WRAP))
    objs_f  = $(addsuffix _f.o ,$(WRAP))
    objects = $(addprefix $(obj_path)/,$(objs) $(objs_f))

    ifeq ($(_IA),mic)
        TARGET_ARCH += -mmic
    endif

    ifeq ($(_IA),ia32)
        ifneq ($(interface),)
            $(warning "Ignoring interface=$(interface) for IA32")
            ILP_OPTS =
            ILP_EXT  = 
        endif
    else
        ifeq (,$(findstring x$(interface),x xlp64 xilp64))
            $(warning "Using interface=lp64 instead of unknown $(interface)")
            ILP_OPTS =
            ILP_EXT  = _lp64
        endif
    endif

.SUFFIXES:
.SUFFIXES: .c .o

vpath %.c wrappers

$(obj_path)/%.o: %.c
	$(_CS) -c -Wall $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) $(ILP_OPTS) \
		-DMKL_DOUBLE -I$(MKLROOT)/include -I$(MKLROOT)/include/fftw $< -o $@

$(obj_path)/%_f.o: %.c
	$(_CS) -c -Wall $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) $(ILP_OPTS) \
		-DMKL_SINGLE -I$(MKLROOT)/include -I$(MKLROOT)/include/fftw $< -o $@

wraplib: $(objects)
	$(AR) $(ARFLAGS) $(INSTALL_DIR)/$(WRAPLIB_FFTW3X_CDFT) $^

mkobjdir:
	-mkdir -p $(obj_path)
	-mkdir -p $(INSTALL_DIR)

clean:
	-rm -rf $(obj_path)
	-rm -f $(INSTALL_DIR)/$(WRAPLIB_FFTW3X_CDFT)

endif
