Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support further Python Interop for callables in Estimation and QIR Compilation #2091

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

swernli
Copy link
Collaborator

@swernli swernli commented Jan 6, 2025

This follows up on #2054 by adding the enhanced support for Q# callables exposed into Python and Python argument arrays in resource estimation and QIR compilation.

…mpilation

This follows up on #2054 by adding the enhanced support for Q# callables exposed into Python and Python argument arrays in resource estimation and QIR compilation.
Comment on lines +318 to +338
qsharp.eval("operation Program() : Result { use q = Qubit(); return MResetZ(q); }")
operation = qsharp.compile("Program()")
qir = str(operation)
assert "define void @ENTRYPOINT__main()" in qir
assert '"required_num_qubits"="1" "required_num_results"="1"' in qir


def test_compile_qir_str_from_python_callable() -> None:
qsharp.init(target_profile=qsharp.TargetProfile.Base)
qsharp.eval("operation Program() : Result { use q = Qubit(); return MResetZ(q); }")
operation = qsharp.compile(qsharp.code.Program)
qir = str(operation)
assert "define void @ENTRYPOINT__main()" in qir
assert '"required_num_qubits"="1" "required_num_results"="1"' in qir


def test_compile_qir_str_from_python_callable_with_single_arg() -> None:
qsharp.init(target_profile=qsharp.TargetProfile.Base)
qsharp.eval(
"operation Program(nQubits : Int) : Result[] { use qs = Qubit[nQubits]; MResetEachZ(qs) }"
)

Check notice

Code scanning / devskim

If untrusted data (data from HTTP requests, user submitted files, etc.) is included in an eval statement it can allow an attacker to inject their own code. Note test

Review eval for untrusted data
Comment on lines +351 to +353
qsharp.eval(
"operation Program(nQubits : Int[]) : Result[] { use qs = Qubit[nQubits[1]]; MResetEachZ(qs) }"
)

Check notice

Code scanning / devskim

If untrusted data (data from HTTP requests, user submitted files, etc.) is included in an eval statement it can allow an attacker to inject their own code. Note test

Review eval for untrusted data
Comment on lines +188 to +198
qsharp.eval(
"""
operation Test() : Unit {
use qs = Qubit[10];
for q in qs {
T(q);
M(q);
}
}
"""
)

Check notice

Code scanning / devskim

If untrusted data (data from HTTP requests, user submitted files, etc.) is included in an eval statement it can allow an attacker to inject their own code. Note test

Review eval for untrusted data
Comment on lines +252 to +262
qsharp.eval(
"""
operation Test(nQubits : Int) : Unit {
use qs = Qubit[nQubits];
for q in qs {
T(q);
M(q);
}
}
"""
)

Check notice

Code scanning / devskim

If untrusted data (data from HTTP requests, user submitted files, etc.) is included in an eval statement it can allow an attacker to inject their own code. Note test

Review eval for untrusted data
pub fn fir_to_qir(
fir_store: &qsc_fir::fir::PackageStore,
capabilities: TargetCapabilityFlags,
compute_properties: Option<PackageStoreComputeProperties>,
entry: &ProgramEntry,
) -> Result<String, qsc_partial_eval::Error> {
let mut program = get_rir_from_compilation(fir_store, compute_properties, entry, capabilities)?;
let compute_properties = compute_properties;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, this looks like it got left behind from an earlier experiment.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about the third sibling, .run() ? I think it would make sense to allow that to take a callable, as well.

And of course, there's .circuit(), which can already take a callable, but uses a different pattern... which is unfortunate, because this new pattern is better. I wouldn't be opposed to updating .circuit() to allow the new pattern as well, but I understand if you don't want to touch it in this PR.

Comment on lines 196 to +208
program,
entry,
entry: Some(entry),
}
}

fn new_from_package_id(
package_store: &'a PackageStore,
compute_properties: &'a PackageStoreComputeProperties,
package_id: PackageId,
capabilities: TargetCapabilityFlags,
) -> Self {
// Create the entry-point callable.
let mut resource_manager = ResourceManager::default();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: refactor new_* methods to use shared private fn.

@@ -639,6 +639,43 @@ impl Interpreter {
})
}

pub fn qirgen_from_callable(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a doc comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants