Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
66 commits
Select commit Hold shift + click to select a range
a75f584
Circuit Diagrams: Rendering of classically controlled circuits
minestarks Feb 11, 2026
9cd2afe
Circuits: Improved ascii art rendering for groups
minestarks Feb 10, 2026
1cdbffb
RIR debug metadata
minestarks Feb 12, 2026
4b20a59
Merge branch 'main' of https://github.com/microsoft/qdk into minestar…
minestarks Feb 12, 2026
a5c905d
Merge commit 'f85d4c26b07fd34f0c3d8d30f0a21e40cf238c2c' into minestar…
minestarks Feb 12, 2026
2de4556
Merge commit 'f85d4c26b07fd34f0c3d8d30f0a21e40cf238c2c' into minestar…
minestarks Feb 12, 2026
d4151a4
update snapshots
minestarks Feb 12, 2026
3ed5447
Show conditionals in circuits based on RIR debug metadata (all the ch…
minestarks Feb 12, 2026
48d9f1f
remove dead code
minestarks Feb 12, 2026
98e060b
minor cleanup
minestarks Feb 23, 2026
764be45
Merge branch 'minestarks/rir-debug-metadata' into minestarks/rir-and-…
minestarks Feb 23, 2026
f50692d
Merge remote-tracking branch 'origin/minestarks/circuit-ascii-groups'…
minestarks Feb 23, 2026
25b1c89
Merge remote-tracking branch 'origin/minestarks/circuit-ux-classical-…
minestarks Feb 23, 2026
648f0b3
Merge remote-tracking branch 'origin/main' into minestarks/rir-and-co…
minestarks Feb 23, 2026
8741792
more minor cleanup
minestarks Feb 23, 2026
c229dd0
Merge branch 'minestarks/rir-and-conditionals' into minestarks/rir-an…
minestarks Feb 23, 2026
bb06943
more minor cleanup
minestarks Feb 23, 2026
7a58da2
add config struct
minestarks Feb 24, 2026
ed3e77e
trim unused entries in dbg info
minestarks Feb 24, 2026
2d3a33a
fix lambda test
minestarks Feb 24, 2026
8e1be15
remove unnecessary instruction metadata
minestarks Feb 24, 2026
fd09aa3
add test for binary instruction short circuit
minestarks Feb 24, 2026
02ae948
Merge branch 'minestarks/rir-debug-metadata' into minestarks/rir-and-…
minestarks Feb 24, 2026
a53ad3a
Merge branch 'minestarks/rir-and-conditionals' into minestarks/rir-an…
minestarks Feb 24, 2026
d1a5fab
handle binary operation short circuit properly
minestarks Feb 24, 2026
d394569
Merge remote-tracking branch 'origin/main' into minestarks/rir-and-co…
minestarks Feb 24, 2026
dbbd242
Merge remote-tracking branch 'origin/main' into minestarks/rir-and-co…
minestarks Feb 24, 2026
8454083
Merge remote-tracking branch 'origin/main' into minestarks/rir-debug-…
minestarks Feb 24, 2026
a86d5ce
handle binary operation short circuit properly
minestarks Feb 24, 2026
15a5b43
helpful renames
minestarks Feb 24, 2026
2a688f8
Merge branch 'minestarks/rir-debug-metadata' into minestarks/rir-and-…
minestarks Feb 24, 2026
b28537a
Merge branch 'minestarks/rir-and-conditionals' into minestarks/rir-an…
minestarks Feb 24, 2026
9cf0e4c
revert unnecessary test edits
minestarks Feb 24, 2026
f4c7329
delete unnecessary comment
minestarks Feb 24, 2026
9b1e6c7
Merge branch 'main' of https://github.com/microsoft/qsharp into mines…
minestarks Feb 24, 2026
0dea4ae
remove dead test
minestarks Feb 24, 2026
129ea01
Merge branch 'main' of https://github.com/microsoft/qsharp into mines…
minestarks Feb 24, 2026
113a58b
remove metadata field from Instruction, instead put it on Call and Br…
minestarks Feb 24, 2026
f0f8077
formatting
minestarks Feb 24, 2026
c21be42
CR feedback and cleanup
minestarks Feb 25, 2026
02a9c63
Merge branch 'main' of https://github.com/microsoft/qdk into minestar…
minestarks Feb 25, 2026
db39c76
update snapshots
minestarks Feb 25, 2026
3400c11
Merge branch 'minestarks/circuit-ux-classical-control' into minestark…
minestarks Feb 25, 2026
aa4a499
Merge remote-tracking branch 'origin/minestarks/rir-debug-metadata' i…
minestarks Feb 25, 2026
d9e72dc
Merge branch 'minestarks/rir-and-conditionals-working' of https://git…
minestarks Feb 25, 2026
21d584a
Merge remote-tracking branch 'origin/main' into minestarks/rir-and-co…
minestarks Feb 25, 2026
f5745ed
fix build
minestarks Feb 25, 2026
b6bdf9b
code cleanup
Feb 25, 2026
d4074b5
review feedback
Feb 26, 2026
552e96e
Merge branch 'main' of https://github.com/microsoft/qsharp into mines…
Feb 26, 2026
357c0f1
Merge branch 'minestarks/circuit-ux-classical-control' into minestark…
Feb 26, 2026
8ab0333
Merge branch 'minestarks/rir-and-conditionals' into minestarks/rir-an…
Feb 26, 2026
901e796
fix build
Feb 26, 2026
bdeb3b9
Merge branch 'main' of https://github.com/microsoft/qsharp into mines…
Feb 26, 2026
d21ffad
add test case
Feb 26, 2026
e7e890e
fall back in vs code
Feb 26, 2026
42178a1
fix missing else
minestarks Feb 26, 2026
49b1249
Apply suggestion from @minestarks
minestarks Feb 26, 2026
7444b33
Merge branch 'minestarks/rir-and-conditionals-working' of https://git…
minestarks Feb 26, 2026
2d2e7ee
Update source/compiler/qsc_circuit/src/rir_to_circuit/control_flow.rs
minestarks Feb 27, 2026
2ea715e
Update source/compiler/qsc_circuit/src/rir_to_circuit/control_flow.rs
minestarks Feb 27, 2026
450c2dd
Update source/compiler/qsc_circuit/src/rir_to_circuit/control_flow.rs
minestarks Feb 27, 2026
d71963f
Update source/compiler/qsc_circuit/src/rir_to_circuit/control_flow.rs
minestarks Feb 27, 2026
a2d7026
delete dead code
Feb 27, 2026
b8adc1d
Merge branch 'minestarks/rir-and-conditionals-working' of https://git…
Feb 27, 2026
49063c0
formatting
Feb 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

130 changes: 125 additions & 5 deletions source/compiler/qsc/src/interpret.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.

#[cfg(test)]
mod circuit_classical_ctl_tests;
#[cfg(test)]
mod circuit_tests;
mod debug;
Expand All @@ -25,8 +27,9 @@ use num_complex::Complex;
use qsc_circuit::{
Circuit, CircuitTracer, TracerConfig,
operations::{entry_expr_for_qubit_operation, qubit_param_info},
rir_to_circuit::rir_to_circuit,
};
use qsc_codegen::qir::{fir_to_qir, fir_to_qir_from_callable};
use qsc_codegen::qir::{fir_to_qir, fir_to_qir_from_callable, fir_to_rir};
use qsc_data_structures::{
error::WithSource,
functors::FunctorApp,
Expand Down Expand Up @@ -68,7 +71,7 @@ use qsc_lowerer::{
map_fir_local_item_to_hir, map_fir_package_to_hir, map_hir_local_item_to_fir,
map_hir_package_to_fir,
};
use qsc_partial_eval::ProgramEntry;
use qsc_partial_eval::{PartialEvalConfig, ProgramEntry};
use qsc_passes::{PackageType, PassContext};
use qsc_rca::PackageStoreComputeProperties;
use rustc_hash::FxHashSet;
Expand Down Expand Up @@ -122,6 +125,8 @@ pub struct Interpreter {
compiler: Compiler,
/// The target capabilities used for compilation.
capabilities: TargetCapabilityFlags,
/// The computed properties for the package store, if any, used for code generation.
compute_properties: Option<PackageStoreComputeProperties>,
/// The number of lines that have so far been compiled.
/// This field is used to generate a unique label
/// for each line evaluated with `eval_fragments`.
Expand Down Expand Up @@ -331,8 +336,10 @@ impl Interpreter {
let package_id = compiler.package_id();

let package = map_hir_package_to_fir(package_id);
if capabilities != TargetCapabilityFlags::all() {
let _ = PassContext::run_fir_passes_on_fir(
let compute_properties = if capabilities == TargetCapabilityFlags::all() {
None
} else {
let compute_properties = PassContext::run_fir_passes_on_fir(
&fir_store,
map_hir_package_to_fir(source_package_id),
capabilities,
Expand All @@ -348,12 +355,15 @@ impl Interpreter {
.map(|error| Error::Pass(WithSource::from_map(&source_package.sources, error)))
.collect::<Vec<_>>()
})?;
}

Some(compute_properties)
};

Ok(Self {
compiler,
lines: 0,
capabilities,
compute_properties,
fir_store,
lowerer: qsc_lowerer::Lowerer::new(),
expr_graph: None,
Expand Down Expand Up @@ -1041,11 +1051,118 @@ impl Interpreter {
)?;
}
}
CircuitGenerationMethod::Static => {
if let Some((callable, args)) = invoke_params {
// Static circuit generation from a callable is not yet supported.
// Fall back to classical eval.
self.invoke_with_tracing_backend(
&mut TracingBackend::<SparseSim>::no_backend(&mut tracer),
&mut out,
callable,
args,
eval_config,
)?;
} else {
return self.static_circuit(entry_expr.as_deref(), tracer_config);
}
}
}
let circuit = tracer.finish(&(self.compiler.package_store(), &self.fir_store));
Ok(circuit)
}

fn static_circuit(
&mut self,
entry_expr: Option<&str>,
tracer_config: TracerConfig,
) -> std::result::Result<Circuit, Vec<Error>> {
if self.capabilities == TargetCapabilityFlags::all() {
return Err(vec![Error::UnsupportedRuntimeCapabilities]);
}

let program = self.compile_to_rir_with_debug_metadata(entry_expr)?;
rir_to_circuit(
&program,
tracer_config,
&[self.package, self.source_package],
&(self.compiler.package_store(), &self.fir_store),
)
.map_err(|e| vec![e.into()])
}

fn compile_to_rir_with_debug_metadata(
&mut self,
entry_expr: Option<&str>,
) -> std::result::Result<qsc_partial_eval::Program, Vec<Error>> {
let (entry, compute_properties) = if let Some(entry_expr) = &entry_expr {
// Compile the expression. This operation will set the expression as
// the entry-point in the FIR store.
let (graph, compute_properties) = self.compile_entry_expr(entry_expr)?;

let Some(compute_properties) = compute_properties else {
// This can only happen if capability analysis was not run.
panic!(
"internal error: compute properties not set after lowering entry expression"
);
};
let package = self.fir_store.get(self.package);
let entry = ProgramEntry {
exec_graph: graph,
expr: (
self.package,
package
.entry
.expect("package must have an entry expression"),
)
.into(),
};
(entry, compute_properties)
} else {
let package = self.fir_store.get(self.source_package);
let entry = ProgramEntry {
exec_graph: package.entry_exec_graph.clone(),
expr: (
self.source_package,
package
.entry
.expect("package must have an entry expression"),
)
.into(),
};
(
entry,
self.compute_properties.clone().expect(
"compute properties should be set if target profile isn't unrestricted",
),
)
};
let (_original, transformed) = fir_to_rir(
&self.fir_store,
self.capabilities,
Some(compute_properties),
&entry,
PartialEvalConfig {
generate_debug_metadata: true,
},
)
.map_err(|e| {
let hir_package_id = match e.span() {
Some(span) => span.package,
None => map_fir_package_to_hir(self.package),
};
let source_package = self
.compiler
.package_store()
.get(hir_package_id)
.expect("package should exist in the package store");
vec![Error::PartialEvaluation(WithSource::from_map(
&source_package.sources,
e,
))]
})?;
Ok(transformed)
}

/// Sets the entry expression for the interpreter.
pub fn set_entry_expr(&mut self, entry_expr: &str) -> std::result::Result<(), Vec<Error>> {
let (graph, _) = self.compile_entry_expr(entry_expr)?;
Expand Down Expand Up @@ -1309,6 +1426,9 @@ pub enum CircuitGenerationMethod {
/// Evaluate the classical parts of the program. No quantum simulation.
/// Will fail if a measurement comparison occurs during evaluation.
ClassicalEval,
/// Compile the program and transform to a circuit with only partial evaluation.
/// Only works for `AdaptiveRIF` compliant programs.
Static,
}

/// A debugger that enables step-by-step evaluation of code
Expand Down
Loading
Loading