#  Gluon and (staggered) quark propagators.
#  MIMD version 7
#
#  Generic make-include file for gluon_prop/quark_prop codes
#  This template file defines rules and macros common to all architectures
#  It is intended to be an include file for other Makefiles.
#  Don't use it by itself!
#
#	"make su3_gluon_prop"		makes the gluon propagator program
#	"make su3_gluon_prop_nogfix"		makes the gluon propagator
#						program without gauge fixing
#						option
#	"make su3_gluon_prop_imp"	makes an improved gluon propagator
#	"make su3_gluon_prop_imp_nofix"		Dito without gauge fixing
#	"make su3_ks_quark_prop"	makes the quark propagator program
#					with standard staggered quarks
#	"make su3_fn_quark_prop"	makes the quark propagator program
#					with "fat+Naik" staggered quarks
#	"make su3_p4_quark_prop"	makes the quark propagator program
#					with "p4" staggered quarks
#	"make su3_asqtad_quark_prop"	makes the quark propagator program
#					with "asqtad" staggered quarks
#	"make su3_asqtad_renorm"	makes the quark renormalization program
#					with "asqtad" staggered quarks
#

MYINCLUDEDIR = .
INCLUDEDIR = ../include
#Where the complex and su3 libraries are
LIBDIR = ../libraries

GLOBAL_HEADERS = ${INCLUDEDIR} ../libraries/include

INLINE_HEADERS = \
  ../sse/include/ \
  ../sse2/include/ \
  ../libraries/include/

MY_HEADERS = \
  lattice.h \
  lattice_qdp.h \
  params.h \
  defines.h \
  gluon_prop_includes.h

HEADERS = ${GLOBAL_HEADERS} ${MY_HEADERS} ${INLINE_HEADERS} ${SCIDAC_HEADERS}

# All required object files
# Basic set from current directory
MY_OBJECTS =         \
  control.o          \
  setup.o            \
  gauge_info.o

# Basic set from generic directory
G_OBJECTS =          \
  check_unitarity.o  \
  d_plaq4.o          \
  io_lat4.o          \
  io_helpers.o       \
  make_lattice.o     \
  nersc_cksum.o \
  reunitarize2.o     \
  restrict_fourier.o \
  io_detect.o        \
  io_lat_utils.o     \
  io_source_cmplx_fm.o \
  remap_stdio_from_args.o \
  path_product.o

# Basic set from generic_ks directory
QUARK_OBJECTS = \
  io_helpers_ks.o \
  io_prop_ks.o \
  io_prop_ks_fm.o \
  ks_source.o        \
  ks_utilities.o \
  ksprop_info.o \
  rephase.o \
  quark_stuff.o

ifeq ($(strip ${QCDOC}),true)
  G_OBJECTS += ploop2.o
else
  G_OBJECTS += ploop3.o
endif

ifeq ($(strip ${HAVEQIO}),true)
  G_OBJECTS += io_scidac.o io_scidac_types.o
  QUARK_OBJECTS += io_scidac_ks.o io_scidac_w.o
endif

# Objects depending on architecture and software package

# Selection of layout
ifeq ($(strip ${QCDOC}),true)
  LAYOUT = layout_qcdoc.o # Required
else
  ifeq ($(strip ${HAVEQDP}),true)
    LAYOUT = layout_qdp.o # Required
  else
    LAYOUT = layout_hyper_prime.o # Choices possible here
  endif
endif

# Selection of a non-QDP FN Dslash
# Choices are dslash_fn.o dslash_fn2.o dslash_fn_dblstore.o
DSLASH_FN = dslash_fn2.o

# Selection of the fermion links algorithm
ifeq ($(strip ${HAVEQOP}),true)
# Interface to access QOP
  FLINKS_FN = ${FLINKS_FNQOP}
else
  ifeq ($(strip ${HAVEQDP}),true)
    FLINKS_FN = fermion_links_asqtad_qdp.o fermion_links_helpers.o
  else
    FLINKS_FN = fermion_links_fn.o fermion_links_helpers.o
  endif
endif

# Selection of the conjugate gradient algorithm
ifeq ($(strip ${HAVEQOP}),true)
# Interface to access QOP
  CONGRAD_FN = d_congrad5_fn_qop_two_src.o d_congrad5_fn_qop.o \
     d_congrad5_fn_qop_D.o d_congrad5_fn_qop_F.o d_congrad_opt.o
#  CONGRAD_FN = d_congrad5_two_src.o d_congrad5_fn.o d_congrad_opt.o
  CONGRAD_FN += ${ASQINVERTQOP}
