-
Notifications
You must be signed in to change notification settings - Fork 946
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MAHOUT-2202 Testing Suite Template (plus MAHOUT-2207) (#442)
* added testing folder * successful pytest * comparison test working * added testing folder * successful pytest * comparison test working * conform to cirq 1.3.0 python reqs * MAHOUT-2202 add license headers * Stable implementation of prototype method * support for arbitrary backends * fixes and tidying * tidying readme * another header * another header fix
- Loading branch information
Showing
7 changed files
with
213 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
|
||
<!-- | ||
Licensed to the Apache Software Foundation (ASF) under one or more | ||
contributor license agreements. See the NOTICE file distributed with | ||
this work for additional information regarding copyright ownership. | ||
The ASF licenses this file to You under the Apache License, Version 2.0 | ||
(the "License"); you may not use this file except in compliance with | ||
the License. You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
--> | ||
Apache Mahout Testing Suite | ||
=========== | ||
For each backend supported in Apache Mahout, the testing suite executes an example circuit using the qumat implementation of the backend, and then executes the same example circuit using the backend's native implementation. The test then checks that the resulting final state vectors are the same. | ||
|
||
The testing suite is run using pytest, which is installed by default using poetry. To run the tests, simply run | ||
``` | ||
pytest | ||
``` | ||
|
||
### How to add a test for a new backend | ||
In order to add *my-new-backend* to the testing suite: | ||
1. Create a file `testing/my-new-backend_helpers.py` | ||
2. In `testing/my-new-backend_helpers.py`, create a function `get_qumat_backend_config` which returns the qumat backend config needed for the qumat implementation of my-new-backend | ||
3. In `testing/my-new-backend_helpers.py`, create a function `get_native_example_final_state_vector` which builds and executes the example circuit using the native implementation of my-new-backend | ||
4. In `testing/test_final_quantum_states.py`, add `"my-new-backend"` to `backends_to_test` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
|
||
# Import necessary Qiskit libraries | ||
from qiskit import Aer, QuantumCircuit, execute | ||
from qiskit.quantum_info import Statevector | ||
|
||
def get_qumat_backend_config(test_type: str = "get_final_state_vector"): | ||
if test_type == "get_final_state_vector": | ||
print("success") | ||
qumat_backend_config = { | ||
'backend_name': 'qiskit', | ||
'backend_options': { | ||
'simulator_type': 'statevector_simulator', | ||
'shots': 1 | ||
} | ||
} | ||
else: | ||
pass | ||
|
||
return qumat_backend_config | ||
|
||
|
||
def get_native_example_final_state_vector(initial_state_ket_str: str = "000") -> Statevector: | ||
n_qubits = len(initial_state_ket_str) | ||
assert n_qubits == 3, print("The current qiskit native testing example is strictly 3 qubits") | ||
|
||
simulator = Aer.get_backend('statevector_simulator') | ||
|
||
qc = QuantumCircuit(n_qubits) | ||
|
||
initial_state = Statevector.from_label(initial_state_ket_str) | ||
qc.initialize(initial_state, range(n_qubits)) | ||
|
||
# Create entanglement between qubits 1 and 2 | ||
qc.h(1) # Apply Hadamard gate on qubit 1 | ||
qc.cx(1, 2) # Apply CNOT gate with qubit 1 as control and qubit 2 as target | ||
|
||
# Prepare the state to be teleported on qubit 0 | ||
qc.h(0) # Apply Hadamard gate on qubit 0 | ||
qc.z(0) # Apply Pauli-Z gate on qubit 0 | ||
|
||
# Perform Bell measurement on qubits 0 and 1 | ||
qc.cx(0, 1) # Apply CNOT gate with qubit 0 as control and qubit 1 as target | ||
qc.h(0) # Apply Hadamard gate on qubit 0 | ||
|
||
# Simulate the circuit | ||
job = execute(qc, simulator) | ||
result = job.result() | ||
|
||
# Get the state vector | ||
state_vector = result.get_statevector() | ||
|
||
return state_vector |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
import numpy as np | ||
from functools import reduce | ||
from qumat.qumat import QuMat | ||
|
||
class BinaryString(str): | ||
def __new__(cls, value): | ||
if not all(char in ['0', '1'] for char in value): | ||
raise ValueError("String contains characters other than '0' and '1'") | ||
return str.__new__(cls, value) | ||
|
||
|
||
def create_np_computational_basis_state(ket_str: BinaryString, | ||
np_dtype: str = "complex128") -> np.array: | ||
single_qubit_state_dict = { | ||
"0": np.array([1, 0], dtype=np_dtype), | ||
"1": np.array([0, 1], dtype=np_dtype) | ||
} | ||
|
||
single_qubit_vectors = map(single_qubit_state_dict.get, ket_str) | ||
computational_basis_vector = reduce(np.kron, single_qubit_vectors) | ||
|
||
return computational_basis_vector | ||
|
||
|
||
def get_qumat_example_final_state_vector(backend_config: dict, initial_state_ket_str: BinaryString = "000"): | ||
n_qubits = len(initial_state_ket_str) | ||
assert n_qubits == 3, print("The current qumat testing example is strictly 3 qubits") | ||
|
||
qumat_instance = QuMat(backend_config) | ||
|
||
qumat_instance.create_empty_circuit(num_qubits=3) | ||
initial_state = create_np_computational_basis_state(initial_state_ket_str) | ||
qumat_instance.circuit.initialize(initial_state, range(n_qubits)) | ||
|
||
qumat_instance.apply_hadamard_gate(qubit_index=1) | ||
qumat_instance.apply_cnot_gate(control_qubit_index=1, target_qubit_index=2) | ||
qumat_instance.apply_hadamard_gate(qubit_index=0) | ||
qumat_instance.apply_pauli_z_gate(qubit_index=0) | ||
qumat_instance.apply_cnot_gate(control_qubit_index=0, target_qubit_index=1) | ||
qumat_instance.apply_hadamard_gate(qubit_index=0) | ||
|
||
state_vector = qumat_instance.get_final_state_vector() | ||
|
||
return state_vector |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# | ||
# Licensed to the Apache Software Foundation (ASF) under one or more | ||
# contributor license agreements. See the NOTICE file distributed with | ||
# this work for additional information regarding copyright ownership. | ||
# The ASF licenses this file to You under the Apache License, Version 2.0 | ||
# (the "License"); you may not use this file except in compliance with | ||
# the License. You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
# | ||
from qumat_helpers import get_qumat_example_final_state_vector | ||
import numpy as np | ||
from importlib import import_module | ||
|
||
def test_final_state_vector(): | ||
# Specify initial computational basis state vector | ||
initial_ket_str = "001" | ||
|
||
backends_to_test = ["qiskit"] | ||
for backend_name in backends_to_test: | ||
backend_module = import_module(f"{backend_name}_helpers", package="qumat") | ||
# use native implementation | ||
native_example_vector = backend_module.get_native_example_final_state_vector(initial_ket_str) | ||
|
||
# use qumat implementation | ||
qumat_backend_config = backend_module.get_qumat_backend_config("get_final_state_vector") | ||
qumat_example_vector = get_qumat_example_final_state_vector(qumat_backend_config, initial_ket_str) | ||
|
||
# Compare final state vectors from qumat vs. native implementation | ||
np.testing.assert_array_equal(qumat_example_vector, native_example_vector) | ||
|