def test_entropy_multiple_executions(accelerators): """Check entropy calculation when the callback is used in multiple executions.""" entropy = callbacks.EntanglementEntropy([0]) target_c = Circuit(2) target_c.add([gates.RY(0, 0.1234), gates.CNOT(0, 1)]) target_state = target_c().numpy() c = Circuit(2, accelerators) c.add(gates.RY(0, 0.1234)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() np.testing.assert_allclose(state.numpy(), target_state) target_c = Circuit(2) target_c.add([gates.RY(0, 0.4321), gates.CNOT(0, 1)]) target_state = target_c().numpy() c = Circuit(2, accelerators) c.add(gates.RY(0, 0.4321)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() np.testing.assert_allclose(state.numpy(), target_state) def target_entropy(t): cos = np.cos(t / 2.0)**2 sin = np.sin(t / 2.0)**2 return -cos * np.log2(cos) - sin * np.log2(sin) target = [0, target_entropy(0.1234), 0, target_entropy(0.4321)] np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol)
def test_entropy_in_compiled_circuit(backend): """Check that entropy calculation works when circuit is compiled.""" from qibo import get_backend entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.CallbackGate(entropy)) c.add(gates.H(0)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) c.compile() final_state = c() K.assert_allclose(entropy[:], [0, 0, 1.0], atol=_atol)
def test_entropy_in_circuit(accelerators): """Check that entropy calculation works in circuit.""" entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add(gates.CallbackGate(entropy)) c.add(gates.H(0)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() target = [0, 0, 1.0] np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol)
def test_callbacks_fusion(backend): """Check entropy calculation in fused circuit.""" from qibo import callbacks entropy = callbacks.EntanglementEntropy([0]) c = Circuit(5) c.add(gates.H(0)) c.add(gates.X(1)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) fused_c = c.fuse() K.assert_allclose(fused_c(), c()) target_entropy = [0.0, 1.0, 0.0, 1.0] K.assert_allclose(entropy[:], target_entropy, atol=1e-7)
def test_entropy_in_distributed_circuit(): """Check that various entropy configurations work in distributed circuit.""" target_c = Circuit(2) target_c.add([gates.H(0), gates.CNOT(0, 1)]) target_state = target_c().numpy() accelerators = {"/GPU:0": 1, "/GPU:1": 1} entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add([gates.H(0), gates.CNOT(0, 1), gates.CallbackGate(entropy)]) final_state = c().numpy() np.testing.assert_allclose(final_state, target_state) np.testing.assert_allclose(entropy[:].numpy(), [1.0], atol=_atol) entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add([gates.H(0), gates.CallbackGate(entropy), gates.CNOT(0, 1)]) final_state = c().numpy() np.testing.assert_allclose(final_state, target_state) np.testing.assert_allclose(entropy[:].numpy(), [0.0], atol=_atol) entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add([gates.CallbackGate(entropy), gates.H(0), gates.CNOT(0, 1)]) final_state = c().numpy() np.testing.assert_allclose(final_state, target_state) np.testing.assert_allclose(entropy[:].numpy(), [0.0], atol=_atol) entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add([gates.CallbackGate(entropy), gates.H(0), gates.CNOT(0, 1), gates.CallbackGate(entropy)]) final_state = c().numpy() np.testing.assert_allclose(final_state, target_state) np.testing.assert_allclose(entropy[:].numpy(), [0, 1.0], atol=_atol) entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add([gates.H(0), gates.CallbackGate(entropy), gates.CNOT(0, 1), gates.CallbackGate(entropy)]) final_state = c().numpy() np.testing.assert_allclose(final_state, target_state) np.testing.assert_allclose(entropy[:].numpy(), [0, 1.0], atol=_atol) entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add([gates.CallbackGate(entropy), gates.H(0), gates.CallbackGate(entropy), gates.CNOT(0, 1)]) final_state = c().numpy() np.testing.assert_allclose(final_state, target_state) np.testing.assert_allclose(entropy[:].numpy(), [0, 0], atol=_atol)
def test_entropy_in_circuit(accelerators): """Check that entropy calculation works in circuit.""" entropy = callbacks.EntanglementEntropy([0], compute_spectrum=True) c = Circuit(2, accelerators) c.add(gates.CallbackGate(entropy)) c.add(gates.H(0)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() target = [0, 0, 1.0] np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol) target_spectrum = [0, 0, np.log(2), np.log(2)] entropy_spectrum = np.concatenate(entropy.spectrum).ravel().tolist() np.testing.assert_allclose(entropy_spectrum, target_spectrum, atol=_atol)
def test_fuse_with_callback(accelerators): """Check entropy calculation in fused circuit.""" from qibo import callbacks entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2, accelerators) c.add(gates.H(0)) c.add(gates.X(1)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) fused_c = c.fuse() target_state = c() final_state = fused_c() np.testing.assert_allclose(final_state, target_state) target_entropy = [0.0, 1.0, 0.0, 1.0] np.testing.assert_allclose(entropy[:], target_entropy, atol=1e-7)
def test_entropy_in_circuit(backend, density_matrix): """Check that entropy calculation works in circuit.""" entropy = callbacks.EntanglementEntropy([0], compute_spectrum=True) c = Circuit(2, density_matrix=density_matrix) c.add(gates.CallbackGate(entropy)) c.add(gates.H(0)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() target = [0, 0, 1.0] K.assert_allclose(entropy[:], target, atol=_atol) target_spectrum = [0, 0, np.log(2), np.log(2)] entropy_spectrum = np.concatenate(entropy.spectrum).ravel().tolist() K.assert_allclose(entropy_spectrum, target_spectrum, atol=_atol)
def test_entropy_large_circuit(backend, accelerators): """Check that entropy calculation works for variational like circuit.""" original_backend = qibo.get_backend() qibo.set_backend(backend) thetas = np.pi * np.random.random((3, 8)) target_entropy = callbacks.EntanglementEntropy([0, 2, 4, 5]) c1 = Circuit(8) c1.add((gates.RY(i, thetas[0, i]) for i in range(8))) c1.add((gates.CZ(i, i + 1) for i in range(0, 7, 2))) state1 = c1() e1 = target_entropy(state1) c2 = Circuit(8) c2.add((gates.RY(i, thetas[1, i]) for i in range(8))) c2.add((gates.CZ(i, i + 1) for i in range(1, 7, 2))) c2.add(gates.CZ(0, 7)) state2 = (c1 + c2)() e2 = target_entropy(state2) c3 = Circuit(8) c3.add((gates.RY(i, thetas[2, i]) for i in range(8))) c3.add((gates.CZ(i, i + 1) for i in range(0, 7, 2))) state3 = (c1 + c2 + c3)() e3 = target_entropy(state3) entropy = callbacks.EntanglementEntropy([0, 2, 4, 5]) c = Circuit(8, accelerators) c.add(gates.CallbackGate(entropy)) c.add((gates.RY(i, thetas[0, i]) for i in range(8))) c.add((gates.CZ(i, i + 1) for i in range(0, 7, 2))) c.add(gates.CallbackGate(entropy)) c.add((gates.RY(i, thetas[1, i]) for i in range(8))) c.add((gates.CZ(i, i + 1) for i in range(1, 7, 2))) c.add(gates.CZ(0, 7)) c.add(gates.CallbackGate(entropy)) c.add((gates.RY(i, thetas[2, i]) for i in range(8))) c.add((gates.CZ(i, i + 1) for i in range(0, 7, 2))) c.add(gates.CallbackGate(entropy)) state = c() np.testing.assert_allclose(state3, state) np.testing.assert_allclose(entropy[:], [0, e1, e2, e3]) qibo.set_backend(original_backend)
def test_entropy_in_compiled_circuit(): """Check that entropy calculation works when circuit is compiled.""" import qibo original_backend = qibo.get_backend() qibo.set_backend("matmuleinsum") entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.CallbackGate(entropy)) c.add(gates.H(0)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) c.compile() state = c() qibo.set_backend("custom") target = [0, 0, 1.0] np.testing.assert_allclose(entropy[:].numpy(), target, atol=_atol) qibo.set_backend(original_backend)
def test_state_callback(backend, density_matrix, copy): statec = callbacks.State(copy=copy) c = Circuit(2, density_matrix=density_matrix) c.add(gates.H(0)) c.add(gates.CallbackGate(statec)) c.add(gates.H(1)) c.add(gates.CallbackGate(statec)) final_state = c() target_state0 = np.array([1, 0, 1, 0]) / np.sqrt(2) target_state1 = np.ones(4) / 2.0 if not copy and K.name == "qibojit": # when copy is disabled in the callback and in-place updates are used target_state0 = target_state1 if density_matrix: target_state0 = np.tensordot(target_state0, target_state0, axes=0) target_state1 = np.tensordot(target_state1, target_state1, axes=0) K.assert_allclose(statec[0], target_state0) K.assert_allclose(statec[1], target_state1)
def test_entropy_in_compiled_circuit(backend): """Check that entropy calculation works when circuit is compiled.""" original_backend = qibo.get_backend() qibo.set_backend(backend) entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.CallbackGate(entropy)) c.add(gates.H(0)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) if backend == "custom": with pytest.raises(RuntimeError): c.compile() else: c.compile() final_state = c() np.testing.assert_allclose(entropy[:], [0, 0, 1.0], atol=_atol) qibo.set_backend(original_backend)
def test_getitem_bad_indexing(backend): entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.RY(0, 0.1234)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) final_state = c() entropy[0] with pytest.raises(IndexError): entropy[1] with pytest.raises(IndexError): entropy["a"]
def test_entropy_multiple_executions(backend, accelerators): """Check entropy calculation when the callback is used in multiple executions.""" target_c = Circuit(4) target_c.add([gates.RY(0, 0.1234), gates.CNOT(0, 1)]) target_state = target_c() entropy = callbacks.EntanglementEntropy([0]) c = Circuit(4, accelerators) c.add(gates.RY(0, 0.1234)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() K.assert_allclose(state, target_state) target_c = Circuit(4) target_c.add([gates.RY(0, 0.4321), gates.CNOT(0, 1)]) target_state = target_c() c = Circuit(4, accelerators) c.add(gates.RY(0, 0.4321)) c.add(gates.CallbackGate(entropy)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() K.assert_allclose(state, target_state) def target_entropy(t): cos = np.cos(t / 2.0) ** 2 sin = np.sin(t / 2.0) ** 2 return - cos * np.log2(cos) - sin * np.log2(sin) target = [0, target_entropy(0.1234), 0, target_entropy(0.4321)] K.assert_allclose(entropy[:], target, atol=_atol) c = Circuit(8, accelerators) with pytest.raises(RuntimeError): c.add(gates.CallbackGate(entropy)) state = c()
def test_entropy_bad_indexing(): """Check exceptions in ``Callback.__getitem__``.""" entropy = callbacks.EntanglementEntropy([0]) c = Circuit(2) c.add(gates.RY(0, 0.1234)) c.add(gates.CNOT(0, 1)) c.add(gates.CallbackGate(entropy)) state = c() entropy[0] with pytest.raises(IndexError): entropy[1] with pytest.raises(IndexError): entropy["a"]
def test_entropy_in_distributed_circuit(backend, accelerators, gateconf, target_entropy): """Check that various entropy configurations work in distributed circuit.""" target_c = Circuit(4) target_c.add([gates.H(0), gates.CNOT(0, 1)]) target_state = target_c() entropy = callbacks.EntanglementEntropy([0]) c = Circuit(4, accelerators) for gate in gateconf: if gate == "H": c.add(gates.H(0)) elif gate == "CNOT": c.add(gates.CNOT(0, 1)) elif gate == "entropy": c.add(gates.CallbackGate(entropy)) final_state = c() K.assert_allclose(final_state, target_state) K.assert_allclose(entropy[:], target_entropy, atol=_atol)
def test_circuit_gate_generator_errors(backend, accelerators): from qibo import callbacks original_backend = qibo.get_backend() qibo.set_backend(backend) smallc = Circuit(2, accelerators=accelerators) smallc.add((gates.H(i) for i in range(2))) with pytest.raises(ValueError): next(smallc.on_qubits(0, 1, 2)) smallc = Circuit(2, accelerators=accelerators) smallc.add(gates.Flatten(np.ones(4) / np.sqrt(2))) with pytest.raises(NotImplementedError): next(smallc.on_qubits(0, 1)) smallc = Circuit(4, accelerators=accelerators) smallc.add(gates.CallbackGate(callbacks.EntanglementEntropy([0, 1]))) with pytest.raises(NotImplementedError): next(smallc.on_qubits(0, 1, 2, 3)) qibo.set_backend(original_backend)
def test_callback_gate_errors(): from qibo import callbacks entropy = callbacks.EntanglementEntropy([0]) gate = gates.CallbackGate(entropy) with pytest.raises(ValueError): gate.construct_unitary()
def test_callback_gate_errors(): """Check errors associated with ``gates.CallbackGate``.""" entropy = callbacks.EntanglementEntropy([0]) gate = gates.CallbackGate(entropy) with pytest.raises(ValueError): gate.construct_unitary()