# Copyright (C) 2001-2020 Quantum ESPRESSO group
#
# 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 2
# of the License. See the file `License' in the root directory
# of the present distribution.
#
# Makefile for fundamental math and utility libraries

include ../make.inc
include install_utils

LAPACK_NETLIB=lapack-3.6.1.tgz
LAPACK_NETLIB_NAME=lapack-3.6.1
LAPACK_NETLIB_URL=http://www.netlib.org/lapack/${LAPACK_NETLIB}

# For NVIDIA Eigensolver
EIGENSOLVER_VERSION=0.3.1
EIGENSOLVER_GPU=v${EIGENSOLVER_VERSION}.tar.gz
EIGENSOLVER_GPU_NAME=Eigensolver_gpu-${EIGENSOLVER_VERSION}
EIGENSOLVER_GPU_URL=https://github.com/NVIDIA/Eigensolver_gpu/archive/${EIGENSOLVER_GPU}

# For DevXlib
DEVXLIB_VERSION=master
DEVXLIB_URL="https://gitlab.com/max-centre/components/devicexlib/-/archive/master/devicexlib-${DEVXLIB_VERSION}.tar.gz"

# MAIN target

all: libcuda

###################################
# LAPACK (includes BLAS)
###################################

liblapack : liblapack_$(LAPACK_LIBS_SWITCH) 

# lapack is external: don't do anything
liblapack_external : 

liblapack_internal:
	$(call download_and_unpack,$(LAPACK_NETLIB_NAME),$(LAPACK_NETLIB_URL),LAPACK,LAPACK)
	if test ! -e ../LAPACK/liblapack.a && test -e make_lapack.inc; then \
	  (cp make_lapack.inc ../LAPACK/make.inc; \
	  cd ../LAPACK; $(MAKE) blaslib lapacklib); else \
        (echo "no configuration file found for lapack"; \
         echo "run configure from main QE dir"; exit); fi 
lapack_clean:
	if test -d ../LAPACK; then (cd ../LAPACK; $(MAKE) clean); fi
lapack_veryclean:
	if test -d ../LAPACK; then (rm -R -f ../LAPACK ../${LAPACK_NETLIB_NAME}); fi

###################################
# FoX
###################################

libfox:
	if test ! -d ../FoX; then \
        mkdir ../FoX; \
	(gzip -dc ../archive/fox.tgz | (cd ../FoX; tar -xvf -)); \
	cd ../FoX/fox/; export FC=$(F90); export FCFLAGS="$(FOX_FLAGS)"; \
	./configure --prefix=$(TOPDIR)/FoX ;\
    touch cp_test; \
    if cp -p cp_test cp_test_1; then \
        echo "cp -p works"; \
    else \
        find -type f | xargs sed -i 's/cp -p/cp/g'; \
    fi; \
	$(MAKE) install; cd ../; rm -fr fox;fi

fox_clean:
	if test -d ../FoX; then (rm -R -f ../FoX); fi

###################################
# CUDA
###################################

libcuda : $(addprefix libcuda_,$(CUDA_EXTLIBS))

libcuda_eigensolver :
	$(call download_and_unpack,$(EIGENSOLVER_GPU_NAME),$(EIGENSOLVER_GPU_URL),EIGENSOLVER_GPU,EIGENSOLVER_GPU)
	if test ! -e ../EIGENSOLVER_GPU/lib_eigsolve/lib_eigsolve.a ; then \
    (cp Makefile.lib_eigsolve ../EIGENSOLVER_GPU/lib_eigsolve/Makefile; \
    cd ../EIGENSOLVER_GPU/lib_eigsolve/; $(MAKE) ); else \
	(echo "No configuration file found for GPU custom eigensolver"; exit); fi

libcuda_eigensolver_clean:
	if test -d ../EIGENSOLVER_GPU; then (cd ../EIGENSOLVER_GPU/lib_eigsolve ; $(MAKE) clean); fi
libcuda_eigensolver_veryclean:
	if test -d ../EIGENSOLVER_GPU; then (rm -R -f ../EIGENSOLVER_GPU ../${EIGENSOLVER_GPU_NAME}); fi

CUDA_PATH := $(if $(GPU_ARCH),$(CUDA_PATH),no)
libcuda_devxlib :
	cd ../external/devxlib; \
    if test ! -e configure; then \
    wget $(DEVXLIB_URL) -O devxlib.tar.gz || curl $(DEVXLIB_URL) -o devxlib.tar.gz ; \
    tar xzf devxlib.tar.gz --strip-components=1 -C . ; \
    rm devxlib.tar.gz ; \
    fi; \
    if test ! -f make.inc; then \
    touch make.inc; \
    $(MAKE) clean; \
    export F90FLAGS="$(FOX_FLAGS)"; \
    ./configure FC=$(F90) CC=$(CC) \
                --with-cuda=$(CUDA_PATH) \
                --with-cuda-cc=$(GPU_ARCH) \
                --with-cuda-runtime=$(CUDA_RUNTIME) \
                --disable-parallel \
                --enable-cuda-env-check=no; \
    fi; \
    make all
	touch ../install/libcuda_devxlib # do not download and configure again

libcuda_devxlib_clean:
	rm libcuda_devxlib
	cd ../external/devxlib; \
	if test -f make.inc; then ($(MAKE) clean); fi
libcuda_devxlib_veryclean:
	cd ../external/devxlib; \
	if test -f make.inc; then ($(MAKE) distclean && rm make.inc); fi

###################################
# BEEF
###################################
# NOTA BENE: BEEF is not strictly speaking a mathematical libraries
# It should be compiled like, and together with, the other XC functionals

libbeef : libbeef_$(BEEF_LIBS_SWITCH)

libbeef_external : fake_libbeef_external

fake_libbeef_external :
	touch fake_libbeef.a
	-rm fake_libbeef.a

libbeef_internal:
	if test ! -d ../LIBBEEF; then mkdir ../LIBBEEF; \
	( gzip -dc ../archive/libbeef-0.1.2.tar.gz |(cd ../LIBBEEF; tar -xvf -)); fi
	cd ../LIBBEEF; $(MAKE)

libbeef_clean:
	if test -d ../LIBBEEF; then (cd ../LIBBEEF ; $(MAKE) clean); fi
libbeef_veryclean:
	if test -d ../LIBBEEF; then (rm -R -f ../LIBBEEF); fi

###################################
# cleaning
###################################

clean: lapack_clean fox_clean libcuda_eigensolver_clean libcuda_devxlib_clean libbeef_clean

veryclean: lapack_veryclean fox_clean libcuda_eigensolver_veryclean libcuda_devxlib_veryclean libbeef_veryclean
