Skip to content

Conversation

@rares1609
Copy link
Contributor

No description provided.

@rares1609 rares1609 requested a review from elenbaasc January 16, 2026 14:11
Copy link
Collaborator

@elenbaasc elenbaasc left a comment

Choose a reason for hiding this comment

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

Thanks for the effort! It seems it was a bit more work that I had anticipated :)

Mostly minor comments. Mainly in regards to the implementation of the map method where you default to using numpy arrays, when simple objects would suffice or are expected in the end anyway, e.g. creating a numpy array and at the end converting it to a list.

Comment on lines +35 to +36
if self.data != other.data:
return False
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is redundant if you follow it with return self.data == other.data

Suggested change
if self.data != other.data:
return False

@@ -1,7 +1,8 @@
# OpenQL MIP-Like Mapper
# OpenQL MIP-Like Mapper. This mapper pass takes inspiration from:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is based on?

"... takes inspiration from" is a bit vague.

self, ir: IR, distance: list[list[int]], num_virtual_qubits: int, num_physical_qubits: int
) -> list[list[int]]:
def _get_reference_counter(self, ir: IR, num_virtual_qubits: int) -> list[list[int]]:
reference_counter = [[0 for _ in range(num_virtual_qubits)] for _ in range(num_virtual_qubits)]
Copy link
Collaborator

Choose a reason for hiding this comment

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

Why does the following replacement not work in this case? (it seems to do the same thing, but when I run the tests they fail..., which is a bit dodgy.)

Suggested change
reference_counter = [[0 for _ in range(num_virtual_qubits)] for _ in range(num_virtual_qubits)]
reference_counter = [[0] * num_virtual_qubits] * num_virtual_qubits

def _get_cost(
self, ir: IR, distance: list[list[int]], num_virtual_qubits: int, num_physical_qubits: int
) -> list[list[int]]:
def _get_reference_counter(self, ir: IR, num_virtual_qubits: int) -> list[list[int]]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

This is a static method:

Suggested change
def _get_reference_counter(self, ir: IR, num_virtual_qubits: int) -> list[list[int]]:
@staticmethod
def _get_reference_counter(ir: IR, num_virtual_qubits: int) -> list[list[int]]:

) -> list[list[int]]:
def _get_reference_counter(self, ir: IR, num_virtual_qubits: int) -> list[list[int]]:
reference_counter = [[0 for _ in range(num_virtual_qubits)] for _ in range(num_virtual_qubits)]
for statement in getattr(ir, "statements", []):
Copy link
Collaborator

Choose a reason for hiding this comment

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

The following should be fine, right?

Suggested change
for statement in getattr(ir, "statements", []):
for statement in ir.statements:

]

@staticmethod
def _get_integrality_and_bounds(num_x_vars: int, num_w_vars: int) -> tuple[np.ndarray, Bounds]:
Copy link
Collaborator

Choose a reason for hiding this comment

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

Also here, the integrality is returned as a numpy array of booleans, but where it is used it expects a list of integers. Why not define it as a list of integers from the start?

reference_counter = self._get_reference_counter(ir, qubit_register_size)

cost, constraints, integrality, bounds = self._get_linearized_formulation(
reference_counter, distance, qubit_register_size, num_physical_qubits
Copy link
Collaborator

Choose a reason for hiding this comment

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

The qubit_register_size and num_physical_qubits can probably be defined as object attributes, i.e. self.qubit_register_size and self.num_physical_qubits, then they don't need to be passed around.

Same goes for num_virtual_qubits * num_physical_qubits, which is used in various places.

Comment on lines +251 to 255
for i in range(num_virtual_qubits):
k = int(np.argmax(x_sol[i]))
mapping.append(k)

return mapping
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
for i in range(num_virtual_qubits):
k = int(np.argmax(x_sol[i]))
mapping.append(k)
return mapping
return list(map(lambda x: int(np.argmax(x)), x_sol))

initial_circuit = str(circuit1)
circuit1.map(mapper=mapper1)
assert str(circuit1) != initial_circuit
assert str(circuit1) == initial_circuit
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would prefer a different mapping to be the result of a test_map_method. Nevertheless, there should also be a test where the map method is applied, and as expected, the mapping remains the same (just like you did in the test_controlled_gates).

def test_get_mapping(self, mapper: IdentityMapper, circuit: Circuit) -> None:
mapping = mapper.map(circuit.ir, circuit.qubit_register_size)
assert mapping == Mapping([0, 1, 2])
assert mapping.items() == Mapping([0, 1, 2]).items()
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this still needed, now that you updated the Mapping.__eq__ method? Maybe this condition self.data == other.data should not be part of that method.

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