def test_apply_errors_basis_state(self): """Test that apply fails for incorrect basis state preparation.""" dev = QulacsDevice(1) with pytest.raises( ValueError, match="BasisState parameter must consist of 0 or 1 integers."): dev.apply([qml.BasisState(np.array([-0.2, 4.2]), wires=[0, 1])]) with pytest.raises( ValueError, match="BasisState parameter and wires must be of equal length." ): dev.apply([qml.BasisState(np.array([0, 1]), wires=[0])]) dev.reset() with pytest.raises( qml.DeviceError, match= "Operation BasisState cannot be used after other Operations have already been applied " "on a qulacs.simulator device.", ): dev.apply([ qml.RZ(0.5, wires=[0]), qml.BasisState(np.array([1, 1]), wires=[0, 1]) ])
def test_invalid_qubit_state_unitary(self): """Test that an exception is raised if the unitary matrix is the wrong size""" dev = QulacsDevice(2) state = np.array([[0, 123.432], [-0.432, 023.4]]) op = qml.QubitUnitary(state, wires=[0, 1]) with pytest.raises(ValueError, match=r"Unitary matrix must be of shape"): dev.apply([op])
def test_invalid_qubit_state_vector(self): """Test that an exception is raised if the state vector is the wrong size""" dev = QulacsDevice(2) state = np.array([0, 123.432]) with pytest.raises(ValueError, match=r"State vector must be of length 2\*\*wires"): op = qml.QubitStateVector(state, wires=[0, 1]) dev.apply([op])
def test_analytic_probability(self, wires, prob, tol): """Test the analytic_probability() function.""" dev = QulacsDevice(4) state = np.array((0, 1, 0, 1)) op = qml.BasisState(state, wires=[0, 1, 2, 3]) dev.apply([op]) res = dev.analytic_probability(wires=wires) res = list(res) assert np.allclose(res, prob, atol=tol)
def test_three_qubit_no_parameters(self, init_state, op, mat, tol): dev = QulacsDevice(3) state = init_state(3) dev.apply([qml.QubitStateVector(state, wires=[0, 1, 2]), op]) dev._obs_queue = [] res = dev.state expected = mat @ state assert np.allclose(res, expected, tol)
def test_expval_hadamard(self, obs, args, wires, supported, mocker): """Test that QulacsDevice.expval() uses native calculations when possible""" dev = QulacsDevice(4) spy = mocker.spy(dev, "probability") dev.expval(obs(*args, wires=wires)) if supported: spy.assert_not_called() else: spy.assert_called_once()
def test_single_qubit_no_parameters(self, init_state, op, mat, tol): """Test PauliX application""" dev = QulacsDevice(1) state = init_state(1) dev.apply([qml.QubitStateVector(state, wires=[0]), op]) dev._obs_queue = [] res = np.abs(dev.state)**2 expected = np.abs(mat @ state)**2 assert np.allclose(res, expected, tol)
def test_two_qubit_no_parameters(self, init_state, op, mat, tol): """Test PauliX application""" dev = QulacsDevice(2) state = init_state(2) dev.apply([qml.QubitStateVector(state, wires=[0, 1]), op]) dev._obs_queue = [] res = dev.state expected = mat @ state assert np.allclose(res, expected, tol)
def test_single_qubit_parameters(self, init_state, op, func, theta, tol): """Test PauliX application""" dev = QulacsDevice(1) state = init_state(1) op.data = [theta] dev.apply([qml.QubitStateVector(state, wires=[0]), op]) dev._obs_queue = [] res = dev.state expected = func(theta) @ state assert np.allclose(res, expected, tol)
def test_qubit_state_vector(self, init_state, tol): """Test QubitStateVector application""" dev = QulacsDevice(1) state = init_state(1) op = qml.QubitStateVector(state, wires=[0]) dev.apply([op]) dev._obs_queue = [] res = dev.state expected = state assert np.allclose(res, expected, tol)
def test_two_qubit_parameters(self, init_state, op, func, theta, tol): """Test parametrized two qubit gates application""" dev = QulacsDevice(2) state = init_state(2) op.data = [theta] dev.apply([qml.QubitStateVector(state, wires=[0, 1]), op]) dev._obs_queue = [] res = np.abs(dev.state)**2 expected = np.abs(func(theta) @ state)**2 assert np.allclose(res, expected, tol)
def test_basis_state(self, state, tol): """Test basis state initialization""" dev = QulacsDevice(4) op = qml.BasisState(state, wires=[0, 1, 2, 3]) dev.apply([op]) dev._obs_queue = [] res = np.abs(dev.state)**2 # compute expected probabilities expected = np.zeros([2**4]) expected[np.ravel_multi_index(state, [2] * 4)] = 1 assert np.allclose(res, expected, tol)
def test_qubit_unitary(self, init_state, mat, tol): """Test QubitUnitary application""" N = int(np.log2(len(mat))) dev = QulacsDevice(N) state = init_state(N) op = qml.QubitUnitary(mat, wires=list(range(N))) dev.apply([qml.QubitStateVector(state, wires=list(range(N))), op]) dev._obs_queue = [] res = dev.state expected = mat @ state assert np.allclose(res, expected, tol)
def test_load_device(self): """Test that the Qulacs device loads correctly.""" dev = QulacsDevice(2, shots=int(1e6)) assert dev.num_wires == 2 assert dev.shots == int(1e6) assert dev.short_name == "qulacs.simulator" assert "model" in dev.__class__.capabilities()
def test_no_gpu_support(self, monkeypatch): """Test that error thrown when gpu set to True but no gpu support found.""" monkeypatch.setattr(QulacsDevice, "gpu_supported", False) with pytest.raises( qml.DeviceError, match="GPU not supported with installed version of qulacs" ): QulacsDevice(3, gpu=True)
def test_device_attributes(self, num_wires, shots): """Test that attributes are set as expected.""" dev = QulacsDevice(wires=num_wires, shots=shots) assert dev.num_wires == num_wires assert dev.shots == shots assert dev._samples is None assert dev._capabilities["model"] == "qubit" assert dev._capabilities["tensor_observables"] assert dev._capabilities["inverse_operations"] assert isinstance(dev._state, QuantumState) assert isinstance(dev._circuit, QuantumCircuit)
def test_reset(self, tol): """Test the reset() function.""" dev = QulacsDevice(4) state = np.array((0, 1, 0, 1)) op = qml.BasisState(state, wires=[0, 1, 2, 3]) dev.apply([op]) dev.reset() expected = [0.0] * 16 expected[0] = 1.0 assert np.allclose(dev._state.get_vector(), expected) assert QuantumCircuit(4).calculate_depth() == 0
def test_expectation(self): """Test that expectation of a non-trivial circuit is correct.""" dev = QulacsDevice(2, shots=int(1e6)) theta = 0.432 phi = 0.123 @qml.qnode(dev) def circuit(): qml.RY(theta, wires=[0]).inv() qml.RY(phi, wires=[1]) qml.CNOT(wires=[0, 1]) return qml.expval(qml.PauliX(wires=0)), qml.expval( qml.PauliX(wires=1)) res = circuit() expected = np.array([np.sin(-theta) * np.sin(phi), np.sin(phi)]) assert np.allclose(res, expected, atol=0.05)
def test_qubit_state_vector_on_wires_subset(self, init_state, device_wires, op_wires, tol): """Test QubitStateVector application on a subset of device wires""" dev = QulacsDevice(device_wires) state = init_state(len(op_wires)) op = qml.QubitStateVector(state, wires=op_wires) dev.apply([op]) dev._obs_queue = [] res = dev.state expected = dev._expand_state(state, op_wires) assert np.allclose(res, expected, tol)
def test_basis_state_on_wires_subset(self, state, device_wires, op_wires, tol): """Test basis state initialization on a subset of device wires""" dev = QulacsDevice(device_wires) op = qml.BasisState(state, wires=op_wires) dev.apply([op]) dev._obs_queue = [] res = np.abs(dev.state)**2 # compute expected probabilities expected = np.zeros([2**len(op_wires)]) expected[np.ravel_multi_index(state, [2] * len(op_wires))] = 1 expected = dev._expand_state(expected, op_wires) assert np.allclose(res, expected, tol)
def test_expand_state(state, op_wires, device_wires, expected, tol): """Test that the expand_state method works as expected.""" dev = QulacsDevice(device_wires) res = dev._expand_state(state, op_wires) assert np.allclose(res, expected, tol)
def test_apply_errors_qubit_state_vector(self): """Test that apply fails for incorrect state preparation.""" dev = QulacsDevice(2) with pytest.raises( ValueError, match="Sum of amplitudes-squared does not equal one."): dev.apply([qml.QubitStateVector(np.array([1, -1]), wires=[0])]) with pytest.raises( ValueError, match=r"State vector must be of length 2\*\*wires."): p = np.array([1, 0, 1, 1, 0]) / np.sqrt(3) dev.reset() dev.apply([qml.QubitStateVector(p, wires=[0, 1])]) with pytest.raises( qml.DeviceError, match= "Operation QubitStateVector cannot be used after other Operations have already been applied " "on a qulacs.simulator device.", ): dev.reset() dev.apply([ qml.RZ(0.5, wires=[0]), qml.QubitStateVector(np.array([0, 1, 0, 0]), wires=[0, 1]) ])