#Makefile

#find MPI path
MPIC++ = $(shell which mpic++)
MPI_ROOT = $(dir $(MPIC++))

#compilers
CC  = mpicc
C++ = mpic++
FC = mpif90
PGICC = pgcc
PGIFC = pgfortran
NVCC = nvcc

#optimizations
#CFLAGS = -g
CFLAGS = -O3
FFLAGS = -O3
NVFLAGS = -gencode=arch=compute_20,code=\"sm_20,compute_20\" -c -O3 \
	-I$(MPI_ROOT)/../include
PGINVFLAGS = -acc -Mcuda -O3 

#libraries
NVLIBS = -L/usr/local/cuda/lib64 -lcudart -lcuda 

#target binaries
BIN = pi-c pi-f pi-omp-c \
	pi-cu-f pi-cu \
	pi-cu-block pi-cu-shared pi-cu-grid pi-cu-grid-reduce \
	pi-mpi-c pi-mpi-f pi-mpi-omp-c pi-cu-mpi \
	pi-pgicu-c pi-pgicu-f pi-pgicu-mpi-f \
	pi-pgicu-reduce-c pi-pgicu-reduce-f

all: $(BIN)

#linker rules
pi-c: pi-c.o
	$(CC) $(CFLAGS) -o pi-c pi-c.o

pi-omp-c: pi-omp-c.o
	$(CC) $(CFLAGS) -fopenmp -o pi-omp-c pi-omp-c.o

pi-mpi-omp-c: pi-mpi-omp-c.o
	$(CC) $(CFLAGS) -fopenmp -o pi-mpi-omp-c pi-mpi-omp-c.o

pi-f: pi-f.o
	$(FC) $(FFLAGS) -o pi-f pi-f.o

pi-mpi-c: pi-mpi-c.o
	$(CC) $(CFLAGS) -o pi-mpi-c pi-mpi-c.o

pi-mpi-f: pi-mpi-f.o
	$(FC) $(FFLAGS) -o pi-mpi-f pi-mpi-f.o

pi-pgicu-mpi-f:
	$(FC) $(PGINVFLAGS) -o pi-pgicu-mpi-f pi-pgicu-mpi-f.f

pi-cu-f: pi-cu-f.o pi-cu-integrate-f.o
	$(FC) $(FFLAGS) $(NVLIBS) -o pi-cu-f pi-cu-f.o pi-cu-integrate-f.o -lstdc++
pi-cu-integrate-f.o:
	$(NVCC) $(NVFLAGS) pi-cu-integrate-f.cu

pi-pgicu-c:
	$(PGICC) $(PGINVFLAGS) -o pi-pgicu-c pi-pgicu-c.c

pi-pgicu-reduce-c:
	$(PGICC) $(PGINVFLAGS) -o pi-pgicu-reduce-c pi-pgicu-reduce-c.c

pi-pgicu-f:
	$(PGIFC) $(PGINVFLAGS) -o pi-pgicu-f pi-pgicu-f.f

pi-pgicu-reduce-f:
	$(PGIFC) $(PGINVFLAGS) -o pi-pgicu-reduce-f pi-pgicu-reduce-f.f

pi-cu.o:
	$(NVCC) $(NVFLAGS) -c pi-cu.cu
pi-cu: pi-cu.o
	$(C++) $(NVLIBS) -o pi-cu pi-cu.o

pi-cu-shared.o:
	$(NVCC) $(NVFLAGS) -c pi-cu-shared.cu
pi-cu-shared: pi-cu-shared.o
	$(C++) $(NVLIBS) -o pi-cu-shared pi-cu-shared.o

pi-cu-block.o:
	$(NVCC) $(NVFLAGS) -c pi-cu-block.cu
pi-cu-block: pi-cu-block.o
	$(C++) $(NVLIBS) -o pi-cu-block pi-cu-block.o

pi-cu-grid.o:
	$(NVCC) $(NVFLAGS) -c pi-cu-grid.cu
pi-cu-grid: pi-cu-grid.o
	$(C++) $(NVLIBS) -o pi-cu-grid pi-cu-grid.o

pi-cu-grid-reduce.o:
	$(NVCC) $(NVFLAGS) -c pi-cu-grid-reduce.cu
pi-cu-grid-reduce: pi-cu-grid-reduce.o
	$(C++) $(NVLIBS) -o pi-cu-grid-reduce pi-cu-grid-reduce.o

pi-cu-mpi.o:
	$(NVCC) $(NVFLAGS) -c pi-cu-mpi.cu
pi-cu-mpi: pi-cu-mpi.o
	$(C++) $(NVLIBS) -o pi-cu-mpi pi-cu-mpi.o

#cleanup rule
clean:
	rm -f $(BIN) *.o
