diff --git a/CMakeLists.txt b/CMakeLists.txt index 933e2308..a54ca24a 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 4bf0ea01..6abff1b6 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 37fc6ad2..1a11a89f 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 bf0d1cd0..c578b2c6 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 8326259b..00000000 --- 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 2bb608be..68befd4c 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 f7a18e41..7f253df0 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 fcc49ab7..8d81d53c 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 */ @@ -35,8 +34,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 00000000..f4957346 --- /dev/null +++ b/quest/include/quest_config.h.in @@ -0,0 +1,83 @@ +/** @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 Luc Jaulmes + * @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 daa1f014..dacdbd79 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