Support¶
Known limitations¶
Limitations on FLEQ types¶
Quantum kernel expressions must be invoked via an evaluation call
eval_hold
oreval_release
. If a function that returns aQExpr
type is simply called from a top-level function, it will have no effect on the quantum backend (Basics: evals, join, identity, and QExpr-returning functions). For example, consider the following example:
QExpr myQExprFunction(qbit &q);
int main() {
...
// WRONG: Returns an unused QExpr value; does NOT invoke the quantum runtime
myQExprFunction(q);
// CORRECT: Invokes the quantum runtime by evaluating a QExpr value
qexpr::eval_hold(myQExprFunction(q));
}
Evaluation calls are not supported inside of
quantum_kernel
functions that also call basic quantum gates.For quantum kernel expressions, there is no appreciable difference between the use of the
-O0
and-O1
optimization flags. See Overview of FLEQ compilation.All
qbit
arguments must be passed by reference.Conventional data passed into and out of
QExpr
-returning functions within the same evaluation or function body should be passed by reference (see Basics: evals, join, identity, and QExpr-returning functions).Arguments of FLEQ types
QExpr
,QList
, andDataList
should be passed by value.The
PROTECT
attribute should be added to aQExpr
-returning function,f
, if:f
usesthis_as_expr
.f
introduces any local variables including local qubits within its body.the evaluation behavior of classical logic inside the body of
f
is order-dependent or branch dependent with respects to other such calls within the evaluation, especially with respect tobind
-enforced ordering or when said classical logic generates side-effects outside the scope of FLEQ.any of the other cases above are in doubt or unclear.
There are known cases where post-quantum sections are not moved/inserted into the approriate branch. This happens in special cases where both
bind
and unresolved branching are used together. When post-processing is desired within aQExpr
, it is best practice to enforce desired order usingbind
and emptyQExpr
-returning functions (returnidentity
orthis_as_expr
without gates) wrapping classical post-processing instructions and including thePROTECT
attribute.QList
declarations created using thelistable
macro e.g.listable(<name>, N)
will be displayed during circuit printing and debugging as<name>_raw
. See QList. The same is true for theDataList
type and theimport_with_name
macros.DataList
casts toint
,double
, andbool
will result in undefined behavior if theDataList
cannot be coerced to that type. See DataList.The command line
-P
flag for printing quantum kernels will only print quantum kernel expressions inside evaluation calls. In addition, it will only print the circuit after optimization and synthesis.Multi-qubit quantum control is limited to control by up to
8
qubits (see Control). This limit can be overcome by chainingcontrol
calls using recursion (see Recursion) or with the explicit use of ancilla.
Classical control flow¶
Functions that return quantum kernel expressions must have a single return statement. The control flow of the function cannot depend on C++ conditionals (if statements) or loops. All classical conditionals inside a
QExpr
function should instead usecIf
(see Branching).Similarly,
let
assignments cannot vary based on classical conditionals (see Let/get). Best practice is to not uselet
andget
with C++ branching.Recursive
QExpr
functions must be able to be unrolled at compile-time. FLEQ does not currently support repeat-until-success loops in a single quantum kernel expression. See Recursion.cIf
statements that cannot be resolved at compile-time can produce an exponential growth in the number of QBBs produced by thatQExpr
(see Branching). This is especially the case when usingjoin
over unresolvedcIf
branching. This exponential blowup can be avoided by usingbind
in the place ofjoin
(see Barriers and binding).Traditional C++ if statements and loops that contain only classical instructions are not encouraged. Best practice is to use
cIf
and recursion as described in Branching and Recursion.
Barriers¶
Measurement results are not available within the same
QExpr
where measurements are invoked, unless they are separated by a barrier likebind
orfence
(see Barriers and binding).qexpr::power
does not distribute overbind
the way it does withjoin
. Best practice is to never usebind
withqexpr::power()
. See Barriers and binding.
Print buffer¶
The order in which
printQuantumLogic
andprintDataList
are displayed is based on a topological sort of the evaluation call dependencies, i.e. the order of traversal of the FLEQ evaluation graph (see Overview of FLEQ compilation).When
exitAtCompile
is found in the dependency of an evaluation call, the exit message is added to the print buffer and the build failure is only triggered once the build is complete, or a different failure point is found.exitAtCompile
triggers a fail regardless of whether the call is within an unresolved branch or not. if one desires an exit be triggered only in one branch of many unresolved branches, consider usingexitAtRuntime
instead.
Bug reporting and feature requests¶
Users can get technical support, share ideas, and report bugs by visiting Intel Communities.