New parallel expression in Q##3298
Conversation
| CircuitEntryPoint::EntryPoint, | ||
| ); | ||
|
|
||
| expect![[r#" |
There was a problem hiding this comment.
It is difficult for me to understand what should be expected from the nested parallel within expressions, so I'll double-check with you. Is this correct and what is expected with the nested setup?
|
Because the
parallel within X {
parallel within {
// Should be subject to `parallel within X`
use q0 = Qubit();
use q1 = Qubit();
Y
} {...}
}
|
| Lambda(CallableKind, Box<Pat>, Box<Expr>), | ||
| /// A literal. | ||
| Lit(Box<Lit>), | ||
| /// A parallel expression: `parallel a` |
There was a problem hiding this comment.
Do we want the target expr to be a block to force a scope on the feature rather than allowing any expr?
There was a problem hiding this comment.
It gets turned into a block if it isn't one as part of lowering into HIR. But from a user-facing syntax perspective, there is value in having it support any expression. For example, for-loops are an expression, and one of the main motiviations is allowing parallel for syntax without having to add an extraneous block.
| let ty = expr.ty.clone(); | ||
| let stmt = hir::Stmt { | ||
| id: self.assigner.next_node(), | ||
| span: Span::default(), | ||
| kind: hir::StmtKind::Expr(expr), | ||
| }; | ||
| let block = hir::Block { | ||
| id: self.assigner.next_node(), | ||
| span: Span::default(), | ||
| ty: ty.clone(), | ||
| stmts: vec![stmt], | ||
| }; | ||
| hir::Expr { | ||
| id: self.assigner.next_node(), | ||
| span: Span::default(), | ||
| ty, | ||
| kind: hir::ExprKind::Block(block), | ||
| } |
There was a problem hiding this comment.
I think the stmt, block, and hir::Expr should use the expr.span rather than Span::default()
| #[error("cannot use dynamic branching in parallel expression")] | ||
| #[diagnostic(help( | ||
| "using branching based on a measurement result in a parallel expression is not supported by the configured target profile" | ||
| ))] | ||
| #[diagnostic(url("https://aka.ms/qdk.qir#use-of-dynamic-branching-in-parallel-expr"))] | ||
| #[diagnostic(code("Qsc.CapabilitiesCk.UseOfDynamicBranchingInParallelExpr"))] | ||
| UseOfDynamicBranchingInParallelExpr(#[label] Span), | ||
|
|
||
| #[error("cannot use dynamic limit for a parallel expression")] | ||
| #[diagnostic(help( | ||
| "using a dynamic limit for a parallel expression is not supported by the configured target profile" | ||
| ))] | ||
| #[diagnostic(url("https://aka.ms/qdk.qir#use-of-dynamic-limit-in-parallel-expr"))] | ||
| #[diagnostic(code("Qsc.CapabilitiesCk.UseOfDynamicLimitInParallelExpr"))] | ||
| UseOfDynamicLimitInParallelExpr(#[label] Span), |
There was a problem hiding this comment.
These anchors don't work yet, need the docs updated.
39a4783 to
134a7a6
Compare
This change adds support for a new parallel expression that alters the behavior of qubit allocation and code generation. There are two forms of the expression: - `parallel <expr>`: For the duration of the expression after the keyword, all qubit release is deferred such that each qubit allocation uses a fresh qubit identifier. In addition, when configured for QIR code generation, no expressions that result in dynamic branching are allowed within the expression and all loops within the expression are unrolled. This ensures that the generated QIR for that expression will be contained within a single LLVM block. Combining these two features (defferred release and enforced single block) maximizs the likelihood that the code corresponding to the expression will be parallelized by the target's compilation and scheduling. - `parallel within <limit> <expr>`: This form has the same semantics as the first form, but with the added integer limit that expresses how many fresh qubit allocations will be used before normal qubit reuse begins. For example, `parallel wthin 4 <expr>` will defer the release of four qubits, and if a fifth allocation is made within the expression then that allocation will draw from the previously deferred qubits, returning to a reuse pattern. This allows the program to express a limited amount of parallelism while still allowing for some reuse, providing more fine grained control over the width/depth (space/time) tradeoff of the algorithm. The limit expression must be a static (compile-time constant) integer. The new expression affects the behavior of QIR code generation, simulation, and resource estimation, and the change includes updated parser, AST, HIR, FIR, and lowering logic for the syntax as well as new RCA checks to enforce the requirements for control flow structure and static integer limits.
|
accidentally closed via bad force push |
This change adds support for a new
parallelexpression that alters the behavior of qubit allocation and code generation. There are two forms of the expression:parallel <expr>: For the duration of the expression after the keyword, all qubit release is deferred such that each qubit allocation uses a fresh qubit identifier. In addition, when configured for QIR code generation, no expressions that result in dynamic branching are allowed within the expression and all loops within the expression are unrolled. This ensures that the generated QIR for that expression will be contained within a single LLVM block. Combining these two features (defferred release and enforced single block) maximizs the likelihood that the code corresponding to the expression will be parallelized by the target's compilation and scheduling.parallel within <limit> <expr>: This form has the same semantics as the first form, but with the added integer limit that expresses how many fresh qubit allocations will be used before normal qubit reuse begins. For example,parallel wthin 4 <expr>will defer the release of four qubits, and if a fifth allocation is made within the expression then that allocation will draw from the previously deferred qubits, returning to a reuse pattern. This allows the program to express a limited amount of parallelism while still allowing for some reuse, providing more fine grained control over the width/depth (space/time) tradeoff of the algorithm. The limit expression must be a static (compile-time constant) integer.The new expression affects the behavior of QIR code generation, simulation, and resource estimation, and the change includes updated parser, AST, HIR, FIR, and lowering logic for the syntax as well as new RCA checks to enforce the requirements for control flow structure and static integer limits.
Fixes #3274