From 99820e881ed26b4b9965499c7c77550547be0cb5 Mon Sep 17 00:00:00 2001 From: paul0403 <79805239+paul0403@users.noreply.github.com> Date: Wed, 18 Dec 2024 18:31:15 -0500 Subject: [PATCH] Skip oqd pytests in build-wheels (#1390) **Context:** A big redesign of oqd ion dialect and the associated toml file format took place during #1260 . Therefore, the frontend oqd pytests (which performs some toml parsing) should be removed, since (a) they are interpreting against the old toml format, and (b) the toml parsing now happens in the mlir layer alongside the actual `--quantum-to-ion` pass, not at the frontend python layer as a standalone. --- .../workflows/build-wheel-linux-x86_64.yaml | 1 - .../workflows/build-wheel-macos-arm64.yaml | 1 - .../workflows/build-wheel-macos-x86_64.yaml | 1 - .../scripts/linux_arm64/rh8/test_wheels.sh | 1 - Makefile | 3 - frontend/test/test_oqd/conftest.py | 38 -- .../test_oqd/oqd/oqd_beam_parameters.toml | 17 - .../test_oqd/oqd/oqd_qubit_parameters.toml | 67 --- .../oqd/test_oqd_database_managers.py | 507 ------------------ frontend/test/test_oqd/oqd/test_oqd_device.py | 56 -- 10 files changed, 692 deletions(-) delete mode 100644 frontend/test/test_oqd/conftest.py delete mode 100644 frontend/test/test_oqd/oqd/oqd_beam_parameters.toml delete mode 100644 frontend/test/test_oqd/oqd/oqd_qubit_parameters.toml delete mode 100644 frontend/test/test_oqd/oqd/test_oqd_database_managers.py delete mode 100644 frontend/test/test_oqd/oqd/test_oqd_device.py 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__])