def test_auto_replacer_priorize_controlstate_rule(): # Check that when a control state is given and it has negative control, # Autoreplacer prioritizes the corresponding decomposition rule before anything else. # (Decomposition rule should have name _decompose_controlstate) # Create test gate and inverse class ControlGate(BasicGate): pass def _decompose_controlstate(cmd): S | cmd.qubits def _decompose_random(cmd): H | cmd.qubits def control_filter(self, cmd): if cmd.gate == ControlGate(): return False return True rule_set.add_decomposition_rule( DecompositionRule(BasicGate, _decompose_random)) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(control_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() ControlGate() | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == H rule_set.add_decomposition_rule( DecompositionRule(BasicGate, _decompose_controlstate)) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(control_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() ControlGate() | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == S
def test_auto_replacer_default_chooser(test_gate_filter): # Test that default decomposition_chooser takes always first rule. backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_replacer.AutoReplacer(), test_gate_filter]) assert len(decompositions[TestGate.__class__.__name__]) == 2 assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() TestGate | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == X
def test_auto_replacer_no_rule_found(): # Check that exception is thrown if no rule is found # For both the cmd and it's inverse (which exists) def h_filter(self, cmd): if cmd.gate == H: return False return True h_filter = _replacer.InstructionFilter(h_filter) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_replacer.AutoReplacer(rule_set), h_filter]) qubit = eng.allocate_qubit() with pytest.raises(_replacer.NoGateDecompositionError): H | qubit eng.flush()
def test_auto_replacer_adds_tags(test_gate_filter): # Test that AutoReplacer puts back the tags backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_replacer.AutoReplacer(), test_gate_filter]) assert len(decompositions[TestGate.__class__.__name__]) == 2 assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() cmd = Command(eng, TestGate, (qb, )) cmd.tags = ["AddedTag"] eng.send([cmd]) eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == X assert len(backend.received_commands[1].tags) == 1 assert backend.received_commands[1].tags[0] == "AddedTag"
def test_auto_replacer_decomposition_chooser(fixture_gate_filter): # Supply a decomposition chooser which always chooses last rule. def test_decomp_chooser(cmd, decomposition_list): return decomposition_list[-1] backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set, test_decomp_chooser), fixture_gate_filter ]) assert len(rule_set.decompositions[SomeGate.__class__.__name__]) == 2 assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() SomeGate | qb eng.flush() assert len(backend.received_commands) == 3 assert backend.received_commands[1].gate == H
def test_auto_replacer_use_inverse_decomposition(): # Check that if there is no decomposition for the gate, that # AutoReplacer runs the decomposition for the inverse gate in reverse # Create test gate and inverse class NoMagicGate(BasicGate): pass class MagicGate(BasicGate): def get_inverse(self): return NoMagicGate() def decompose_no_magic_gate(cmd): qb = cmd.qubits Rx(0.6) | qb H | qb def recognize_no_magic_gate(cmd): return True rule_set.add_decomposition_rule( DecompositionRule(NoMagicGate, decompose_no_magic_gate, recognize_no_magic_gate)) def magic_filter(self, cmd): if cmd.gate == MagicGate(): return False return True backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[ _replacer.AutoReplacer(rule_set), _replacer.InstructionFilter(magic_filter) ]) assert len(backend.received_commands) == 0 qb = eng.allocate_qubit() MagicGate() | qb eng.flush() for cmd in backend.received_commands: print(cmd) assert len(backend.received_commands) == 4 assert backend.received_commands[1].gate == H assert backend.received_commands[2].gate == Rx(-0.6)
def test_auto_replacer_searches_parent_class_for_rule(): class DerivedSomeGate(SomeGateClass): pass def test_gate_filter_func(self, cmd): if (cmd.gate == X or cmd.gate == H or isinstance(cmd.gate, ClassicalInstructionGate)): return True return False i_filter = _replacer.InstructionFilter(test_gate_filter_func) backend = DummyEngine(save_commands=True) eng = MainEngine(backend=backend, engine_list=[_replacer.AutoReplacer(rule_set), i_filter]) qb = eng.allocate_qubit() DerivedSomeGate() | qb eng.flush() received_gate = backend.received_commands[1].gate assert received_gate == X or received_gate == H