@@ -388,12 +388,15 @@ def add_qiskit_data(
388
388
elif instr .base_gate .base_class is qiskit_gates .ZGate :
389
389
optype = OpType .CnZ
390
390
else :
391
- if instr .base_gate .base_class in _known_qiskit_gate :
391
+ if (
392
+ instr .base_gate .base_class in _known_qiskit_gate
393
+ or instr .base_gate .base_class == UnitaryGate
394
+ ):
392
395
optype = OpType .QControlBox # QControlBox case handled below
393
396
else :
394
397
raise NotImplementedError (
395
398
f"qiskit ControlledGate with base gate { instr .base_gate } "
396
- + "not implemented"
399
+ + "not implemented. "
397
400
)
398
401
elif type (instr ) in [PauliEvolutionGate , UnitaryGate ]:
399
402
pass # Special handling below
@@ -411,17 +414,24 @@ def add_qiskit_data(
411
414
bits = [self .cbmap [bit ] for bit in cargs ]
412
415
413
416
if optype == OpType .QControlBox :
414
- base_tket_gate = _known_qiskit_gate [instr .base_gate .base_class ]
415
417
params = [param_to_tk (p ) for p in instr .base_gate .params ]
416
418
n_base_qubits = instr .base_gate .num_qubits
417
419
sub_circ = Circuit (n_base_qubits )
418
420
# use base gate name for the CircBox (shows in renderer)
419
421
sub_circ .name = instr .base_gate .name .capitalize ()
420
- sub_circ .add_gate (base_tket_gate , params , list (range (n_base_qubits )))
422
+ if type (instr .base_gate ) == UnitaryGate :
423
+ assert len (cargs ) == 0
424
+ add_qiskit_unitary_to_tkc (
425
+ sub_circ , instr .base_gate , sub_circ .qubits , condition_kwargs
426
+ )
427
+ else :
428
+ base_tket_gate = _known_qiskit_gate [instr .base_gate .base_class ]
429
+ sub_circ .add_gate (
430
+ base_tket_gate , params , list (range (n_base_qubits ))
431
+ )
421
432
c_box = CircBox (sub_circ )
422
433
q_ctrl_box = QControlBox (c_box , instr .num_ctrl_qubits )
423
434
self .tkc .add_qcontrolbox (q_ctrl_box , qubits )
424
-
425
435
elif isinstance (instr , (Initialize , StatePreparation )):
426
436
# Check how Initialize or StatePrep is constructed
427
437
if isinstance (instr .params [0 ], str ):
@@ -462,37 +472,8 @@ def add_qiskit_data(
462
472
ccbox = CircBox (circ )
463
473
self .tkc .add_circbox (ccbox , qubits )
464
474
elif type (instr ) == UnitaryGate :
465
- # Note reversal of qubits, to account for endianness (pytket unitaries
466
- # are ILO-BE == DLO-LE; qiskit unitaries are ILO-LE == DLO-BE).
467
- params = instr .params
468
- assert len (params ) == 1
469
- u = cast (np .ndarray , params [0 ])
470
475
assert len (cargs ) == 0
471
- n = len (qubits )
472
- if n == 0 :
473
- assert u .shape == (1 , 1 )
474
- self .tkc .add_phase (np .angle (u [0 ][0 ]) / np .pi )
475
- elif n == 1 :
476
- assert u .shape == (2 , 2 )
477
- u1box = Unitary1qBox (u )
478
- self .tkc .add_unitary1qbox (u1box , qubits [0 ], ** condition_kwargs )
479
- elif n == 2 :
480
- assert u .shape == (4 , 4 )
481
- u2box = Unitary2qBox (u )
482
- self .tkc .add_unitary2qbox (
483
- u2box , qubits [1 ], qubits [0 ], ** condition_kwargs
484
- )
485
- elif n == 3 :
486
- assert u .shape == (8 , 8 )
487
- u3box = Unitary3qBox (u )
488
- self .tkc .add_unitary3qbox (
489
- u3box , qubits [2 ], qubits [1 ], qubits [0 ], ** condition_kwargs
490
- )
491
- else :
492
- raise NotImplementedError (
493
- f"Conversion of { n } -qubit unitary gates not supported"
494
- )
495
-
476
+ add_qiskit_unitary_to_tkc (self .tkc , instr , qubits , condition_kwargs )
496
477
elif optype == OpType .Barrier :
497
478
self .tkc .add_barrier (qubits )
498
479
elif optype == OpType .CircBox :
@@ -529,6 +510,40 @@ def add_qiskit_data(
529
510
self .add_xs (num_ctrl_qubits , ctrl_state , qargs )
530
511
531
512
513
+ def add_qiskit_unitary_to_tkc (
514
+ tkc : Circuit ,
515
+ u_gate : UnitaryGate ,
516
+ qubits : List [Qubit ],
517
+ condition_kwargs : Dict [str , Any ],
518
+ ) -> None :
519
+ # Note reversal of qubits, to account for endianness (pytket unitaries
520
+ # are ILO-BE == DLO-LE; qiskit unitaries are ILO-LE == DLO-BE).
521
+ params = u_gate .params
522
+ assert len (params ) == 1
523
+ u = cast (np .ndarray , params [0 ])
524
+
525
+ n = len (qubits )
526
+ if n == 0 :
527
+ assert u .shape == (1 , 1 )
528
+ tkc .add_phase (np .angle (u [0 ][0 ]) / np .pi )
529
+ elif n == 1 :
530
+ assert u .shape == (2 , 2 )
531
+ u1box = Unitary1qBox (u )
532
+ tkc .add_unitary1qbox (u1box , qubits [0 ], ** condition_kwargs )
533
+ elif n == 2 :
534
+ assert u .shape == (4 , 4 )
535
+ u2box = Unitary2qBox (u )
536
+ tkc .add_unitary2qbox (u2box , qubits [1 ], qubits [0 ], ** condition_kwargs )
537
+ elif n == 3 :
538
+ assert u .shape == (8 , 8 )
539
+ u3box = Unitary3qBox (u )
540
+ tkc .add_unitary3qbox (u3box , qubits [2 ], qubits [1 ], qubits [0 ], ** condition_kwargs )
541
+ else :
542
+ raise NotImplementedError (
543
+ f"Conversion of { n } -qubit unitary gates not supported."
544
+ )
545
+
546
+
532
547
def qiskit_to_tk (qcirc : QuantumCircuit , preserve_param_uuid : bool = False ) -> Circuit :
533
548
"""
534
549
Converts a qiskit :py:class:`qiskit.QuantumCircuit` to a pytket :py:class:`Circuit`.
0 commit comments