# This makefile is for the command line version
# of the Microsoft Visual Studio Compiler on Windows 10.
# The option '-O3' is unknown and replaced by '-O2'.

QDsrc=../../Ada/Math_Lib/QD/C
MPD=../Norms
CNV=../Norms
MAT=../Matrices

# location of the command line Microsoft Visual Studio Compiler
# CL="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\bin\Hostx64\x64"
CL="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\bin\Hostx64\x64"

# include path for the Microsoft Visual Studio Compiler
# includepath="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\include"
includepath="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\include"

# include path for the Windows Kit
# winkitucrt="C:\Program Files (x86)\Windows Kits\10\Include\10.0.18362.0\ucrt"
winkitucrt="C:\Program Files (x86)\Windows Kits\10\Include\10.0.22000.0\ucrt"

# libaries of the Microsoft Visual Studio compiler
# libdirvs="C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.25.28610\lib\x64"
libdirvs="C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.36.32532\lib\x64"

# libraries of the Windows Kits
# libdirkitum="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\um\x64"
# libdirkitucrt="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.18362.0\ucrt\x64"
libdirkitum="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\um\x64"
libdirkitucrt="C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22000.0\ucrt\x64"

# include files of the CUDA SDK
# CUDASDK="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2"
CUDASDK="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1"
# library folder of the CUDA SDK
# CUDALIB="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v10.2\lib\x64"
CUDALIB="C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.1\lib\x64"

# tested on two different NVIDIA GPUs

# the architecture flag for Ampere A100
# smflag=sm_80
# the architecture flag for RTX 4080
smflag=sm_89

# simple tensor core matrix multiplication :

smTCGemm:
	nvcc -ccbin=$(CL) -O2 -o smTCGemm -arch=$(smflag) simpleTensorCoreGemm.cu

pi64bits:
	gcc -o pi64bits bits_of_pi.c

splitting_doubles.o:
	@-echo ">>> compiling splitting doubles ..."
	g++ -O3 -c splitting_doubles.cpp

splitting_doubles.obj:
	@-echo ">>> compiling splitting doubles ..."
	$(CL)\cl /c -I$(winkitucrt) -I$(includepath) -O2 \
                      splitting_doubles.cpp \
                 /Fo: splitting_doubles.obj /EHsc

test_split: splitting_doubles.o
	@-echo ">>> compiling test splitting doubles..."
	g++ -c test_splitting_doubles.cpp -o test_splitting_doubles.o
	@-echo ">>> linking ..."
	g++ -o test_split test_splitting_doubles.o splitting_doubles.o

double_double.o:
	@-echo ">>> compiling double double ..."
	g++ -O3 -c -I$(QDsrc) $(QDsrc)/double_double.c

double_double.obj:
	@-echo ">>> compiling double double ..."
	$(CL)\cl /c -I$(QDsrc) -I$(winkitucrt) -I$(includepath) -O2 \
                      $(QDsrc)/double_double.cpp \
                 /Fo: double_double.obj /EHsc

quad_double.o:
	@-echo ">>> compiling quad double ..."
	g++ -O3 -c -I$(QDsrc) $(QDsrc)/quad_double.c

octo_double.o:
	@-echo ">>> compiling octo double ..."
	g++ -O3 -c -I$(QDsrc) $(QDsrc)/octo_double.c

hexa_double.o:
	@-echo ">>> compiling hexa double ..."
	g++ -O3 -c -I$(QDsrc) $(QDsrc)/hexa_double.c

double_double_functions.o:
	@-echo ">>> compiling double double functions ..."
	g++ -O3 -c -I$(MPD) $(MPD)/double_double_functions.cpp

double_double_functions.obj:
	@-echo ">>> compiling double double functions ..."
	$(CL)\cl /c -I$(MPD) -I$(winkitucrt) -I$(includepath) -O2 \
                      $(MPD)/double_double_functions.cpp \
                 /Fo: double_double_functions.obj /EHsc

quad_double_functions.o:
	@-echo ">>> compiling quad double functions ..."
	g++ -O3 -c -I$(MPD) $(MPD)/quad_double_functions.cpp

octo_double_functions.o:
	@-echo ">>> compiling octo double functions ..."
	g++ -O3 -c -I$(MPD) $(MPD)/octo_double_functions.cpp

hexa_double_functions.o:
	@-echo ">>> compiling hexa double functions ..."
	g++ -O3 -c -I$(MPD) $(MPD)/hexa_double_functions.cpp

random_numbers.o:
	@-echo ">>> compiling double random numbers"
	g++ -O3 -c -I$(MPD) $(MPD)/random_numbers.cpp

