#===============================================================================
# Copyright 2006 Intel Corporation.
#
# This software and the related documents are Intel copyrighted  materials,  and
# your use of  them is  governed by the  express license  under which  they were
# provided to you (License).  Unless the License provides otherwise, you may not
# use, modify, copy, publish, distribute,  disclose or transmit this software or
# the related documents without Intel's prior written permission.
#
# This software and the related documents  are provided as  is,  with no express
# or implied  warranties,  other  than those  that are  expressly stated  in the
# License.
#===============================================================================

##  Content:
##      Makefile for Intel(R) oneMKL FFTW3 MPI wrapper library.
##      This library allows to use Intel(R) oneMKL CDFT routines through MPI FFTW interface.
##******************************************************************************

help:
	@echo
	@echo "Usage: make libintel64 [<options>]"
	@echo
	@echo "Intel(R) oneAPI DPC++/C++ Compiler is the default compiler."
	@echo
	@echo "  libintel64"
	@echo "      A makefile target to build FFTW3 MPI interfaces to"
	@echo "      Intel(R) oneMKL for Intel(R) 64 architecture."
	@echo
	@echo "  <options>"
	@echo
	@echo "    compiler={intel|gnu}"
	@echo "        The C compiler 'icx' or 'gcc' will be used."
	@echo "        Default: intel"
	@echo
	@echo "    mpi={intelmpi|mpich2|openmpi}"
	@echo "        Intel(R) MPI, MPICH, or Open MPI implementation of MPI will"
	@echo "        be used."
	@echo "        Default: intelmpi"
	@echo
	@echo "    interface={lp64|ilp64}"
	@echo "        The lp64 interface uses the 32-bit integer type, while the"
	@echo "        ilp64 interface uses the 64-bit integer type."
	@echo "        Default: lp64"
	@echo
	@echo "    MKLROOT=<path>"
	@echo "        Intel(R) oneMKL installation directory."
	@echo "        Default: ../../../.."
	@echo
	@echo "    INSTALL_DIR=<path>"
	@echo "        The built library will be installed in <path>."
	@echo "        Default: \$$(MKLROOT)/lib"
	@echo
	@echo "    INSTALL_LIBNAME=<name>"
	@echo "        The name of the built library without the '.a' extension."
	@echo "        The default value depends on 'interface' in use, for example,"
	@echo "        'libfftw3x_cdft_lp64'."
	@echo
	@echo "    mpidir=<path>"
	@echo "        MPI installation directory. MPI scripts are taken from"
	@echo "        \$$(mpidir)/bin. You need to set this variable only if the"
	@echo "        MPI scripts cannot be found in PATH. When using MPICH, make"
	@echo "        sure that the compiler in use is the same one that built MPICH."
	@echo "        This variable is not predefined."
	@echo
	@echo "    CFLAGS=<flags>"
	@echo "        Additional compilation flags."
	@echo "        This variable is not predefined."
	@echo
	@echo "    CPPFLAGS=<flags>"
	@echo "        Additional preprocessor flags."
	@echo "        This variable is not predefined."
	@echo
	@echo "    TARGET_ARCH=<flags>"
	@echo "        Additional architecture-specific flags."
	@echo "        This variable is not predefined."
	@echo
	@echo "    AR=<program>"
	@echo "        The specified archive-maintaining program will be used."
	@echo "        Default: $(AR)"
	@echo
	@echo "    ARFLAGS=<flags>"
	@echo "        The specified modifier flags will be given to \$$(AR)."
	@echo "        Default: $(ARFLAGS)"
	@echo
	@echo
	@echo "Usage example:"
	@echo
	@echo "  make libintel64"
	@echo "      This command builds FFTW3 MPI interfaces to Intel(R) oneMKL"
	@echo "      for Intel(R) 64 architecture using Intel(R) MPI and"
	@echo "      Intel(R) oneAPI DPC++/C++ Compiler. The built library"
	@echo "      'libfftw3x_cdft_lp64.a' is installed in ../../../../lib and"
	@echo "      uses the 32-bit integer type."
	@echo

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

include fftw3x_cdft.lst

## Please use the command line parameters to override the values below
MKLROOT = ../../../..
CFLAGS += -Wall -Werror -std=c99

ifndef mpi
    mpi = intelmpi
else
    ifeq (,$(findstring $(mpi),intelmpi mpich2 openmpi))
        $(error "Set mpi to one of: intelmpi 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
obj_path = ./obj_$(_IA)$(ILP_EXT)
else
obj_path = $(INSTALL_DIR)/obj_$(_IA)$(ILP_EXT)
endif

ifeq ($(mpi),intelmpi)
    ifdef mpidir
       _BD = $(mpidir)/bin/
    endif
    ifeq ($(compiler),intel)
        _CS = $(_BD)mpiicx
    endif
    ifeq ($(compiler),gnu)
        _CS = $(_BD)mpicc
    endif
endif

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

ifeq ($(mpi),openmpi)
    ifdef mpidir
       _BD = $(mpidir)/bin/
    endif
    ifeq ($(compiler),intel)
        _CS = OMPI_CC=icx $(_BD)mpicc
    endif
    ifeq ($(compiler),gnu)
        _CS = OMPI_CC=gcc $(_BD)mpicc
    endif
endif

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

.PHONY: libintel64

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

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

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

    ifeq (,$(findstring x$(interface),x xlp64 xilp64))
        $(warning "Using interface=lp64 instead of unknown $(interface)")
        ILP_OPTS =
        ILP_EXT  = _lp64
    endif

.SUFFIXES:
.SUFFIXES: .c .o

vpath %.c wrappers

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

$(obj_path)/%_f.o: %.c
	$(_CS) -c $(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
