Skip to content

Commit db12c14

Browse files
authored
fix: Convert noncontiguous qubit indices (#194)
Applies noncontiguous qubit conversion for all non-fully-connected devices (as opposed to just Rigetti devices). Also improves efficiency by calling conversion only once rather than for each supported 2q gate.
1 parent 9789479 commit db12c14

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

qiskit_braket_provider/providers/adapter.py

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -372,6 +372,11 @@ def _qpu_target(
372372
else properties.action.get(DeviceActionType.JAQCD)
373373
)
374374
connectivity = properties.paradigm.connectivity
375+
connectivity_graph = (
376+
_contiguous_qubit_indices(connectivity.connectivityGraph)
377+
if not connectivity.fullyConnected
378+
else None
379+
)
375380

376381
for operation in action_properties.supportedOperations:
377382
instruction = _GATE_NAME_TO_QISKIT_GATE.get(operation.lower(), None)
@@ -385,18 +390,18 @@ def _qpu_target(
385390
elif instruction.num_qubits == 2:
386391
target.add_instruction(
387392
instruction,
388-
_2q_instruction_properties(qubit_count, connectivity, properties),
393+
_2q_instruction_properties(qubit_count, connectivity_graph),
389394
)
390395

391396
target.add_instruction(Measure(), {(i,): None for i in range(qubit_count)})
392397
return target
393398

394399

395-
def _2q_instruction_properties(qubit_count, connectivity, properties):
400+
def _2q_instruction_properties(qubit_count, connectivity_graph):
396401
instruction_props = {}
397402

398403
# building coupling map for fully connected device
399-
if connectivity.fullyConnected:
404+
if not connectivity_graph:
400405
for src in range(qubit_count):
401406
for dst in range(qubit_count):
402407
if src != dst:
@@ -405,25 +410,18 @@ def _2q_instruction_properties(qubit_count, connectivity, properties):
405410

406411
# building coupling map for device with connectivity graph
407412
else:
408-
if isinstance(
409-
properties, (RigettiDeviceCapabilities, RigettiDeviceCapabilitiesV2)
410-
):
411-
connectivity.connectivityGraph = _convert_aspen_qubit_indices(
412-
connectivity.connectivityGraph
413-
)
414-
415-
for src, connections in connectivity.connectivityGraph.items():
413+
for src, connections in connectivity_graph.items():
416414
for dst in connections:
417415
instruction_props[(int(src), int(dst))] = None
418416

419417
return instruction_props
420418

421419

422-
def _convert_aspen_qubit_indices(connectivity_graph: dict) -> dict:
423-
"""Aspen qubit indices are discontinuous (label between x0 and x7, x being
420+
def _contiguous_qubit_indices(connectivity_graph: dict) -> dict:
421+
"""Device qubit indices may be noncontiguous (label between x0 and x7, x being
424422
the number of the octagon) while the Qiskit transpiler creates and/or
425-
handles coupling maps with continuous indices. This function converts the
426-
discontinuous connectivity graph from Aspen to a continuous one.
423+
handles coupling maps with contiguous indices. This function converts the
424+
noncontiguous connectivity graph from Aspen to a contiguous one.
427425
428426
Args:
429427
connectivity_graph (dict): connectivity graph from Aspen. For example
@@ -432,30 +430,32 @@ def _convert_aspen_qubit_indices(connectivity_graph: dict) -> dict:
432430
"7": ["0","1","2"]}
433431
434432
Returns:
435-
dict: Connectivity graph with continuous indices. For example for an
436-
input connectivity graph with discontinuous indices (qubit 0, 1, 2 and
433+
dict: Connectivity graph with contiguous indices. For example for an
434+
input connectivity graph with noncontiguous indices (qubit 0, 1, 2 and
437435
then qubit 7) as shown here:
438436
{"0": ["1", "2", "7"], "1": ["0","2","7"], "2": ["0","1","7"],
439437
"7": ["0","1","2"]}
440438
the qubit index 7 will be mapped to qubit index 3 for the qiskit
441-
transpilation step. Thereby the resultant continous qubit indices
439+
transpilation step. Thereby the resultant contiguous qubit indices
442440
output will be:
443441
{"0": ["1", "2", "3"], "1": ["0","2","3"], "2": ["0","1","3"],
444442
"3": ["0","1","2"]}
445443
"""
446-
# Creates list of existing qubit indices which are discontinuous.
447-
indices = [int(key) for key in connectivity_graph.keys()]
448-
indices.sort()
449-
# Creates a list of continuous indices for number of qubits.
444+
# Creates list of existing qubit indices which are noncontiguous.
445+
indices = sorted(
446+
int(i)
447+
for i in set.union(*[{k} | set(v) for k, v in connectivity_graph.items()])
448+
)
449+
# Creates a list of contiguous indices for number of qubits.
450450
map_list = list(range(len(indices)))
451-
# Creates a dictionary to remap the discontinuous indices to continuous.
451+
# Creates a dictionary to remap the noncontiguous indices to contiguous.
452452
mapper = dict(zip(indices, map_list))
453-
# Performs the remapping from the discontinuous to the continuous indices.
454-
continous_connectivity_graph = {
453+
# Performs the remapping from the noncontiguous to the contiguous indices.
454+
contiguous_connectivity_graph = {
455455
mapper[int(k)]: [mapper[int(v)] for v in val]
456456
for k, val in connectivity_graph.items()
457457
}
458-
return continous_connectivity_graph
458+
return contiguous_connectivity_graph
459459

460460

461461
def to_braket(

0 commit comments

Comments
 (0)