diff --git a/.github/workflows/build-wheel-linux-x86_64.yaml b/.github/workflows/build-wheel-linux-x86_64.yaml index 835a91e83a..c703aa5970 100644 --- a/.github/workflows/build-wheel-linux-x86_64.yaml +++ b/.github/workflows/build-wheel-linux-x86_64.yaml @@ -494,7 +494,6 @@ jobs: python${{ matrix.python_version }} -m pytest frontend/test/async_tests # python${{ matrix.python_version }} -m pytest frontend/test/pytest --runbraket=LOCAL -n auto python${{ matrix.python_version }} -m pytest frontend/test/test_oqc/oqc -n auto - python${{ matrix.python_version }} -m pytest frontend/test/test_oqd/oqd -n auto - name: Run Standalone Plugin Tests # Run only on Thursday at the given time diff --git a/.github/workflows/build-wheel-macos-arm64.yaml b/.github/workflows/build-wheel-macos-arm64.yaml index da44c345b4..2c2fa5c751 100644 --- a/.github/workflows/build-wheel-macos-arm64.yaml +++ b/.github/workflows/build-wheel-macos-arm64.yaml @@ -475,7 +475,6 @@ jobs: python${{ matrix.python_version }} -m pytest frontend/test/async_tests # python${{ matrix.python_version }} -m pytest frontend/test/pytest --runbraket=LOCAL -n auto python${{ matrix.python_version }} -m pytest frontend/test/test_oqc/oqc -n auto - python${{ matrix.python_version }} -m pytest frontend/test/test_oqd/oqd -n auto - name: Run Standalone Plugin Tests # Run only on Thursday at the given time diff --git a/.github/workflows/build-wheel-macos-x86_64.yaml b/.github/workflows/build-wheel-macos-x86_64.yaml index 0967a48a19..b51bf58b6e 100644 --- a/.github/workflows/build-wheel-macos-x86_64.yaml +++ b/.github/workflows/build-wheel-macos-x86_64.yaml @@ -447,7 +447,6 @@ jobs: python${{ matrix.python_version }} -m pytest frontend/test/async_tests # python${{ matrix.python_version }} -m pytest frontend/test/pytest --runbraket=LOCAL -n auto python${{ matrix.python_version }} -m pytest frontend/test/test_oqc/oqc -n auto - python${{ matrix.python_version }} -m pytest frontend/test/test_oqd/oqd -n auto - name: Run Standalone Plugin Tests # Run only on Thursday at the given time diff --git a/.github/workflows/scripts/linux_arm64/rh8/test_wheels.sh b/.github/workflows/scripts/linux_arm64/rh8/test_wheels.sh index e0b8ce9e0c..f8f6ab13fc 100644 --- a/.github/workflows/scripts/linux_arm64/rh8/test_wheels.sh +++ b/.github/workflows/scripts/linux_arm64/rh8/test_wheels.sh @@ -47,4 +47,3 @@ export PATH=/catalyst/llvm-build/bin:/opt/_internal/cpython-${PYTHON_MAJOR_MINOR /usr/bin/python3 -m pytest /catalyst/frontend/test/async_tests # /usr/bin/python3 -m pytest -v /catalyst/frontend/test/pytest --runbraket=LOCAL -n auto /usr/bin/python3 -m pytest /catalyst/frontend/test/test_oqc/oqc -n auto -/usr/bin/python3 -m pytest /catalyst/frontend/test/test_oqd/oqd -n auto diff --git a/Makefile b/Makefile index 0a5c62618c..6221200561 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,6 @@ COVERAGE_REPORT ?= term-missing ENABLE_OPENQASM?=ON TEST_BACKEND ?= "lightning.qubit" TEST_BRAKET ?= NONE -SKIP_OQD ?= true ENABLE_ASAN ?= OFF TOML_SPECS ?= $(shell find ./runtime ./frontend -name '*.toml' -not -name 'pyproject.toml') @@ -168,7 +167,6 @@ endif @echo "check the Catalyst PyTest suite" $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/pytest --tb=native --backend=$(TEST_BACKEND) --runbraket=$(TEST_BRAKET) $(PARALLELIZE) $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/test_oqc/oqc - $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/test_oqd/oqd --skip-oqd=$(SKIP_OQD) $(PARALLELIZE) ifeq ($(TEST_BRAKET), NONE) $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/async_tests --tb=native --backend=$(TEST_BACKEND) endif @@ -276,7 +274,6 @@ coverage-frontend: @echo "Generating coverage report for the frontend" $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/pytest $(PARALLELIZE) --cov=catalyst --tb=native --cov-report=$(COVERAGE_REPORT) $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/test_oqc/oqc $(PARALLELIZE) --cov=catalyst --cov-append --tb=native --cov-report=$(COVERAGE_REPORT) - $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/test_oqd/oqd --skip-oqd=$(SKIP_OQD) $(PARALLELIZE) --cov=catalyst --cov-append --tb=native --cov-report=$(COVERAGE_REPORT) ifeq ($(TEST_BRAKET), NONE) $(ASAN_COMMAND) $(PYTHON) -m pytest frontend/test/async_tests --tb=native --backend=$(TEST_BACKEND) --tb=native endif diff --git a/frontend/test/test_oqd/conftest.py b/frontend/test/test_oqd/conftest.py deleted file mode 100644 index eb2d1ef1ba..0000000000 --- a/frontend/test/test_oqd/conftest.py +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright 2024 Xanadu Quantum Technologies Inc. - -# Licensed 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. -""" -Pytest configuration file for OQD test suite. -""" - -import pytest - - -def pytest_addoption(parser): - """Add pytest custom options.""" - parser.addoption( - "--skip-oqd", - action="store", - default="false", - choices=["true", "false"], - help="Skip the OQD test suite (true/false)", - ) - - -def pytest_collection_modifyitems(config, items): - """A pytest items modifier method""" - if config.getoption("--skip-oqd") == "true": - skip_oqd = pytest.mark.skip(reason="Skipping the OQD test suite") - for item in items: - if "oqd" in item.nodeid: - item.add_marker(skip_oqd) diff --git a/frontend/test/test_oqd/oqd/oqd_beam_parameters.toml b/frontend/test/test_oqd/oqd/oqd_beam_parameters.toml deleted file mode 100644 index 73431efc8f..0000000000 --- a/frontend/test/test_oqd/oqd/oqd_beam_parameters.toml +++ /dev/null @@ -1,17 +0,0 @@ -oqd_config_schema = "v0.1" - -[beams.downstate_upstate] -transition = "downstate_upstate" -rabi = "2 * math.pi * 1e6" -detuning = 0 -phase = 0 -polarization = nan -wavevector = nan - -[beams.downstate_estate] -transition = "downstate_estate" -rabi = "2 * math.pi * 1e6" -detuning = 0 -phase = 0 -polarization = nan -wavevector = nan diff --git a/frontend/test/test_oqd/oqd/oqd_qubit_parameters.toml b/frontend/test/test_oqd/oqd/oqd_qubit_parameters.toml deleted file mode 100644 index c8d931e613..0000000000 --- a/frontend/test/test_oqd/oqd/oqd_qubit_parameters.toml +++ /dev/null @@ -1,67 +0,0 @@ -oqd_config_schema = "v0.1" - -# Ions -# ---- - -[ions.Yb171] -mass = 171 -charge = +1 -position = [0, 0, 0] - -levels.downstate.principal = 6 -levels.downstate.spin = 0.5 -levels.downstate.orbital = 0 -levels.downstate.nuclear = 0.5 -levels.downstate.spin_orbital = 0.5 -levels.downstate.spin_orbital_nuclear = 0 -levels.downstate.spin_orbital_nuclear_magnetization = 0 -levels.downstate.energy = 0 - -levels.upstate.principal = 6 -levels.upstate.spin = 0.5 -levels.upstate.orbital = 0 -levels.upstate.nuclear = 0.5 -levels.upstate.spin_orbital = 0.5 -levels.upstate.spin_orbital_nuclear = 1 -levels.upstate.spin_orbital_nuclear_magnetization = 0 -levels.upstate.energy = "2 * math.pi * 12.643e9" - -levels.estate.principal = 5 -levels.estate.spin = 0.5 -levels.estate.orbital = 1 -levels.estate.nuclear = 0.5 -levels.estate.spin_orbital = 0.5 -levels.estate.spin_orbital_nuclear = 0 -levels.estate.spin_orbital_nuclear_magnetization = 0 -levels.estate.energy = "2 * math.pi * 811.52e12" - -[ions.Yb171.transitions.downstate_upstate] -level1 = "downstate" -level2 = "upstate" -einsteinA = "" - -[ions.Yb171.transitions.downstate_estate] -level1 = "downstate" -level2 = "estate" -einsteinA = "" - -[ions.Yb171.transitions.estate_upstate] -level1 = "estate" -level2 = "upstate" -einsteinA = "" - - -# Phonons -# ------- - -[phonons.COM_x] -energy = "2 * math.pi * 5e6" -eigenvector = [1, 0, 0] - -[phonons.COM_y] -energy = "2 * math.pi * 5e6" -eigenvector = [0, 1, 0] - -[phonons.COM_z] -energy = "2 * math.pi * 1e6" -eigenvector = [0, 0, 1] diff --git a/frontend/test/test_oqd/oqd/test_oqd_database_managers.py b/frontend/test/test_oqd/oqd/test_oqd_database_managers.py deleted file mode 100644 index 2cc75ca470..0000000000 --- a/frontend/test/test_oqd/oqd/test_oqd_database_managers.py +++ /dev/null @@ -1,507 +0,0 @@ -# Copyright 2024 Xanadu Quantum Technologies Inc. - -# Licensed 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. - -"""Tests for parsing and loading the configuration files for an Open Quantum Design (OQD) -trapped-ion quantum computer device. -""" - -import math -import pathlib -import textwrap - -import pytest - -from catalyst.third_party.oqd import ( - OQDBeamDatabase, - OQDDeviceDatabase, - OQDQubitDatabase, -) -from catalyst.third_party.oqd.oqd_database_managers import ( - _parse_value_or_expression_as_float, - _string_or_collection_of_strings_to_set, -) - -FRONTEND_ROOT_PATH = pathlib.Path(__file__).parent.parent.parent.parent -OQD_SRC_DIR = FRONTEND_ROOT_PATH / "catalyst/third_party/oqd/src/" -OQD_TEST_DIR = FRONTEND_ROOT_PATH / "test/test_oqd/oqd/" - - -class TestOQDDeviceDatabase: - """Test suite for the OQDDeviceDatabase class.""" - - def test_from_toml_production(self): - """ - Tests that the OQDDeviceDatabase.from_toml method can load the device properties from the - oqd_device_parameters.toml file used in production. - - Here, we only test that we can load the file; we do not check any values since they are - subject to change in the production TOML file. - """ - device_database = OQDDeviceDatabase.from_toml(OQD_SRC_DIR / "oqd_device_parameters.toml") - assert device_database.parameters - - def test_from_toml_string(self): - """ - Tests that the OQDDeviceDatabase.from_toml method can load the device properties from a - TOML document string. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.1" - - # Parameters - [parameters.N_load] - description = "Number of ions" - stage = "Loading" - process = "Ablation" - equation = "" - value = 1 - unit = "" - - [parameters.w_ablation] - description = "Ablation laser frequency" - stage = "Loading" - process = "Ablation" - equation = "" - value = 532 - unit = "nm" - """ - ) - - properties = OQDDeviceDatabase.from_toml(toml_document) - assert properties.parameters - - assert properties.parameters["N_load"] - assert properties.parameters["N_load"].name == "N_load" - assert properties.parameters["N_load"].description == "Number of ions" - assert properties.parameters["N_load"].stage == "Loading" - assert properties.parameters["N_load"].process == "Ablation" - assert properties.parameters["N_load"].equation == "" - assert properties.parameters["N_load"].value == 1 - assert properties.parameters["N_load"].unit == "" - - assert properties.parameters["w_ablation"] - assert properties.parameters["w_ablation"].name == "w_ablation" - assert properties.parameters["w_ablation"].description == "Ablation laser frequency" - assert properties.parameters["w_ablation"].stage == "Loading" - assert properties.parameters["w_ablation"].process == "Ablation" - assert properties.parameters["w_ablation"].equation == "" - assert properties.parameters["w_ablation"].value == 532 - assert properties.parameters["w_ablation"].unit == "nm" - - def test_from_toml_invalid(self): - """ - Tests that the OQDDeviceDatabase.from_toml method raises a ValueError when the TOML document - is invalid. - """ - with pytest.raises(ValueError, match="Failed to load TOML document"): - OQDDeviceDatabase.from_toml("Invalid TOML document") - - -class TestOQDQubitDatabase: - """Test suite for the OQDQubitDatabase class.""" - - def test_from_toml_production(self): - """ - Tests that the OQDQubitDatabase.from_toml method can load the qubit parameters from the - oqd_qubit_parameters.toml file used in production. - - Here, we only test that we can load the file; we do not check any values since they are - subject to change in the production TOML file. - """ - qubit_database = OQDQubitDatabase.from_toml(OQD_SRC_DIR / "oqd_qubit_parameters.toml") - assert qubit_database - assert qubit_database.ion_parameters - assert qubit_database.phonon_parameters - - def test_from_toml(self): - """ - Tests that the OQDQubitDatabase.from_toml method can load the qubit parameters from a sample - oqd_qubit_parameters.toml file. - """ - qubit_database = OQDQubitDatabase.from_toml(OQD_TEST_DIR / "oqd_qubit_parameters.toml") - assert qubit_database - - # Check ion parameters - assert qubit_database.ion_parameters - assert qubit_database.ion_parameters["Yb171"] - - ion_params_yb171 = qubit_database.ion_parameters["Yb171"] - assert ion_params_yb171.mass == 171 - assert ion_params_yb171.charge == +1 - assert ion_params_yb171.position == [0, 0, 0] - assert set(ion_params_yb171.levels.keys()) == {"estate", "upstate", "downstate"} - - # Check ion level parameters - assert math.isclose(ion_params_yb171.levels["downstate"].energy, 0.0) - assert math.isclose(ion_params_yb171.levels["upstate"].energy, 2 * math.pi * 12.643e9) - assert math.isclose(ion_params_yb171.levels["estate"].energy, 2 * math.pi * 811.52e12) - - assert set(ion_params_yb171.transitions.keys()) == { - "downstate_upstate", - "downstate_estate", - "estate_upstate", - } - - # Check ion transition parameters - assert ion_params_yb171.transitions["downstate_upstate"].level1 == "downstate" - assert ion_params_yb171.transitions["downstate_upstate"].level2 == "upstate" - - assert ion_params_yb171.transitions["downstate_estate"].level1 == "downstate" - assert ion_params_yb171.transitions["downstate_estate"].level2 == "estate" - - assert ion_params_yb171.transitions["estate_upstate"].level1 == "estate" - assert ion_params_yb171.transitions["estate_upstate"].level2 == "upstate" - - # Check phonon parameters - assert qubit_database.phonon_parameters - assert math.isclose(qubit_database.phonon_parameters["COM_x"].energy, 2 * math.pi * 5e6) - assert math.isclose(qubit_database.phonon_parameters["COM_y"].energy, 2 * math.pi * 5e6) - assert math.isclose(qubit_database.phonon_parameters["COM_z"].energy, 2 * math.pi * 1e6) - - assert qubit_database.phonon_parameters["COM_x"].eigenvector == [1, 0, 0] - assert qubit_database.phonon_parameters["COM_y"].eigenvector == [0, 1, 0] - assert qubit_database.phonon_parameters["COM_z"].eigenvector == [0, 0, 1] - - def test_from_toml_with_ion_filter(self): - """ - Tests that the OQDQubitDatabase.from_toml method can load the qubit parameters from a sample - oqd_qubit_parameters.toml file and filter the ions by name. - """ - # Select params only for ion Yb171 - qubit_database_yb171 = OQDQubitDatabase.from_toml( - OQD_TEST_DIR / "oqd_qubit_parameters.toml", ion_species_filter="Yb171" - ) - assert qubit_database_yb171.ion_parameters.keys() == {"Yb171"} - - # Select params only for ion Yb171, but input as list[str] - qubit_database_yb171 = OQDQubitDatabase.from_toml( - OQD_TEST_DIR / "oqd_qubit_parameters.toml", ion_species_filter=["Yb171"] - ) - assert qubit_database_yb171.ion_parameters.keys() == {"Yb171"} - - # Selecting params for ion that does not exist should result in empty dict - qubit_database_invalid = OQDQubitDatabase.from_toml( - OQD_TEST_DIR / "oqd_qubit_parameters.toml", ion_species_filter=["none"] - ) - assert not qubit_database_invalid.ion_parameters - - # Incorrect filter type should raise TypeError - with pytest.raises(TypeError, match="Expected a string or a collection of strings"): - OQDQubitDatabase.from_toml( - OQD_TEST_DIR / "oqd_qubit_parameters.toml", ion_species_filter=1 - ) - - def test_from_toml_with_phonon_filter(self): - """ - Tests that the OQDQubitDatabase.from_toml method can load the qubit parameters from a sample - oqd_qubit_parameters.toml file and filter the phonon modes by name. - """ - # Select params only for phonon mode COM_x - qubit_database_comx = OQDQubitDatabase.from_toml( - OQD_TEST_DIR / "oqd_qubit_parameters.toml", phonon_mode_filter=["COM_x"] - ) - assert qubit_database_comx.phonon_parameters.keys() == {"COM_x"} - - # Selecting params for phonon mode that does not exist should result in empty dict - qubit_database_invalid = OQDQubitDatabase.from_toml( - OQD_TEST_DIR / "oqd_qubit_parameters.toml", phonon_mode_filter=["none"] - ) - assert not qubit_database_invalid.phonon_parameters - - -class TestOQDQubitDatabaseInvalid: - """Test suite for the OQDQubitDatabase class given invalid TOML input.""" - - def test_from_toml_invalid(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises a ValueError when the TOML document - is invalid. - """ - with pytest.raises(ValueError, match="Failed to load TOML document"): - OQDQubitDatabase.from_toml("Invalid TOML document") - - def test_from_toml_invalid_missing_schema(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises an error if the TOML file is - missing the schema key. - """ - toml_document = textwrap.dedent( - """\ - # Empty TOML document - """ - ) - - with pytest.raises( - AssertionError, match="TOML document must contain key 'oqd_config_schema'" - ): - OQDQubitDatabase.from_toml(toml_document) - - def test_from_toml_invalid_schema(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises an error if the TOML file contains - an invalid schema. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.0" # This is an invalid schema - """ - ) - - with pytest.raises(AssertionError, match="Unsupported OQD TOML config schema"): - OQDQubitDatabase.from_toml(toml_document) - - def test_from_toml_invalid_missing_ions(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises an error if the TOML file is - missing the 'ions' key. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.1" - - # --- Ions --- # - # This section intentionally left blank - - # --- Phonons --- # - [phonons.COM_x] - energy = "2 * math.pi * 5e6" - eigenvector = [1, 0, 0] - """ - ) - - with pytest.raises( - AssertionError, match="TOML document for OQD qubit parameters must contain key 'ions'" - ): - OQDQubitDatabase.from_toml(toml_document) - - def test_from_toml_invalid_missing_phonons(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises an error if the TOML file is - missing the 'phonons' key. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.1" - - # --- Ions --- # - [ions.Yb171] - mass = 171 - charge = +1 - position = [0, 0, 0] - - # --- Phonons --- # - # This section intentionally left blank - """ - ) - - with pytest.raises( - AssertionError, - match="TOML document for OQD qubit parameters must contain key 'phonons'", - ): - OQDQubitDatabase.from_toml(toml_document) - - def test_from_toml_invalid_expr(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises an error if the TOML file contains - an invalid arithmetic expression. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.1" - - # --- Ions --- # - [ions.Yb171] - mass = 171 - charge = +1 - position = [0, 0, 0] - - levels.downstate.principal = 6 - levels.downstate.spin = 0.5 - levels.downstate.orbital = 0 - levels.downstate.nuclear = 0.5 - levels.downstate.spin_orbital = 0.5 - levels.downstate.spin_orbital_nuclear = 0 - levels.downstate.spin_orbital_nuclear_magnetization = 0 - levels.downstate.energy = 0 - - levels.upstate.principal = 6 - levels.upstate.spin = 0.5 - levels.upstate.orbital = 0 - levels.upstate.nuclear = 0.5 - levels.upstate.spin_orbital = 0.5 - levels.upstate.spin_orbital_nuclear = 1 - levels.upstate.spin_orbital_nuclear_magnetization = 0 - levels.upstate.energy = "1 + math.sin('a') + math.cos" # Invalid arithmetic expression - - levels.estate.principal = 5 - levels.estate.spin = 0.5 - levels.estate.orbital = 1 - levels.estate.nuclear = 0.5 - levels.estate.spin_orbital = 0.5 - levels.estate.spin_orbital_nuclear = 0 - levels.estate.spin_orbital_nuclear_magnetization = 0 - levels.estate.energy = "1 + math.sin('a') + math.cos" # Invalid arithmetic expression - - # --- Phonons --- # - [phonons.COM_x] - energy = "2 * math.pi * 5e6" - eigenvector = [1, 0, 0] - """ - ) - - with pytest.raises(ValueError, match="Invalid expression:"): - OQDQubitDatabase.from_toml(toml_document) - - -class TestOQDBeamDatabase: - """Tests for the OQDBeamDatabase class.""" - - def test_from_toml_production(self): - """ - Tests that the OQDBeamDatabase.from_toml method can load the beam parameters from the - oqd_beam_parameters.toml file used in production. - - Here, we only test that we can load the file; we do not check any values since they are - subject to change in the production TOML file. - """ - beam_database = OQDBeamDatabase.from_toml(OQD_SRC_DIR / "oqd_beam_parameters.toml") - assert beam_database.beam_parameters - - def test_from_toml(self): - """ - Tests that the OQDBeamDatabase.from_toml method can load the beam parameters from a - sample oqd_beam_parameters.toml file. - """ - beam_database = OQDBeamDatabase.from_toml(OQD_TEST_DIR / "oqd_beam_parameters.toml") - assert beam_database.beam_parameters - - assert beam_database.beam_parameters["downstate_upstate"] - assert beam_database.beam_parameters["downstate_upstate"].transition == "downstate_upstate" - assert math.isclose( - beam_database.beam_parameters["downstate_upstate"].rabi, 2 * math.pi * 1e6 - ) - assert beam_database.beam_parameters["downstate_upstate"].detuning == 0 - assert beam_database.beam_parameters["downstate_upstate"].phase == 0 - assert math.isnan(beam_database.beam_parameters["downstate_upstate"].polarization) - assert math.isnan(beam_database.beam_parameters["downstate_upstate"].wavevector) - - assert beam_database.beam_parameters["downstate_estate"] - assert beam_database.beam_parameters["downstate_estate"].transition == "downstate_estate" - assert math.isclose( - beam_database.beam_parameters["downstate_estate"].rabi, 2 * math.pi * 1e6 - ) - assert beam_database.beam_parameters["downstate_estate"].detuning == 0 - assert beam_database.beam_parameters["downstate_estate"].phase == 0 - assert math.isnan(beam_database.beam_parameters["downstate_estate"].polarization) - assert math.isnan(beam_database.beam_parameters["downstate_estate"].wavevector) - - def test_from_toml_invalid(self): - """ - Tests that the OQDBeamDatabase.from_toml method raises a ValueError when the TOML document - is invalid. - """ - with pytest.raises(ValueError, match="Failed to load TOML document"): - OQDBeamDatabase.from_toml("Invalid TOML document") - - def test_from_toml_invalid_missing_schema(self): - """ - Tests that the OQDQubitDatabase.from_toml method raises an error if the TOML file is - missing the schema key. - """ - toml_document = textwrap.dedent( - """\ - # Empty TOML document - """ - ) - - with pytest.raises( - AssertionError, match="TOML document must contain key 'oqd_config_schema'" - ): - OQDBeamDatabase.from_toml(toml_document) - - def test_from_toml_invalid_schema(self): - """ - Tests that the OQDBeamDatabase.from_toml method raises an error if the TOML file contains - an invalid schema. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.0" # This is an invalid schema - """ - ) - - with pytest.raises(AssertionError, match="Unsupported OQD TOML config schema"): - OQDBeamDatabase.from_toml(toml_document) - - def test_from_toml_invalid_beams(self): - """ - Tests that the OQDBeamDatabase.from_toml method raises an error if the TOML file is - missing the 'beams' key. - """ - toml_document = textwrap.dedent( - """\ - oqd_config_schema = "v0.1" - - # --- Beams --- # - # This section intentionally left blank - """ - ) - - with pytest.raises( - AssertionError, match="TOML document for OQD beam parameters must contain key 'beams'" - ): - OQDBeamDatabase.from_toml(toml_document) - - -class TestOQDDatabaseManagerUtils: - """ - Tests for the miscellaneous utility functions in the oqd_database_managers module. - """ - - def test_parse_value_or_expression_as_float(self): - """ - Tests that the _parse_value_or_expression_as_float function works as expected. - """ - assert _parse_value_or_expression_as_float(1.0) == 1.0 - assert _parse_value_or_expression_as_float(1) == 1.0 - assert math.isnan(_parse_value_or_expression_as_float(math.nan)) - assert _parse_value_or_expression_as_float("1.0") == 1.0 - assert _parse_value_or_expression_as_float("1") == 1.0 - - with pytest.raises(ValueError, match="Invalid expression"): - _parse_value_or_expression_as_float("invalid") - - with pytest.raises(TypeError, match="Expected a number or string"): - _parse_value_or_expression_as_float(None) - - with pytest.raises(TypeError, match="Expected a number or string"): - _parse_value_or_expression_as_float([1, 2, 3]) - - def test_string_or_collection_of_strings_to_set(self): - """ - Tests that the _string_or_collection_of_strings_to_set function works as expected. - """ - assert _string_or_collection_of_strings_to_set("a") == {"a"} - assert _string_or_collection_of_strings_to_set(["a", "b", "c"]) == {"a", "b", "c"} - - with pytest.raises(TypeError, match="Expected a string or a collection of strings"): - _string_or_collection_of_strings_to_set(1) - - with pytest.raises(AssertionError, match="All items in collection must be strings"): - _string_or_collection_of_strings_to_set([1, 2, 3]) - - -if __name__ == "__main__": - pytest.main(["-x", __file__]) diff --git a/frontend/test/test_oqd/oqd/test_oqd_device.py b/frontend/test/test_oqd/oqd/test_oqd_device.py deleted file mode 100644 index ef1a3f3713..0000000000 --- a/frontend/test/test_oqd/oqd/test_oqd_device.py +++ /dev/null @@ -1,56 +0,0 @@ -# Copyright 2024 Xanadu Quantum Technologies Inc. - -# Licensed 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. - -"""Tests for the Open Quantum Design (OQD) trapped-ion quantum computer device. -""" - -import pennylane as qml -import pytest - - -class TestOQDDevice: - """Test the OQD device python layer for Catalyst.""" - - def test_device_initialization(self): - """Test that the OQD device is correctly initialized. - - The test checks that the backend, ion, shots, and wires parameters are correctly set. - """ - device = qml.device("oqd", backend="default", shots=1024, wires=8) - - assert device.backend == "default" - assert device.shots == qml.measurements.Shots(1024) - assert device.wires == qml.wires.Wires(range(0, 8)) - - def test_device_initialization_invalid_backend(self): - """Test that the OQD device raises an error when an invalid backend is provided.""" - with pytest.raises(ValueError, match="The backend invalid is not supported"): - qml.device("oqd", backend="invalid", shots=1024, wires=8) - - def test_device_python_execution_not_implemented(self): - """Test that the OQD device raises an error for native Python execution.""" - device = qml.device("oqd", backend="default", shots=1024, wires=8) - - @qml.qnode(device) - def circuit(): - qml.RX(0.1, wires=0) - qml.RY(0.2, wires=1) - return qml.expval(qml.PauliZ(0)), qml.expval(qml.PauliZ(1)) - - with pytest.raises(NotImplementedError, match="The OQD device only supports Catalyst"): - circuit() - - -if __name__ == "__main__": - pytest.main(["-x", __file__])