random_numbers.obj:
	@-echo ">>> compiling random number generators ..."
	$(CL)\cl /c -I$(MPD) -I$(winkitucrt) -I$(includepath) -O2 \
                      $(MPD)/random_numbers.cpp \
                 /Fo: random_numbers.obj /EHsc

random2_vectors.o:
	@-echo ">>> compiling double double random vector generators ..."
	g++ -O3 -c -I$(MPD) $(MPD)/random2_vectors.cpp

random2_vectors.obj:
	@-echo ">>> compiling double double random vector generators ..."
	$(CL)\cl /c -I$(MPD) -I$(winkitucrt) -I$(includepath) -O2 \
                      $(MPD)/random2_vectors.cpp \
                 /Fo: random2_vectors.obj /EHsc

random2_matrices.o:
	@-echo ">>> compiling double double random matrix generators ..."
	g++ -O3 -c -I$(MPD) -I$(MAT) $(MAT)/random2_matrices.cpp

random2_matrices.obj:
	@-echo ">>> compiling double double random matrix generators ..."
	$(CL)\cl /c -I$(MPD) -I$(winkitucrt) -I$(includepath) -O2 \
               $(MAT)/random2_matrices.cpp \
                 /Fo: random2_matrices.obj /EHsc

random4_vectors.o:
	@-echo ">>> compiling quad double random vector generators ..."
	g++ -O3 -c -I$(MPD) $(MPD)/random4_vectors.cpp

random4_matrices.o:
	@-echo ">>> compiling quad double random matrix generators ..."
	g++ -O3 -c -I$(MPD) -I$(MAT) $(MAT)/random4_matrices.cpp

random8_vectors.o:
	@-echo ">>> compiling octo double random vector generators ..."
	g++ -O3 -c -I$(MPD) $(MPD)/random8_vectors.cpp

random8_matrices.o:
	@-echo ">>> compiling octo double random matrix generators ..."
	g++ -O3 -c -I$(MPD) -I$(MAT) $(MAT)/random8_matrices.cpp

random16_vectors.o:
	@-echo ">>> compiling hexa double random vector generators ..."
	g++ -O3 -c -I$(MPD) $(MPD)/random16_vectors.cpp

random16_matrices.o:
	@-echo ">>> compiling hexa double random matrix generators ..."
	g++ -O3 -c -I$(MPD) -I$(MAT) $(MAT)/random16_matrices.cpp

vectored_double_doubles.o:
	@-echo ">>> compiling vectored double doubles ..."
	g++ -O3 -c -I$(QDsrc) -I$(MPD) vectored_double_doubles.cpp

vectored_double_doubles.obj:
	@-echo ">>> compiling vectored double doubles ..."
	$(CL)\cl /c -I$(QDsrc) -I$(MPD) -I$(winkitucrt) -I$(includepath) -O2 \
                      vectored_double_doubles.cpp \
                 /Fo: vectored_double_doubles.obj /EHsc

vectored_quad_doubles.o:
	@-echo ">>> compiling vectored quad doubles ..."
	g++ -O3 -c -I$(QDsrc) -I$(MPD) vectored_quad_doubles.cpp

vectored_octo_doubles.o:
	@-echo ">>> compiling vectored octo doubles ..."
	g++ -O3 -c -I$(QDsrc) -I$(MPD) vectored_octo_doubles.cpp

vectored_hexa_doubles.o:
	@-echo ">>> compiling vectored hexa doubles ..."
	g++ -O3 -c -I$(QDsrc) -I$(MPD) vectored_hexa_doubles.cpp

random_series.o:
	@-echo ">>> compiling double random series generators ..."
	g++ -O3 -c -I$(MPD) -I$(CNV) $(CNV)/random_series.cpp

random_matrices.o:
	@-echo ">>> compiling double random matrix generators ..."
	g++ -O3 -c -I$(MPD) -I$(CNV) -I$(MAT) $(MAH)/random_matrices.cpp

double_matrix_multiplications.o:
	@-echo ">>> compiling double matrix multiplications ..."
	g++ -O3 -c double_matrix_multiplications.cpp

double_matrix_multiplications.obj:
	@-echo ">>> compiling double matrix multiplications ..."
	$(CL)\cl /c -I$(winkitucrt) -I$(includepath) -O2 \
                    double_matrix_multiplications.cpp \
                 /Fo: double_matrix_multiplications.obj /EHsc

test_mmm: random_numbers.o random_series.o random_matrices.o \
          double_matrix_multiplications.o
	@-echo ">>> compiling test_mmm ..."
	g++ -c -I$(MAT) test_mmm.cpp -o test_mmm.o
	@-echo ">>> linking ..."
	g++ -o test_mmm test_mmm.o \
               random_numbers.o random_series.o random_matrices.o \
               double_matrix_multiplications.o

ddmm_host.o:
	@-echo ">>> compiling ddmm_host ..."
	g++ -c -O3 -I$(MPD) -I$(CNV) -I$(MAT) ddmm_host.cpp \
               -o ddmm_host.o

ddmm_host.obj:
	@-echo ">>> compiling ddmm_host ..."
	$(CL)\cl /c -I$(winkitucrt) -I$(includepath) -O2 \
                    -I$(MPD) -I$(CNV) -I$(MAT) ddmm_host.cpp \
                 /Fo: ddmm_host.obj /EHsc

ddmm_kernels.obj:
	@-echo ">>> compiling ddmm_kernels ..."
	nvcc -ccbin=$(CL) -arch=$(smflag) -I$(MPD) -c -O3 ddmm_kernels.cu \
             -o ddmm_kernels.obj

test_ddmm.obj:
	@-echo ">>> compiling test_ddmm ..."
	$(CL)\cl /c -I$(winkitucrt) -I$(includepath) -O2 \
                    -I$(MPD) -I$(CNV) -I$(MAT) test_ddmm.cpp \
                 /I$(CUDASDK)/include /Fo: test_ddmm.obj /EHsc

test_ddmm: double_double.obj double_double_functions.obj \
           random_numbers.obj random2_vectors.obj random2_matrices.obj \
           ddmm_host.obj ddmm_kernels.obj test_ddmm.obj
	@-echo ">>> linking ..."
	nvcc -ccbin=$(CL) -o test_ddmm test_ddmm.obj \
               ddmm_host.obj ddmm_kernels.obj \
               double_double.obj double_double_functions.obj \
               random_numbers.obj random2_vectors.obj random2_matrices.obj

test_vdd: double_double.o double_double_functions.o \
          random_numbers.o random2_vectors.o random2_matrices.o \
          splitting_doubles.o vectored_double_doubles.o \
          double_matrix_multiplications.o ddmm_host.o 
	@-echo ">>> compiling test_vdd ..."
	g++ -c -I$(QDsrc) -I$(MPD) -I$(MAT) test_vdd.cpp -o test_vdd.o
	@-echo ">>> linking ..."
	g++ -o test_vdd test_vdd.o double_matrix_multiplications.o \
               double_double.o double_double_functions.o \
               random_numbers.o random2_vectors.o random2_matrices.o \
               splitting_doubles.o vectored_double_doubles.o ddmm_host.o

test_vqd: double_double.o quad_double.o \
          double_double_functions.o quad_double_functions.o \
          random_numbers.o random4_vectors.o random4_matrices.o \
          splitting_doubles.o vectored_quad_doubles.o \
          double_matrix_multiplications.o
	@-echo ">>> compiling test_vqd ..."
	g++ -c -I$(QDsrc) -I$(MPD) -I$(MAT) test_vqd.cpp -o test_vqd.o
	@-echo ">>> linking ..."
	g++ -o test_vqd test_vqd.o double_matrix_multiplications.o \
               double_double.o quad_double.o \
               double_double_functions.o quad_double_functions.o \
               random_numbers.o random4_vectors.o random4_matrices.o \
               splitting_doubles.o vectored_quad_doubles.o

test_vod: double_double.o quad_double.o octo_double.o \
          double_double_functions.o quad_double_functions.o \
          octo_double_functions.o double_matrix_multiplications.o \
          random_numbers.o random8_vectors.o random8_matrices.o \
          splitting_doubles.o vectored_octo_doubles.o
	@-echo ">>> compiling test_vod ..."
	g++ -c -I$(QDsrc) -I$(MPD) -I$(MAT) test_vod.cpp -o test_vod.o
	@-echo ">>> linking ..."
	g++ -o test_vod test_vod.o \
               double_double.o quad_double.o octo_double.o \
               double_double_functions.o quad_double_functions.o \
               octo_double_functions.o double_matrix_multiplications.o \
               random_numbers.o random8_vectors.o random8_matrices.o \
               splitting_doubles.o vectored_octo_doubles.o

test_vhd: double_double.o quad_double.o octo_double.o hexa_double.o \
          double_double_functions.o quad_double_functions.o \
          octo_double_functions.o hexa_double_functions.o \
          random_numbers.o random16_vectors.o random16_matrices.o \
          splitting_doubles.o vectored_hexa_doubles.o
	@-echo ">>> compiling test_vhd ..."
	g++ -c -I$(QDsrc) -I$(MPD) -I$(MAT) test_vhd.cpp -o test_vhd.o
	@-echo ">>> linking ..."
	g++ -o test_vhd test_vhd.o \
               double_double.o quad_double.o octo_double.o hexa_double.o \
               double_double_functions.o quad_double_functions.o \
               octo_double_functions.o hexa_double_functions.o \
               random_numbers.o random16_vectors.o random16_matrices.o \
               splitting_doubles.o vectored_hexa_doubles.o

smDMMA_host.obj:
	@-echo ">>> compiling smDMMA_host ..."
	$(CL)\cl /c smDMMA_host.cpp \
                 -I$(winkitucrt) -I$(includepath) -I$(MAT) -O2 \
                 /Fo: smDMMA_host.obj /EHsc

smDMMA_kernels.obj:
	@-echo ">>> compiling smDMMA_kernels ..."
	nvcc -ccbin=$(CL) -arch=$(smflag) -c -O3 smDMMA_kernels.cu \
             -o smDMMA_kernels.obj

test_dd_setup.obj:
	@-echo ">>> compiling test_dd_setup ..."
	$(CL)\cl /c -O2 test_dd_setup.cpp -I$(winkitucrt) -I$(includepath) \
                 /Fo: test_dd_setup.obj /EHsc

test_dd_setup: smDMMA_host.obj test_dd_setup.obj \
        double_matrix_multiplications.obj \
        double_double.obj double_double_functions.obj \
        random_numbers.obj random2_vectors.obj random2_matrices.obj \
        splitting_doubles.obj vectored_double_doubles.obj
	@-echo ">>> linking ..."
	nvcc -ccbin=$(CL) -o test_dd_setup.exe test_dd_setup.obj \
                 smDMMA_host.obj double_matrix_multiplications.obj \
                 double_double.obj double_double_functions.obj \
                 random_numbers.obj random2_vectors.obj random2_matrices.obj \
                 splitting_doubles.obj vectored_double_doubles.obj

test_smDMMA.obj:
	@-echo ">>> compiling test_smDMMA ..."
	$(CL)\cl /c -O2 test_smDMMA.cpp -I$(winkitucrt) -I$(includepath) \
                 /I$(CUDASDK)/include /Fo: test_smDMMA.obj /EHsc

test_smDMMA: smDMMA_host.obj smDMMA_kernels.obj test_smDMMA.obj \
        double_matrix_multiplications.obj \
        double_double.obj double_double_functions.obj \
        random_numbers.obj random2_vectors.obj random2_matrices.obj \
        splitting_doubles.obj vectored_double_doubles.obj
	@-echo ">>> linking ..."
	nvcc -ccbin=$(CL) -o test_smDMMA.exe \
             smDMMA_host.obj smDMMA_kernels.obj test_smDMMA.obj \
             double_matrix_multiplications.obj \
             double_double.obj double_double_functions.obj \
             random_numbers.obj random2_vectors.obj random2_matrices.obj \
             splitting_doubles.obj vectored_double_doubles.obj

clean:
	del *~
	del smTCGemm.exe smTCGemm.lib smTCGemm.exp
	del smDMMA_host.obj smDMMA_kernels.obj test_smDMMA.obj
	del test_smDMMA.exe test_smDMMA.lib test_smDMMA.exp
	del pi64bits.exe
	del test_split.exe splitting_doubles.o test_splitting_doubles.o
	del splitting_doubles.obj
	del random_numbers.o random2_vectors.o random2_matrices.o
	del random_numbers.obj random2_vectors.obj random2_matrices.obj
	del double_double.o double_double_functions.o
	del double_double.obj double_double_functions.obj
	del vectored_double_doubles.o test_vdd.o
	del vectored_double_doubles.obj
	del double_matrix_multiplications.o
	del double_matrix_multiplications.obj
	del test_mmm.exe test_mmm.o random_series.o random_matrices.o
	del test_vdd.exe
	del quad_double.o quad_double_functions.o
	del random4_vectors.o random4_matrices.o
	del vectored_quad_doubles.o test_vqd.o
	del test_vqd.exe
	del octo_double.o octo_double_functions.o
	del random8_vectors.o  random8_matrices.o
	del vectored_octo_doubles.o test_vod.o
	del test_vod.exe
	del hexa_double.o hexa_double_functions.o
	del random16_vectors.o random16_matrices.o
	del vectored_hexa_doubles.o test_vhd.o
	del test_vhd.exe
	del test_dd_setup.obj test_dd_setup.exe
	del test_dd_setup.lib test_dd_setup.exp
	del ddmm_host.obj ddmm_kernels.obj
	del test_ddmm.obj test_ddmm.exe
	del test_ddmm.lib test_ddmm.exp
