Skip to content

Commit

Permalink
Bug fixes found during bash (#1916)
Browse files Browse the repository at this point in the history
- Qiskit dep version set in lock step with aqp
- output semantics can be configured on the backends needed for QIR
generation. Program type exported as well.
- Program type is separated from name of operation.
- Updating to use walrus operator to simplify logic (supported by Python
3.8+).
- Fixed doc comments
- Fixed Q# code generation for debugging
- RE now uses `compile_qasm_enriching_errors` so that entry points with
input vars are rejected.

---------

Co-authored-by: Stefan J. Wernli <[email protected]>
Co-authored-by: Mine Starks <[email protected]>
  • Loading branch information
3 people authored Sep 18, 2024
1 parent 7f6e302 commit 099da18
Show file tree
Hide file tree
Showing 22 changed files with 572 additions and 215 deletions.
2 changes: 1 addition & 1 deletion build.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,7 +514,7 @@ def run_ci_historic_benchmark():
"ipykernel",
"nbconvert",
"pandas",
"qiskit>=1.2.0,<1.3.0",
"qiskit>=1.2.0,<2.0.0",
]
subprocess.run(pip_install_args, check=True, text=True, cwd=root_dir, env=pip_env)

Expand Down
16 changes: 9 additions & 7 deletions compiler/qsc_qasm3/src/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ impl QasmCompiler {
self.prepend_runtime_decls();
let program_ty = self.config.program_ty.clone();
let (package, signature) = match program_ty {
ProgramType::File(name) => self.build_file(name),
ProgramType::Operation(name) => self.build_operation(name),
ProgramType::File => self.build_file(),
ProgramType::Operation => self.build_operation(),
ProgramType::Fragments => (self.build_fragments(), None),
};

Expand All @@ -156,11 +156,12 @@ impl QasmCompiler {

/// Build a package with namespace and an operation
/// containing the compiled statements.
fn build_file<S: AsRef<str>>(&mut self, name: S) -> (Package, Option<OperationSignature>) {
fn build_file(&mut self) -> (Package, Option<OperationSignature>) {
let tree = self.source.tree();
let whole_span = span_for_syntax_node(tree.syntax());
let (operation, mut signature) = self.create_entry_operation(name, whole_span);
let ns = "qasm3_import";
let operation_name = self.config.operation_name();
let (operation, mut signature) = self.create_entry_operation(operation_name, whole_span);
let ns = self.config.namespace();
signature.ns = Some(ns.to_string());
let top = build_top_level_ns_with_item(whole_span, ns, operation);
(
Expand All @@ -173,10 +174,11 @@ impl QasmCompiler {
}

/// Creates an operation with the given name.
fn build_operation<S: AsRef<str>>(&mut self, name: S) -> (Package, Option<OperationSignature>) {
fn build_operation(&mut self) -> (Package, Option<OperationSignature>) {
let tree = self.source.tree();
let whole_span = span_for_syntax_node(tree.syntax());
let (operation, signature) = self.create_entry_operation(name, whole_span);
let operation_name = self.config.operation_name();
let (operation, signature) = self.create_entry_operation(operation_name, whole_span);
(
Package {
nodes: Box::new([TopLevelNode::Stmt(Box::new(ast::Stmt {
Expand Down
42 changes: 30 additions & 12 deletions compiler/qsc_qasm3/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ mod types;
#[cfg(test)]
pub(crate) mod tests;

use std::fmt::Write;
use std::{fmt::Write, sync::Arc};

use miette::Diagnostic;
use qsc::Span;
Expand Down Expand Up @@ -393,6 +393,8 @@ pub struct CompilerConfig {
pub qubit_semantics: QubitSemantics,
pub output_semantics: OutputSemantics,
pub program_ty: ProgramType,
operation_name: Option<Arc<str>>,
namespace: Option<Arc<str>>,
}

impl CompilerConfig {
Expand All @@ -401,13 +403,29 @@ impl CompilerConfig {
qubit_semantics: QubitSemantics,
output_semantics: OutputSemantics,
program_ty: ProgramType,
operation_name: Option<Arc<str>>,
namespace: Option<Arc<str>>,
) -> Self {
Self {
qubit_semantics,
output_semantics,
program_ty,
operation_name,
namespace,
}
}

fn operation_name(&self) -> Arc<str> {
self.operation_name
.clone()
.unwrap_or_else(|| Arc::from("program"))
}

fn namespace(&self) -> Arc<str> {
self.namespace
.clone()
.unwrap_or_else(|| Arc::from("qasm3_import"))
}
}

impl Default for CompilerConfig {
Expand All @@ -416,27 +434,27 @@ impl Default for CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::Qiskit,
program_ty: ProgramType::Fragments,
operation_name: None,
namespace: None,
}
}
}

/// Represents the type of compilation out to create
/// Represents the type of compilation output to create
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ProgramType {
/// Creates an operation in a namespace as if the program is a standalone
/// file. The param is the name of the operation to create. Input are
/// lifted to the operation params. Output are lifted to the operation
/// return type. The operation is marked as `@EntryPoint` as long as there
/// are no input parameters.
File(String),
/// Creates an operation program is a standalone function. The param is the
/// name of the operation to create. Input are lifted to the operation
/// params. Output are lifted to the operation return type.
Operation(String),
/// file. Inputs are lifted to the operation params. Output are lifted to
/// the operation return type. The operation is marked as `@EntryPoint`
/// as long as there are no input parameters.
File,
/// Programs are compiled to a standalone function. Inputs are lifted to
/// the operation params. Output are lifted to the operation return type.
Operation,
/// Creates a list of statements from the program. This is useful for
/// interactive environments where the program is a list of statements
/// imported into the current scope.
/// This is also useful for testing indifidual statements compilation.
/// This is also useful for testing individual statements compilation.
Fragments,
}

Expand Down
68 changes: 40 additions & 28 deletions compiler/qsc_qasm3/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,13 @@ fn compile_qasm_to_qir(source: &str, profile: Profile) -> Result<String, Vec<Rep
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::Qiskit,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::Qiskit,
ProgramType::File,
Some("Test".into()),
None,
),
);
fail_on_compilation_errors(&unit);
let package = unit.package.expect("no package found");
Expand Down Expand Up @@ -150,11 +152,13 @@ pub fn qasm_to_program_fragments(source: QasmSource, source_map: SourceMap) -> Q
qasm_to_program(
source,
source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
program_ty: ProgramType::Fragments,
output_semantics: OutputSemantics::OpenQasm,
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::Fragments,
None,
None,
),
)
}

Expand All @@ -164,11 +168,13 @@ pub fn compile_qasm_to_qsharp_file(source: &str) -> miette::Result<String, Vec<R
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::OpenQasm,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::File,
Some("Test".into()),
None,
),
);
if unit.has_errors() {
let errors = unit.errors.into_iter().map(Report::new).collect();
Expand All @@ -187,11 +193,13 @@ pub fn compile_qasm_to_qsharp_operation(source: &str) -> miette::Result<String,
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::OpenQasm,
program_ty: ProgramType::Operation("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::Operation,
Some("Test".into()),
None,
),
);
if unit.has_errors() {
let errors = unit.errors.into_iter().map(Report::new).collect();
Expand All @@ -217,11 +225,13 @@ pub fn compile_qasm_to_qsharp_with_semantics(
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
CompilerConfig::new(
qubit_semantics,
output_semantics: OutputSemantics::Qiskit,
program_ty: ProgramType::Fragments,
},
OutputSemantics::Qiskit,
ProgramType::Fragments,
None,
None,
),
);
qsharp_from_qasm_compilation(unit)
}
Expand Down Expand Up @@ -251,11 +261,13 @@ pub fn compile_qasm_stmt_to_qsharp_with_semantics(
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
CompilerConfig::new(
qubit_semantics,
output_semantics: OutputSemantics::Qiskit,
program_ty: ProgramType::Fragments,
},
OutputSemantics::Qiskit,
ProgramType::Fragments,
None,
None,
),
);
if unit.has_errors() {
let errors = unit.errors.into_iter().map(Report::new).collect();
Expand Down
24 changes: 14 additions & 10 deletions compiler/qsc_qasm3/src/tests/declaration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,13 @@ fn duration_literal() -> miette::Result<(), Vec<Report>> {
let unit = crate::qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::OpenQasm,
program_ty: ProgramType::Fragments,
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::Fragments,
None,
None,
),
);
println!("{:?}", unit.errors);
assert!(unit.errors.len() == 5);
Expand Down Expand Up @@ -100,11 +102,13 @@ fn stretch() {
let unit = crate::compile::qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::OpenQasm,
program_ty: ProgramType::Fragments,
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::Fragments,
None,
None,
),
);
assert!(unit.has_errors());
println!("{:?}", unit.errors);
Expand Down
48 changes: 28 additions & 20 deletions compiler/qsc_qasm3/src/tests/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@ fn using_re_semantics_removes_output() -> miette::Result<(), Vec<Report>> {
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::ResourceEstimation,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::ResourceEstimation,
ProgramType::File,
Some("Test".into()),
None,
),
);
fail_on_compilation_errors(&unit);
let qsharp = gen_qsharp(&unit.package.expect("no package found"));
Expand Down Expand Up @@ -90,11 +92,13 @@ fn using_qasm_semantics_captures_all_classical_decls_as_output() -> miette::Resu
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::OpenQasm,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::File,
Some("Test".into()),
None,
),
);
fail_on_compilation_errors(&unit);
let qsharp = gen_qsharp(&unit.package.expect("no package found"));
Expand Down Expand Up @@ -144,11 +148,13 @@ fn using_qiskit_semantics_only_bit_array_is_captured_and_reversed(
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::Qiskit,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::Qiskit,
ProgramType::File,
Some("Test".into()),
None,
),
);
fail_on_compilation_errors(&unit);
let qsharp = gen_qsharp(&unit.package.expect("no package found"));
Expand Down Expand Up @@ -205,11 +211,13 @@ c2[2] = measure q[4];
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::Qiskit,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::Qiskit,
ProgramType::File,
Some("Test".into()),
None,
),
);
fail_on_compilation_errors(&unit);
let package = unit.package.expect("no package found");
Expand Down
12 changes: 7 additions & 5 deletions compiler/qsc_qasm3/src/tests/sample_circuits/bell_pair.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,13 @@ fn it_compiles() {
let unit = qasm_to_program(
res.source,
res.source_map,
CompilerConfig {
qubit_semantics: QubitSemantics::Qiskit,
output_semantics: OutputSemantics::OpenQasm,
program_ty: ProgramType::File("Test".to_string()),
},
CompilerConfig::new(
QubitSemantics::Qiskit,
OutputSemantics::OpenQasm,
ProgramType::File,
Some("Test".into()),
None,
),
);
print_compilation_errors(&unit);
assert!(!unit.has_errors());
Expand Down
Loading

0 comments on commit 099da18

Please sign in to comment.