Support¶
Known limitations¶
Limitations on FLEQ types¶
Quantum kernel expressions must be invoked via an evaluation call
eval_holdoreval_release. If a function that returns aQExprtype 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_kernelfunctions that also call basic quantum gates.For quantum kernel expressions, there is no appreciable difference between the use of the
-O0and-O1optimization flags. See Overview of FLEQ compilation.All
qbitarguments 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, andDataListshould be passed by value.The
PROTECTattribute should be added to aQExpr-returning function,f, if:fusesthis_as_expr.fintroduces any local variables including local qubits within its body.the evaluation behavior of classical logic inside the body of
fis 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
bindand unresolved branching are used together. When post-processing is desired within aQExpr, it is best practice to enforce desired order usingbindand emptyQExpr-returning functions (returnidentityorthis_as_exprwithout gates) wrapping classical post-processing instructions and including thePROTECTattribute.QListdeclarations created using thelistablemacro e.g.listable(<name>, N)will be displayed during circuit printing and debugging as<name>_raw. See QList. The same is true for theDataListtype and theimport_with_namemacros.DataListcasts toint,double, andboolwill result in undefined behavior if theDataListcannot be coerced to that type. See DataList.The command line
-Pflag 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
8qubits (see Control). This limit can be overcome by chainingcontrolcalls 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
QExprfunction should instead usecIf(see Branching).Similarly,
letassignments cannot vary based on classical conditionals (see Let/get). Best practice is to not useletandgetwith C++ branching.Recursive
QExprfunctions 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.cIfstatements 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 usingjoinover unresolvedcIfbranching. This exponential blowup can be avoided by usingbindin 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
cIfand recursion as described in Branching and Recursion.
Barriers¶
Measurement results are not available within the same
QExprwhere measurements are invoked, unless they are separated by a barrier likebindorfence(see Barriers and binding).qexpr::powerdoes not distribute overbindthe way it does withjoin. Best practice is to never usebindwithqexpr::power(). See Barriers and binding.
Print buffer¶
The order in which
printQuantumLogicandprintDataListare 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
exitAtCompileis 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.exitAtCompiletriggers 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 usingexitAtRuntimeinstead.
Bug reporting and feature requests¶
Users can get technical support, share ideas, and report bugs by visiting Intel Communities.