# -*- makefile-gmake -*-

# Makefile for C input files located outside of the gkeyll/ repository.

ARCH_FLAGS ?= -march=native
CUDA_ARCH ?= 70
# Warning flags: -Wall -Wno-unused-variable -Wno-unused-function -Wno-missing-braces
CFLAGS ?= -O3 -g -ffast-math -fPIC -MMD -MP
LDFLAGS = 
PREFIX ?= ${HOME}/gkylsoft

# determine OS we are running on
UNAME = $(shell uname)

# Default lapack include and libraries: we prefer linking to static library
LAPACK_INC_DIR ?= $(PREFIX)/OpenBLAS/include/
LAPACK_LIB_DIR ?= $(PREFIX)/OpenBLAS/lib/
LAPACK_LIB_NAME ?= openblas
LAPACK_LIBS ?= -l${LAPACK_LIB_NAME}

# SuperLU includes and libraries
SUPERLU_INC_DIR ?= $(PREFIX)/superlu/include/
ifeq ($(UNAME), Darwin)
	SUPERLU_LIB_DIR ?= $(PREFIX)/superlu/lib/
else
	SUPERLU_LIB_DIR ?= $(PREFIX)/superlu/lib64/
endif
SUPERLU_LIB_NAME ?= superlu
SUPERLU_LIBS ?= -l$(SUPERLU_LIB_NAME)

# Include config.mak file (if it exists)
-include $(PREFIX)/gkeyll/share/config.mak

CFLAGS = -O3 -g -ffast-math -I. 

G0_INC_DIR = ${PREFIX}/gkeyll/include
G0_LIB_DIR = ${PREFIX}/gkeyll/lib
G0_LIB = ${FIN_APP_LIB}

USING_NVCC =
NVCC_FLAGS =
CUDA_LIBS =
ifeq ($(CC), nvcc)
       USING_NVCC = yes
       CFLAGS = -O3 -g --forward-unknown-to-host-compiler --use_fast_math -ffast-math -MMD -MP -fPIC
       NVCC_FLAGS = -x cu -dc -arch=sm_${CUDA_ARCH} --compiler-options="-fPIC"
       LDFLAGS += -arch=sm_${CUDA_ARCH}
       ifdef CUDAMATH_LIB_DIR
              CUDA_LIBS = -L${CUDAMATH_LIB_DIR}
       else
              CUDA_LIBS =
       endif
       CUDA_LIBS += -lcublas -lcusparse -lcusolver
endif

G0_LIBS = ${G0_LIB} ${CUDA_LIBS} -lm -lpthread
G0_RPATH = -Wl,-rpath,${G0_LIB_DIR}

# On OSX we should use Accelerate framework
ifeq ($(UNAME), Darwin)
	LAPACK_LIB_DIR = .
	LAPACK_INC_DIR = core # dummy
	LAPACK_LIB_NAME = 
	LAPACK_LIBS = -framework Accelerate
	CFLAGS += -DGKYL_USING_FRAMEWORK_ACCELERATE
endif

# Read MPI paths and flags if needed 
USING_MPI =
MPI_RPATH = 
MPI_INC_DIR = zero # dummy
MPI_LIB_DIR = .
ifeq (${USE_MPI}, 1)
	USING_MPI = yes
	MPI_INC_DIR = ${CONF_MPI_INC_DIR}
	MPI_LIB_DIR = ${CONF_MPI_LIB_DIR}
	MPI_RPATH = -Wl,-rpath,${CONF_MPI_LIB_DIR}
	MPI_LIBS = -lmpi
	CFLAGS += -DGKYL_HAVE_MPI
endif

# Directory for storing shared data, like ADAS
GKYL_SHARE_DIR ?= "${INSTALL_PREFIX}/gkeyll/share"
CFLAGS += -DGKYL_SHARE_DIR=$(GKYL_SHARE_DIR)

# Read NCCL paths and flags if needed (needs MPI and NVCC)
USING_NCCL =
NCCL_INC_DIR = zero # dummy
NCCL_LIB_DIR = .
ifeq (${USE_NCCL}, 1)
ifdef USING_MPI
ifdef USING_NVCC
	USING_NCCL = yes
	NCCL_INC_DIR = ${CONF_NCCL_INC_DIR}
	NCCL_LIB_DIR = ${CONF_NCCL_LIB_DIR}
	NCCL_LIBS = -lnccl
	CFLAGS += -DGKYL_HAVE_NCCL
