######################################################################
##
## Makefile for gcd routines
##
## author: morain@lix.polytechnique.fr
##
VERSION="2022.07.06a"
VERSION="2022.07.21a"
VERSION="2022.08.31a"
VERSION="2022.08.31b"
######################################################################

# where the two following directories should be
GMPDIR=..................
GMPLIB=$(GMPDIR)/lib
GMPH=$(GMPDIR)/include

# where to put the binaries
BINDEST=.
# do not forget to create the directory
BINDIR=./bin/$(BINDEST)
# the source directory once we are in BINDIR
SRC = ..

## default options
OPT = -W -Wall -Wmissing-prototypes
OFLAGS = -g $(OPT) # -pg
## tests
OFLAGS = -O2 $(OPT) # -pg
DFLAGS = -DUSE_GMP -DPRODUCTION # -DFINDTHRESHOLD # 
CFLAGS = $(OFLAGS) $(DFLAGS)
LDFLAGS = # -pg # -p

all: testgcd

testgcd: 
	make DIR=$(BINDIR) GMPDIR=$(GMPDIR) \
	CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" DLIB=$(DLIB) atestgcd

atestgcd:
	rev=`git rev-list HEAD | head -1`; \
	cd $(DIR); \
	make -f $(SRC)/Makefile DIR=$(DIR) \
	CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" \
	DLIB=$(DLIB) REV="$$rev" btestgcd

clean:
	make DIR=$(BINDIR) aclean

aclean:
	cd $(DIR); /bin/rm *.o

FILES = src/gcd_common.c src/gcd_common.h \
	src/gcd_euclid.c src/gcd_euclid.h \
	src/gcd_jebelean.c src/gcd_jebelean.h \
	src/gcd_matrix.c src/gcd_matrix.h \
	src/gcd_thull_yap.c src/gcd_thull_yap.h \
	src/gcd_utils.c src/gcd_utils.h \
	src/qseq.c src/qseq.h src/regular.c src/regular.h \
	src/git_version.h src/testgcd.c \
	Makefile README

##src/gcd_pan_wang.c src/gcd_pan_wang.h

tgz:
	tar zcvf gcd.$(VERSION).tgz $(FILES)

######################################################################
## Tests and benchmarks
######################################################################

slowgcdrecette:
	for target in gcd; do \
	    for algo in euclid jebelean; do \
	        echo "##### recette for $$algo"; \
	        $(BINDIR)/testgcd -algo $$algo -recette $$target; \
	    done; \
	done

SLOWALGOS=euclid jebelean
SLOWALGOS=jebelean
SLOWFAMILIES=random2 # random
SLOWARGS=-sizemin 8 -sizemax 50 -ntests 1000 -verbose 1
SLOWFAMILIES=mB1 mB2 mC mD pA pB
SLOWARGS=-imin 20 -imax 200
slowgcdtests:
	for algo in $(SLOWALGOS); do \
	    echo "##### tests for $$algo"; \
	    args="-algo $$algo $(SLOWARGS)"; \
	    for target in gcd; do \
		for family in $(SLOWFAMILIES); do \
	            echo "##### $$target for $$algo with family $$family"; \
	            $(BINDIR)/testgcd $$args -test $$target -family $$family; \
	        done; \
	    done; \
	done

TYFAMILIES=mB1 mB2 mC mD pA pB
TYARGS=-imin 20 -imax 100
TYFAMILIES=random
TYARGS=-sizemin 10 -sizemax 510 -sizeincr 10 -ntests 100
thullyaptests:
	args="-algo thullyap $(TYARGS)"; \
	for target in gcd hgcd; do \
	    for family in $(TYFAMILIES); do \
	        echo "##### Thull/Yap for $$family"; \
		$(BINDIR)/testgcd $$args -test $$target -family $$family; \
	    done; \
	done  

BENCHALGOS=euclid jebelean thullyap gmp
BENCHFAMILIES=random random2
gcdbenchmarks:
	args="-test gcd -sizemin 100 -sizemax 15100 -sizeincr 100"; \
	args="$$args -ntests 10"; \
	for family in $(BENCHFAMILIES); do \
	    echo "##### family $$family"; \
	    for algo in $(BENCHALGOS); do \
		echo "##### algo $$algo"; \
		$(BINDIR)/testgcd $$args -algo $$algo -family $$family; \
	    done; \
	done

######################################################################
COMMONLIB = $(GMPLIB)/libgmp.a -lpthread -lrt -lm -fopenmp

IPATH = -I$(GMPH) -I./$(SRC)/src

## use all
GCDOBJS = gcd_pan_wang.o gcd_thull_yap.o gcd_jebelean.o gcd_euclid.o \
	  gcd_common.o regular.o gcd_matrix.o qseq.o gcd_utils.o
## do not use pan_wang
GCDOBJS = gcd_thull_yap.o gcd_jebelean.o gcd_euclid.o \
	  gcd_common.o regular.o gcd_matrix.o qseq.o gcd_utils.o

GCDLIB = libgcd.a

btestgcd: $(GCDLIB) testgcd.o
	$(CC) $(LDFLAGS) $(IPATH) testgcd.o $(GCDLIB) $(COMMONLIB) -o testgcd

$(GCDLIB): $(GCDOBJS)
	-rm -f $(GCDLIB)
	ar cr $(GCDLIB) $(GCDOBJS)
	ranlib $(GCDLIB)

testgcd.o: $(SRC)/src/testgcd.c
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/testgcd.c

gcd_utils.o: $(SRC)/src/gcd_utils.c $(SRC)/src/gcd_utils.h
	echo "#define GIT_VERSION \"$(REV)\"" > $(SRC)/src/git_version.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_utils.c

qseq.o: $(SRC)/src/qseq.c $(SRC)/src/qseq.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/qseq.c

regular.o: $(SRC)/src/regular.c $(SRC)/src/regular.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/regular.c

gmp_fft.o: $(SRC)/src/gmp_fft.c $(SRC)/src/gmp_fft.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gmp_fft.c

gcd_matrix.o: $(SRC)/src/gcd_matrix.c $(SRC)/src/gcd_matrix.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_matrix.c

gcd_common.o: $(SRC)/src/gcd_common.c $(SRC)/src/gcd_common.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_common.c

gcd_euclid.o: $(SRC)/src/gcd_euclid.c $(SRC)/src/gcd_euclid.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_euclid.c

gcd_jebelean.o: $(SRC)/src/gcd_jebelean.c $(SRC)/src/gcd_jebelean.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_jebelean.c

gcd_thull_yap.o: $(SRC)/src/gcd_thull_yap.c $(SRC)/src/gcd_thull_yap.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_thull_yap.c

gcd_pan_wang.o: $(SRC)/src/gcd_pan_wang.c $(SRC)/src/gcd_pan_wang.h
	$(CC) $(CFLAGS) $(IPATH) -c $(SRC)/src/gcd_pan_wang.c
