-
Notifications
You must be signed in to change notification settings - Fork 15
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
Separate channels from natives #983
Separate channels from natives #983
Conversation
@stavros11 I had to touch again the compiler, because the I now have a dedicated call for qibolab/src/qibolab/compilers/compiler.py Lines 123 to 129 in 7f8e47f
this is because they are creating the sequence on the fly qibolab/src/qibolab/compilers/default.py Lines 16 to 23 in 7f8e47f
But I wonder whether it's worth to treat them as the RX , just hard-coding the sequence pulse (it could be a (ch, null) in the JSON, and then load it only to receive the channel name).
It's true that in principle we may infer the channel, giving the qubit name and its role. But this is true in general, i.e. we can replace |
qibolab/src/qibolab/compilers/compiler.py Lines 63 to 98 in 7f8e47f
All this interface (but Not in this PR, but it's worth an issue (at least concerning tests). |
In 1c8c52e I introduced a container, alternative to the plain In this case, I tried to wrap a |
d56bc17
to
9ac2d23
Compare
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## serialization-interface #983 +/- ##
===========================================================
- Coverage 41.63% 41.59% -0.04%
===========================================================
Files 79 79
Lines 5421 5421
===========================================================
- Hits 2257 2255 -2
- Misses 3164 3166 +2
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
a072cd5
to
83a6679
Compare
9ac2d23
to
f9d4daf
Compare
And fully deprecate the qubit pair object
And also platform creation, which is actually untested, though running
Best effort, cf. #984
f9d4daf
to
2171caa
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @alecandido. Other than the native_gates
property which could be easily implemented here and I believe would improve the quality of life of qibocal developers, we can probably merge this. My other concerns are in the comments below, but are not strictly necessary to fix in this PR.
qibolab/src/qibolab/compilers/compiler.py
Lines 63 to 98 in 7f8e47f
def __setitem__(self, key: type[gates.Gate], rule: Callable): """Set a new rule to the compiler. If a rule already exists for the gate, it will be overwritten. """ self.rules[key] = rule def __getitem__(self, item: type[gates.Gate]) -> Callable: """Get an existing rule for a given gate.""" try: return self.rules[item] except KeyError: raise KeyError(f"Compiler rule not available for {item}.") def __delitem__(self, item: type[gates.Gate]): """Remove rule for the given gate.""" try: del self.rules[item] except KeyError: KeyError(f"Cannot remove {item} from compiler because it does not exist.") def register(self, gate_cls): """Decorator for registering a function as a rule in the compiler. Using this decorator is optional. Alternatively the user can set the rules directly via ``__setitem__``. Args: gate_cls: Qibo gate object that the rule will be assigned to. """ def inner(func): self[gate_cls] = func return func return inner All this interface (but
__getitem__
) is never used and never tested. We should that (testing), and maybe even mention in the docs.Not in this PR, but it's worth an issue (at least concerning tests).
The idea was to allow the users to alter the compiler by adding more rules or modifying existing ones. However, dropping this interface is also an option. Modifications are still allowed on compiler.rules
through Python's dict
interface anyway, so it is not super useful to reinvent it here.
if isinstance(gate, (gates.M)): | ||
qubits = [ | ||
natives.single_qubit[platform.get_qubit(q).name] for q in gate.qubits | ||
] | ||
return rule(gate, qubits) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully like all these if
s as it's a bit against of the idea of having the dict of rules (which can also be modified by user) and delegate as much possible to that. However, I have not spend time to thought in detail for a better mechanism so I don't want to just complain without providing any alternatives. Maybe a simple one, without thinking much, would be to pass the whole platform
to each rule, as it was before.
If you also don't fully like it, maybe we could open an issue and try to improve in the future. I am not sure if it's for 0.2 as the compiler is not the usual user interfacing kind, but could also be thought as interface for another kind of users.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't fully like all these
if
s as it's a bit against of the idea of having the dict of rules (which can also be modified by user) and delegate as much possible to that. However, I have not spend time to thought in detail for a better mechanism so I don't want to just complain without providing any alternatives. Maybe a simple one, without thinking much, would be to pass the wholeplatform
to each rule, as it was before.
I'm not fully convinced, but I also don't fully like the idea of passing everything down below.
This is truly the trade-off I arrived, in which I'm essentially dividing in 2+ categories: single-qubit, two-qubit, special handling.
Since the special is a catch-all category, maybe it's worth to just pass everything down just in this case.
For the other two categories, it should be pretty clear what to do. But unfortunately you can isolate them only if you remove the special ones before, since M
and Align
may also apply to one and two qubits. Maybe we could have a list of those that should be treated as special, and expose it to the user for extensions.
If you also don't fully like it, maybe we could open an issue and try to improve in the future. I am not sure if it's for 0.2 as the compiler is not the usual user interfacing kind, but could also be thought as interface for another kind of users.
In principle, the compiler is only used by the user for extensions. Since we do not believe that extensions are immediately needed, we could keep it private, and publish only at a later stage.
@@ -50,6 +54,38 @@ def fill(self, options: ExecutionParameters): | |||
return options | |||
|
|||
|
|||
class TwoQubitContainer(dict[QubitPairId, TwoQubitNatives]): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class looks like a lot of code overhead, that is also quite obscure for someone without experience with pydantic, just to handle the pairs of symmetric two-qubit gates, but at this stage I trust that there was no simpler solution.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This class looks like a lot of code overhead, that is also quite obscure for someone without experience with pydantic, just to handle the pairs of symmetric two-qubit gates, but at this stage I trust that there was no simpler solution.
Yes, I also don't like it. And I even tried the alternative, as written above #983 (comment)
I hoped Pydantic had a better interface for subclassing builtins, but that's the easiest. Already importing pydantic_core
is a bit of failure from the point of view of maintainability (it's truly their qibo_core
, btw Pydantic people are those maintaining PyO3, the framework we're also using for qibo_core
).
But that's truly the easiest way I found 😞
I'm undecided here: on the one side is not that bad, but mostly because I don't expect people to play much with the compiler, for the time being. In which case it would be just unused (as it is). Instead, the moment people would start using that, maybe the full dictionary API might become handy, so we should encourage accessing the attribute. So, maybe it's really the case of dropping it. But I'd keep |
Done in d9a210f |
I don't have a clear solution for the other two conversations in this PR, so I'll do nothing. For me, they are both a bit unsatisfactory, but also not critical. Thus, I will not open issues. |
Closes #982