-
Couldn't load subscription status.
- Fork 165
Fix for quest.h generation #645
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…pe, which ensures correct values are generated in the header file.
|
Hmm I'm now getting hit by a bunch of multiple definition errors when attempting to compile CQ-SimBE as a consequence of trying to include All of which is to say I think I'm now an advocate of separatiing the |
|
Drat! It's true that those preprocessors aren't needed by the user source; they only affect backend compilation. They need only "survive" past compilation for users who wish to know the compiled backends during compilation of their own source code. So I'm with you about moving them to a bespoke, optional header. Then // ensure defined
#ifndef COMPILE_MPI
#error "Compiler must define COMPILE_MPI"
#endif
// ensure valid
#if ! (COMPILE_MPI == 0 || COMPILE_MPI == 1)
#error "Macro COMPILE_MPI must have value 0 or 1"
#endifto // permit undefined else ensure valid
#if ! (COMPILE_MPI == 0 || COMPILE_MPI == 1)
#error "Macro COMPILE_MPI must have value 0 or 1, or else be undefined"
#endif
// (above exploits undefined preprocessor == 0 in C/C++ standards)and rename it to The new So all agreed! Alas I'm insufficiently knowledgeable in CMake configs to make |
|
I think the changes needed are pretty minor, so will try them out over the next few days and hit you with the PR! If I get stuck I'll definitely be asking Luc ;) |
… undefined as proposed by @TysonRayJones
…ined, as proposed by @TysonRayJones
|
Okay! We no longer generate |
|
Wew brilliant! 🎉 Enabling non-cmake compilationCan I throw a minor spanner in the works? 😅 It'd be neat to make extricable the build from cmake so that manual compilation (like through this bash script - though I must update it) remains possible. It's inessential but super useful for debugging compilation. This is currently only prevented by #include "quest/include/config.h"since Some quick ideas:
Do you have any thoughts on these? I lean personally toward 1. with the justification that Other preprocessorsThe This does not seem a huge problem: it's "too late" for users to adjust the default epsilon, and they'll instead have to use runtime control. This might be better than caching QuEST/quest/include/precision.h Lines 123 to 131 in f3baf34
to e.g. /*
* RE-CONFIGURABLE DEFAULT VALIDATION PRECISION
*
* which is overridable when compiling the QuEST source by defining
* DEFAULT_VALIDATION_EPSILON. Beware that updating this macro
* after compilation (e.g. after installing QuEST) has no effect, though
* epsilon can be overridden at runtime using setValidationEpsilon()
*/What do you think about this? Is it a pitfall? Will users deliberately exposing the config macros (as per above) be tricked by |
|
RE non-cmake compilation: So actually, with the removal of the modes header I would of course also update RE To be honest I suspect a user messing with this really needs to know what they're doing, so I'm not too upset about it being fiddly to do :) Here I vote for just updating the doc as you suggest to make it clear it's a property of the QuEST library, not of the application code they build against that library. |
|
I can see an argument here for expanding config.h to include the default validation epsilon set at compile time, for similar record-keeping/occasional-onward-propagation purposes! |
|
| #if FLOAT_PRECISION == 1 | |
| #define DEFAULT_VALIDATION_EPSILON 1E-5 | |
| #elif FLOAT_PRECISION == 2 | |
| #define DEFAULT_VALIDATION_EPSILON 1E-12 | |
| #elif FLOAT_PRECISION == 4 | |
| #define DEFAULT_VALIDATION_EPSILON 1E-13 |
PERMIT_NODES_TO_SHARE_GPU
TLDR I will change
PERMIT_NODES_TO_SHARE_GPUto an environment variable unless objected to! Reasoning below (in context) for posterity.
The remaining preprocessors which can differ between compilation and include are:
Lines 78 to 88 in 4d44ec8
| #ifndef PERMIT_NODES_TO_SHARE_GPU | |
| #define PERMIT_NODES_TO_SHARE_GPU 0 | |
| #endif | |
| #ifndef INCLUDE_DEPRECATED_FUNCTIONS | |
| #define INCLUDE_DEPRECATED_FUNCTIONS 0 | |
| #endif | |
| #ifndef DISABLE_DEPRECATION_WARNINGS | |
| #define DISABLE_DEPRECATION_WARNINGS 0 | |
| #endif |
The latter two are unimportant and should be link-time overridable since they merely control user-source-compile-time warnings. But PERMIT_NODES_TO_SHARE_GPU is stickier - it appears it two sources:
QuEST/quest/src/api/environment.cpp
Lines 105 to 111 in 4d44ec8
| // each MPI process must use a unique GPU. This is critical when | |
| // initializing cuQuantum, so we don't re-init cuStateVec on any | |
| // paticular GPU (causing runtime error), but still ensures we | |
| // keep good performance in our custom backend GPU code; there is | |
| // no reason to use multi-nodes-per-GPU except for dev/debugging. | |
| if (useGpuAccel && useDistrib && ! PERMIT_NODES_TO_SHARE_GPU) | |
| validate_newEnvNodesEachHaveUniqueGpu(caller); |
QuEST/quest/src/core/validation.cpp
Lines 1361 to 1370 in 4d44ec8
| void validate_newEnvNodesEachHaveUniqueGpu(const char* caller) { | |
| // this validation can be disabled for debugging/dev purposes | |
| // (caller should explicitly check this preprocessor too for clarity) | |
| if (PERMIT_NODES_TO_SHARE_GPU) | |
| return; | |
| bool uniqueGpus = ! gpu_areAnyNodesBoundToSameGpu(); | |
| assertAllNodesAgreeThat(uniqueGpus, report::MULTIPLE_NODES_BOUND_TO_SAME_GPU, caller); | |
| } |
(Its second appearance is totally redundant; that must be that 3am flavour of "defensive design" woops 😅 )
The purpose of PERMIT_NODES_TO_SHARE_GPU is just to disable validation which prevent users from mistakingly over-subscribing GPUs and experiencing unexpected performance degradation. It's useful to disable this validation when unit-testing MPI+GPU hybridisation on a single GPU.
If it were to remain a compile-time flag, I suppose it should also be recorded by quest_config.h. BUT there's really no need for this to be fixed at compile-time - it seems a gratuitous tedium to have to recompile/re-install QuEST just to change it! Ideally one should wish to easily change it between launches of a QuEST executable.
It's a little clumsy to be specified at runtime however, since that validation occurs during initQuESTEnv() before which no user-configuration can be done. It also seems gross to add it as a necessary parameter to initCustomQuESTEnv() since it "feels" like a meta setting that should never need to be referenced except when being disabled.
So, it seems prudent to change it to an environment-variable. Would this cause any issues? Would that jeopardise QuEST's ability to run on extremely stripped-down systems like microcontrollers?? 😅
Test macros
Is it okay to neglect the test-specific macros? Are the tests even included in the installation?
Lines 30 to 48 in 4d44ec8
| // 0 = perform all, and a sensible value to accelerate tests is 50 | |
| #ifndef TEST_MAX_NUM_QUBIT_PERMUTATIONS | |
| #define TEST_MAX_NUM_QUBIT_PERMUTATIONS 0 | |
| #endif | |
| // 0 = perform all (very slow), while 4 limits to superops = 8-qubit matrices | |
| #ifndef TEST_MAX_NUM_SUPEROP_TARGETS | |
| #define TEST_MAX_NUM_SUPEROP_TARGETS 4 | |
| #endif | |
| // 0 = use all available deployments at once, 1 = try all combinations in-turn | |
| #ifndef TEST_ALL_DEPLOYMENTS | |
| #define TEST_ALL_DEPLOYMENTS 1 | |
| #endif | |
| // number of times to repeat each "[mixed]" test (minimum 1) | |
| #ifndef TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS | |
| #define TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS 10 | |
| #endif |
so that the COMPILE_CUQUANTUM preprocessor need only ever be consulted by the source during compilation, as proposed by Oliver in #645
This allows it to be changed post-compilation/installation, pre-execution, as per the machination in #645 Additionally inserted whitespaces into cmake error message about MacOS multithreading to make the advised commands clearer
|
I've had the 🚿 epiphany 🚿 that the discussed overridable preprocessors fall into three categories: those which must be known at...
All 1. must be saved by cmake, all 2. must never be saved, and 3. should never have been preprocessors! Instead, all 3. should be environment variables; they offer no benefit to being decided at source-compile-time which instead reduces flexibility. I propose changing all below macros to environment variables:
(tests)
The latter four are a little irritating to refactor since they are accessed outside the source so shouldn't use the internal convenience functions for obtaining env-vars. This puts 'don't repeat yourself' in tension with 'separation of concerns', but I'll find some compromising design. I'll ergo not merge #650 and instead extend it in a new PR to properly handle environment variables. That should resolve everything; there will be no remaining preprocessors needing saving by cmake, no ineffectual-overridable macros, |
|
Sounds great to me! (Apologies for the delay, was travelling now attending a conference!) |
|
Wew brilliant! No problem about the micro-delay - I'm supposed to be on holiday but I have norovirus 😭 I'll merge this PR, commit the env-vars, then will commit renaming of One final thing regarding these lines: QuEST/quest/include/config.h.in Lines 5 to 9 in 1f1e702
A user optionally including |
|
Ooft, really sorry to hear about the norovirus 😬 that's a bad time even if you weren't meant to be on holiday... Exactly so, this tells the user what was compiled into the QuEST library -- redefining elsewhere will, at best, do nothing. So not a bad idea to warn the user they're being silly. My original logic there was just that they all needed to be defined in the QuEST build, so if any was undefined they should all be defined. Final question, should we rename them to |
|
Thanks very much! It's pretty grim, though it's making me appreciate all the good work my bowels ordinarily perform. Gotcha! A |
|
I would say no, as user code stays the same! (Unless you were doing something really weird). It only maybe matters to whoever builds the library. Plus most people will set these preprocessor directives through the magic of CMake, and that interface remains unchanged 😁 |
|
Sorry this is a bit verbose and I’m joining a bit late. But everything seems sorted now, no? 😅 |
|
Ok perf! Let's rename the vars in another PR (after I merge the env-var one) to make that change more explicit. Sorry for the delay in merging this! |
which enable configuring QuEST's execution after compilation, before QuEST environment initialisation, solving some of the issues lamented in #645 and generally being more sensible/convenient. It also patched an esoteric bug in the parsing of floating-point numbers, affecting functions like initInlinePauliStrSum(). Refactor included: - adding (basic) utilities for parsing environment variables. - changing PERMIT_NODES_TO_SHARE_GPU and DEFAULT_EPSILON_ENV_VAR_NOT_A_REAL from macros to environment variables. The latter empowers users to disable all numerically-sensitive validation without modifying or recompiling their code. - patching the parsing of non-quadruple-precision floats which would previously see numbers beyond the qcomp-range silently over or underflow instead of throwing an error (see commit a66f797). - inserted whitespaces into cmake error message about MacOS multithreading to make the advised commands clearer. A subsequent commit will refactor some unit-testing macros to non-QuEST-managed environment variables.
which enables post-compilation pre-runtime configuring of the unit tests without hooking into QuEST's internal environment variable facilities. The macros... - TEST_MAX_NUM_QUBIT_PERMUTATIONS - TEST_MAX_NUM_SUPEROP_TARGETS - TEST_ALL_DEPLOYMENTS - TEST_NUM_MIXED_DEPLOYMENT_REPETITIONS are now environment variables, along with new variable TEST_NUM_QUBITS_IN_QUREG which controls the size of the Quregs in the unit tests. With this commit, all preprocessors considered in #645 have become environment variables
- 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
Hi Tyson,
Hope the unitary hack is going well!
I've finally updated to 4.1 locally and spotted a subtle bug with Luc's custom
compile_optionfunction in CMake -- the variables set within it were dutifully thrown away at return. The fix is trivial, just needed to addedPARENT_SCOPEto the set command.As that function also independently set
target_compile_definitionsthe library itself is still compiled correctly, this bug would only impact downstream projects (like my CQ!).Cheers,
Oliver