endif
endif
endif

# Read CUDSS paths and flags if needed (needs MPI and NVCC)
USING_CUDSS =
CUDSS_INC_DIR = zero # dummy
CUDSS_LIB_DIR = .
CUDSS_RPATH =
ifeq (${USE_CUDSS}, 1)
ifdef USING_NVCC
	USING_CUDSS = yes
	CUDSS_INC_DIR = ${CONF_CUDSS_INC_DIR}
	CUDSS_LIB_DIR = ${CONF_CUDSS_LIB_DIR}
	CUDSS_RPATH = -Xlinker "-rpath,${CONF_CUDSS_LIB_DIR}"
	CUDSS_LIBS = -lcudss
	CFLAGS += -DGKYL_HAVE_CUDSS
endif
endif

# Read LUA paths and flags if needed 
LUA_RPATH = 
LUA_INC_DIR = zero # dummy
LUA_LIB_DIR = .
ifeq (${USE_LUA}, 1)
	USING_LUA = yes
	LUA_INC_DIR = ${CONF_LUA_INC_DIR}
	LUA_LIB_DIR = ${CONF_LUA_LIB_DIR}
	LUA_RPATH = -Wl,-rpath,${CONF_LUA_LIB_DIR}
	LUA_LIBS = -l${CONF_LUA_LIB}
	CFLAGS += -DGKYL_HAVE_LUA
endif

INCLUDES = -I${G0_INC_DIR} -I${LAPACK_INC_DIR} -I${SUPERLU_INC_DIR} -I${MPI_INC_DIR} -I${LUA_INC_DIR} -I${NCCL_INC_DIR} -I${CUDSS_INC_DIR}
LIB_DIRS = -L${LAPACK_LIB_DIR} -L${SUPERLU_LIB_DIR} -L${MPI_LIB_DIR} -L${LUA_LIB_DIR} -L${NCCL_LIB_DIR} -L${CUDSS_LIB_DIR}
EXT_LIBS = ${LAPACK_LIBS} ${SUPERLU_LIBS} ${MPI_RPATH} ${MPI_LIBS} ${LUA_RPATH} ${LUA_LIBS} ${NCCL_LIBS} ${CUDSS_RPATH} ${CUDSS_LIBS} -lm -lpthread -ldl

# Find all .c files and generate corresponding executable names
SRCS := $(wildcard *.c)
BINS := $(SRCS:.c=)

.PHONY: all clean help moments moments-unit moments-regression

# Default target: build all if no FILE specified, otherwise build specific file
all: cs-1d-guassian-advection cs-2d-rotflow cs-vlasov-cos-pot

# Help target to show usage
help:
	@echo "Usage:"
	@echo "  make           - Build all .c files into executables"
	@echo "  make name      - Build only name.c into executable 'name'"
	@echo "  make clean     - Remove all executables and generated files"
	@echo "  make help      - Show this help message"

cs-2d-rotflow: cs-2d-rotflow.c adiff.c 
	${CC} ${CFLAGS} -I. ${INCLUDES} adiff.c $< -o $@ -L${G0_LIB_DIR} ${G0_RPATH} ${G0_LIBS} ${LIB_DIRS} ${EXT_LIBS}

cs-vlasov-cos-pot: cs-vlasov-cos-pot.c adiff.c 
	${CC} ${CFLAGS} -I. ${INCLUDES} adiff.c $< -o $@ -L${G0_LIB_DIR} ${G0_RPATH} ${G0_LIBS} ${LIB_DIRS} ${EXT_LIBS}

cs-1d-guassian-advection: cs-1d-guassian-advection.c adiff.c 
	${CC} ${CFLAGS} -I. ${INCLUDES} adiff.c $< -o $@ -L${G0_LIB_DIR} ${G0_RPATH} ${G0_LIBS} ${LIB_DIRS} ${EXT_LIBS}

clean:
	rm -rf $(BINS) *.d *.png *.gkyl *~
