[unitaryHACK] Strawberry Fields: Gaussian Merge#591
[unitaryHACK] Strawberry Fields: Gaussian Merge#591nquesada merged 40 commits intoXanaduAI:masterfrom
Conversation
|
Hi @federico0112 : as a first suggestion, I'd like to ask you to start looking into the |
|
@federico0112 : it looks like you are almost there in terms of linting. You only need two three more docstrings and a whitespace issue. |
Codecov Report
@@ Coverage Diff @@
## master #591 +/- ##
==========================================
+ Coverage 98.42% 98.44% +0.02%
==========================================
Files 75 76 +1
Lines 8608 8752 +144
==========================================
+ Hits 8472 8616 +144
Misses 136 136
Continue to review full report at Codecov.
|
|
@federico0112 : can you pass
|
|
@federico0112 : for what I can see you have not added new tests. A trivial tests this compiler should have is that it should pass all the tests the Gaussian compiler passes. Then you should create a new test file in |
|
Can this test be the one you gave me? Would that be enough or do I need more test cases |
|
That is a potential test, but more are needed. For those I suggest you for example try to compile the program showed in the issue [#574]. Keep in mind that you will want to use small parameters for all the gates that generate photons so that you don't need gigantic photon number cutoff. Moreover, you will want to modify tests for @pytest.mark.parametrize("depth", [1, 3, 6])
@pytest.mark.parametrize("width", [5, 10, 15])
@pytest.mark.parametrize("compiler", ["gaussian_unitary", "gaussian_merge"])
def test_gaussian_program(depth, width, compiler):
"""Tests that a circuit and its compiled version produce the same Gaussian state"""
eng = sf.LocalEngine(backend="gaussian")
eng1 = sf.LocalEngine(backend="gaussian")
circuit = sf.Program(width)
with circuit.context as q:
for _ in range(depth):
U, s, V, alphas = random_params(width, 2.0 / depth, 1.0)
ops.Interferometer(U) | q
for i in range(width):
ops.Sgate(s[i]) | q[i]
ops.Interferometer(V) | q
for i in range(width):
ops.Dgate(np.abs(alphas[i]), np.angle(alphas[i])) | q[i]
compiled_circuit = circuit.compile(compiler=compiler)
cv = eng.run(circuit).state.cov()
mean = eng.run(circuit).state.means()
cv1 = eng1.run(compiled_circuit).state.cov()
mean1 = eng1.run(compiled_circuit).state.means()
assert np.allclose(cv, cv1)
assert np.allclose(mean, mean1) |
|
Ah I see, thats interesting I've never done test coverage in Python. Ill work on getting the test coverage up. Is this required for the bounty? I am going to be busy all tonight and I don't know if I'll be able to finish it by midnight tonight. It's okay if it is required, just curious. |
josh146
left a comment
There was a problem hiding this comment.
Thanks @federico0112 for this great contribution 💯
I've left a couple of preliminary comments, in particular, don't forget to run black on the new and modified files as @nquesada mentions!
black -l 100 strawberryfields/compilers/__init__.py
black -l 100 strawberryfields/compilers/gaussian_merge.py
Is this required for the bounty? I am going to be busy all tonight and I don't know if I'll be able to finish it by midnight tonight. It's okay if it is required, just curious.
The requirement for the bounty is that the PR passes code review and is merged in --- this requires passing our coverage checks as well :)
| "BSgate", | ||
| "CKgate", | ||
| "S2gate", | ||
| } |
There was a problem hiding this comment.
I'm curious if it makes sense to include GaussianTransformation as a primitive? That way, it will avoid the GaussianTransformation from being needlessly decomposed and 're-merged'.
It might also make sense to include all decompositions here, with the exception of the Graph ones.
There was a problem hiding this comment.
Agreed not sure why I haven't added it
| gaussian_transform, successors, displacement_mapping | ||
| ) | ||
|
|
||
| # Add edges for all successor/predecessor operations of the merged operations |
There was a problem hiding this comment.
Great commenting throughout this method @federico0112!
| return True | ||
| return False | ||
|
|
||
| def recursive_d_gate_successors(self, gate): |
There was a problem hiding this comment.
Out of curiosity, how come the Dgate is merged separately compared to the GaussianTransform?
There was a problem hiding this comment.
The displacement gates never get actually merged into the gaussian transform, cause thats what Gaussian Unitary does. So I had to add logic to handle them. I put the after the gaussian transform and add edges to the successive operations that were not merged. Most of what made the code more complicated was trying to deal with displacement gates.
Co-authored-by: Josh Izaac <josh146@gmail.com> Co-authored-by: Nicolas Quesada <nicolas@xanadu.ai>
|
HI @federico0112 : Great progress so far. There are still a few lines of It seems like most of them are related to displacements. |
|
I made a change to the unit test. It should increase the code coverage |
|
Hi @federico0112 : there still some part of the compiler not covered by the tests (https://app.codecov.io/gh/XanaduAI/strawberryfields/compare/591/diff#diff-c3RyYXdiZXJyeWZpZWxkcy9jb21waWxlcnMvZ2F1c3NpYW5fbWVyZ2UucHk=). You might need to design some specific tests to cover those edge cases. |
|
I just realized that I left out a function that was not being used anymore (figured out a better way to achieve the same thing). Thats why it wasn't covered by the unit tests. |
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: Josh Izaac <josh146@gmail.com>
Co-authored-by: antalszava <antalszava@gmail.com>
| - For each operation (op) check and obtain Gaussian operations that can be merged | ||
| (get_valid_gaussian_merge_ops). | ||
| - If the operation has successor gaussian operations that can be merged, | ||
| then merge them using gaussian_unitary.py. | ||
| - Determine displacement gates, from gaussian unitary merge, and map them to the qumodes acted upon | ||
| (add_displacement_gates). | ||
| - Attach predecessor operations of the main operation (op) to new Gaussian transform operations. | ||
| - Attach successor non Gaussian operations of op to a displacement gate, if present, | ||
| or a gaussian transform operation from the merged operations (add_non_gaussian_successor_gates). | ||
| - Attach all non-merged predecessor and successor of the merged operations to the new gaussian | ||
| transform and displacement gates (add_gaussian_pre_and_succ_gates). | ||
| - Remove nodes of operations that were merged in and convert DAG to sequence. |
There was a problem hiding this comment.
| - For each operation (op) check and obtain Gaussian operations that can be merged | |
| (get_valid_gaussian_merge_ops). | |
| - If the operation has successor gaussian operations that can be merged, | |
| then merge them using gaussian_unitary.py. | |
| - Determine displacement gates, from gaussian unitary merge, and map them to the qumodes acted upon | |
| (add_displacement_gates). | |
| - Attach predecessor operations of the main operation (op) to new Gaussian transform operations. | |
| - Attach successor non Gaussian operations of op to a displacement gate, if present, | |
| or a gaussian transform operation from the merged operations (add_non_gaussian_successor_gates). | |
| - Attach all non-merged predecessor and successor of the merged operations to the new gaussian | |
| transform and displacement gates (add_gaussian_pre_and_succ_gates). | |
| - Remove nodes of operations that were merged in and convert DAG to sequence. | |
| - For each operation (op) check and obtain Gaussian operations that can be merged (get_valid_gaussian_merge_ops). | |
| - If the operation has successor gaussian operations that can be merged, then merge them using gaussian_unitary.py. | |
| - Determine displacement gates, from gaussian unitary merge, and map them to the qumodes acted upon (add_displacement_gates). | |
| - Attach predecessor operations of the main operation (op) to new Gaussian transform operations. | |
| - Attach successor non Gaussian operations of op to a displacement gate, if present, or a gaussian transform operation from the merged operations (add_non_gaussian_successor_gates). | |
| - Attach all non-merged predecessor and successor of the merged operations to the new gaussian | |
| transform and displacement gates (add_gaussian_pre_and_succ_gates). | |
| - Remove nodes of operations that were merged in and convert DAG to sequence. |
| # measurements | ||
| "MeasureFock", | ||
| "MeasureHomodyne", |
There was a problem hiding this comment.
I think it is a bad idea to leave measurement here for the time being.
Co-authored-by: Nicolas Quesada <nicolas@xanadu.ai>
Co-authored-by: Nicolas Quesada <nicolas@xanadu.ai>
Co-authored-by: Nicolas Quesada <nicolas@xanadu.ai>
Co-authored-by: Josh Izaac <josh146@gmail.com>
|
This is a fantastic addition to Strawberry Fields, thanks for all the hard work @federico0112 . |
|
Dear @crazy4pi314 --- The fantastic addition by @federico0112 is now merged into SF. It was a lot of fun being part of the unitaryhack this year. Looking forward to the next one! |
Adds hybrid Gaussian Merge compiler that merges gaussian operations into Gaussian Tranform operations in a program with non-Gaussian and Gaussian operations.
Before submitting
Please complete the following checklist when submitting a PR:
All new features must include a unit test.
If you've fixed a bug or added code that should be tested, add a test to the
test directory!
All new functions and code must be clearly commented and documented.
If you do make documentation changes, make sure that the docs build and
render correctly by running
make docs.Ensure that the test suite passes, by running
make test.Ensure that code is properly formatted, by running
make formatorblack -l 100 strawberryfields. You will need to have the Black code format installed:pip install black.Add a new entry to the
.github/CHANGELOG.mdfile, summarizing thechange, and including a link back to the PR.
The Strawberry Fields source code conforms to
PEP8 standards.
We check all of our code against Pylint.
To lint modified files, simply
pip install pylint, and thenrun
pylint strawberryfields/path/to/file.py.When all the above are checked, delete everything above the dashed
line and fill in the pull request template.
Context: #574
Description of the Change: Adds hybrid Gaussian Merge compiler that merges gaussian operations into Gaussian Tranform operations in a program with non-Gaussian and Gaussian operations.
Benefits: Can potantially reduce calculation overhead by reducing the number of gaussian operations in a circuit
Possible Drawbacks: Circuits with displacement and squeezing gates require precise cutoff values, determining the correct cutoff and displacement/squeezing parameters has to be done manually.
Related GitHub Issues: #574