# -*- Mode: Makefile; -*-
#
# See COPYRIGHT in top-level directory.
#
# Override the compilers and flags for your system on the command line, e.g.
#   make MPICC=cc                              (HPE Cray compiler wrappers)
#   make MPICC=mpiicx CC=icx OMPFLAG=-qopenmp  (Intel oneAPI)
#   make CC=nvc OMPFLAG=-mp                    (NVIDIA HPC compilers)
#   make MPICC=mpifcc CC=fcc OMPFLAG=-Kopenmp  (Fujitsu)
#
# The GPU example is not part of "make". Build it with "make gpu" and say
# which compiler you use:
#   make gpu COMPILER=cray                     (HPE Cray compilers, any GPU; the
#                                               craype-accel module sets the GPU)
#   make gpu COMPILER=amd    GPU_ARCH=gfx942   (AMD compilers, AMD GPU)
#   make gpu COMPILER=nvidia                   (NVIDIA HPC compilers, NVIDIA GPU)
#   make gpu COMPILER=intel  MPICC=mpiicx      (Intel oneAPI, Intel GPU)
# Run "make gpu" on its own to see this list.

# Same names in upper case also work (COMPILER=CRAY, as in CloverLeaf)
COMPILER ?=
override COMPILER := $(shell echo $(COMPILER) | tr A-Z a-z)

# The Cray compiler wrapper for MPI is "cc"
ifeq ($(COMPILER),cray)
MPICC   ?= cc
endif
MPICC   ?= mpicc
OMPFLAG ?= -fopenmp
CFLAGS  ?= -O0 -g -Wall -std=c99

MPI_BINS = simple deadlock split memory_debugging
OMP_BINS = saxpy_omp
GPU_BINS = gpu_saxpy

# OpenMP offload flags for each compiler. GPU_ARCH is the AMD GPU
# architecture, for example gfx942 (MI300A, MI300X) or gfx90a (MI250X).
GPU_ARCH ?= gfx942
GPUFLAGS_cray   = -fopenmp
GPUFLAGS_amd    = -fopenmp -fopenmp-targets=amdgcn-amd-amdhsa -Xopenmp-target=amdgcn-amd-amdhsa -march=$(GPU_ARCH)
GPUFLAGS_nvidia = -mp=gpu
GPUFLAGS_intel  = -fiopenmp -fopenmp-targets=spir64
GPUFLAGS ?= $(GPUFLAGS_$(COMPILER))

all: $(MPI_BINS) $(OMP_BINS)

$(MPI_BINS): %: %.c
	$(MPICC) $(CFLAGS) $< -o $@

$(OMP_BINS): %: %.c
	$(CC) $(CFLAGS) $(OMPFLAG) $< -o $@

gpu: check-gpu $(GPU_BINS)

$(GPU_BINS): %: %.c
	$(MPICC) $(CFLAGS) $(GPUFLAGS) $< -o $@

check-gpu:
	@if [ -z "$(GPUFLAGS)" ]; then \
	  echo "Say which compiler to build with:"; \
	  echo "  make gpu COMPILER=cray                     HPE Cray compilers (the craype-accel module sets the GPU)"; \
	  echo "  make gpu COMPILER=amd    GPU_ARCH=gfx942   AMD compilers, AMD GPU"; \
	  echo "  make gpu COMPILER=nvidia                   NVIDIA HPC compilers, NVIDIA GPU"; \
	  echo "  make gpu COMPILER=intel  MPICC=mpiicx      Intel oneAPI, Intel GPU"; \
	  echo "Or give the flags yourself: make gpu GPUFLAGS='...'"; \
	  exit 1; \
	fi

clean:
	rm -f $(MPI_BINS) $(OMP_BINS) $(GPU_BINS)

.PHONY: all gpu check-gpu clean
