From 62349148169bbfeb343936e1da6df8a548538dbe Mon Sep 17 00:00:00 2001 From: Tyson Jones Date: Thu, 26 Jun 2025 22:41:42 +0200 Subject: [PATCH 1/2] made config header optional - renamed config.h to quest_config.h and made it an optional include which demands no macros are pre-defined, as per the discussions in #645 - added a COMPILE_HIP macro merely for book-keeping - added TODO for 'installing' in compile.md doc - explained quest_config.h in compile.md doc - corrected a typo in docs/README.md --- CMakeLists.txt | 15 +++++- docs/README.md | 2 +- docs/compile.md | 34 +++++++++++++- quest/include/CMakeLists.txt | 2 +- quest/include/config.h.in | 22 --------- quest/include/modes.h | 11 +++-- quest/include/precision.h | 10 +++- quest/include/quest.h | 2 - quest/include/quest_config.h.in | 82 +++++++++++++++++++++++++++++++++ utils/docs/Doxyfile | 2 +- 10 files changed, 147 insertions(+), 35 deletions(-) delete mode 100644 quest/include/config.h.in create mode 100644 quest/include/quest_config.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 933e23086..a54ca24a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -348,12 +348,25 @@ if (ENABLE_HIP) endif() endif() +# COMPILE_CUDA=1 whenever ENABLE_CUDA=1 OR ENABLE_HIP=1, +# since HIP sneakily overrides the CUDA API and so too +# requires that the CUDA-calling code is compiled. In +# this way, COMPILE_CUDA can be thought of as COMPILE_GPU if (ENABLE_CUDA OR ENABLE_HIP) compile_option(COMPILE_CUDA 1) else() compile_option(COMPILE_CUDA 0) endif() +# we also define COMPILE_HIP only for quest_config.h to +# log it; the macro is never used internally, and the GPU +# code differentiates CUDA vs HIP using __NVCC__ vs __HIP__ +if (ENABLE_HIP) + compile_option(COMPILE_HIP 1) +else() + compile_option(COMPILE_HIP 0) +endif() + if (ENABLE_DEPRECATED_API) target_compile_definitions(QuEST PRIVATE INCLUDE_DEPRECATED_FUNCTIONS=1) @@ -504,7 +517,7 @@ install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/quest/include/quest.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" ) -install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/quest/include/config.h" +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/include/quest/include/quest_config.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/quest/include" ) diff --git a/docs/README.md b/docs/README.md index 4bf0ea018..6abff1b60 100644 --- a/docs/README.md +++ b/docs/README.md @@ -31,7 +31,7 @@ Interested in contributing? Then check out: - ๐Ÿ—๏ธย ย [`architecture.md`](architecture.md) to understand the code structure. - ๐ŸŽจย ย [`styleguide.md`](styleguide.md) for some tips on writing neat code. -Want to learn how what's under the hood? Read the +Want to learn what's under the hood? Read the - ๐Ÿ†ย ย [whitepaper](https://www.nature.com/articles/s41598-019-47174-9) which featured in Scientific Report's [Top 100 in Physics](https://www.nature.com/collections/ecehgdfcba/) - ๐Ÿ“ย ย [preprint](https://arxiv.org/abs/2311.01512) which derives `v4`'s optimised algorithms. - ๐Ÿงชย ย [tests](/tests) which compare QuEST's outputs to non-optimised calculations. diff --git a/docs/compile.md b/docs/compile.md index 37fc6ad23..1a11a89f8 100644 --- a/docs/compile.md +++ b/docs/compile.md @@ -29,6 +29,7 @@ Compiling is configured with variables supplied by the [`-D` flag](https://cmake > - Basic > - Optimising > - Linking +> - Installing > - Configuring > * Location > * Precision @@ -235,9 +236,40 @@ and the executable can thereafter be run (from within `build`) via ./myexec ``` -You can pass compiler and linker flags needed by your source files through the [`CMAKE_C_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html), [`CMAKE_CXX_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html) and [`CMAKE_EXE_LINKER_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_EXE_LINKER_FLAGS.html) CMake flags as detailed in the below section. Note however that if your configuration becomes complicated or your source code requires different `C`/`C++` standards than the QuEST source, you should consider separately compiling QuEST then linking it +You can pass compiler and linker flags needed by your source files through the [`CMAKE_C_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html), [`CMAKE_CXX_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_FLAGS.html) and [`CMAKE_EXE_LINKER_FLAGS`](https://cmake.org/cmake/help/latest/variable/CMAKE_EXE_LINKER_FLAGS.html) CMake flags as detailed in the below section. Note however that if your configuration becomes complicated or your source code requires different `C`/`C++` standards than the QuEST source, you should consider separately compiling and potentially installing QuEST then linking it to your project as a library! + +------------------ + + + + + +## Installing + + +> TODO! + + +### Preprocessors + +When compiling QuEST for installation, all the variables and macros detailed in the proceeding section can be specified. +To later access the specified values during compilation of an executable _using_ QuEST, include: +```C++ +#include "quest.h" +#include "quest_config.h" +``` +The latter will define the below preprocessors as saved by CMake during compilation. +- [`FLOAT_PRECISION`](https://quest-kit.github.io/QuEST/group__precision.html#ga924ddc4b02996976cfdf425549ebec20) +- `COMPILE_MPI` (informed by `ENABLE_DISTRIBUTION`) +- `COMPILE_OPENMP` (informed by `ENABLE_MULTITHREADING`) +- `COMPILE_CUDA` (informed by either `ENABLE_CUDA` or `ENABLE_HIP`) +- `COMPILE_HIP` (informed only by `ENABLE_HIP`) +- `COMPILE_CUQUANTUM` (informed by `ENABLE_CUQUANTUM`) + + + ------------------ diff --git a/quest/include/CMakeLists.txt b/quest/include/CMakeLists.txt index bf0d1cd09..c578b2c64 100644 --- a/quest/include/CMakeLists.txt +++ b/quest/include/CMakeLists.txt @@ -2,4 +2,4 @@ # @author Erich Essmann # @author Luc Jaulmes (using config file) -configure_file(config.h.in "${CMAKE_BINARY_DIR}/include/quest/include/config.h" @ONLY) +configure_file(quest_config.h.in "${CMAKE_BINARY_DIR}/include/quest/include/quest_config.h" @ONLY) diff --git a/quest/include/config.h.in b/quest/include/config.h.in deleted file mode 100644 index 8326259b6..000000000 --- a/quest/include/config.h.in +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CONFIG_H -#define CONFIG_H - -// be warned, the below is sensitive to whitespace after the slash -#if !defined(FLOAT_PRECISION)\ - || !defined(COMPILE_MPI)\ - || !defined(COMPILE_OPENMP)\ - || !defined(COMPILE_CUDA)\ - || !defined(COMPILE_CUQUANTUM) - -// bind compile settings to installed exec -#if !@MULTI_LIB_HEADERS@ -#cmakedefine FLOAT_PRECISION @FLOAT_PRECISION@ -#cmakedefine01 COMPILE_MPI -#cmakedefine01 COMPILE_OPENMP -#cmakedefine01 COMPILE_CUDA -#cmakedefine01 COMPILE_CUQUANTUM -#endif - -#endif - -#endif \ No newline at end of file diff --git a/quest/include/modes.h b/quest/include/modes.h index 2bb608be9..68befd4cf 100644 --- a/quest/include/modes.h +++ b/quest/include/modes.h @@ -1,6 +1,9 @@ /** @file - * Compile-time checks that all expected - * preprocessor macros are defined and valid + * Compile-time checks that all expected preprocessor macros + * are defined and valid. The checks are only 'really' performed + * when the QuEST source is being compiled. After installation, + * the macros herein are undefined (unless the user strangely + * defines them) which automatically passes the validation * * @author Tyson Jones * @@ -15,8 +18,8 @@ -// ensure all mode flags are valid values -// undefined allowed as undefined == 0 in C/C++ standards +// ensure all optionally-defined mode flags have valid values +// (undefined allowed as undefined == 0 in C/C++ standards) #if ! (COMPILE_MPI == 0 || COMPILE_MPI == 1) #error "Macro COMPILE_MPI must have value 0 or 1" diff --git a/quest/include/precision.h b/quest/include/precision.h index f7a18e416..7f253df04 100644 --- a/quest/include/precision.h +++ b/quest/include/precision.h @@ -1,6 +1,12 @@ /** @file - * User-overridable numerical precision of - * both the QuEST API and backends + * User-overridable numerical precision of both the QuEST API and backends. + * + * Note this file includes some validation of macro values (e.g. that when + * COMPILE_CUDA=1, FLOAT_PRECISION < 4), checked when the QuEST source is + * compiled. When QuEST is installed, these checks "appear" redundantly + * repeated by the user's code which indirectly includes this header; but + * the macros should no longer be defined by then and so are treated as + * having a value of zero by the compiler, which passes all validation. * * @author Tyson Jones * @author Milos Prokop (patched trig overloads in v3) diff --git a/quest/include/quest.h b/quest/include/quest.h index fcc49ab76..95c15c792 100644 --- a/quest/include/quest.h +++ b/quest/include/quest.h @@ -35,8 +35,6 @@ // debuggers in case a subsequent include fails #include "quest/include/version.h" -#include "quest/include/config.h" - // include before API headers since it validates // preprocessor configuration, and affirms macro // preconditions assumed by subsequent header diff --git a/quest/include/quest_config.h.in b/quest/include/quest_config.h.in new file mode 100644 index 000000000..8ce2a4f9d --- /dev/null +++ b/quest/include/quest_config.h.in @@ -0,0 +1,82 @@ +/** @file + * An optional user-facing header which exposes the + * compile-time macros which configured QuEST's + * installation. The actual header file is produced + * by CMake from this config-file, so cannot be + * accessed by manual compilation. + * + * In detail, the below user-specified CMake variables... + * + * - ENABLE_DISTRIBUTION + * - ENABLE_MULTITHREADING + * - ENABLE_CUDA + * - ENABLE_CUQUANTUM + * - FLOAT_PRECISION + * + * respectively inform the below preprocessors which are + * needed to compile and optionally install QuEST: + * + * - COMPILE_MPI + * - COMPILE_OPENMP + * - COMPILE_CUDA + * - COMPILE_CUQUANTUM + * - FLOAT_PRECISION (yes, the same name) + * + * (additionally, COMPILE_HIP is used for book-keeping and + * is never consulted by the QuEST source) + * + * After the QuEST source is compiled, these preprocessors + * are discarded such that the compiled configuration of an + * installed QuEST library can only be known at runtime via + * functions like reportQuESTEnv(). This optional header + * exposes the source-compile-time values (as saved by CMake) + * so that users can know the configuration when compiling + * their own code which interfaces with an installed QuEST + * library. This is useful when e.g. integrating QuEST with + * external tools with compile-time variables informed by + * QuEST's. This header is not included in quest.h so that + * both compilation of QuEST without installation AND manual + * compilation (i.e. without cmake) remain possible. + * + * @author Oliver Brown + * @author Tyson Jones (validation & doc) + */ + +#ifndef QUEST_CONFIG_H +#define QUEST_CONFIG_H + + +// the saved preprocessors exposed by this header must not +// be prior defined, else the user might unwittingly override +// them and misconstrue QuEST's installed configuration + +#if defined(FLOAT_PRECISION) || \ + defined(COMPILE_MPI) || \ + defined(COMPILE_OPENMP) || \ + defined(COMPILE_CUDA) || \ + defined(COMPILE_CUQUANTUM) || \ + defined(COMPILE_HIP) + + #error \ + "Header 'quest_config.h' was included but one or more macros exposed therein was already defined. "\ + "Only include this header to learn (at compile-time) the configuration of an installed QuEST library." + +#endif + + +// bind compile settings to installed exec + +#if !@MULTI_LIB_HEADERS@ + + #cmakedefine FLOAT_PRECISION @FLOAT_PRECISION@ + + #cmakedefine01 COMPILE_MPI + #cmakedefine01 COMPILE_OPENMP + #cmakedefine01 COMPILE_CUDA + #cmakedefine01 COMPILE_CUQUANTUM + #cmakedefine01 COMPILE_HIP + +#endif + + +#endif // QUEST_CONFIG_H diff --git a/utils/docs/Doxyfile b/utils/docs/Doxyfile index daa1f0143..dacdbd79e 100644 --- a/utils/docs/Doxyfile +++ b/utils/docs/Doxyfile @@ -376,7 +376,7 @@ OPTIMIZE_OUTPUT_SLICE = NO # Note see also the list of default file extension mappings. # all source code (even headers) is C++, but example.c code is C. -# in=C is necessary to parse quest.h.in (a CMake configured header) +# in=C is necessary to parse quest_config.h.in (a CMake configured header) EXTENSION_MAPPING = h=C++ hpp=C++ cpp=C++ cu=C++ cuh=C++ c=C in=C # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments From 2aedd2a36c4b47e8508a5f85f83ccd9fe6c633b0 Mon Sep 17 00:00:00 2001 From: Tyson Jones Date: Thu, 26 Jun 2025 22:45:36 +0200 Subject: [PATCH 2/2] correcting author attribution --- quest/include/quest.h | 1 - quest/include/quest_config.h.in | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/quest/include/quest.h b/quest/include/quest.h index 95c15c792..8d81d53c1 100644 --- a/quest/include/quest.h +++ b/quest/include/quest.h @@ -7,7 +7,6 @@ * deprecated v3 API, before including this header. * * @author Tyson Jones - * @author Luc Jaulmes (patching CMake install) * * @defgroup api ๐Ÿ“‹ API */ diff --git a/quest/include/quest_config.h.in b/quest/include/quest_config.h.in index 8ce2a4f9d..f49573467 100644 --- a/quest/include/quest_config.h.in +++ b/quest/include/quest_config.h.in @@ -38,6 +38,7 @@ * both compilation of QuEST without installation AND manual * compilation (i.e. without cmake) remain possible. * + * @author Luc Jaulmes * @author Oliver Brown * @author Tyson Jones (validation & doc) */