Merged
Conversation
and unit test, for completeness
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Example PR A
Sub PR 4
This PR demonstrates how to add new QuEST API functions which directly return a
qcomp.The problem
QuEST is agnostic to
CandC++using a myriad of tricks. This includes resolving theqcomptype to the natural, respectiveCandC++complex types. While aCuser may believe theqcompis defined asa
C++user (and the internal QuEST library) may meanwhile believe it to beAs such, a
Cuser might pass a_Complexto aC++function expecting astd::complex<double>. Alas, this is undefined behaviour! For historical reasons, complex primitives were never integrated into the ABI. It is ergo illegal for aCuser to directly pass aqcompto its internalC++functions.The solution
While the type
qcompdiffers betweenCandC++, they do have the same memory layout. This is guaranteed by theC99andC++11standards as indicated here, and means it is okay to pass pointers toqcompover the ABI. Ergo, QuEST'sC++functions can safely accept and returnqcomp*and be directly invoked byCcode.Passing superfluous pointers is gross though, and we still wish for the
CandC++interfaces to be identical. So, to define a new API function which returns aqcomp, we...quest/include/calculations.h) withoutextern "C".qcomp calcAmpSum(Qureg qureg);C++-only version in the corresponding source file (e.g.quest/src/api/calculatons.cpp), also withoutextern "C".C-compatible version of the function just under the above function, which calls the above function, but safely "returns" theqcompby overwriting a pointer.C-only version of the function inquest/include/wrappers.hwith an identical signature to theC++definition but which invokes_wrap_calcAmpSumabove.A regrettable side-effect of this trick is that the intendedly private function
_wrap_calcAmpSumis declared (asextern) in the header. This is necessary to prevent the theCcompiler parsingwrappers.hfrom panicking about the missing symbol, but meansCusers can see and call_wrap_calcAmpSum. Although calling it is harmless, hopefully the ugly prefix dissuades IDEs from listing the routine!This PR
We generalise the existing
calcRealAmpSum(which returned a real-valued primitive without problem) to returnqcomp, retaining aCandC++agnostic API via the above process. We also define its unit test for completeness.The combined changes of this and the previous example PRs can be seen in #615.