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

[feature] AutoQASM: Free parameters #762

Merged
merged 10 commits into from
Oct 30, 2023

Conversation

laurencap
Copy link
Contributor

@laurencap laurencap commented Oct 26, 2023

Issue #, if available:
Part 1 of #757

Description of changes:

This allows statements such as rx(0, FreeParameter("theta")) in AutoQASM programs.

When converted to OpenQASM, the resulting program has an input statement, such as input float[32] theta;.

This PR will be followed by these additional works to complete the feature:

  1. Support expressions of parameters
  2. Support other types besides float
  3. Support free parameters in conditional statements
  4. Documentation -- when the feature is more complete

Testing done:
New test file!

Merge Checklist

Put an x in the boxes that apply. You can also fill these out after creating the PR. If you're unsure about any of them, don't hesitate to ask. We're here to help! This is simply a reminder of what we are going to look for before merging your pull request.

General

Tests

  • I have added tests that prove my fix is effective or that my feature works (if appropriate)
  • I have checked that my tests are not configured for a specific region or account (if appropriate)

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

@codecov
Copy link

codecov bot commented Oct 27, 2023

Codecov Report

All modified and coverable lines are covered by tests ✅

Comparison is base (a079c52) 100.00% compared to head (c4ae77a) 100.00%.
Report is 9 commits behind head on feature/autoqasm.

Additional details and impacted files
@@                Coverage Diff                 @@
##           feature/autoqasm      #762   +/-   ##
==================================================
  Coverage            100.00%   100.00%           
==================================================
  Files                   162       162           
  Lines                  9655      9653    -2     
  Branches               2077      2076    -1     
==================================================
- Hits                   9655      9653    -2     
Files Coverage Δ
src/braket/devices/local_simulator.py 100.00% <100.00%> (ø)
src/braket/experimental/autoqasm/api.py 100.00% <100.00%> (ø)
...braket/experimental/autoqasm/instructions/gates.py 100.00% <100.00%> (ø)
...experimental/autoqasm/instructions/instructions.py 100.00% <100.00%> (ø)
...rc/braket/experimental/autoqasm/program/program.py 100.00% <100.00%> (ø)

... and 3 files with indirect coverage changes

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@laurencap laurencap marked this pull request as ready for review October 28, 2023 16:56
@laurencap laurencap requested a review from a team as a code owner October 28, 2023 16:56
Copy link
Contributor

@rmshaffer rmshaffer left a comment

Choose a reason for hiding this comment

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

🎉

@@ -52,14 +55,14 @@ def cnot(
def cphaseshift(
control: QubitIdentifierType,
target: QubitIdentifierType,
angle: float,
angle: Union[float, FreeParameterExpression],
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if there is a good way to define an alias for this union type. Seems like user-defined gates should also technically be using this as a type hint, and we wouldn't want users to have to copy this. Does it make sense to have an AngleIdentifierType that we expose as aq.Angle (just like aq.Qubit for QubitIdentifierType)? Or is that too specific - are there other types that should be supported with this pattern too? Gates can only take angles, but in general input parameters to a program can be other types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's a good question. Aaron pointed out that we'll want to migrate from float to OpenQASM angles, because gates are not supposed to take floats.

It actually makes the code less clean to include the FreeParameterExpression -- there's a type check somewhere that gate parameters should only be floats, so we have to do extra work to ignore the FreeParameterExpression.

I feel like allowing the type hint to just hint at what the concrete value should eventually be is probably best in user code. The ParameterExpressions bit feels noisy and unproductive, even if it's true.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah I'm noticing now that gate_calibrations produce signatures with angle, so we should prioritize consistency using angles everywhere. I didn't realize they are already used in some places

Copy link
Contributor

Choose a reason for hiding this comment

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

Aaron pointed out that we'll want to migrate from float to OpenQASM angles, because gates are not supposed to take floats.

This is just a consideration for the IR we generate. Users will still certainly provide floats

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, gate definitions in OQ3 must use angle params, so we do use that for @aq.gate and @aq.gate_calibration. OQ3 allows implicitly casting float to angle, so technically everything else could use float and be fine, I think. But I also agree that if possible we should try to avoid exposing that to users, who just want to use float everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ah okay, wasn't aware of the implicit cast. That's good news

@laurencap laurencap merged commit eca82e6 into amazon-braket:feature/autoqasm Oct 30, 2023
22 checks passed
Comment on lines +33 to +36
@aq.main
def simple_parametric():
rx(0, FreeParameter("theta"))
measure(0)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a bit confused by this ux over something like

@aq.main
def simple_parametric(theta):
    rx(0, theta)
    measure(0)

It seems like ^ is simpler and gives users a spot to designate inputs as ints etc

Copy link
Contributor

Choose a reason for hiding this comment

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

I believe this already works with this implementation. User can then call either simple_parametric(pi/2) or simple_parametric(FreeParameter("theta")) depending on whether they want a fixed or parameterized program.

Comment on lines +54 to +55
measurements = _test_parametric_on_local_sim(simple_parametric(), {"theta": 3.14})
assert 0 not in measurements["__bit_0__"]
Copy link
Contributor

Choose a reason for hiding this comment

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

I didn't notice this on the first pass, but all of these tests which check measurement results after rotating by 3.14 are going to have some low probability of failure. Can you use pi instead?

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

Successfully merging this pull request may close these issues.

4 participants