diff --git a/CLANG_default.mk b/CLANG_default.mk deleted file mode 100644 index 4bc290d..0000000 --- a/CLANG_default.mk +++ /dev/null @@ -1,123 +0,0 @@ -# Basic Defintions for using GNU-compiler suite sequentially -# requires setting of COMPILER=CLANG_ - -#CLANGPATH=//usr/lib/llvm-10/bin/ -CC = ${CLANGPATH}clang -CXX = ${CLANGPATH}clang++ -#CXX = ${CLANGPATH}clang++ -lomptarget -fopenmp-targets=nvptx64-nvidia-cuda --cuda-path=/opt/pgi/linux86-64/2017/cuda/8.0 -#F77 = gfortran -LINKER = ${CXX} - -#http://clang.llvm.org/docs/UsersManual.html#options-to-control-error-and-warning-messages -WARNINGS += -Weverything -Wno-c++98-compat -Wno-sign-conversion -Wno-date-time -Wno-shorten-64-to-32 -Wno-padded -ferror-limit=1 -WARNINGS += -Wdocumentation -Wconversion -Wshadow -Wfloat-conversion -pedantic -#-fsyntax-only -Wdocumentation -Wconversion -Wshadow -Wfloat-conversion -pedantic - -CXXFLAGS += -O3 -std=c++17 -ferror-limit=1 ${WARNINGS} -# don't use -Ofast -# -ftrapv -LINKFLAGS += -O3 - -# different libraries in Ubuntu or manajaró -ifndef UBUNTU -UBUNTU=1 -endif - -# BLAS, LAPACK -LINKFLAGS += -llapack -lblas -# -lopenblas -ifeq ($(UBUNTU),1) -# ubuntu -else -# on archlinux -LINKFLAGS += -lcblas -endif - -# interprocedural optimization -CXXFLAGS += -flto -LINKFLAGS += -flto - -# very good check -# http://clang.llvm.org/extra/clang-tidy/ -# good check, see: http://llvm.org/docs/CodingStandards.html#include-style -SWITCH_OFF=,-readability-magic-numbers,-readability-redundant-control-flow,-readability-redundant-member-init -SWITCH_OFF+=,-readability-redundant-member-init,-readability-isolate-declaration -#READABILITY=,readability*${SWITCH_OFF} -#TIDYFLAGS = -checks=llvm-*,-llvm-header-guard -header-filter=.* -enable-check-profile -extra-arg="-std=c++17" -extra-arg="-fopenmp" -TIDYFLAGS = -checks=llvm-*,-llvm-header-guard${READABILITY} -header-filter=.* -enable-check-profile -extra-arg="-std=c++17" -extra-arg="-fopenmp" -#TIDYFLAGS += -checks='modernize* -# ??? -#TIDYFLAGS = -checks='cert*' -header-filter=.* -# MPI checks ?? -#TIDYFLAGS = -checks='mpi*' -# ?? -#TIDYFLAGS = -checks='performance*' -header-filter=.* -#TIDYFLAGS = -checks='portability-*' -header-filter=.* -#TIDYFLAGS = -checks='readability-*' -header-filter=.* - -default: ${PROGRAM} - -${PROGRAM}: ${OBJECTS} - $(LINKER) $^ ${LINKFLAGS} -o $@ - -clean: - @rm -f ${PROGRAM} ${OBJECTS} - -clean_all:: clean - @rm -f *_ *~ *.bak *.log *.out *.tar - -codecheck: tidy_check -tidy_check: - clang-tidy ${SOURCES} ${TIDYFLAGS} -- ${SOURCES} -# see also http://clang-developers.42468.n3.nabble.com/Error-while-trying-to-load-a-compilation-database-td4049722.html - -run: clean ${PROGRAM} -# time ./${PROGRAM} ${PARAMS} - ./${PROGRAM} ${PARAMS} - -# tar the current directory -MY_DIR = `basename ${PWD}` -tar: clean_all - @echo "Tar the directory: " ${MY_DIR} - @cd .. ;\ - tar cf ${MY_DIR}.tar ${MY_DIR} *default.mk ;\ - cd ${MY_DIR} -# tar cf `basename ${PWD}`.tar * - -doc: - doxygen Doxyfile - -######################################################################### - -.cpp.o: - $(CXX) -c $(CXXFLAGS) -o $@ $< - -.c.o: - $(CC) -c $(CFLAGS) -o $@ $< - -.f.o: - $(F77) -c $(FFLAGS) -o $@ $< - -################################################################################################## -# some tools -# Cache behaviour (CXXFLAGS += -g tracks down to source lines; no -pg in linkflags) -cache: ${PROGRAM} - valgrind --tool=callgrind --simulate-cache=yes ./$^ ${PARAMS} -# kcachegrind callgrind.out. & - kcachegrind `ls -1tr callgrind.out.* |tail -1` - -# Check for wrong memory accesses, memory leaks, ... -# use smaller data sets -mem: ${PROGRAM} - valgrind -v --leak-check=yes --tool=memcheck --undef-value-errors=yes --track-origins=yes --log-file=$^.addr.out --show-reachable=yes ./$^ ${PARAMS} - -# Simple run time profiling of your code -# CXXFLAGS += -g -pg -# LINKFLAGS += -pg -prof: ${PROGRAM} - perf record ./$^ ${PARAMS} - perf report -# gprof -b ./$^ > gp.out -# kprof -f gp.out -p gprof & - -codecheck: tidy_check diff --git a/GCC_default.mk b/GCC_default.mk deleted file mode 100644 index e9e0a0c..0000000 --- a/GCC_default.mk +++ /dev/null @@ -1,196 +0,0 @@ -# Basic Defintions for using GNU-compiler suite sequentially -# requires setting of COMPILER=GCC_ - -CC = gcc -CXX = g++ -F77 = gfortran -LINKER = ${CXX} - -WARNINGS = -Wall -pedantic -Wextra -Weffc++ -Woverloaded-virtual -Wfloat-equal -Wshadow \ - -Wredundant-decls -fmax-errors=1 -# -Wunreachable-code -Winline -CXXFLAGS += -ffast-math -O3 -march=native -std=c++17 ${WARNINGS} -#CXXFLAGS += -Ofast -funroll-all-loops -std=c++17 ${WARNINGS} -#-msse3 -# -ftree-vectorizer-verbose=2 -DNDEBUG -# -ftree-vectorizer-verbose=5 -# -ftree-vectorize -fdump-tree-vect-blocks=foo.dump -fdump-tree-pre=stderr - -# CFLAGS = -ffast-math -O3 -DNDEBUG -msse3 -fopenmp -fdump-tree-vect-details -# CFLAGS = -ffast-math -O3 -funroll-loops -DNDEBUG -msse3 -fopenmp -ftree-vectorizer-verbose=2 -# #CFLAGS = -ffast-math -O3 -DNDEBUG -msse3 -fopenmp -# FFLAGS = -ffast-math -O3 -DNDEBUG -msse3 -fopenmp -# LFLAGS = -ffast-math -O3 -DNDEBUG -msse3 -fopenmp -LINKFLAGS += -O3 - -#architecture -#CPU = -march=znver2 -CXXFLAGS += ${CPU} -LINKFLAGS += ${CPU} - -# different libraries in Ubuntu or manajaró -ifndef UBUNTU -UBUNTU=1 -endif - -# BLAS, LAPACK -ifeq ($(UBUNTU),1) -LINKFLAGS += -llapack -lblas -# -lopenblas -else -# on archlinux -LINKFLAGS += -llapack -lopenblas -lcblas -endif - -# interprocedural optimization -#CXXFLAGS += -flto -#LINKFLAGS += -flto - -# for debugging purpose (save code) -# -fsanitize=leak # only one out the three can be used -# -fsanitize=address -# -fsanitize=thread -SANITARY = -fsanitize=address -fsanitize=undefined -fsanitize=null -fsanitize=return \ - -fsanitize=bounds -fsanitize=alignment -fsanitize=float-divide-by-zero -fsanitize=float-cast-overflow \ - -fsanitize=bool -fsanitize=enum -fsanitize=vptr -#CXXFLAGS += ${SANITARY} -#LINKFLAGS += ${SANITARY} - -# profiling tools -#CXXFLAGS += -pg -#LINKFLAGS += -pg - - -default: ${PROGRAM} - -${PROGRAM}: ${OBJECTS} - $(LINKER) $^ ${LINKFLAGS} -o $@ - -clean: - @rm -f ${PROGRAM} ${OBJECTS} - -clean_all:: clean - -@rm -f *_ *~ *.bak *.log *.out *.tar *.orig *.optrpt - -@rm -rf html - -run: clean ${PROGRAM} -#run: ${PROGRAM} -# time ./${PROGRAM} ${PARAMS} - ./${PROGRAM} ${PARAMS} - -# tar the current directory -MY_DIR = `basename ${PWD}` -tar: clean_all - @echo "Tar the directory: " ${MY_DIR} - @cd .. ;\ - tar cf ${MY_DIR}.tar ${MY_DIR} *default.mk ;\ - cd ${MY_DIR} -# tar cf `basename ${PWD}`.tar * -#find . -size +10M > large_files -#--exclude-from ${MY_DIR}/large_files - -zip: clean - @echo "Zip the directory: " ${MY_DIR} - @cd .. ;\ - zip -r ${MY_DIR}.zip ${MY_DIR} *default.mk ;\ - cd ${MY_DIR} - -doc: - doxygen Doxyfile - -######################################################################### -.SUFFIXES: .f90 - -.cpp.o: - $(CXX) -c $(CXXFLAGS) -o $@ $< -# $(CXX) -c $(CXXFLAGS) -o $@ $< 2>&1 | tee -a $<.log -# $(CXX) -c $(CXXFLAGS) -o $@ $< 2>&1 | tee -a $(<:.cpp=.log) - -.c.o: - $(CC) -c $(CFLAGS) -o $@ $< - -.f.o: - $(F77) -c $(FFLAGS) -o $@ $< - -.f90.o: - $(F77) -c $(FFLAGS) -o $@ $< - -################################################################################################## -# some tools -# Cache behaviour (CXXFLAGS += -g tracks down to source lines; no -pg in linkflags) -cache: ${PROGRAM} - valgrind --tool=callgrind --simulate-cache=yes ./$^ ${PARAMS} -# kcachegrind callgrind.out. & - kcachegrind `ls -1tr callgrind.out.* |tail -1` - -# Check for wrong memory accesses, memory leaks, ... -# use smaller data sets -# no "-pg" in compile/link options -mem: ${PROGRAM} - valgrind -v --leak-check=yes --tool=memcheck --undef-value-errors=yes --track-origins=yes --log-file=$^.addr.out --show-reachable=yes ./$^ ${PARAMS} -# Graphical interface -# valkyrie - -# Simple run time profiling of your code -CXXFLAGS += -g -pg -LINKFLAGS += -pg -prof: ${PROGRAM} - ./$^ ${PARAMS} - gprof -b ./$^ > gp.out -# kprof -f gp.out -p gprof & - -# sudo apt install gprofng-gui -# https://parallel.computer/presentations/PPoPP2023/2023-Ruud-Slides.pdf -# read §3 in https://sourceware.org/binutils/docs/gprofng.html -# /usr/bin/gp-collect-app -o test.1.er -p on -S on /home/ghaase/Lectures/Math2CPP/Codes/seq/jacobi_oo_stl/main.GCC_ -prof2: ${PROGRAM} - gprofng collect app -h auto ./$^ ${PARAMS} -# gprofng display text -functions `ls -1tdr test.*.er |tail -1` - gprofng display text -script gprofng_script2 `ls -1tdr test.*.er |tail -1` -# gprofng display text -script gprofng_script2 test.*.er -# gprofng display gui & - -prof3: ${PROGRAM} - perf record ./$^ ${PARAMS} - perf report -# perf in Ubuntu 20.04: https://www.howtoforge.com/how-to-install-perf-performance-analysis-tool-on-ubuntu-20-04/ -# * install -# * sudo vi /etc/sysctl.conf -# add kernel.perf_event_paranoid = 0 - -#Trace your heap: -#> heaptrack ./main.GCC_ -#> heaptrack_gui heaptrack.main.GCC_..gz -heap: ${PROGRAM} - heaptrack ./$^ ${PARAMS} - heaptrack_gui `ls -1tr heaptrack.$^.* |tail -1` & - -codecheck: $(SOURCES) - cppcheck --enable=all --inconclusive --std=c++17 --suppress=missingIncludeSystem $^ - - -######################################################################## -# get the detailed status of all optimization flags -info: - echo "detailed status of all optimization flags" - $(CXX) --version - $(CXX) -Q $(CXXFLAGS) --help=optimizers - lscpu - inxi -C - lstopo - -# Excellent hardware info -# hardinfo -# Life monitoring of CPU frequency etc. -# sudo i7z - -# Memory consumption -# vmstat -at -SM 3 -# xfce4-taskmanager - - -# https://www.tecmint.com/check-linux-cpu-information/ -#https://www.tecmint.com/monitor-cpu-and-gpu-temperature-in-ubuntu/ - -# Debugging: -# https://wiki.archlinux.org/index.php/Debugging diff --git a/ex1B_data-IO_and_vectors/Makefile b/cpp_workspace/ex5/ex5_1/Makefile similarity index 91% rename from ex1B_data-IO_and_vectors/Makefile rename to cpp_workspace/ex5/ex5_1/Makefile index b854f57..f5bc097 100644 --- a/ex1B_data-IO_and_vectors/Makefile +++ b/cpp_workspace/ex5/ex5_1/Makefile @@ -13,7 +13,7 @@ COMPILER=GCC_ # COMPILER=PGI_ -SOURCES = main.cpp ../ex1A_mean_values/means.cpp +SOURCES = main.cpp mylib.cpp OBJECTS = $(SOURCES:.cpp=.o) PROGRAM = main.${COMPILER} diff --git a/utils/info.h b/cpp_workspace/ex5/ex5_1/check_env.h similarity index 56% rename from utils/info.h rename to cpp_workspace/ex5/ex5_1/check_env.h index b8aaecf..41bd99d 100644 --- a/utils/info.h +++ b/cpp_workspace/ex5/ex5_1/check_env.h @@ -1,15 +1,9 @@ -// -// Gundolf Haase, Oct 18 2024 -// #pragma once -#ifdef __NVCC__ -#include -#endif +#include #ifdef _OPENMP #include #endif -#include #include //##################################### @@ -18,9 +12,9 @@ // http://www.cplusplus.com/doc/tutorial/preprocessor/ // also: export OMP_DISPLAY_ENV=VERBOSE //##################################### -/** Checks for compilers, its versions, threads etc. on CPU +/** Checks for compilers, its versions, threads etc. * - @param[in] argc number of command line arguments + @param[in] argc number of command line arguemnts @param[in] argv command line arguments as array of C-strings */ template @@ -41,28 +35,25 @@ void check_env(T argc, char const *argv[]) // Ignore warnings for #pragma omp unrecognice #pragma warning disable 3180 -#elif defined __NVCC__ -//#pragma message(" ########## NVCC ###############") -// https://docs.nvidia.com/cuda/cuda-compiler-driver-nvcc/ - std::cout << "NVCC " << __CUDACC_VER_MAJOR__ << "." << __CUDACC_VER_MINOR__ ; +#elif defined __PGI +#pragma message(" ########## PGI ###############") + std::cout << "PGI " << __PGIC__ << "." << __PGIC_MINOR__ << "." << __PGIC_PATCHLEVEL__; #elif defined __clang__ #pragma message(" ########## CLANG ###############") std::cout << "CLANG " << __clang_major__ << "." << __clang_minor__ << "."; // << __clang_patchlevel__; #elif defined __GNUC__ -//#pragma message(" ########## Gnu ###############") +#pragma message(" ########## Gnu ###############") std::cout << "Gnu " << __GNUC__ << "." << __GNUC_MINOR__ << "." << __GNUC_PATCHLEVEL__; #else #pragma message(" ########## unknown Compiler ###############") std::cout << "unknown"; #endif std::cout << " C++ standard: " << __cplusplus << std::endl; - + // Parallel environments std::cout << "Parallel: "; #if defined MPI_VERSION -#ifndef __GNUC__ #pragma message(" ########## MPI ###############") -#endif #ifdef OPEN_MPI std::cout << "OpenMPI "; #else @@ -76,9 +67,8 @@ void check_env(T argc, char const *argv[]) //https://stackoverflow.com/questions/1304363/how-to-check-the-version-of-openmp-on-linux std::unordered_map const map{ {200505, "2.5"}, {200805, "3.0"}, {201107, "3.1"}, {201307, "4.0"}, {201511, "4.5"}, {201611, "5.0"}, {201811, "5.0"}}; -#ifndef __GNUC__ #pragma message(" ########## OPENMP ###############") -#endif + //std::cout << _OPENMP; std::cout << "OpenMP "; try { std::cout << map.at(_OPENMP); @@ -105,41 +95,5 @@ void check_env(T argc, char const *argv[]) std::cout << "Date : " << __DATE__ << " " << __TIME__; std::cout << "\n#######################################################################\n"; } - - - -/** @brief Lists basic properties of GPU - */ -inline -void printGPUInfo() -{ - using std::cout, std::endl, std::boolalpha; -#ifdef __NVCC__ - cout <<"\n++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"; - // https://devblogs.nvidia.com/how-query-device-properties-and-handle-errors-cuda-cc/ - int nDevices; - cudaError_t err = cudaGetDeviceCount(&nDevices); - if (err != cudaSuccess) printf("%i : %s\n", err, cudaGetErrorString(err)); - - // https://docs.nvidia.com/cuda/cuda-runtime-api/structcudaDeviceProp.html - cudaDeviceProp prop; - // https://www.cs.cmu.edu/afs/cs/academic/class/15668-s11/www/cuda-doc/html/group__CUDART__DEVICE_g5aa4f47938af8276f08074d09b7d520c.html - err = cudaGetDeviceProperties (&prop, 0); - if (err != cudaSuccess) printf("%i : %s\n", err, cudaGetErrorString(err)); - cout << "We work on " << nDevices << " x " << prop.name << " GPU \n with " - << prop.multiProcessorCount << " Multiprocessors (SME)" - << ", Compute capability " << prop.major << "." << prop.minor << endl; - cout << "global Mem: " << prop.totalGlobalMem/1024/1000/1000 << " GB" << endl; - cout << "shared Mem per SME: " << prop.sharedMemPerMultiprocessor/1024 << "kB" - << " shared Mem per Block: " << prop.sharedMemPerBlock/1024 << " kB" - << " 32b-Registers per Block: " << prop.regsPerBlock << endl; - cout << "global L2 cache: " << prop.l2CacheSize/1024 << " kB" - << " local L1 cache supported: " << boolalpha << bool(prop.localL1CacheSupported) << endl; - cout << "max Threads per Block:" << prop.maxThreadsPerBlock << endl; - cout <<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"; -#else - cout << endl << "No compiler support for GPU" << endl; -#endif -} - +// HG diff --git a/cpp_workspace/ex5/ex5_1/main.cpp b/cpp_workspace/ex5/ex5_1/main.cpp new file mode 100644 index 0000000..c261c29 --- /dev/null +++ b/cpp_workspace/ex5/ex5_1/main.cpp @@ -0,0 +1,142 @@ +#include "check_env.h" +#include "mylib.h" +#include // atoi() +#include // strncmp() +#include +#include +#include // OpenMP +#include +#include +using namespace std; + +int main(int argc, char const *argv[]) +{ + omp_set_schedule(omp_sched_static, 2000000); + //omp_set_schedule(omp_sched_dynamic, 1000000); + //omp_set_schedule(omp_sched_guided, 1000000); + //omp_set_schedule(omp_sched_auto, 1); // chunk size does not matter for auto + + + // Speedup for different number of cores (incl. hyperthreading) + omp_set_num_threads(8); + + // Print number of available processors + cout << "Number of available processors: " << omp_get_num_procs() << endl; + + // Currently executing parallel code? -> no + cout << "Currently in parallel? " << omp_in_parallel() << endl; + + + int const NLOOPS = 10; // chose a value such that the benchmark runs at least 10 sec. + unsigned int N = 500000001; + + +//########################################################################## +// Read Parameter from command line (C++ style) + cout << "Checking command line parameters for: -n " << endl; + for (int i = 1; i < argc; i++) + { + cout << " arg[" << i << "] = " << argv[i] << endl; + string ss(argv[i]); + if ("-n"==ss && i + 1 < argc) // found "-n" followed by another parameter + { + N = static_cast(atoi(argv[i + 1])); + } + else + { + cout << "Corect call: " << argv[0] << " -n \n"; + } + } + + cout << "\nN = " << N << endl; + + check_env(argc, argv); +//######################################################################## + int nthreads; // OpenMP + #pragma omp parallel default(none) shared(cout,nthreads) + { + stringstream inparallel; + inparallel << "Currently in parallel? " << omp_in_parallel() << endl; + + + int const th_id = omp_get_thread_num(); // OpenMP + int const nthrds = omp_get_num_threads(); // OpenMP + stringstream ss; + ss << "C++: Hello World from thread " << th_id << " / " << nthrds << endl; + #pragma omp critical + { + cout << ss.str(); // output to a shared ressource + cout << inparallel.str() << endl; + } + #pragma omp master + nthreads = nthrds; // transfer nn to to master thread + } + cout << " " << nthreads << " threads have been started." << endl; + +//########################################################################## +// Memory allocation + cout << "Memory allocation\n"; + + vector x(N), y(N); + + cout.precision(2); + cout << 2.0 * N *sizeof(x[0]) / 1024 / 1024 / 1024 << " GByte Memory allocated\n"; + cout.precision(6); + +//########################################################################## +// Data initialization +// Special: x_i = i+1; y_i = 1/x_i ==> == N + for (unsigned int i = 0; i < N; ++i) + { + x[i] = i + 1; + y[i] = 1.0 / x[i]; + } + +//########################################################################## + cout << "\nStart Benchmarking\n"; + +// Do calculation + double tstart = omp_get_wtime(); // OpenMP + + double sk(0.0); + for (int i = 0; i < NLOOPS; ++i) + { + //sk = scalar(x, y); + sk = scalar_parallel(x, y); + //sk = scalar_trans(x, y); + //sk = norm(x); + } + + double t1 = omp_get_wtime() - tstart; // OpenMP + + t1 /= NLOOPS; // divide by number of function calls + +//########################################################################## +// Check the correct result + cout << "\n = " << sk << endl; + if (static_cast(sk) != N) + { + cout << " !! W R O N G result !!\n"; + } + cout << endl; + +//########################################################################## +// Timings and Performance + cout << endl; + cout.precision(2); + cout << "Total benchmarking time: " << t1*NLOOPS << endl; + cout << "Timing in sec. : " << t1 << endl; + cout << "GFLOPS : " << 2.0 * N / t1 / 1024 / 1024 / 1024 << endl; + cout << "GiByte/s : " << 2.0 * N / t1 / 1024 / 1024 / 1024 * sizeof(x[0]) << endl; + +//######################################################################### + + cout << "\n Try the reduction with an STL-vektor \n"; + + auto vr = reduction_vec_append(5); + cout << "done\n"; + cout << vr << endl; + + + return 0; +} // memory for x and y will be deallocated their destructors diff --git a/cpp_workspace/ex5/ex5_1/mylib.cpp b/cpp_workspace/ex5/ex5_1/mylib.cpp new file mode 100644 index 0000000..b5f2697 --- /dev/null +++ b/cpp_workspace/ex5/ex5_1/mylib.cpp @@ -0,0 +1,137 @@ +#include "mylib.h" +#include // assert() +#include +#include +#include // multiplies<>{} +#include +#include // iota() +#ifdef _OPENMP +#include +#endif +#include +using namespace std; + + +double scalar_parallel(vector const &x, vector const &y) +{ + assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG + size_t const N = x.size(); + double sum = 0.0; +#pragma omp parallel default(none) shared(x,y,N, cout) reduction(+:sum) + { + const size_t nthreads = omp_get_num_threads(); + const size_t threadnum = omp_get_thread_num(); + const size_t chunksize = N/nthreads; + + + size_t start = threadnum*chunksize; + size_t end = start + chunksize; + if (threadnum == nthreads - 1) + end = N; + + + for (size_t i = start; i < end; ++i) + { + sum += x[i] * y[i]; + } + + } + return sum; +} + + +vector reduction_vec_append(int n) +{ + vector vec(n); +#pragma omp parallel default(none) shared(cout) reduction(VecAppend:vec) + { + #pragma omp barrier + #pragma omp critical + cout << omp_get_thread_num() << " : " << vec.size() << endl; + #pragma omp barrier + iota( vec.begin(),vec.end(), omp_get_thread_num() ); + #pragma omp barrier + + } + return vec; +} + + + + + + + + + + + +double scalar(vector const &x, vector const &y) +{ + assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG + size_t const N = x.size(); + double sum = 0.0; +#pragma omp parallel for default(none) shared(x,y,N) reduction(+:sum) schedule(runtime) // added schedule(runtime) + for (size_t i = 0; i < N; ++i) + { + sum += x[i] * y[i]; + //sum += exp(x[i])*log(y[i]); + } + return sum; +} + + +double norm(vector const &x) +{ + size_t const N = x.size(); + double sum = 0.0; +#pragma omp parallel for default(none) shared(x,N) reduction(+:sum) schedule(runtime) // added schedule(runtime) + for (size_t i = 0; i < N; ++i) + { + sum += x[i]*x[i]; + } + return sum; +} + + +vector reduction_vec(int n) +{ + vector vec(n); +#pragma omp parallel default(none) shared(cout) reduction(VecAdd:vec) + { + #pragma omp barrier + #pragma omp critical + cout << omp_get_thread_num() << " : " << vec.size() << endl; + #pragma omp barrier + iota( vec.begin(),vec.end(), omp_get_thread_num() ); + #pragma omp barrier + + } + return vec; +} + + +double scalar_trans(vector const &x, vector const &y) +{ + assert(x.size() == y.size()); // switch off via compile flag: -DNDEBUG + vector z(x.size()); + //list z(x.size()); // parallel for-loop on iterators not possible (missing 'operator-') + // c++-20 CLANG_, ONEAPI_:condition of OpenMP for loop must be a relational comparison + + transform(cbegin(x),cend(x),cbegin(y),begin(z),std::multiplies<>{}); + + double sum = 0.0; +#pragma omp parallel for default(none) shared(z) reduction(+:sum) schedule(runtime) // added schedule(runtime) + for (auto pi = cbegin(z); pi!=cend(z); ++pi) + { + sum += *pi; + } + //for (auto val: z) + //{ + //sum += val; + //} + return sum; +} + + + diff --git a/cpp_workspace/ex5/ex5_1/mylib.h b/cpp_workspace/ex5/ex5_1/mylib.h new file mode 100644 index 0000000..fe1948a --- /dev/null +++ b/cpp_workspace/ex5/ex5_1/mylib.h @@ -0,0 +1,88 @@ +#pragma once +#include +#include // setw() +#include +#include +#include + +/** Inner product + @param[in] x vector + @param[in] y vector + @return resulting Euclidian inner product +*/ +double scalar_parallel(std::vector const &x, std::vector const &y); +double scalar(std::vector const &x, std::vector const &y); +double scalar_trans(std::vector const &x, std::vector const &y); + + + +// Declare additional reduction operation in OpenMP for STL-vector +#pragma omp declare reduction(VecAppend : std::vector : omp_out.insert(omp_out.end(), omp_in.begin(), omp_in.end())) \ + initializer (omp_priv=omp_orig) + +std::vector reduction_vec_append(int n); + + +/** l2-norm + @param[in] x vector + @return resulting Euclidian norm +*/ +double norm(std::vector const &x); + +/** Vector @p b adds its elements to vector @p a . + @param[in] a vector + @param[in] b vector + @return a+=b componentwise +*/ +template +std::vector &operator+=(std::vector &a, std::vector const &b) +{ + assert(a.size()==b.size()); + for (size_t k = 0; k < a.size(); ++k) { + a[k] += b[k]; + } + return a; +} + +// Declare the reduction operation in OpenMP for an STL-vector +// omp_out += omp_in requires operator+=(vector &, vector const &) from above +// ------------------------------------------------------------ +// https://scc.ustc.edu.cn/zlsc/tc4600/intel/2016.0.109/compiler_c/common/core/GUID-7312910C-D175-4544-99C5-29C12D980744.htm +// https://gist.github.com/eruffaldi/7180bdec4c8c9a11f019dd0ba9a2d68c +// https://stackoverflow.com/questions/29633531/user-defined-reduction-on-vector-of-varying-size +// see also p.74ff in https://www.fz-juelich.de/ias/jsc/EN/AboutUs/Staff/Hagemeier_A/docs-parallel-programming/OpenMP-Slides.pdf +#pragma omp declare reduction(VecAdd : std::vector : omp_out += omp_in) \ + initializer (omp_priv=omp_orig) + +// Templates are n o t possible, i.e. the reduction has to be declared fore a specified type. +//template +//#pragma omp declare reduction(VecAdd : std::vector : omp_out += omp_in) initializer (omp_priv(omp_orig)) +// MS: template nach #pragma !? + +// ------------------------------------------------------------ + +/** Test for vector reduction. + * + * The thread-private vectors of size @p n are initialized via @f$v_k^{tID}=tID+k@f$. + * Afterwards these vectors are accumulated, i.e., + * @f$v_k= \sum_{tID=0}^{numThreads} v_k^{tID}@f$. + * + * @param[in] n size of global/private vector + * @return resulting global vector. +*/ +std::vector reduction_vec(int n); + + + +/** Output of a vector. + @param[in,out] s output stream + @param[in] x vector + @return modified output stream +*/ +template +std::ostream &operator<<(std::ostream &s, std::vector const &x) +{ + for (auto const &v : x) s << std::setw(4) << v << " "; + return s; +} + diff --git a/utils/timing.h b/cpp_workspace/ex5/ex5_1/timing.h similarity index 51% rename from utils/timing.h rename to cpp_workspace/ex5/ex5_1/timing.h index 7e52921..11d8da2 100644 --- a/utils/timing.h +++ b/cpp_workspace/ex5/ex5_1/timing.h @@ -1,12 +1,9 @@ -// -// Gundolf Haase, Oct 18 2024 -// #pragma once #include // timing #include -//using Clock = std::chrono::system_clock; //!< The wall clock timer chosen -using Clock = std::chrono::high_resolution_clock; +using Clock = std::chrono::system_clock; //!< The wall clock timer chosen +//using Clock = std::chrono::high_resolution_clock; using TPoint= std::chrono::time_point; // [Galowicz, C++17 STL Cookbook, p. 29] @@ -16,9 +13,9 @@ std::stack MyStopWatch; //!< starting time of stopwatch /** Starts stopwatch timer. * Use as @code tic(); myfunction(...) ; double tsec = toc(); @endcode * - * The timining can be nested and the recent time point is stored on top of the stack. + * The timining is allowed to be nested and the recent time is stored on top of the stack. * - * @return recent time point + * @return recent time * @see toc */ inline auto tic() @@ -29,7 +26,7 @@ inline auto tic() /** Returns the elapsed time from stopwatch. * - * The time point from top of the stack is used + * The time from top of the stack is used * if time point @p t_b is not passed as input parameter. * Use as @code tic(); myfunction(...) ; double tsec = toc(); @endcode * or as @code auto t_b = tic(); myfunction(...) ; double tsec = toc(t_b); @endcode @@ -49,3 +46,25 @@ inline double toc(TPoint const &t_b = MyStopWatch.top()) MyStopWatch.pop(); return FpSeconds(t_e-t_b).count(); } + +#include +#include +/** Executes function @p f and measures/prints elapsed wall clock time in seconds + * + * Call as + * @code measure("Time for (b = b + 1)", [&]() { + thrust::transform(b.begin(), b.end(), b.begin(), increment()); + }); @endcode + * + * @param[in] label additional string to be printed with the measurement. + * @param[in] f function to execute. + * @author Therese Bösmüller, 2025 + * +*/ +auto measure = [](const std::string& label, auto&& f) { + auto start = std::chrono::high_resolution_clock::now(); + f(); + auto stop = std::chrono::high_resolution_clock::now(); + auto duration = std::chrono::duration_cast(stop - start).count(); + std::cout << label << ": " << duration << " microseconds" << std::endl; +}; // ';' is needed for a visible documentation of this lambda-function diff --git a/ex3_benchmarks/Makefile b/cpp_workspace/ex5/ex5_2/Makefile similarity index 67% rename from ex3_benchmarks/Makefile rename to cpp_workspace/ex5/ex5_2/Makefile index 1daf792..7363b62 100644 --- a/ex3_benchmarks/Makefile +++ b/cpp_workspace/ex5/ex5_2/Makefile @@ -13,9 +13,7 @@ COMPILER=GCC_ # COMPILER=PGI_ -#SOURCES = main.cpp benchmarks.cpp benchmark_tests.cpp factorization_solve.cpp factorization_solve_tests.cpp -# GH -SOURCES = main.cpp benchmarks.cpp benchmark_tests.cpp factorization_solve.cpp factorization_solve_tests.cpp vdop.cpp getmatrix.cpp +SOURCES = main.cpp mylib.cpp OBJECTS = $(SOURCES:.cpp=.o) PROGRAM = main.${COMPILER} @@ -29,4 +27,5 @@ ifndef COMPILER COMPILER=GCC_ endif + include ../${COMPILER}default.mk diff --git a/ex1B_data-IO_and_vectors/data_1.txt b/cpp_workspace/ex5/ex5_2/data_1.txt similarity index 100% rename from ex1B_data-IO_and_vectors/data_1.txt rename to cpp_workspace/ex5/ex5_2/data_1.txt diff --git a/cpp_workspace/ex5/ex5_2/main.GCC_ b/cpp_workspace/ex5/ex5_2/main.GCC_ new file mode 100755 index 0000000..ef16f39 Binary files /dev/null and b/cpp_workspace/ex5/ex5_2/main.GCC_ differ diff --git a/cpp_workspace/ex5/ex5_2/main.cpp b/cpp_workspace/ex5/ex5_2/main.cpp new file mode 100644 index 0000000..1bea099 --- /dev/null +++ b/cpp_workspace/ex5/ex5_2/main.cpp @@ -0,0 +1,130 @@ +#include "mylib.h" +#include +#include +#include +#include +using namespace std; + + +int main() +{ + // read vector from file + vector data_vector = {}; + + ifstream input_stream("data_1.txt"); + + size_t line; + while(input_stream >> line) + { + data_vector.push_back(line); + } + data_vector.shrink_to_fit(); + + + + + // specify loops + size_t NLOOPS = 10000; + + + + // ############# Parallelization with openMP ############# + // calculate arithmetic mean, geometric mean and harmonic mean + double am_omp, gm_omp, hm_omp; + + double tstart = omp_get_wtime(); + + for (size_t i = 0; i < NLOOPS; ++i) + means_omp(data_vector, am_omp, gm_omp, hm_omp); + + double t_means_omp = (omp_get_wtime() - tstart)/NLOOPS; + + // calculate minimum and maximum + size_t min, max; + + tstart = omp_get_wtime(); + + for (size_t i = 0; i < NLOOPS; ++i) + minmax_omp(data_vector, min, max); + + double t_minmax_omp = (omp_get_wtime() - tstart)/NLOOPS; + + + + + + + // ############# Parallelization with C++ algorithms ############# + // calculate arithmetic mean, geometric mean and harmonic mean + double am_cpp, gm_cpp, hm_cpp; + + tstart = omp_get_wtime(); + + for (size_t i = 0; i < NLOOPS; ++i) + means_cpp(data_vector, am_cpp, gm_cpp, hm_cpp); + + double t_means_cpp = (omp_get_wtime() - tstart)/NLOOPS; + + // calculate minimum and maximum + size_t min_cpp, max_cpp; + + tstart = omp_get_wtime(); + + for (size_t i = 0; i < NLOOPS; ++i) + minmax_cpp(data_vector, min_cpp, max_cpp); + + double t_minmax_cpp = (omp_get_wtime() - tstart)/NLOOPS; + + + + + + // print results + cout << "####### OpenMP #######" << endl; + cout << "minimum: " << min << endl; + cout << "maximum: " << max << endl; + cout << "duration: " << t_minmax_omp << endl << endl; + + cout << "arithmetic mean: " << am_omp << endl; + cout << "geometric mean: " << gm_omp << endl; + cout << "harmonic mean: " << hm_omp << endl; + cout << "duration: " << t_means_omp << endl << endl; + + + cout << "####### C++ #######" << endl; + cout << "minimum: " << min_cpp << endl; + cout << "maximum: " << max_cpp << endl; + cout << "duration: " << t_minmax_cpp << endl << endl; + + cout << "arithmetic mean: " << am_cpp << endl; + cout << "geometric mean: " << gm_cpp << endl; + cout << "harmonic mean: " << hm_cpp << endl; + cout << "duration: " << t_means_cpp << endl << endl; + + + + // ####### OpenMP ####### + // minimum: 1 + // maximum: 1000 + // duration: 3.52086e-06 + + // arithmetic mean: 498.184 + // geometric mean: 364.412 + // harmonic mean: 95.6857 + // duration: 5.90171e-06 + + // ####### C++ ####### + // minimum: 1 + // maximum: 1000 + // duration: 1.76816e-05 + + // arithmetic mean: 498.184 + // geometric mean: 364.412 + // harmonic mean: 95.6857 + // duration: 2.35728e-05 + + // --> the openMP variant is faster in both cases + + + return 0; +} diff --git a/cpp_workspace/ex5/ex5_2/main.o b/cpp_workspace/ex5/ex5_2/main.o new file mode 100644 index 0000000..0a6cbf3 Binary files /dev/null and b/cpp_workspace/ex5/ex5_2/main.o differ diff --git a/cpp_workspace/ex5/ex5_2/mylib.cpp b/cpp_workspace/ex5/ex5_2/mylib.cpp new file mode 100644 index 0000000..34e5992 --- /dev/null +++ b/cpp_workspace/ex5/ex5_2/mylib.cpp @@ -0,0 +1,103 @@ +#include "mylib.h" +#include +#include +#include +#include +#include +#include + +using namespace std; + + +void means_omp(const std::vector numbers, double &am, double &gm, double &hm) +{ + size_t const n = numbers.size(); + + am = 0.; + gm = 0.; + hm = 0.; + +#pragma omp parallel for shared(numbers, n, cout) reduction(+:am, gm, hm) + for (size_t i = 0; i < n; ++i) + { + am += numbers[i]; + gm += log(numbers[i]); + hm += 1.0/numbers[i]; + + // #pragma omp critical + // { + // cout << "Thread number " << omp_get_thread_num() << " processes value " << numbers[i] << endl; + // } + } + + am /= n; + gm = exp(gm/n); + hm = n/hm; +} + + +void minmax_omp(const std::vector numbers, size_t &global_min, size_t &global_max) +{ + size_t const n = numbers.size(); + + global_min = -1; // gives the maximum size_t value + global_max = 0; + +#pragma omp parallel shared(numbers, n, global_min, global_max) + { + const size_t nthreads = omp_get_num_threads(); + const size_t threadnum = omp_get_thread_num(); + const size_t chunksize = n/nthreads; + + + size_t start = threadnum*chunksize; + size_t end = start + chunksize; + if (threadnum == nthreads - 1) + end = n; + + + size_t local_min = -1; + size_t local_max = 0; + for (size_t i = start; i < end ; ++i) + { + if (numbers[i] < local_min) + local_min = numbers[i]; + + if (numbers[i] > local_max) + local_max = numbers[i]; + } + + #pragma omp critical + { + if (local_min < global_min) + global_min = local_min; + + if (local_max > global_max) + global_max = local_max; + } + } +} + + +void means_cpp(const std::vector numbers, double &am, double &gm, double &hm) +{ + size_t const n = numbers.size(); + + am = reduce(std::execution::par, numbers.begin(), numbers.end()); + gm = transform_reduce(std::execution::par, numbers.begin(), numbers.end(), 0.0, plus{}, [] (size_t x) -> double { return log(x); } ); + hm = transform_reduce(std::execution::par, numbers.begin(), numbers.end(), 0.0, plus{}, [] (size_t x) -> double { return 1.0/x; }); + + am /= n; + gm = exp(gm/n); + hm = n/hm; +} + + +void minmax_cpp(const std::vector numbers, size_t &global_min, size_t &global_max) +{ + auto min_it = min_element(std::execution::par, numbers.begin(), numbers.end()); + auto max_it = max_element(std::execution::par, numbers.begin(), numbers.end()); + + global_min = *min_it; + global_max = *max_it; +} \ No newline at end of file diff --git a/cpp_workspace/ex5/ex5_2/mylib.h b/cpp_workspace/ex5/ex5_2/mylib.h new file mode 100644 index 0000000..01d2fa9 --- /dev/null +++ b/cpp_workspace/ex5/ex5_2/mylib.h @@ -0,0 +1,42 @@ +#include + +/** + This function calculates arithmetic mean, geometric mean and harmonic mean of an integer vector. + Uses openMP parallelization. + @param[in] numbers vector containing integers + @param[out] am arithmetic mean + @param[out] gm geometric mean + @param[out] hm harmonic mean +*/ +void means_omp(const std::vector numbers, double &am, double &gm, double &hm); + + +/** + This function calculates the minimum and maximum of a vector. + Uses openMP parallelization. + @param[in] numbers vector containing integers + @param[out] global_min minimum + @param[out] global_max maximum +*/ +void minmax_omp(const std::vector numbers, size_t &global_min, size_t &global_max); + + +/** + This function calculates arithmetic mean, geometric mean and harmonic mean of an integer vector. + Uses C++ parallelization. + @param[in] numbers vector containing integers + @param[out] am arithmetic mean + @param[out] gm geometric mean + @param[out] hm harmonic mean +*/ +void means_cpp(const std::vector numbers, double &am, double &gm, double &hm); + + +/** + This function calculates the minimum and maximum of a vector. + Uses C++ parallelization. + @param[in] numbers vector containing integers + @param[out] global_min minimum + @param[out] global_max maximum +*/ +void minmax_cpp(const std::vector numbers, size_t &global_min, size_t &global_max); \ No newline at end of file diff --git a/cpp_workspace/ex5/ex5_2/mylib.o b/cpp_workspace/ex5/ex5_2/mylib.o new file mode 100644 index 0000000..7b34810 Binary files /dev/null and b/cpp_workspace/ex5/ex5_2/mylib.o differ diff --git a/cpp_workspace/ex5/ex5_3/Makefile b/cpp_workspace/ex5/ex5_3/Makefile new file mode 100644 index 0000000..4a714a3 --- /dev/null +++ b/cpp_workspace/ex5/ex5_3/Makefile @@ -0,0 +1,30 @@ +# +# use GNU-Compiler tools +COMPILER=GCC_ +# alternatively from the shell +# export COMPILER=GCC_ +# or, alternatively from the shell +# make COMPILER=GCC_ + +# use Intel compilers +#COMPILER=ICC_ + +# use PGI compilers +# COMPILER=PGI_ + + +SOURCES = main.cpp goldbach.cpp +OBJECTS = $(SOURCES:.cpp=.o) + +PROGRAM = main.${COMPILER} + +# uncomment the next to lines for debugging and detailed performance analysis +CXXFLAGS += -g +LINKFLAGS += -g +# do not use -pg with PGI compilers + +ifndef COMPILER + COMPILER=GCC_ +endif + +include ../${COMPILER}default.mk diff --git a/ex1F_goldbachs_conjecture/goldbach.cpp b/cpp_workspace/ex5/ex5_3/goldbach.cpp similarity index 77% rename from ex1F_goldbachs_conjecture/goldbach.cpp rename to cpp_workspace/ex5/ex5_3/goldbach.cpp index 0c7de59..55709c3 100644 --- a/ex1F_goldbachs_conjecture/goldbach.cpp +++ b/cpp_workspace/ex5/ex5_3/goldbach.cpp @@ -1,4 +1,7 @@ #include "goldbach.h" +#include +#include +#include size_t single_goldbach(size_t k) { @@ -7,12 +10,13 @@ size_t single_goldbach(size_t k) size_t counter = 0; +#pragma omp parallel for shared(relevant_primes, m, k) reduction(+:counter) for(size_t i = 0; i < m; ++i) { for(size_t j = i; j < m; ++j) { if(relevant_primes[i] + relevant_primes[j] == k) - counter += 1; + ++counter; } } @@ -27,7 +31,7 @@ std::vector count_goldbach(size_t n) std::vector counter_vector(n + 1, 0); - +#pragma omp parallel for shared(relevant_primes, m, n) reduction(VecAdd:counter_vector) for(size_t i = 0; i < m; ++i) { for(size_t j = i; j < m; ++j) diff --git a/cpp_workspace/ex5/ex5_3/goldbach.h b/cpp_workspace/ex5/ex5_3/goldbach.h new file mode 100644 index 0000000..15df6d4 --- /dev/null +++ b/cpp_workspace/ex5/ex5_3/goldbach.h @@ -0,0 +1,45 @@ +#pragma once +#include "mayer_primes.h" +#include +#include + + +/** + This function returns the number of possible decompositions of an integer into a sum of two prime numbers. + @param[in] k first integer + @param[out] count number of decompositions +*/ +size_t single_goldbach(size_t k); + + +/** + This function returns the number of possible decompositions into a sum of two prime numbers of all even integers in the interval [4,n]. + @param[in] n upper integer bound + @param[out] count_vector vector containing the number of decompositions for a natural number the corresponding index +*/ +std::vector count_goldbach(size_t n); + + +/** Vector @p b adds its elements to vector @p a . + @param[in] a vector + @param[in] b vector + @return a+=b componentwise +*/ +template +std::vector &operator+=(std::vector &a, std::vector const &b) +{ + assert(a.size()==b.size()); + for (size_t k = 0; k < a.size(); ++k) { + a[k] += b[k]; + } + return a; +} + +// Declare the reduction operation in OpenMP for an STL-vector +// omp_out += omp_in requires operator+=(vector &, vector const &) from above +// ------------------------------------------------------------ +// https://scc.ustc.edu.cn/zlsc/tc4600/intel/2016.0.109/compiler_c/common/core/GUID-7312910C-D175-4544-99C5-29C12D980744.htm +// https://gist.github.com/eruffaldi/7180bdec4c8c9a11f019dd0ba9a2d68c +// https://stackoverflow.com/questions/29633531/user-defined-reduction-on-vector-of-varying-size +// see also p.74ff in https://www.fz-juelich.de/ias/jsc/EN/AboutUs/Staff/Hagemeier_A/docs-parallel-programming/OpenMP-Slides.pdf +#pragma omp declare reduction(VecAdd : std::vector : omp_out += omp_in) initializer (omp_priv=omp_orig) \ No newline at end of file diff --git a/cpp_workspace/ex5/ex5_3/main.cpp b/cpp_workspace/ex5/ex5_3/main.cpp new file mode 100644 index 0000000..1be01c2 --- /dev/null +++ b/cpp_workspace/ex5/ex5_3/main.cpp @@ -0,0 +1,45 @@ +#include "goldbach.h" +#include +#include +#include +using namespace std; + + +int main() +{ + cout << "Check: 694 has "<< single_goldbach(694) << " decompositions." << endl << "----------------------------------------" << endl; + + for(size_t n : {10000, 100000, 400000, 1000000, 2000000}) + { + double t_start = omp_get_wtime(); + + auto goldbach_vector = count_goldbach(n); + + auto max_it = max_element(goldbach_vector.begin(), goldbach_vector.end()); + size_t max_number = distance(goldbach_vector.begin(), max_it); + + double t_end = omp_get_wtime() - t_start; + + cout << "The number " << max_number << " has " << *max_it << " decompositions. Duration: " << t_end << endl; + } + + /* + ###### WITHOUT PARALLELIZATION ###### + The number 9240 has 329 decompositions. Duration: 0.00307696 + The number 99330 has 2168 decompositions. Duration: 0.189839 + The number 390390 has 7094 decompositions. Duration: 1.3042 + The number 990990 has 15594 decompositions. Duration: 5.45034 + The number 1981980 has 27988 decompositions. Duration: 47.1807 + + + ###### WITH PARALLELIZATION ###### + The number 9240 has 329 decompositions. Duration: 0.000734854 + The number 99330 has 2168 decompositions. Duration: 0.0251322 + The number 390390 has 7094 decompositions. Duration: 0.487375 + The number 990990 has 15594 decompositions. Duration: 6.16972 + The number 1981980 has 27988 decompositions. Duration: 31.5699 + */ + + + return 0; +} \ No newline at end of file diff --git a/ex1F_goldbachs_conjecture/mayer_primes.h b/cpp_workspace/ex5/ex5_3/mayer_primes.h similarity index 100% rename from ex1F_goldbachs_conjecture/mayer_primes.h rename to cpp_workspace/ex5/ex5_3/mayer_primes.h diff --git a/cpp_workspace/ex5/ex5_4/Makefile b/cpp_workspace/ex5/ex5_4/Makefile new file mode 100644 index 0000000..b2129d8 --- /dev/null +++ b/cpp_workspace/ex5/ex5_4/Makefile @@ -0,0 +1,30 @@ +# +# use GNU-Compiler tools +COMPILER=GCC_ +# alternatively from the shell +# export COMPILER=GCC_ +# or, alternatively from the shell +# make COMPILER=GCC_ + +# use Intel compilers +#COMPILER=ICC_ + +# use PGI compilers +# COMPILER=PGI_ + + +SOURCES = main.cpp benchmarks.cpp benchmark_tests.cpp +OBJECTS = $(SOURCES:.cpp=.o) + +PROGRAM = main.${COMPILER} + +# uncomment the next to lines for debugging and detailed performance analysis +CXXFLAGS += -g +LINKFLAGS += -g +# do not use -pg with PGI compilers + +ifndef COMPILER + COMPILER=GCC_ +endif + +include ../${COMPILER}default.mk diff --git a/ex3_benchmarks/benchmark_tests.cpp b/cpp_workspace/ex5/ex5_4/benchmark_tests.cpp similarity index 80% rename from ex3_benchmarks/benchmark_tests.cpp rename to cpp_workspace/ex5/ex5_4/benchmark_tests.cpp index 961b32a..35ed87b 100644 --- a/ex3_benchmarks/benchmark_tests.cpp +++ b/cpp_workspace/ex5/ex5_4/benchmark_tests.cpp @@ -5,7 +5,7 @@ #include using namespace std::chrono; -vector test_A(const size_t &NLOOPS, const size_t &N, const function&, const vector&)>& scalar_function) +vector test_A(const size_t &NLOOPS, const size_t &N) { cout << "#################### (A) ####################" << endl; cout << "\nLOOPS = " << NLOOPS << endl; @@ -39,7 +39,7 @@ vector test_A(const size_t &NLOOPS, const size_t &N, const function test_A(const size_t &NLOOPS, const size_t &N, const function{t_diff, Gflops, MemBandwidth}; +} + +vector test_A_sum(const size_t &NLOOPS, const size_t &N) +{ + cout << "#################### (A) sum ####################" << endl; + cout << "\nLOOPS = " << NLOOPS << endl; + cout << "\nN = " << N << endl; + + +// Memory allocation + cout << "Memory allocation\n"; + + vector x(N); + + cout.precision(2); + cout << 1.0*N *sizeof(x[0]) / 1024 / 1024 / 1024 << " GByte Memory allocated\n"; + cout.precision(6); + + +// Data initialization + + for (size_t i = 0; i < N; ++i) { - auto sk1 = sqrt(scalar(x, x)); - ss2 += sk1; // prevents the optimizer from removing unused calculation results. + x[i] = 1; } - auto t4 = system_clock::now(); // stop timer - auto duration2 = duration_cast(t4 - t3); // duration in microseconds - double t_diff2 = static_cast(duration2.count()) / 1e6; // overall duration in seconds - t_diff2 = t_diff2/NLOOPS; // duration per loop seconds + + cout << "\nStart Benchmarking sum\n"; + + auto t1 = system_clock::now(); // start timer +// Do calculation + double check(0.0),ss(0.0); + for (size_t i = 0; i < NLOOPS; ++i) + { + check = sum(x); + ss += check; // prevents the optimizer from removing unused calculation results. + } + + auto t2 = system_clock::now(); // stop timer + auto duration = duration_cast(t2 - t1); // duration in microseconds + double t_diff = static_cast(duration.count()) / 1e6; // overall duration in seconds + t_diff = t_diff/NLOOPS; // duration per loop seconds - cout << "ss(norm): " << ss2 << endl; - cout << "Timing in sec. : " << t_diff2 << endl; + +// Check the correct result + cout << "\n = " << check << endl; + if (static_cast(check) != N) + cout << " !! W R O N G result !!\n"; + cout << endl; +// Timings and Performance + cout << endl; + cout.precision(2); - + + double Gflops = 1.0*N / t_diff / 1024 / 1024 / 1024; + double MemBandwidth = 1.0*N / t_diff / 1024 / 1024 / 1024 * sizeof(x[0]); + + cout << "Total duration : " << t_diff*NLOOPS << endl; + cout << "Timing in sec. : " << t_diff << endl; + cout << "GFLOPS : " << Gflops << endl; + cout << "GiByte/s : " << MemBandwidth << endl; return vector{t_diff, Gflops, MemBandwidth}; } -vector test_B(const size_t &NLOOPS, const size_t &N, const size_t &M, const function(const vector&, const vector&)>& MatVec_function) +vector test_B(const size_t &NLOOPS, const size_t &N, const size_t &M) { cout << "#################### (B) ####################" << endl; @@ -138,7 +180,7 @@ vector test_B(const size_t &NLOOPS, const size_t &N, const size_t &M, co for (size_t i = 0; i < NLOOPS; ++i) { - b = MatVec_function(A, x); + b = MatVec_parallel(A, x); } auto t2 = system_clock::now(); // stop timer @@ -174,7 +216,7 @@ vector test_B(const size_t &NLOOPS, const size_t &N, const size_t &M, co } -vector test_C(const size_t &NLOOPS, const size_t &L, const size_t &M, const size_t &N, const function(const vector&, const vector&, size_t const &shared_dim)>& MatMat_function) +vector test_C(const size_t &NLOOPS, const size_t &L, const size_t &M, const size_t &N) { cout << "#################### (C) ####################" << endl; cout << "\nLOOPS = " << NLOOPS << endl; @@ -211,11 +253,11 @@ vector test_C(const size_t &NLOOPS, const size_t &L, const size_t &M, co // Do calculation vector C(M*N); double check; - double check_sum; // GH: initialize + double check_sum = 0; for (size_t i = 0; i < NLOOPS; ++i) { - C = MatMat_function(A, B, L); + C = MatMat_parallel(A, B, L); check = C[N*17]; check_sum += check; // prevents the optimizer from removing unused calculation results. @@ -292,7 +334,7 @@ vector test_D(const size_t &NLOOPS, const size_t &N, const size_t &p) for (size_t i = 0; i < NLOOPS; ++i) { - y = poly(a, x); + y = poly_parallel(a, x); check = y[0]; check_sum += check; // prevents the optimizer from removing unused calculation results. @@ -330,4 +372,4 @@ vector test_D(const size_t &NLOOPS, const size_t &N, const size_t &p) return vector{t_diff, Gflops, MemBandwidth}; -} +} \ No newline at end of file diff --git a/cpp_workspace/ex5/ex5_4/benchmark_tests.h b/cpp_workspace/ex5/ex5_4/benchmark_tests.h new file mode 100644 index 0000000..45c64a9 --- /dev/null +++ b/cpp_workspace/ex5/ex5_4/benchmark_tests.h @@ -0,0 +1,13 @@ +#pragma once +#include +using namespace std; + +vector test_A(const size_t &NLOOPS, const size_t &N); + +vector test_A_sum(const size_t &NLOOPS, const size_t &N); + +vector test_B(const size_t &NLOOPS, const size_t &N, const size_t &M); + +vector test_C(const size_t &NLOOPS, const size_t &L, const size_t &M, const size_t &N); + +vector test_D(const size_t &NLOOPS, const size_t &N, const size_t &p); \ No newline at end of file diff --git a/cpp_workspace/ex5/ex5_4/benchmarks.cpp b/cpp_workspace/ex5/ex5_4/benchmarks.cpp new file mode 100644 index 0000000..c0eb7d9 --- /dev/null +++ b/cpp_workspace/ex5/ex5_4/benchmarks.cpp @@ -0,0 +1,141 @@ +#include "benchmarks.h" +#include // assert() +#include +#include +#include +#include + +// (A) Inner product of two vectors (from skalar_stl) +double scalar_parallel(vector const &x, vector const &y) +{ + assert(x.size() == y.size()); + size_t const N = x.size(); + double sum = 0.0; +//#pragma omp parallel for default(none) shared(x, y, N) reduction(+:sum) schedule(runtime) +#pragma omp parallel for shared(x, y, N) reduction(+:sum) + for (size_t i = 0; i < N; ++i) + { + sum += x[i] * y[i]; + } + return sum; +} + +// (A) Vector entry sum +double sum(vector const &x) +{ + double sum = 0.0; +#pragma omp parallel for shared(x) reduction(+:sum) + for (size_t i = 0; i < x.size(); ++i) + { + sum += x[i]; + } + return sum; +} + + +// (B) Matrix-vector product (from intro_vector_densematrix) +vector MatVec_parallel(vector const &A, vector const &x) +{ + size_t const nelem = A.size(); + size_t const N = x.size(); + assert(nelem % N == 0); // make sure multiplication is possible + size_t const M = nelem/N; + + vector b(M); + +#pragma omp parallel for shared(A, x, N, M, b) + for (size_t i = 0; i < M; ++i) + { + double tmp = 0.0; + for (size_t j = 0; j < N; ++j) + tmp += A[N*i + j] * x[j]; + b[i] = tmp; + } + + return b; +} + + +// (C) Matrix-matrix product +vector MatMat_parallel(vector const &A, vector const &B, size_t const &L) +{ + size_t const nelem_A = A.size(); + size_t const nelem_B = B.size(); + + assert(nelem_A % L == 0 && nelem_B % L == 0); + + size_t const M = nelem_A/L; + size_t const N = nelem_B/L; + + + vector C(M*N); + + +#pragma omp parallel for shared(A, B, M, N, L, C) + for (size_t i = 0; i < M; ++i) + { + for (size_t k = 0; k < L; ++k) + { + for (size_t j = 0; j < N; ++j) + { + C[N*i + j] += A[L*i + k]*B[N*k + j]; + } + + } + } + + return C; +} + + +// (D) Evaluation of a polynomial function +vector poly_parallel(vector const &a, vector const &x) +{ + size_t const N = x.size(); + size_t const p = a.size() - 1; + vector y(N, 0); + +#pragma omp parallel for shared(a, x, N, p, y) + for (size_t i = 0; i < N; ++i) + { + double x_temp = x[i]; + double y_temp = 0; + for (size_t k = 0; k < p + 1; ++k) + { + y_temp += x_temp*y_temp + a[p - k]; + } + y[i] = y_temp; + } + + return y; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/cpp_workspace/ex5/ex5_4/benchmarks.h b/cpp_workspace/ex5/ex5_4/benchmarks.h new file mode 100644 index 0000000..2b55d2b --- /dev/null +++ b/cpp_workspace/ex5/ex5_4/benchmarks.h @@ -0,0 +1,55 @@ +#pragma once +#include +using namespace std; + +/** (A) Inner product of two vectors (from skalar_stl) + @param[in] x vector + @param[in] y vector + @return resulting Euclidian inner product +*/ +double scalar_parallel(vector const &x, vector const &y); + + +/** (A) Sum entries of vector + @param[in] x vector + @return sum +*/ +double sum(vector const &x); + + +/** (B) Matrix-vector product (from intro_vector_densematrix) + * @param[in] A dense matrix (1D access) + * @param[in] u vector + * + * @return resulting vector +*/ +vector MatVec_parallel(vector const &A, vector const &x); + + +/** (C) Matrix-matrix product + * @param[in] A MxL dense matrix (1D access) + * @param[in] B LxN dense matrix (1D access) + * @param[in] shared_dim shared dimension L + * + * @return resulting MxN matrix +*/ +vector MatMat_parallel(vector const &A, vector const &B, size_t const &shared_dim); + + +/** (D) Evaluation of a polynomial function using Horner's scheme + * @param[in] a coefficient vector + * @param[in] x vector with input values + * + * @return vector with output values +*/ +vector poly_parallel(vector const &a, vector const &x); + + + + + + + + + + diff --git a/cpp_workspace/ex5/ex5_4/main.cpp b/cpp_workspace/ex5/ex5_4/main.cpp new file mode 100644 index 0000000..d8fa63d --- /dev/null +++ b/cpp_workspace/ex5/ex5_4/main.cpp @@ -0,0 +1,84 @@ +#include "benchmark_tests.h" +#include +#include + +int main() +{ + vector> results_scalar; + results_scalar.push_back(test_A(2000000, pow(10,3))); + results_scalar.push_back(test_A(1000000, pow(10,4))); + results_scalar.push_back(test_A(100000, pow(10,5))); + results_scalar.push_back(test_A(10000, pow(10,6))); + results_scalar.push_back(test_A(750, pow(10,7))); + results_scalar.push_back(test_A(125, pow(10,8))); + + + vector> results_sum; + results_sum.push_back(test_A_sum(3000000, pow(10,3))); + results_sum.push_back(test_A_sum(2000000, pow(10,4))); + results_sum.push_back(test_A_sum(1000000, pow(10,5))); + results_sum.push_back(test_A_sum(50000, pow(10,6))); + results_sum.push_back(test_A_sum(2000, pow(10,7))); + results_sum.push_back(test_A_sum(250, pow(10,8))); + + + test_B(100, 20000, 10000); + + test_C(25, 500, 1000, 1500); + + test_D(100, 100, 1000000); + + + + cout << endl << "###### Scalar ######" << endl; + cout << "Timing\tGFLOPS\tGiByte/s" << endl; + cout << "------------------------------" << endl; + for (size_t i = 0; i < results_scalar.size(); ++i) + cout << results_scalar[i][0] << "\t" << results_scalar[i][1] << "\t" << results_scalar[i][2] << endl; + + cout << endl << "###### Sum ######" << endl; + cout << "Timing\tGFLOPS\tGiByte/s" << endl; + cout << "------------------------------" << endl; + for (size_t i = 0; i < results_sum.size(); ++i) + cout << results_sum[i][0] << "\t" << results_sum[i][1] << "\t" << results_sum[i][2] << endl; + + + + + // ###### Scalar ###### + // Timing GFLOPS GiByte/s + // ------------------------------ + // 3.4e-06 0.54 4.3 + // 4.6e-06 4 32 + // 1.6e-05 12 95 + // 0.0011 1.7 13 + // 0.0097 1.9 15 + // 0.075 2.5 20 + + + // ###### Sum ###### + // Timing GFLOPS GiByte/s + // ------------------------------ + // 5.5e-06 0.17 1.3 + // 5.4e-06 1.7 14 + // 1.5e-05 6.1 49 + // 0.00013 7.2 57 + // 0.0033 2.8 23 + // 0.032 2.9 23 + + + + + + // ######### NOT PARALLEL (from exercise sheet 2) ######### + // Timing GFLOPS GiByte/s + // ---------------------------------- + // (A) 0.038 2.5 20 + // (B) 0.13 2.9 23 + // (C) 0.44 3.2 25 + // (D) 0.19 1.5 12 + + + + return 0; +} diff --git a/ex1A_mean_values/main.cpp b/ex1A_mean_values/main.cpp deleted file mode 100644 index 03da30f..0000000 --- a/ex1A_mean_values/main.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include "means.h" -#include -#include -using namespace std; - -int main(int argc, char **argv) -{ - double arithmetic_mean, geometric_mean, harmonic_mean; - - // Fixed version - calculate_means(1, 4, 16, arithmetic_mean, geometric_mean, harmonic_mean); - cout << arithmetic_mean << ", " << geometric_mean << ", " << harmonic_mean << endl; - - calculate_means(2, 3, 5, arithmetic_mean, geometric_mean, harmonic_mean); - cout << arithmetic_mean << ", " << geometric_mean << ", " << harmonic_mean << endl; - - calculate_means(1000, 4000, 16000, arithmetic_mean, geometric_mean, harmonic_mean); - cout << arithmetic_mean << ", " << geometric_mean << ", " << harmonic_mean << endl; - cout << "--------------------------------" << endl; - - - - // Scalable version - calculate_means(vector {1, 4, 16}, arithmetic_mean, geometric_mean, harmonic_mean); - cout << arithmetic_mean << ", " << geometric_mean << ", " << harmonic_mean << endl; - - calculate_means(vector {2, 3, 5}, arithmetic_mean, geometric_mean, harmonic_mean); - cout << arithmetic_mean << ", " << geometric_mean << ", " << harmonic_mean << endl; - - calculate_means(vector {1000, 4000, 16000}, arithmetic_mean, geometric_mean, harmonic_mean); - cout << arithmetic_mean << ", " << geometric_mean << ", " << harmonic_mean << endl; - - - return 0; -} diff --git a/ex1A_mean_values/means.cpp b/ex1A_mean_values/means.cpp deleted file mode 100644 index 903a9e2..0000000 --- a/ex1A_mean_values/means.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "../ex1A_mean_values/means.h" -#include -#include - -void calculate_means(int a, int b, int c, double &am, double &gm, double &hm) -{ - am = (a + b + c)/3.0; - gm = exp((log(a)+log(b)+log(c))/3); - hm = 3.0/(1.0/a + 1.0/b + 1.0/c); -} - -void calculate_means(std::vector numbers, double &am, double &gm, double &hm) -{ - int n = numbers.size(); - - am = 0.; - gm = 0.; - hm = 0.; - - for (int i = 0; i < n; ++i) - { - am += numbers[i]; - gm += log(numbers[i]); - hm += 1.0/numbers[i]; - } - - am /= n; - gm = exp(gm/n); - hm = n/hm; -} \ No newline at end of file diff --git a/ex1A_mean_values/means.h b/ex1A_mean_values/means.h deleted file mode 100644 index 4a12964..0000000 --- a/ex1A_mean_values/means.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once -#include - -/** - This function calculates arithmetic mean, geometric mean and harmonic mean of three integers. - @param[in] a first integer - @param[in] b second integer - @param[in] c third integer - @param[out] am arithmetic mean - @param[out] gm geometric mean - @param[out] hm harmonic mean -*/ -void calculate_means(int a, int b, int c, double &am, double &gm, double &hm); - -/** - This function calculates arithmetic mean, geometric mean and harmonic mean of an integer vector. - @param[in] numbers vector containing integers - @param[out] am arithmetic mean - @param[out] gm geometric mean - @param[out] hm harmonic mean -*/ -void calculate_means(std::vector numbers, double &am, double &gm, double &hm); - diff --git a/ex1B_data-IO_and_vectors/main.cpp b/ex1B_data-IO_and_vectors/main.cpp deleted file mode 100644 index 0acb48f..0000000 --- a/ex1B_data-IO_and_vectors/main.cpp +++ /dev/null @@ -1,53 +0,0 @@ -#include "../ex1A_mean_values/means.h" -#include -#include -#include -#include -#include -using namespace std; - - -int main(int argc, char **argv) -{ - // read vector from file - vector data_vector = {}; - - ifstream input_stream("data_1.txt"); - - int line; - while(input_stream >> line) - { - data_vector.push_back(line); - } - data_vector.shrink_to_fit(); - - - // calculate minimum and maximum - vector::iterator min_it = min_element(data_vector.begin(), data_vector.end()); - vector::iterator max_it = max_element(data_vector.begin(), data_vector.end()); - - // calculate arithmetic mean, geometric mean and harmonic mean - double am, gm, hm; - calculate_means(data_vector, am, gm, hm); - - - // calculate standard deviation - double sd = 0.; - int n = data_vector.size(); - for (int i = 0; i < n; ++i) - { - sd += pow(data_vector[i] - am, 2); - } - sd = sqrt(sd/n); - - - // print results - cout << "minimum: " << *min_it << endl; - cout << "maximum: " << *max_it << endl; - cout << "arithmetic mean: " << am << endl; - cout << "geometric mean: " << gm << endl; - cout << "harmonic mean: " << hm << endl; - cout << "standard deviation: " << sd << endl; - - return 0; -} diff --git a/ex1C_summation_of_specified_numbers/main.cpp b/ex1C_summation_of_specified_numbers/main.cpp deleted file mode 100644 index f469cd2..0000000 --- a/ex1C_summation_of_specified_numbers/main.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "special_sum.h" -#include "../utils/timing.h" -#include -#include -#include -using namespace std; - -int main(int argc, char **argv) -{ - // check results and compare speeds - for(size_t n : {15, 1001, 1432987}) - { - cout << "n = " << n << endl; - size_t sum_1, sum_2; - - tic(); - for(size_t i = 0; i < 1000; ++i) - sum_1 = special_sum_loop(n); - double time_1 = toc(); - - tic(); - for(size_t i = 0; i < 1000; ++i) - sum_2 = special_sum_noloop(n); - double time_2 = toc(); - - cout << "loop: " << sum_1 << "\t\tDuration: " << time_1 << endl; - cout << "no loop: " << sum_2 << "\t\tDuration: " << time_2 << endl << "---------------------------------------------------" << endl; - } - - return 0; -} diff --git a/ex1C_summation_of_specified_numbers/special_sum.cpp b/ex1C_summation_of_specified_numbers/special_sum.cpp deleted file mode 100644 index d2860ff..0000000 --- a/ex1C_summation_of_specified_numbers/special_sum.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "special_sum.h" - -size_t gauss_sum(size_t n) -{ - return (n*(n+1))/2; -} - -size_t special_sum_loop(size_t n) -{ - size_t sum = 0; - for (size_t i = 1; i < n+1; ++i) - { - if (i % 3 == 0 || i % 5 == 0) - { - sum += i; - } - } - return sum; -} - -size_t special_sum_noloop(size_t n) -{ - size_t factor_3 = gauss_sum(n/3); // dividing int by int automatically gets rounded off - size_t factor_5 = gauss_sum(n/5); - size_t factor_15 = gauss_sum(n/15); - - return factor_3*3 + factor_5*5 - factor_15*15; -} \ No newline at end of file diff --git a/ex1C_summation_of_specified_numbers/special_sum.h b/ex1C_summation_of_specified_numbers/special_sum.h deleted file mode 100644 index a77964b..0000000 --- a/ex1C_summation_of_specified_numbers/special_sum.h +++ /dev/null @@ -1,18 +0,0 @@ -#include - -/** - This function returns the sum of all positive integers less or equal n which are a multiples of 3 or of 5, WITH using a loop. - @param[in] n - @param[out] M -*/ -size_t special_sum_loop(size_t n); - - -/** - This function returns the sum of all positive integers less or equal n which are a multiples of 3 or of 5, WITHOUT using a loop. - Example: For n=15, we have 60 = 3+5+6+9+10+12+15 = (1+2+3+4+5)*3 + (1+2+3)*5 - 1*15 - Formula: M = (\sum_{i=1}^{k_3} i)*3 + (\sum_{i=1}^{k_5} i)*5 - (\sum_{i=1}^{k_15} i)*15 - @param[in] n - @param[out] M -*/ -size_t special_sum_noloop(size_t n); \ No newline at end of file diff --git a/ex1D_kahan_summation/main.cpp b/ex1D_kahan_summation/main.cpp deleted file mode 100644 index 8d93e96..0000000 --- a/ex1D_kahan_summation/main.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "mylib.h" -#include -#include -using namespace std; - -int main(int argc, char **argv) -{ - for(size_t i = 1; i < 8; ++i) - { - size_t n = pow(10,i); - vector x(n); - for (size_t k = 0; k < n; ++k) - x[k] = 1.0/(k + 1); - - - // compute scalar products - double sum_1 = scalar(x, x); - double sum_2 = Kahan_skalar(x, x); - - // compute error - double err_1 = abs(sum_1 - pow(M_PI,2)/6); - double err_2 = abs(sum_2 - pow(M_PI,2)/6); - - cout << "n = " << n << endl; - cout << "Normal scalar product: " << sum_1 << "\terror: " << err_1 << endl; - cout << "Kahan scalar product: " << sum_2 << "\terror: " << err_2 << endl; - cout << endl; - } - - - - return 0; -} diff --git a/ex1D_kahan_summation/mylib.cpp b/ex1D_kahan_summation/mylib.cpp deleted file mode 100644 index 11fc394..0000000 --- a/ex1D_kahan_summation/mylib.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "mylib.h" -#include // assert() -#include -#include -using namespace std; - -double scalar(vector const &x, vector const &y) -{ - assert(x.size() == y.size()); - size_t const N = x.size(); - double sum = 0.0; - for (size_t i = 0; i < N; ++i) - { - sum += x[i] * y[i]; - } - return sum; -} - - - -double Kahan_skalar(vector const &x, vector const &y) -{ - double sum = 0; - double c = 0; - size_t n = x.size(); - for (size_t i = 0; i < n; ++i) - { - double z = x[i]*y[i] - c; // c is the part that got lost in the last iteration - double t = sum + z; // when adding sum + z, the lower digits are lost if sum is large - c = (t - sum) - z; // now we recover the lower digits to add in the next iteration - sum = t; - } - return sum; -} \ No newline at end of file diff --git a/ex1D_kahan_summation/mylib.h b/ex1D_kahan_summation/mylib.h deleted file mode 100644 index 7914250..0000000 --- a/ex1D_kahan_summation/mylib.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef FILE_MYLIB -#define FILE_MYLIB -#include - -/** Inner product - @param[in] x vector - @param[in] y vector - @return resulting Euclidian inner product -*/ -double scalar(std::vector const &x, std::vector const &y); - -/** Inner product using BLAS routines - @param[in] x vector - @param[in] y vector - @return resulting Euclidian inner product -*/ -double scalar_cblas(std::vector const &x, std::vector const &y); -float scalar_cblas(std::vector const &x, std::vector const &y); - - -/** L_2 Norm of a vector - @param[in] x vector - @return resulting Euclidian norm -*/ -double norm(std::vector const &x); - -double Kahan_skalar(std::vector const &x, std::vector const &y); - - -#endif diff --git a/ex1E_vector_vs_list/main.cpp b/ex1E_vector_vs_list/main.cpp deleted file mode 100644 index 13ec435..0000000 --- a/ex1E_vector_vs_list/main.cpp +++ /dev/null @@ -1,59 +0,0 @@ -#include "../utils/timing.h" -#include -#include -#include -#include -#include -#include -using namespace std; - - -size_t random_integer(int lower_bound, int upper_bound) -{ - unsigned seed = chrono::system_clock::now().time_since_epoch().count(); - - minstd_rand0 generator (seed); - - return lower_bound + generator() % (upper_bound - lower_bound + 1); -} - -int main(int argc, char **argv) -{ - // start with generating a sorted vector/list - size_t n = 10000; - vector x_vec = {}; - list x_list = {}; - for(size_t k = 0; k < n; ++k) - { - x_vec.push_back(k + 1); - x_list.push_back(k + 1); - } - - - // insert new random entries such that the container stays sorted - tic(); - for(size_t i = 0; i < n; ++i) - { - size_t new_entry = random_integer(1,n); - auto it = lower_bound(x_vec.begin(), x_vec.end(), new_entry); - x_vec.insert(it, new_entry); - } - double time_1 = toc(); - - tic(); - for(size_t i = 0; i < n; ++i) - { - size_t new_entry = random_integer(1,n); - auto it = lower_bound(x_list.begin(), x_list.end(), new_entry); - x_list.insert(it, new_entry); - } - double time_2 = toc(); - - - // check results - cout << "New vector is sorted: " << std::boolalpha << is_sorted(x_vec.begin(), x_vec.end()) << "\tsize: " << x_vec.size() << "\tduration: " << time_1 << endl; - cout << "New list is sorted: " << std::boolalpha << is_sorted(x_list.begin(), x_list.end()) << "\tsize: " << x_list.size() << "\tduration: " << time_2 << endl; - - - return 0; -} diff --git a/ex1F_goldbachs_conjecture/goldbach.h b/ex1F_goldbachs_conjecture/goldbach.h deleted file mode 100644 index 5794ad4..0000000 --- a/ex1F_goldbachs_conjecture/goldbach.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once -#include "mayer_primes.h" -#include -#include -#include -#include - - -/** - This function returns the number of possible decompositions of an integer into a sum of two prime numbers. - @param[in] k first integer - @param[out] count number of decompositions -*/ -size_t single_goldbach(size_t k); - -/** - This function returns the number of possible decompositions into a sum of two prime numbers of all even integers in the interval [4,n]. - @param[in] n upper integer bound - @param[out] count_vector vector containing the number of decompositions for a natural number the corresponding index -*/ -std::vector count_goldbach(size_t n); \ No newline at end of file diff --git a/ex1F_goldbachs_conjecture/main.cpp b/ex1F_goldbachs_conjecture/main.cpp deleted file mode 100644 index e85654f..0000000 --- a/ex1F_goldbachs_conjecture/main.cpp +++ /dev/null @@ -1,37 +0,0 @@ -#include "../utils/timing.h" -#include "goldbach.h" -#include -#include -using namespace std; - - -int main(int argc, char **argv) -{ - cout << "Check: 694 has "<< single_goldbach(694) << " decompositions." << endl << "----------------------------------------" << endl; - - - for(size_t n : {10000, 100000, 400000, 1000000, 2000000}) - { - tic(); - - auto goldbach_vector = count_goldbach(n); - - auto max_it = max_element(goldbach_vector.begin(), goldbach_vector.end()); - size_t max_number = distance(goldbach_vector.begin(), max_it); - - double time = toc(); - - cout << "The number " << max_number << " has " << *max_it << " decompositions. Duration: " << time << endl; - } - - /* - The number 9240 has 329 decompositions. Duration: 0.00572876 - The number 99330 has 2168 decompositions. Duration: 0.3342 - The number 390390 has 7094 decompositions. Duration: 4.23734 - The number 990990 has 15594 decompositions. Duration: 29.5817 - The number 1981980 has 27988 decompositions. Duration: 135.985 - */ - - - return 0; -} \ No newline at end of file diff --git a/ex1G_dense_matrices_access/DenseMatrix.h b/ex1G_dense_matrices_access/DenseMatrix.h deleted file mode 100644 index edf5160..0000000 --- a/ex1G_dense_matrices_access/DenseMatrix.h +++ /dev/null @@ -1,71 +0,0 @@ -#pragma once -#include "sigmoid.h" -#include -#include -using namespace std; - -class DenseMatrix -{ - private: - vector M; - size_t n; - size_t m; - - - public: - vector Mult(const vector &x) const - { - vector y(n,0); - for(size_t i = 0; i < n; ++i) // iterate row - { - for(size_t j = 0; j < m; ++j) // iterate column - { - y[i] += M[i*m + j]*x[j]; - } - } - return y; - } - - vector MultT(const vector &y) const - { - vector x(m,0); - for(size_t j = 0; j < m; ++j) // iterate column - { - for(size_t i = 0; i < n; ++i) // iterate row - { - x[j] += M[i*m + j]*y[i]; - } - } - return x; - } - - void Print() const - { - for(size_t i = 0; i < n; ++i) // iterate row - { - for(size_t j = 0; j < m; ++j) // iterate column - { - cout << M[i*m + j] << " "; - } - cout << endl; - } - cout << endl; - } - - - DenseMatrix(size_t n, size_t m) - { - this->n = n; - this->m = m; - M = vector(n*m); - size_t nm = max(n,m); - - for(size_t i = 0; i < n; ++i) // iterate row - { - for(size_t j = 0; j < m; ++j) // iterate column - { - M[i*m + j] = sigmoid(x_entry(i,nm))*sigmoid(x_entry(j,nm)); - } - } - } -}; \ No newline at end of file diff --git a/ex1G_dense_matrices_access/ProductMatrix.h b/ex1G_dense_matrices_access/ProductMatrix.h deleted file mode 100644 index 8f40764..0000000 --- a/ex1G_dense_matrices_access/ProductMatrix.h +++ /dev/null @@ -1,52 +0,0 @@ -#pragma once -#include -#include -#include -using namespace std; - -class ProductMatrix -{ - private: - vector u; - vector v; - size_t n; - size_t m; - - public: - vector Mult(const vector &x) const - { - vector y(n,0); - for(int i = 0; i < n; ++i) - { - for(int j = 0; j < m; ++j) - { - y[i] += v[j]*x[j]; - } - y[i] *= u[i]; - } - return y; - } - - vector MultT(const vector &y) const - { - vector x(m,0); - for(int j = 0; j < m; ++j) - { - for(int i = 0; i < n; ++i) - { - x[j] += y[i]*u[i]; - } - x[j] *= v[j]; - } - return x; - } - - ProductMatrix(const vector &u, const vector &v) - { - n = u.size(); - m = v.size(); - this->u = u; - this->v = v; - - } -}; \ No newline at end of file diff --git a/ex1G_dense_matrices_access/main.cpp b/ex1G_dense_matrices_access/main.cpp deleted file mode 100644 index fede0cc..0000000 --- a/ex1G_dense_matrices_access/main.cpp +++ /dev/null @@ -1,93 +0,0 @@ -#include "../utils/timing.h" -#include "DenseMatrix.h" -#include "ProductMatrix.h" -#include - -int main() -{ - // b) ------------------------------------------------------------------------------------------------------ - DenseMatrix const M(5,3); - vector const u{{1, 2, 3}}; - vector f1 = M.Mult(u); - vector const v{{-1, 2, -3, 4, -5}}; - vector f2 = M.MultT(v); - - M.Print(); - - for(size_t i = 0; i < f1.size(); ++i) - cout << f1[i] << endl; - cout << endl; - - - for(size_t j = 0; j < f2.size(); ++j) - cout << f2[j] << " "; - cout << endl << "-------------------------------------------------" << endl; - - // c) ------------------------------------------------------------------------------------------------------ - size_t n = pow(10,3); - DenseMatrix const M_1(n,n); - vector x(n, 1.0); - - size_t n_loops = 100; - vector y_1; - vector y_2; - - double time_1 = 0; - double time_2 = 0; - - tic(); - for(int l = 0; l < n_loops; ++l) - y_1 = M_1.Mult(x); - time_1 += toc(); - - tic(); - for(int l = 0; l < n_loops; ++l) - y_2 = M_1.MultT(x); - time_2 += toc(); - - vector error_vec(n,0); - for(int i = 0; i < n; ++i) - error_vec[i] = abs(y_1[i] - y_2[i]); - double sup_error = *max_element(error_vec.begin(), error_vec.end()); - - - cout << "n = " << n << endl; - cout << "Average duration for Mult: " << time_1/n_loops << endl; - cout << "Average duration for MultT: " << time_2/n_loops << endl; - cout << "sup-error: " << sup_error << endl; - cout << "-------------------------------------------------" << endl; - - // d) ------------------------------------------------------------------------------------------------------ - vector u_M(n,0); - for(int i = 0; i < n; ++i) - u_M[i] = sigmoid(x_entry(i, n)); - - ProductMatrix const M_2(u_M, u_M); - - time_1 = 0; - time_2 = 0; - - tic(); - for(int l = 0; l < n_loops; ++l) - y_1 = M_2.Mult(x); - time_1 += toc(); - - tic(); - for(int l = 0; l < n_loops; ++l) - y_2 = M_2.MultT(x); - time_2 += toc(); - - for(int i = 0; i < n; ++i) - error_vec[i] = abs(y_1[i] - y_2[i]); - sup_error = *max_element(error_vec.begin(), error_vec.end()); - - - cout << "n = " << n << endl; - cout << "Average duration for Mult: " << time_1/n_loops << endl; - cout << "Average duration for MultT: " << time_2/n_loops << endl; - cout << "sup-error: " << sup_error << endl; - cout << "-------------------------------------------------" << endl; - - - return 0; -} diff --git a/ex1G_dense_matrices_access/sigmoid.h b/ex1G_dense_matrices_access/sigmoid.h deleted file mode 100644 index 9fd581f..0000000 --- a/ex1G_dense_matrices_access/sigmoid.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once -#include - -double sigmoid(double x) -{ - return 1./(1. + exp(-x)); -} - -double x_entry(size_t k, size_t nm) -{ - return (10.*k)/(nm - 1) - 5.; -} \ No newline at end of file diff --git a/ex2A_stationary_heat_equation_fixed_lambda/ex2A.pdf b/ex2A_stationary_heat_equation_fixed_lambda/ex2A.pdf deleted file mode 100644 index 390a856..0000000 Binary files a/ex2A_stationary_heat_equation_fixed_lambda/ex2A.pdf and /dev/null differ diff --git a/ex2B_stationary_heat_equation_variable_lambda/ex2B.pdf b/ex2B_stationary_heat_equation_variable_lambda/ex2B.pdf deleted file mode 100644 index 5e03e75..0000000 Binary files a/ex2B_stationary_heat_equation_variable_lambda/ex2B.pdf and /dev/null differ diff --git a/ex2C_peclet_problem/ex2C.pdf b/ex2C_peclet_problem/ex2C.pdf deleted file mode 100644 index 71b75d3..0000000 Binary files a/ex2C_peclet_problem/ex2C.pdf and /dev/null differ diff --git a/ex2C_peclet_problem/main.py b/ex2C_peclet_problem/main.py deleted file mode 100644 index d8cb768..0000000 --- a/ex2C_peclet_problem/main.py +++ /dev/null @@ -1,18 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt - -def u(x,p): - return (np.exp(p*x) - 1)/(np.exp(p) - 1) - -x = np.linspace(0, 1, 200) - - -plt.figure(figsize=(8, 5)) -for p in [ -3, -1, -0.5, 0.5, 2, 4]: - plt.plot(x, u(x, p), label="p ="+ str(p)) - -plt.xlabel('x') -plt.ylabel('u(x)') -plt.legend() -plt.grid(True) -plt.show() diff --git a/ex3_benchmarks/Doxyfile b/ex3_benchmarks/Doxyfile deleted file mode 100644 index 58d8e68..0000000 --- a/ex3_benchmarks/Doxyfile +++ /dev/null @@ -1,2563 +0,0 @@ -# Doxyfile 1.8.20 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the configuration -# file that follow. The default is UTF-8 which is also the encoding used for all -# text before the first occurrence of this tag. Doxygen uses libiconv (or the -# iconv built into libc) for the transcoding. See -# https://www.gnu.org/software/libiconv/ for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = Skalar_seq_stl - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# The OUTPUT_TEXT_DIRECTION tag is used to specify the direction in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all generated output in the proper direction. -# Possible values are: None, LTR, RTL and Context. -# The default value is: None. - -OUTPUT_TEXT_DIRECTION = None - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the JAVADOC_BANNER tag is set to YES then doxygen will interpret a line -# such as -# /*************** -# as being the beginning of a Javadoc-style comment "banner". If set to NO, the -# Javadoc-style will behave just like regular comments and it will not be -# interpreted by doxygen. -# The default value is: NO. - -JAVADOC_BANNER = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# By default Python docstrings are displayed as preformatted text and doxygen's -# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the -# doxygen's special commands can be used and the contents of the docstring -# documentation blocks is shown as doxygen documentation. -# The default value is: YES. - -PYTHON_DOCSTRING = YES - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines (in the resulting output). You can put ^^ in the value part of an -# alias to insert a newline as if a physical newline was in the original file. -# When you need a literal { or } or , in the value part of an alias you have to -# escape them by means of a backslash (\), this can lead to conflicts with the -# commands \{ and \} for these it is advised to use the version @{ and @} or use -# a double escape (\\{ and \\}) - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = NO - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice -# sources only. Doxygen will then generate output that is more tailored for that -# language. For instance, namespaces will be presented as modules, types will be -# separated into more groups, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_SLICE = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, JavaScript, -# Csharp (C#), C, C++, D, PHP, md (Markdown), Objective-C, Python, Slice, VHDL, -# Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: -# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser -# tries to guess whether the code is fixed or free formatted code, this is the -# default for Fortran type files). For instance to make doxygen treat .inc files -# as Fortran files (default is PHP), and .f files as C (default is Fortran), -# use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See https://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up -# to that level are automatically included in the table of contents, even if -# they do not have an id attribute. -# Note: This feature currently applies only to Markdown headings. -# Minimum value: 0, maximum value: 99, default value: 5. -# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. - -TOC_INCLUDE_HEADINGS = 5 - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use -# during processing. When set to 0 doxygen will based this on the number of -# cores available in the system. You can set it explicitly to a value larger -# than 0 to get more control over the balance between CPU load and processing -# speed. At this moment only the input processing can be done using multiple -# threads. Since this is still an experimental feature the default is set to 1, -# which efficively disables parallel processing. Please report any issues you -# encounter. Generating dot graphs in parallel is controlled by the -# DOT_NUM_THREADS setting. -# Minimum value: 0, maximum value: 32, default value: 1. - -NUM_PROC_THREADS = 1 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual -# methods of a class will be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIV_VIRTUAL = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# declarations. If set to NO, these declarations will be included in the -# documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# (including Cygwin) and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. If -# EXTRACT_ALL is set to YES then this flag will automatically be disabled. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: https://www.gnu.org/software/libiconv/) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C comment), -# *.doc (to be provided as doxygen C comment), *.txt (to be provided as doxygen -# C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd, -# *.vhdl, *.ucf, *.qsf and *.ice. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.markdown \ - *.md \ - *.mm \ - *.dox \ - *.py \ - *.f90 \ - *.f \ - *.for \ - *.vhd \ - *.vhdl - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = YES - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = YES - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# entity all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see https://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = YES - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# https://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = YES - -# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML -# documentation will contain a main index with vertical navigation menus that -# are dynamically created via JavaScript. If disabled, the navigation index will -# consists of multiple levels of tabs that are statically embedded in every HTML -# page. Disable this option to support browsers that do not have JavaScript, -# like the Qt help browser. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_MENUS = YES - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: https://developer.apple.com/xcode/), introduced with OSX -# 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy -# genXcode/_index.html for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: https://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the main .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = NO - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg -# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see -# https://inkscape.org) to generate formulas as SVG images instead of PNGs for -# the HTML output. These images will generally look nicer at scaled resolutions. -# Possible values are: png (the default) and svg (looks nicer but requires the -# pdf2svg or inkscape tool). -# The default value is: png. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FORMULA_FORMAT = png - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANSPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands -# to create new LaTeX commands to be used in formulas as building blocks. See -# the section "Including formulas" for details. - -FORMULA_MACROFILE = - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# https://www.mathjax.org) which uses client side JavaScript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = YES - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from https://www.mathjax.org before deployment. -# The default value is: https://cdn.jsdelivr.net/npm/mathjax@2. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /