Implement RGate in Rust#12662
Conversation
|
One or more of the following people are relevant to this code:
|
Pull Request Test Coverage Report for Build 9673800273Details
💛 - Coveralls |
ElePT
left a comment
There was a problem hiding this comment.
Thanks for the PR! it looks pretty good, I just left a couple of comments.
| from qiskit.circuit.library.standard_gates import get_standard_gate_name_mapping | ||
|
|
||
| SKIP_LIST = {"rx", "ry", "ecr"} | ||
| SKIP_LIST = {"rx", "ry", "ecr", "r"} |
There was a problem hiding this comment.
Why add the r gate to the SKIP_LIST? All others haven't been implemented yet, but r has an implementation.
There was a problem hiding this comment.
Good question. I added and removed several times while debugging. I'll recheck.
There was a problem hiding this comment.
Fixed in 7eef0f3 (#12662). It failed because the decomposition had an error.
| let theta_expr = match ¶ms[0] { | ||
| Param::Float(theta) => Param::Float(*theta), | ||
| Param::ParameterExpression(theta) => { | ||
| Param::ParameterExpression(theta.clone_ref(py)) | ||
| } | ||
| Param::Obj(_) => unreachable!(), | ||
| }; | ||
| let (phi_expr1, phi_expr2) = match ¶ms[0] { | ||
| Param::Float(phi) => (Param::Float(*phi - 1.0), Param::Float(-*phi + 1.0)), | ||
| Param::ParameterExpression(phi) => { | ||
| let phiexpr1 = phi | ||
| .call_method1(py, intern!(py, "__add__"), ((-PI / 2.0),)) | ||
| .expect("Unexpected Qiskit python bug"); | ||
| let phiexpr2 = phiexpr1 | ||
| .call_method1(py, intern!(py, "__rmul__"), (-1.0,)) | ||
| .expect("Unexpected Qiskit python bug"); | ||
| ( | ||
| Param::ParameterExpression(phiexpr1), | ||
| Param::ParameterExpression(phiexpr2), | ||
| ) | ||
| } | ||
| Param::Obj(_) => unreachable!(), | ||
| }; | ||
| let defparams = smallvec![theta_expr, phi_expr1, phi_expr2]; | ||
| Some( | ||
| CircuitData::from_standard_gates( | ||
| py, | ||
| 1, | ||
| [(Self::UGate, defparams, smallvec![Qubit(0)])], | ||
| FLOAT_ZERO, | ||
| ) | ||
| .expect("Unexpected Qiskit python bug"), | ||
| ) | ||
| }), |
There was a problem hiding this comment.
I think this could be more readable if we used helper functions like multiply_param, and maybe add one for adding a scalar to a parameter in the same fashion. But I am fine merging the implementation as-is and beautifying it later.
There was a problem hiding this comment.
My first iteration did not fit with the helper function, nor one for add. But it's changed a lot since I last tried. I'll revisit it; readability and encapsulation is important.
There was a problem hiding this comment.
I did something similar to your suggest in 49c8dcd (#12662). This factors out cloning a Param. This is only used once now, but can be used whenever a Param needs to be cloned. I find the code much more readable at the call point.
Regarding factoring out add_param: There are pros and cons to doing this. Disadvantages: The branch with -*phi + PI / 2.0 is more readable if it is not nested calls. In fact, this made it slightly easier for me to spot the error -*phi + 1.0.
Another one is that it requires two match statements rather than one, so -*phi + PI / 2.0 won't be optimized. I'm not sure, but I doubt this will matter in the future for performance.
But, I'm on the fence. Currently, the second match arm would be much more readable with your suggestion. I can implement and use add_param quickly if you prefer. I'm inclined to do it just to look at it.
There was a problem hiding this comment.
Implemented your suggestion in 07fec37 (#12662). I'm not 100% sure there isn't a non-negligible efficiency hit. But I think it's easier to read and will be easier to build on.
There was a problem hiding this comment.
I see your point, I think we could merge the code as-is and once all Rust standard gates are in place, maybe run the benchmarks with/without add_param to see if there is indeed a significant performance hit.
Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
Pull Request Test Coverage Report for Build 9681898421Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
There is an error in the expression for decomposition of the R gate in the port to Rust. This fixes the error and re-enables the skipped test that failed because of the incorrect expression.
To clone the enum, each variant must be handled separately. This is currently used once, but can be used each time a `Param` is cloned. In case more work needs to be done within match arms, one might choose not to use this function, but rather clone in each of these arms.
This handles `Float` and `ParameterExpression` variants uniformly.
Pull Request Test Coverage Report for Build 9688190770Details
💛 - Coveralls |
* Implement RGate in Rust * Update crates/circuit/src/operations.rs Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com> * Fix error in decomposition of RGate There is an error in the expression for decomposition of the R gate in the port to Rust. This fixes the error and re-enables the skipped test that failed because of the incorrect expression. * Factor cloning the Param enum in Rust To clone the enum, each variant must be handled separately. This is currently used once, but can be used each time a `Param` is cloned. In case more work needs to be done within match arms, one might choose not to use this function, but rather clone in each of these arms. * Run cargo fmt * Implement and use addition for enum Param This handles `Float` and `ParameterExpression` variants uniformly. --------- Co-authored-by: Elena Peña Tapia <57907331+ElePT@users.noreply.github.com>
This completes all tasks of implementing
RGatein Rust rather than Python.This replaces
#12507 has been modified and split into the present PR and #12651