##########################################################################################################################################################
#
#
#
#  Makefile for compiling the Genetic algorithm package for MAGIX
#  Copyright (C) 2009 - 2024  Thomas Moeller
#
#  I. Physikalisches Institut, University of Cologne
#
#
#
#  Makefile options:    - "defaultsmp":         builds the default MAGIX version using SMP
#
#                                               Used files:     ../../../../xclass/core/src/Module_Variables.f90
#                                                               ../../../../xclass/core/src/Module_FunctionCalling.f90
#                                                               ../lib/default/Module_Default__SMP.f90
#                                                               ../lib/starter/SMP/SMP__Starter__Program.f90
#                                                               src/Genetic__Core.f90
#
#
#                       - "defaultmpi":         builds the default MAGIX version using MPI
#
#                                               Used files:     ../../../../xclass/core/src/Module_Variables.f90
#                                                               ../../../../xclass/core/src/Module_FunctionCalling.f90
#                                                               ../lib/default/Module_Default__MPI.f90
#                                                               ../lib/starter/MPI/MPI__Starter__Program.f90
#                                                               src/Genetic__Core.f90
#
#
#                       - "myxclasssmp":        builds the myXCLASS optimized MAGIX version using SMP
#
#                                               Used files:     ../../../../xclass/core/src/Module_Variables.f90
#                                                               ../../../../xclass/core/src/Module_FunctionCalling.f90
#                                                               ../../../../xclass/core/src/Module_myXCLASS__Core.f90
#                                                               ../lib/smp/Module_myXCLASS__SMP.f90
#                                                               ../lib/starter/SMP/SMP__Starter__Program.f90
#                                                               src/Genetic__Core.f90
#
#
#                       - "myxclassmpi":        builds the myXCLASS optimized MAGIX version using MPI
#
#                                               Used files:     ../../../../xclass/core/src/Module_Variables.f90
#                                                               ../../../../xclass/core/src/Module_FunctionCalling.f90
#                                                               ../../../../xclass/core/src/Module_myXCLASS__Core.f90
#                                                               ../lib/mpi/Module_myXCLASS__MPI.f90
#                                                               ../lib/starter/MPI/MPI__Starter__Program.f90
#                                                               src/Genetic__Core.f90
#
#
#                       - "myxclassgpu":        builds the myXCLASS optimized MAGIX version using GPU (CUDA)
#
#                                               Used files:     ../../../../xclass/core/src/Module_Variables.f90
#                                                               ../../../../xclass/core/src/Module_FunctionCalling.f90
#                                                               ../lib/default/Module_myXCLASS__GPU.f90
#                                                               ../lib/starter/SMP/myXCLASS__SMP__Starter__Program.f90
#                                                               src/Genetic__Core.f90
#
#
#  Versions of the program:
#
#  Who           When        What
#
#  T. Moeller    2009-09-07  Initial version
#  T. Moeller    2014-08-31  modified for myXCLASS and GPU optimization
#  T. Moeller    2014-09-05  add MPI version
#  T. Moeller    2019-03-13  rearrangement of external libraries
#
#
#
#  License:
#
#    GNU GENERAL PUBLIC LICENSE
#    Version 3, 29 June 2007
#    (Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>)
#
#
#    This program is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation, either version 3 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
##########################################################################################################################################################


#=========================================================================================================================================================
#=========================================================================================================================================================
# define general settings
#=========================================================================================================================================================
#=========================================================================================================================================================


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# specify name of algorithm
NameAlgorithm = Genetic


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Various compilation programs and flags. You need to make sure these are correct for your system
SHELL = /bin/bash


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# suffixes' list
.SUFFIXES:
.SUFFIXES: .o .f90


#=========================================================================================================================================================
#=========================================================================================================================================================
# define subdirectories
#=========================================================================================================================================================
#=========================================================================================================================================================


# standard MAGIX directories
bindir = bin


# set path of folder containing algorithm source file(s)
coresrcdir = src


# set path of folder containing algorithm source file(s)
libdir = ../lib/general


# set path starter file(s)
starterlibdir = ../lib/starter


# set path of source files for MAGIX default version
defaultlibdir = ../lib/default


## set path of mpi related library
mpilibdir = ../lib/mpi


# set path of external libraries
extlibdir = ../../../../external


# set path of external libraries
INCLUDEDIR = ../../../../xclass/core/obj


#=========================================================================================================================================================
#=========================================================================================================================================================
# define source and objects files
#=========================================================================================================================================================
#=========================================================================================================================================================


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# general (core) algorithm file
CoreFSRC = $(coresrcdir)/$(NameAlgorithm)__Core.f90                                         ## core fortran source file


# starter file for default MAGIX version (SMP version)
StarterSMPFSRC = $(starterlibdir)/SMP/SMP__Starter__Program.f90                             ## default fortran source file


# MPI starter program for default MAGIX version (MPI version)
StarterMPIFSRC = $(starterlibdir)/MPI/MPI__Starter__Program.f90


# GPU starter program for myXCLASS optimized version of MAGIX (GPU version)
# (use SMP starter because starter for GPU is identical to SMP starter)
StarterGPUFSRC = $(starterlibdir)/SMP/SMP__Starter__Program.f90


#=========================================================================================================================================================
# DEFAULT MAGIX version
#=========================================================================================================================================================


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# default SMP MAGIX version
DEFAULTEXECSMP = $(NameAlgorithm)__SMP-Starter.exe                                          ## final binary file (default SMP version)


# default module model file (SMP version)
DefaultModelSMPFSRC = $(defaultlibdir)/Module_Default__SMP.f90


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# default MPI MAGIX version
DEFAULTEXECMPI = $(NameAlgorithm)__MPI-Starter.exe                                          ## final binary file (default MPI version)


# default module model file (MPI version)
DefaultModelMPIFSRC = $(defaultlibdir)/Module_Default__MPI.f90


#=========================================================================================================================================================
# myXCLASS optimized MAGIX version
#=========================================================================================================================================================


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# myXCLASS MAGIX version (SMP)
myXCLASSEXECSMP = $(NameAlgorithm)__SMP-Starter__myXCLASS.exe                               ## final binary file (myXCLASS SMP version)


# myXCLASS module file (SMP)
myXCLASSModelSMPFSRC = $(mpilibdir)/Module_myXCLASS__SMP.f90


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# myXCLASS MAGIX version (MPI)
myXCLASSEXECMPI = $(NameAlgorithm)__MPI-Starter__myXCLASS.exe                               ## final binary file (myXCLASS MPI version)


# myXCLASS module file (MPI)
myXCLASSModelMPIFSRC = $(mpilibdir)/Module_myXCLASS__MPI.f90


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# myXCLASS MAGIX version (GPU)
myXCLASSEXECGPU = $(NameAlgorithm)__SMP-Starter__myXCLASS.exe                               ## final binary file (myXCLASS GPU version)


# myXCLASS module file (GPU)
myXCLASSModelGPUFSRC = $(mpilibdir)/Module_myXCLASS__GPU.f90
#---------------------------------------------------------------------------------------------------------------------------------------------------------


# define path and name of object files
XOBJ = $(INCLUDEDIR)/Module_Variables.o \
       $(INCLUDEDIR)/Module_FunctionCalling.o \
       $(INCLUDEDIR)/Module_myXCLASS__Core.o



#=========================================================================================================================================================
#=========================================================================================================================================================
# add libraries
#=========================================================================================================================================================
#=========================================================================================================================================================


# add cfitsio library
libcfitsio = -L$(extlibdir)/CFITSIO/bin -lcfitsio


# add fftw3 library
libfftw3 = -L$(extlibdir)/FFTW/bin -lfftw3


# add SQLite3 library
libsqlite3 = -L$(extlibdir)/SQLite/bin -lsqlitex


# add additional library
# -lm:          library of basic mathematical functions
# -lz:          dynamic library libz.so.x.y.z (library for data compression, required by cfitsio)
# -lcurl:       dynamic linking library (the multiprotocol file transfer library)
# -ldl:         dynamic linking library
# -lpthread:    POSIX threads library
# -lgomp:       GCC OpenMP shared support library
libadd = -lm -lz -lcurl -ldl -lpthread -lgomp


# define combined library flags
# environment variables "XCLASSFINCLUDE" and "XCLASSLDFLAGS" are needed to find libraries on arm-MAC machines
liball = ${XCLASSFINCLUDE} ${XCLASSLDFLAGS} $(libcfitsio) $(libfftw3) $(libsqlite3) $(libadd)


#=========================================================================================================================================================
#=========================================================================================================================================================
# define FORTRAN compiler and corresponding flags
#=========================================================================================================================================================
#=========================================================================================================================================================


# set fortran compiler using environment variable 'XCLASS_FORTRAN_COMPILER'
ifndef XCLASS_FORTRAN_COMPILER
    FC = gfortran
else
    FC = ${XCLASS_FORTRAN_COMPILER}
endif


# set fortran compiler and flags
FFLAGSGNU = -O3 -fopenmp -ffree-form -ffree-line-length-none -fbounds-check -frange-check -Wunused -fallow-argument-mismatch
FFLAGSGNUDBG = -g -O0 -fbacktrace -fopenmp -ffree-form -ffree-line-length-none -fbounds-check -frange-check -Wall -Wextra -fallow-argument-mismatch


# set mpi compiler and flags
FCMPI = mpif90
FFLAGSMPI = $(FFLAGSGNU)


