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

Adding compiled QASM to the result #688

Merged
merged 7 commits into from
Aug 4, 2018

Conversation

delapuente
Copy link
Contributor

@delapuente delapuente commented Jul 26, 2018

Fix #671

Details and comments

Compiled QASM is part of the Qobj entity but it is required by the Result interface. This patch copies the QASM to the Result instance to make it available.

@delapuente delapuente added this to the 0.6 milestone Jul 26, 2018
@ajavadia
Copy link
Member

I think this is fine to temporarily make the get_ran_qasm() method work. But as I mentioned in the issue, the Compiled QASM should not remain part of the Qobj at all. This will happen when all devices and all simulators start executing pure JSON-format Qobj (and not QASM text anymore).

@delapuente delapuente force-pushed the issue-671-get_ran_qasm branch 3 times, most recently from 47553d9 to 23a3c1a Compare July 30, 2018 09:57
experiment_result['compiled_circuit_qasm'] = qasm


def _find_experiment_result(result, name):
Copy link
Member

Choose a reason for hiding this comment

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

Can you reeevaluate if this function is really needed? Seems we could avoid an extra function if it is made a one-liner with next(x for x in result['result'] if blah) (not really blocking anyway).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I try to avoid this kind of one-liners since they are, usually, harder to read. I can move it inside copy_qasm_from_qobj_into_result as an auxiliary function or a lambda variable, though.

Copy link
Member

Choose a reason for hiding this comment

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

I also dislike lots of small functions, but your choice.

if experiment_result['name'] == name:
return experiment_result

return None
Copy link
Member

Choose a reason for hiding this comment

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

This one I'm a bit more concerned about: is there really a case where it could really return None? If that is the case, line 427 would fail at:

experiment_result['compiled_circuit_qasm'] = qasm

Copy link
Contributor Author

@delapuente delapuente Jul 31, 2018

Choose a reason for hiding this comment

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

As far as I know, nope, it would expose an inconsistency between the Qobj and Result instances but the linter complained if I did not add a return value for this code-path. I can add a warning and avoid accessing it if None is returned. Does it make sense?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think explicitly taking care of the None case would be good.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm going to keep this as a private function. With the one-liner, I can not add the warning and by moving it inside the copy_qasm_from_qobj_into_result function, makes the function hard to read.

@@ -414,3 +414,22 @@ def get_qubitpol_vs_xval(self, nqubits, xvals_dict=None):
circuit_name, z_dicts[qubit_ind])

return qubitpol, xvals


def copy_qasm_from_qobj_into_result(qobj, result):
Copy link
Member

Choose a reason for hiding this comment

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

shouldn't this be a private method?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't think so. It is related to the Result type but it does not seem like an operation on the Result type. Ideally, it should be placed near the simulators which are the ones using it but I did not want to add a new file nor I was sure about where to add it.



def copy_qasm_from_qobj_into_result(qobj, result):
"""Find the several QASM belonging to the Qobj experiments and copy them
Copy link
Member

Choose a reason for hiding this comment

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

grammar nit: "Find the QASMs belonging to ..."

experiment_result['compiled_circuit_qasm'] = qasm


def _find_experiment_result(result, name):
Copy link
Member

Choose a reason for hiding this comment

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

I also dislike lots of small functions, but your choice.

if experiment_result['name'] == name:
return experiment_result

return None
Copy link
Member

Choose a reason for hiding this comment

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

Yeah I think explicitly taking care of the None case would be good.

self.circuit.ccx(q[0], q[1], q[2])
self.circuit.measure(q, c)

def test_local_execute_and_get_ran_qasm(self):
Copy link
Member

Choose a reason for hiding this comment

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

Why create a new test file? Can you include in the the already existing test_wrapper.py?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I did it because test_wrapper.py seems to be testing the functions related to register() and adding this functionality was somehow polluting the test case.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah but it should not just test register. As the name suggests, it should test the wrapper, which has several components (available_backends, register, execute).
Our test_wrapper.py needs to get more complete and this is a good addition to it.

@ajavadia
Copy link
Member

ajavadia commented Aug 2, 2018

@delapuente I see you modified the qasm_simulator files so they copy the qasm into result. Did you test that the devices and online simulators do the same thing?

@delapuente
Copy link
Contributor Author

Unfortunately, I was trying to test if remote backends return the QASM but they took too long (more than 20 min.)

@delapuente delapuente force-pushed the issue-671-get_ran_qasm branch from 7b48eab to 52f500a Compare August 2, 2018 16:50
@ajavadia
Copy link
Member

ajavadia commented Aug 2, 2018

The online simulator should be quick.
The device, yes, could take longer. But let's make sure they are all consistent before merging.

@delapuente
Copy link
Contributor Author

I can confirm get_ran_qasm() is working for the online simulator and devices. 🎉

@delapuente delapuente force-pushed the issue-671-get_ran_qasm branch from 52f500a to 64d2125 Compare August 3, 2018 09:23
@ajavadia
Copy link
Member

ajavadia commented Aug 4, 2018

Ok great. I added the qasm to the result generated by local_unitary_simulator too which seemed left out.

@ajavadia ajavadia merged commit cf06614 into Qiskit:master Aug 4, 2018
@delapuente delapuente deleted the issue-671-get_ran_qasm branch November 8, 2018 15:09
lia-approves pushed a commit to edasgupta/qiskit-terra that referenced this pull request Jul 30, 2019
* Adding the regression test

* Adding compiled QASM to the result

* Disable CPP backends if not available

* Avoid copying unexistent QASM code

* Moving `get_ran_qasm` test into the `test_wrapper.py` test suite.

* add qasm to the unitary simulator too
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