else
  ifeq ($(strip ${HAVEQDP}),true)
#    Here you may use the fn_qdp set or the fn_1sum_qdp set
#    CONGRAD_FN = d_congrad5_two_src.o d_congrad5_fn_qdp.o \
#       d_congrad5_fn_qdp_D.o d_congrad5_fn_qdp_F.o d_congrad_opt.o
    CONGRAD_FN = d_congrad5_two_src.o d_congrad5_fn_qdp.o \
       d_congrad5_fn_qdp_D.o d_congrad5_fn_qdp_F.o d_congrad_opt.o
  else
    # Choose a non_QDP FN conjugate gradient algorithm
    CONGRAD_FN = d_congrad5_two_src.o d_congrad5_fn.o d_congrad_opt.o
  endif
endif

# Selection of the multimass inverter
ifeq ($(strip ${HAVEQOP}),true)
# Interface to access QOP
  INV_FN_OBJECTS = ${CONGRAD_FN} ${DSLASH_FN}
  MULTI_INV_FN = ks_multicg.o ks_multicg_offset_qop.o \
    ks_multicg_offset_qop_D.o  ks_multicg_offset_qop_F.o
else
  ifeq ($(strip ${HAVEQDP}),true)
    QDP_OBJECTS = map_milc_to_qdp_D.o map_milc_to_qdp_F.o
    INV_FN_OBJECTS = ${CONGRAD_FN} ${DSLASH_FN} dslash_fn_qdp_D.o \
      dslash_fn_qdp_F.o 
    MULTI_INV_FN = ks_multicg.o ks_multicg_offset_qdp.o \
      ks_multicg_offset_qdp_D.o ks_multicg_offset_qdp_F.o
  else
    INV_FN_OBJECTS = ${CONGRAD_FN} ${DSLASH_FN}
    MULTI_INV_FN = ks_multicg.o ks_multicg_offset.o
  endif
endif

# The only choice for inverters and Dslash for EO actions
INV_EO_OBJECTS = d_congrad5_eo.o d_congrad_opt.o dslash_eo.o
MULTI_INV_EO = ks_multicg.o ks_multicg_offset.o

# For EO actions we don't precompute the fat links for Dslash at the moment
FN_OBJECTS = ${FLINKS_FN} ${INV_FN_OBJECTS}
EO_OBJECTS = ${INV_EO_OBJECTS}

# EDRAM allocation for QCDOC
ifeq ($(strip ${QCDOC}),true)
  QCDOC_OBJECTS = qcdoc_alloc.o
endif

ADD_OBJECTS = ${MACHINE_DEP_IO} ${COMMPKG} ${QCDOC_OBJECTS} ${QDP_OBJECTS} \
   ${SCIDAC_OBJECTS}

# Generic QOP objects
ifeq ($(strip ${HAVEQOP}),true)
  ADD_OBJECTS += ${GENERICQOP}
endif

OBJECTS = ${MY_OBJECTS} ${G_OBJECTS} ${LAYOUT} ${ADD_OBJECTS} ${EXTRA_OBJECTS}

#Libraries for complex numbers and su3 functions
P = $(strip ${PRECISION})
QCDLIB = ${LIBDIR}/su3.${P}.a ${LIBDIR}/complex.${P}.a 

LIBRARIES = ${QCDLIB} ${SCIDAC_LIBRARIES}

# Default rule for C compilation
.c.o: ; ${CC} -c ${CFLAGS}  $*.c

# To force a full remake when changing targets
LASTMAKE = .lastmake.${MAKEFILE}.${P}.${MYTARGET}

${LASTMAKE}:
	-/bin/rm -f .lastmake.* quark_action.h
	${MAKE} -f ${MAKEFILE} clean
	touch ${LASTMAKE}

# All make files used in this compilation
ALL_MAKES = \
   Make_template \
   ${MAKEFILE} \
   ../Make_template_qop \
   ../Make_template_scidac \
   ../generic/Make_template \
   ../generic_ks/Make_template \
   ../generic_wilson/Make_template

# To force a remake when changing any make file, header, or target
${OBJECTS} : ${HEADERS} ${LASTMAKE} ${ALL_MAKES}

ifeq ($(strip ${HAVEQOP}),true)
  ${FLINKS_FNQOP}: quark_action.h
endif
fermion_links_helpers.o: quark_action.h
fermion_links_fn.o: quark_action.h
quark_stuff.o: quark_action.h

# Directories where we store the improved action headers
QUARKIMP = ../generic_ks/imp_actions

quark_action.h: ${QUARKIMP}/${QUARK}
	@echo Copying quark_action.h from ${QUARKIMP}/${QUARK}
	/bin/cp ${QUARKIMP}/${QUARK} quark_action.h

ifeq ($(strip ${QCDOC}),true)
  DQCDOC = -DQCDOC
endif
 
ifeq ($(strip ${HAVEQMP}),true)
  DHAVE_QMP = -DHAVE_QMP
endif
 
ifeq ($(strip ${HAVEQIO}),true)
  DHAVE_QIO = -DHAVE_QIO
endif
 
ifeq ($(strip ${HAVEQDP}),true)
  DHAVE_QDP = -DHAVE_QDP
endif
                                                                                
ifeq ($(strip ${HAVEQOP}),true)
  DHAVE_QOP = -DHAVE_QOP
endif
                                                                                
DARCH = ${DQCDOC} ${DHAVE_QMP} ${DHAVE_QIO} ${DHAVE_QDP} ${DHAVE_QOP}
                                                                                
##### Targets:
#               ("FN" = "fat+Naik")

## NOTE: here QUARK is not actually used!
su3_gluon_prop_nogfix::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DGLUON_PROP" \
	"EXTRA_OBJECTS= gluon_prop.o"

su3_gluon_prop_imp_nogfix::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DGLUON_PROP" \
	"EXTRA_OBJECTS= gluon_prop_imp.o"

su3_gluon_prop::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DGLUON_PROP -DGFIX" \
	"EXTRA_OBJECTS= gluon_prop.o gaugefix2.o gaugefixfft.o"

su3_gluon_prop_imp::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DGLUON_PROP -DGFIX -DIMP_GFIX" \
	"EXTRA_OBJECTS= gluon_prop_imp.o gaugefix2.o gaugefixfft.o"

su3_ks_quark_prop::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DFN -DQUARK_PROP -DGFIX" \
	"QUARK = onelink_action.h" \
	"EXTRA_OBJECTS= ${FN_OBJECTS} ${MULTI_INV_FN} \
	${QUARK_OBJECTS} quark_prop.o gaugefix2.o gaugefixfft.o"

su3_fn_quark_prop::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DFN -DQUARK_PROP -DGFIX -DNAIK" \
	"QUARK = naik_action.h" \
	"EXTRA_OBJECTS= ${FN_OBJECTS} ${MULTI_INV_FN} \
	${QUARK_OBJECTS} quark_prop.o gaugefix2.o gaugefixfft.o"

su3_p4_quark_prop::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DEO -DQUARK_PROP -DGFIX" \
	"QUARK = p4_action.h" \
	"EXTRA_OBJECTS= ${EO_OBJECTS} ${MULTI_INV_EO} \
	${QUARK_OBJECTS} quark_prop.o gaugefix2.o gaugefixfft.o"

su3_asqtad_quark_prop::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DFN -DQUARK_PROP -DGFIX -DNAIK" \
	"QUARK = asqtad_action.h" \
	"EXTRA_OBJECTS= ${FN_OBJECTS} ${MULTI_INV_FN} \
	${QUARK_OBJECTS} quark_prop.o gaugefix2.o gaugefixfft.o"

su3_asqtad_renorm::
	${MAKE} -f ${MAKEFILE} target "MYTARGET= $@" \
	"DEFINES= -DFN -DQUARK_PROP -DQUARK_RENORM -DGFIX -DNAIK" \
	"QUARK = asqtad_action.h" \
	"EXTRA_OBJECTS= ${FN_OBJECTS} ${MULTI_INV_FN} \
	${QUARK_OBJECTS} quark_renorm.o gaugefix2.o gaugefixfft.o"

clean:
	-/bin/rm -f *.o


# Rules for generic routines
include ../generic/Make_template

# Rules for generic_ks routines
include ../generic_ks/Make_template

# Rules for generic_wilson routines
include ../generic_wilson/Make_template

libmake:
	@echo Building libraries with ${MAKELIBRARIES}
	cd ${LIBDIR} ;\
	${MAKE} -f ${MAKELIBRARIES} "APP_CC=${CC}" "PRECISION=${PRECISION}" all

localmake: ${OBJECTS} ${LIBRARIES}
	${LD} -o ${MYTARGET} ${LDFLAGS} \
	${OBJECTS} ${QCDLIB} ${ILIB} -lm
	touch localmake

target:	libmake localmake