# set PGI Compiler and flags
FCPGI = pgf90
# FFLAGSGPU = -O4 -mp -Mbounds -Mcuda=fastmath,nofma -r4 -Mconcur=allcores
# FFLAGSGPU = -g -O3 -mp -Mbounds -Mcuda=emu
# FFLAGSGPU = -fast -mp -Mbounds -Mcuda=fastmath
FFLAGSGPU = -fast -Mipa=fast,inline -Mconcur -mp -Mprefetch -Mcuda=rdc
FFLAGSLIBGPU = $(FFLAGSGPU) $(liball)


# set Intel compiler and flags (NOT tested !!!)
FCINTEL = ifort
FFLAGSINTEL = -O3 -openmp -shared-intel -r8 -traceback -fstack-security-check -fp-stack-check -W1 -override-limits
FFLAGSLIBINTEL = $(FFLAGSINTEL) -liomp5 $(liball)


#=========================================================================================================================================================
#=========================================================================================================================================================
# define rules
#=========================================================================================================================================================
#=========================================================================================================================================================


#---------------------------------------------------------------------------------------------------------------------------------------------------------
# make the binaries and clean up the directory
both: cleandefault buildgnusmpdefault cleanmyxclass buildmyxclasssmp cleanpast move
bothgpu: cleandefault buildgnusmpdefault cleanmyxclass buildmyxclassgpu cleanpast move


# options for default MAGIX version
defaultsmp: cleandefault buildgnusmpdefault cleanpast move
defaultmpi: cleandefault buildgnumpidefault cleanpast move


# options for myXCLASS
myxclasssmp: cleanmyxclass buildmyxclasssmp cleanpast move
myxclassmpi: cleanmyxclass buildmyxclassmpi cleanpast move
myxclassmpidbg: cleanmyxclass buildmyxclassmpi cleanpast move
myxclassgpu: cleanmyxclass buildmyxclassgpu cleanpast move


#=========================================================================================================================================================
# build up source code including Module files


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# build default version (SMP version)
buildgnusmpdefault:
	$(FC) $(FFLAGSGNU) $(XOBJ) $(DefaultModelSMPFSRC) $(CoreFSRC) $(StarterSMPFSRC) -o $(DEFAULTEXECSMP) $(liball)


buildinteldefault:
	$(FCINTEL) $(FFLAGSLIBINTEL) $(XOBJ) $(DefaultModelSMPFSRC) $(CoreFSRC) $(StarterSMPFSRC) -o $(DEFAULTEXECSMP) $(liball)


# build myXCLASS optimized MAGIX version (SMP version)
buildmyxclasssmp:
	$(FC) $(FFLAGSGNU) $(XOBJ) $(myXCLASSModelSMPFSRC) $(CoreFSRC) $(StarterSMPFSRC) -o $(myXCLASSEXECSMP) $(liball)


#- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# build default version (MPI version)
buildgnumpidefault:
	$(FCMPI) $(FFLAGSMPI) -I$(INCLUDEDIR) $(XOBJ) $(DefaultModelMPIFSRC) $(CoreFSRC) $(StarterMPIFSRC) -o $(DEFAULTEXECMPI) $(liball)


# build myXCLASS optimized MAGIX version (MPI version)
buildmyxclassmpi:
	$(FCMPI) $(FFLAGSMPI) -I$(INCLUDEDIR) $(XOBJ) $(myXCLASSModelMPIFSRC) $(CoreFSRC) $(StarterMPIFSRC) -o $(myXCLASSEXECMPI) $(liball)


# for DEBUGGING: build myXCLASS optimized MAGIX version (MPI version)
myxclassmpidbg:
	$(FCMPI) $(FFLAGSGNUDBG) -I$(INCLUDEDIR) $(XOBJ) $(myXCLASSModelMPIFSRC) $(CoreFSRC) $(StarterMPIFSRC) -o $(myXCLASSEXECMPI) $(liball)


# build myXCLASS optimized MAGIX version (GPU version)
buildmyxclassgpu:
	$(FCPGI) $(FFLAGSLIBGPU) -I$(INCLUDEDIR) $(XOBJ) $(myXCLASSModelGPUFSRC) $(CoreFSRC) $(StarterGPUFSRC) -o $(myXCLASSEXECGPU) $(liball)


#---------------------------------------------------------------------------------------------------------------------------------------------------------
# clean directories and previous compilations
cleandefault:
	rm -f *.mod *.o $(bindir)/$(DEFAULTEXECSMP) $(bindir)/$(DEFAULTEXECMPI)
cleanmyxclass:
	rm -f *.mod *.o $(bindir)/$(myXCLASSEXECSMP) $(bindir)/$(myXCLASSEXECMPI) $(bindir)/$(myXCLASSEXECGPU)
cleanpast:
	rm -f *.mod *.o *.oo


#---------------------------------------------------------------------------------------------------------------------------------------------------------
# move module file to bin directory
move:
	mv *.exe $(bindir)/
