diff --git a/doc/introduction/data.rst b/doc/introduction/data.rst
index f283c43e48a..51625232b63 100644
--- a/doc/introduction/data.rst
+++ b/doc/introduction/data.rst
@@ -97,6 +97,36 @@ use them directly in a PennyLane circuits as follows:
>>> print(circuit())
-1.0791430411076344
+Viewing Available Dataset Names
+-------------------------------
+
+We can call the
+:func:`~pennylane.data.list_data_names` function to get a snapshot of the names of the currently available datasets.
+This function returns a list of strings as shown below.
+
+>>> qml.data.list_data_names()
+["bars-and-stripes",
+ "downscaled-mnist",
+ "hamlib-max-3-sat",
+ "hamlib-maxcut",
+ "hamlib-travelling-salesperson-problem",
+ "hidden-manifold",
+ "hyperplanes",
+ "ketgpt",
+ "learning-dynamics-incoherently",
+ "linearly-separable",
+ "mnisq",
+ "mqt-bench",
+ "plus-minus",
+ "qchem",
+ "qspin",
+ "rydberggpt",
+ "two-curves"]
+
+Note that this example limits the results
+of the function calls for clarity and that as more data becomes available, the results of these
+function calls will change.
+
Viewing Available Datasets
--------------------------
@@ -161,8 +191,9 @@ Quantum Datasets Functions and Classes
.. autosummary::
:nosignatures:
- ~pennylane.data.list_datasets
~pennylane.data.list_attributes
+ ~pennylane.data.list_data_names
+ ~pennylane.data.list_datasets
~pennylane.data.load
~pennylane.data.load_interactive
~pennylane.data.Dataset
diff --git a/doc/releases/changelog-dev.md b/doc/releases/changelog-dev.md
index 237b52b1942..7f2a89b3bf8 100644
--- a/doc/releases/changelog-dev.md
+++ b/doc/releases/changelog-dev.md
@@ -24,6 +24,59 @@
[Haldane](https://journals.aps.org/prl/pdf/10.1103/PhysRevLett.61.2015) models on a lattice.
[(#6201)](https://github.com/PennyLaneAI/pennylane/pull/6201/)
+* A `has_sparse_matrix` property is added to `Operator` to indicate whether a sparse matrix is defined.
+ [(#6278)](https://github.com/PennyLaneAI/pennylane/pull/6278)
+ [(#6310)](https://github.com/PennyLaneAI/pennylane/pull/6310)
+
+
Improvements ðŸ›
+
+* RTD support for `qml.labs` added to API.
+ [(#6397)](https://github.com/PennyLaneAI/pennylane/pull/6397)
+
+* Module-level sandboxing added to `qml.labs` via pre-commit hooks.
+ [(#6369)](https://github.com/PennyLaneAI/pennylane/pull/6369)
+
+* `qml.matrix` now works with empty objects (such as empty tapes, `QNode`s and quantum functions that do
+ not call operations, single operators with empty decompositions).
+ [(#6347)](https://github.com/PennyLaneAI/pennylane/pull/6347)
+
+* PennyLane is now compatible with NumPy 2.0.
+ [(#6061)](https://github.com/PennyLaneAI/pennylane/pull/6061)
+ [(#6258)](https://github.com/PennyLaneAI/pennylane/pull/6258)
+ [(#6342)](https://github.com/PennyLaneAI/pennylane/pull/6342)
+
+* PennyLane is now compatible with Jax 0.4.28.
+ [(#6255)](https://github.com/PennyLaneAI/pennylane/pull/6255)
+
+* `qml.qchem.excitations` now optionally returns fermionic operators.
+ [(#6171)](https://github.com/PennyLaneAI/pennylane/pull/6171)
+
+* The `diagonalize_measurements` transform now uses a more efficient method of diagonalization
+ when possible, based on the `pauli_rep` of the relevant observables.
+ [(#6113)](https://github.com/PennyLaneAI/pennylane/pull/6113/)
+
+* The `QuantumScript.copy` method now takes `operations`, `measurements`, `shots` and
+ `trainable_params` as keyword arguments. If any of these are passed when copying a
+ tape, the specified attributes will replace the copied attributes on the new tape.
+ [(#6285)](https://github.com/PennyLaneAI/pennylane/pull/6285)
+ [(#6363)](https://github.com/PennyLaneAI/pennylane/pull/6363)
+
+* Datasets are now downloaded via Dataset API.
+ [(#6126)](https://github.com/PennyLaneAI/pennylane/pull/6126)
+
+* The `Hermitian` operator now has a `compute_sparse_matrix` implementation.
+ [(#6225)](https://github.com/PennyLaneAI/pennylane/pull/6225)
+
+* All PL templates are now unit tested to ensure JIT compatibility.
+ [(#6309)](https://github.com/PennyLaneAI/pennylane/pull/6309)
+
+* `qml.QutritBasisStatePreparation` is now JIT compatible.
+ [(#6308)](https://github.com/PennyLaneAI/pennylane/pull/6308)
+
+* `qml.AmplitudeAmplification` is now compatible with QJIT.
+ [(#6306)](https://github.com/PennyLaneAI/pennylane/pull/6306)
+
+
Calculating Polynomials 🔢
Readout Noise ðŸ“
@@ -426,6 +479,7 @@ Diksha Dhawan,
Lillian M. A. Frederiksen,
Pietropaolo Frisoni,
Emiliano Godinez,
+Anthony Hayes,
Austin Huang,
Soran Jahangiri,
Jacob Kitchen,
diff --git a/pennylane/data/__init__.py b/pennylane/data/__init__.py
index 2f07debe26d..10c34c74b35 100644
--- a/pennylane/data/__init__.py
+++ b/pennylane/data/__init__.py
@@ -37,6 +37,7 @@
load
load_interactive
list_attributes
+ list_data_names
list_datasets
In addition, various dataset types are provided
@@ -207,16 +208,24 @@ class QuantumOscillator(qml.data.Dataset, data_name="quantum_oscillator", identi
DatasetMolecule,
DatasetNone,
DatasetOperator,
+ DatasetPyTree,
DatasetScalar,
DatasetSparseArray,
DatasetString,
DatasetTuple,
- DatasetPyTree,
)
from .base import DatasetNotWriteableError
from .base.attribute import AttributeInfo, DatasetAttribute, attribute
from .base.dataset import Dataset, field
-from .data_manager import DEFAULT, FULL, list_attributes, list_datasets, load, load_interactive
+from .data_manager import (
+ DEFAULT,
+ FULL,
+ list_attributes,
+ list_datasets,
+ list_data_names,
+ load,
+ load_interactive,
+)
__all__ = (
"AttributeInfo",
@@ -240,6 +249,7 @@ class QuantumOscillator(qml.data.Dataset, data_name="quantum_oscillator", identi
"load",
"load_interactive",
"list_attributes",
+ "list_data_names",
"list_datasets",
"DEFAULT",
"FULL",
diff --git a/pennylane/data/attributes/__init__.py b/pennylane/data/attributes/__init__.py
index a699d6b5a05..7b7f3600cfb 100644
--- a/pennylane/data/attributes/__init__.py
+++ b/pennylane/data/attributes/__init__.py
@@ -20,11 +20,11 @@
from .molecule import DatasetMolecule
from .none import DatasetNone
from .operator import DatasetOperator
+from .pytree import DatasetPyTree
from .scalar import DatasetScalar
from .sparse_array import DatasetSparseArray
from .string import DatasetString
from .tuple import DatasetTuple
-from .pytree import DatasetPyTree
__all__ = (
"DatasetArray",
diff --git a/pennylane/data/base/graphql.py b/pennylane/data/base/graphql.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/pennylane/data/data_manager/__init__.py b/pennylane/data/data_manager/__init__.py
index e8f274c30e9..220a83e23c7 100644
--- a/pennylane/data/data_manager/__init__.py
+++ b/pennylane/data/data_manager/__init__.py
@@ -16,21 +16,29 @@
them.
"""
+import sys
import urllib.parse
from concurrent import futures
from functools import lru_cache
from pathlib import Path
from time import sleep
-from typing import Iterable, Mapping, Optional, Union
-import sys
+from typing import Any, Iterable, Mapping, Optional, Union
+
from requests import get, head
from pennylane.data.base import Dataset
from pennylane.data.base.hdf5 import open_hdf5_s3
from pennylane.data.data_manager import progress
+from .graphql import (
+ get_dataset_urls,
+ _get_parameter_tree,
+ list_data_names,
+ list_attributes,
+)
from .foldermap import DataPath, FolderMapView, ParamArg
-from .params import DEFAULT, FULL, format_params
+from .params import DEFAULT, FULL, format_params, provide_defaults
+
S3_URL = "https://datasets.cloud.pennylane.ai/datasets/h5"
FOLDERMAP_URL = f"{S3_URL}/foldermap.json"
@@ -52,7 +60,8 @@ def _get_data_struct():
response = get(DATA_STRUCT_URL, timeout=5.0)
response.raise_for_status()
- return response.json()
+
+S3_URL = "https://datasets.cloud.pennylane.ai/datasets/h5"
def _download_partial( # pylint: disable=too-many-arguments
@@ -119,15 +128,15 @@ def _download_full(s3_url: str, dest: Path, block_size: int, pbar_task: Optional
f.write(block)
-def _download_dataset( # pylint:disable=too-many-arguments
- s3_url: str,
+def _download_dataset( # pylint: disable=too-many-arguments
+ dataset_url: str,
dest: Path,
attributes: Optional[Iterable[str]],
block_size: int,
force: bool,
pbar_task: Optional[progress.Task],
) -> None:
- """Downloads the dataset at ``data_path`` to ``dest``, optionally downloading
+ """Downloads the dataset at ``dataset_url`` to ``dest``, optionally downloading
only requested attributes. If ``attributes`` is not provided, every attribute
will be requested.
@@ -139,7 +148,7 @@ def _download_dataset( # pylint:disable=too-many-arguments
if attributes is not None or dest.exists():
_download_partial(
- s3_url,
+ dataset_url,
dest=dest,
attributes=attributes,
overwrite=force,
@@ -147,40 +156,39 @@ def _download_dataset( # pylint:disable=too-many-arguments
pbar_task=pbar_task,
)
else:
- _download_full(s3_url, dest=dest, block_size=block_size, pbar_task=pbar_task)
+ _download_full(dataset_url, dest=dest, block_size=block_size, pbar_task=pbar_task)
def _download_datasets( # pylint: disable=too-many-arguments
- s3_base_url: str,
+ data_name: str,
folder_path: Path,
- data_paths: list[DataPath],
+ dataset_urls: list[str],
+ dataset_ids: list[str],
attributes: Optional[Iterable[str]],
force: bool,
block_size: int,
num_threads: int,
pbar: Optional[progress.Progress],
) -> list[Path]:
- """Downloads the datasets with given ``data_paths`` to ``folder_path``, copying the
- directory structure of the bucket at ``s3_base_url``.
+ """Downloads the datasets with given ``dataset_urls`` to ``folder_path``.
If ``pbar`` is provided, a progress task will be added for each requested dataset.
Returns:
list[Path]: List of downloaded dataset paths
"""
- # URL-escape special characters like '+', '$', and '%' in the data path
- s3_urls = [f"{s3_base_url}/{urllib.parse.quote(str(data_path))}" for data_path in data_paths]
+ file_names = [dataset_id + ".h5" for dataset_id in dataset_ids]
+ dest_paths = [folder_path / data_name / data_id for data_id in file_names]
- dest_paths = [folder_path / data_path for data_path in data_paths]
for path_parents in set(path.parent for path in dest_paths):
path_parents.mkdir(parents=True, exist_ok=True)
if pbar is not None:
if attributes is None:
- file_sizes = [int(head(s3_url).headers["Content-Length"]) for s3_url in s3_urls]
+ file_sizes = [int(head(url).headers["Content-Length"]) for url in dataset_urls]
else:
# Can't get file sizes for partial downloads
- file_sizes = (None for _ in s3_urls)
+ file_sizes = (None for _ in dataset_urls)
pbar_tasks = [
pbar.add_task(str(dest_path.relative_to(folder_path)), total=file_size)
@@ -190,11 +198,11 @@ def _download_datasets( # pylint: disable=too-many-arguments
pbar_tasks = (None for _ in dest_paths)
with futures.ThreadPoolExecutor(min(num_threads, len(dest_paths))) as pool:
- for s3_url, dest_path, pbar_task in zip(s3_urls, dest_paths, pbar_tasks):
+ for url, dest_path, pbar_task in zip(dataset_urls, dest_paths, pbar_tasks):
futs = [
pool.submit(
_download_dataset,
- s3_url,
+ url,
dest_path,
attributes=attributes,
force=force,
@@ -209,12 +217,11 @@ def _download_datasets( # pylint: disable=too-many-arguments
return dest_paths
-def _validate_attributes(data_struct: dict, data_name: str, attributes: Iterable[str]):
+def _validate_attributes(data_name: str, attributes: Iterable[str]):
"""Checks that ``attributes`` contains only valid attributes for the given
``data_name``. If any attributes do not exist, raise a ValueError."""
- invalid_attributes = [
- attr for attr in attributes if attr not in data_struct[data_name]["attributes"]
- ]
+ valid_attributes = list_attributes(data_name)
+ invalid_attributes = [attr for attr in attributes if attr not in valid_attributes]
if not invalid_attributes:
return
@@ -223,7 +230,7 @@ def _validate_attributes(data_struct: dict, data_name: str, attributes: Iterable
else:
values_err = f"{invalid_attributes} are invalid attributes for '{data_name}'"
- raise ValueError(f"{values_err}. Valid attributes are: {data_struct[data_name]['attributes']}")
+ raise ValueError(f"{values_err}. Valid attributes are: {valid_attributes}")
def load( # pylint: disable=too-many-arguments
@@ -257,7 +264,7 @@ def load( # pylint: disable=too-many-arguments
Returns:
list[:class:`~pennylane.data.Dataset`]
- .. seealso:: :func:`~.load_interactive`, :func:`~.list_attributes`, :func:`~.list_datasets`.
+ .. seealso:: :func:`~.load_interactive`, :func:`~.list_attributes`, :func:`~.list_data_names`.
**Example**
@@ -320,25 +327,39 @@ def load( # pylint: disable=too-many-arguments
>>> print(circuit())
-1.0791430411076344
"""
- foldermap = _get_foldermap()
- data_struct = _get_data_struct()
-
params = format_params(**params)
if attributes:
- _validate_attributes(data_struct, data_name, attributes)
+ _validate_attributes(data_name, attributes)
+
+ folder_path = Path(folder_path)
+
+ if data_name == "other":
+ data_name = params[0]["values"][0]
+ params = []
+
+ params = provide_defaults(data_name, params)
+ params = [param for param in params if ("values", ParamArg.FULL) not in list(param.items())]
+
+ dataset_ids_and_urls = get_dataset_urls(data_name, params)
+ if dataset_ids_and_urls == []:
+ raise ValueError(
+ "No datasets exist for the provided configuration.\n"
+ "Please check the available datasets by using the ``qml.data.list_datasets()`` function."
+ )
- folder_path = Path(folder_path).resolve()
- data_paths = [data_path for _, data_path in foldermap.find(data_name, **params)]
+ dataset_urls = [dataset_url for _, dataset_url in dataset_ids_and_urls]
+ dataset_ids = [dataset_id for dataset_id, _ in dataset_ids_and_urls]
progress_bar = progress_bar if progress_bar is not None else sys.stdout.isatty()
if progress_bar:
with progress.Progress() as pbar:
download_paths = _download_datasets(
- S3_URL,
+ data_name,
folder_path,
- data_paths,
+ dataset_urls,
+ dataset_ids,
attributes,
force=force,
block_size=block_size,
@@ -348,9 +369,10 @@ def load( # pylint: disable=too-many-arguments
else:
download_paths = _download_datasets(
- S3_URL,
+ data_name,
folder_path,
- data_paths,
+ dataset_urls,
+ dataset_ids,
attributes,
force=force,
block_size=block_size,
@@ -402,69 +424,55 @@ def remove_paths(foldermap):
return remove_paths(_get_foldermap())
-def list_attributes(data_name):
- r"""List the attributes that exist for a specific ``data_name``.
+def _interactive_request_data_name(data_names):
+ """Prompt the user to select a data name."""
+ print("Please select the data name from the following:")
+ for i, option in enumerate(data_names):
+ print(f"{i + 1}: {option}")
+ choice = input("Choice of data name: ").strip()
+ if choice not in data_names:
+ raise ValueError(f"Must select a single data name from {data_names}")
+ return choice
- Args:
- data_name (str): The type of the desired data
- Returns:
- list (str): A list of accepted attributes for a given data name
+def _interactive_request_attributes(attribute_options):
+ """Prompt the user to select a list of attributes."""
+ print(
+ 'Please select a list of attributes from the following available attributes or "full" for all attributes.'
+ )
+ for i, option in enumerate(attribute_options):
+ print(f"{i + 1}: {option}")
- .. seealso:: :func:`~.load_interactive`, :func:`~.list_datasets`, :func:`~.load`.
+ choice_input = input("Comma-separated list of attributes: ")
+ choices = [str(choice).strip() for choice in choice_input.strip("[]").split(",")]
+ if "full" in choices:
+ return attribute_options
+ if not (choices and set(choices).issubset(set(attribute_options))):
+ raise ValueError(f"Must select a list of attributes from {attribute_options}")
- **Example**
+ return choices
- >>> qml.data.list_attributes(data_name="qchem")
- ['molname',
- 'basis',
- 'bondlength',
- ...
- 'vqe_params',
- 'vqe_energy']
- """
- data_struct = _get_data_struct()
- if data_name not in data_struct:
- raise ValueError(
- f"Currently the hosted datasets are of types: {list(data_struct)}, but got {data_name}."
- )
- return data_struct[data_name]["attributes"]
+def _interactive_requests(parameters, parameter_tree):
+ """Prompts the user to select parameters for datasets one at a time."""
-def _interactive_request_attributes(options):
- """Prompt the user to select a list of attributes."""
- prompt = "Please select attributes:"
- for i, option in enumerate(options):
- if option == "full":
- option = "full (all attributes)"
- prompt += f"\n\t{i+1}) {option}"
- print(prompt)
- choices = input(f"Choice (comma-separated list of options) [1-{len(options)}]: ").split(",")
- try:
- choices = list(map(int, choices))
- except ValueError as e:
- raise ValueError(f"Must enter a list of integers between 1 and {len(options)}") from e
- if any(choice < 1 or choice > len(options) for choice in choices):
- raise ValueError(f"Must enter a list of integers between 1 and {len(options)}")
- return [options[choice - 1] for choice in choices]
-
-
-def _interactive_request_single(node, param):
- """Prompt the user to select a single option from a list."""
- options = list(node)
- if len(options) == 1:
- print(f"Using {options[0]} as it is the only {param} available.")
- sleep(1)
- return options[0]
- print(f"Please select a {param}:")
- print("\n".join(f"\t{i+1}) {option}" for i, option in enumerate(options)))
- try:
- choice = int(input(f"Choice [1-{len(options)}]: "))
- except ValueError as e:
- raise ValueError(f"Must enter an integer between 1 and {len(options)}") from e
- if choice < 1 or choice > len(options):
- raise ValueError(f"Must enter an integer between 1 and {len(options)}")
- return options[choice - 1]
+ branch = parameter_tree
+ for param in parameters:
+
+ if len(branch["next"]) == 1:
+ branch = next(iter(branch["next"].values()))
+ continue
+
+ print(f"Available options for {param}:")
+ for i, option in enumerate(branch["next"].keys()):
+ print(f"{i + 1}: {option}")
+ user_value = input(f"Please select a {param}:").strip()
+ try:
+ branch = branch["next"][user_value]
+ except KeyError as e:
+ raise ValueError(f"Must enter a valid {param}:") from e
+
+ return branch
def load_interactive():
@@ -475,14 +483,15 @@ def load_interactive():
**Example**
- .. seealso:: :func:`~.load`, :func:`~.list_attributes`, :func:`~.list_datasets`.
+ .. seealso:: :func:`~.load`, :func:`~.list_attributes`, :func:`~.list_data_names`.
.. code-block :: pycon
>>> qml.data.load_interactive()
- Please select a data name:
- 1) qspin
- 2) qchem
+ Please select the data name from the following:
+ 1: qspin
+ 2: qchem
+ 3: other
Choice [1-2]: 1
Please select a sysname:
...
@@ -503,37 +512,24 @@ def load_interactive():
force: False
dest folder: /Users/jovyan/Downloads/datasets
Would you like to continue? (Default is yes) [Y/n]:
-
"""
- foldermap = _get_foldermap()
- data_struct = _get_data_struct()
+ data_names = list_data_names()
+ data_name = _interactive_request_data_name(data_names)
- node = foldermap
- data_name = _interactive_request_single(node, "data name")
+ parameters, attribute_options, parameter_tree = _get_parameter_tree(data_name)
- description = {}
- value = data_name
-
- params = data_struct[data_name]["params"]
- for param in params:
- node = node[value]
- value = _interactive_request_single(node, param)
- description[param] = value
-
- attributes = _interactive_request_attributes(
- [attribute for attribute in data_struct[data_name]["attributes"] if attribute not in params]
- )
+ dataset_id = _interactive_requests(parameters, parameter_tree)
+ attributes = _interactive_request_attributes(attribute_options)
force = input("Force download files? (Default is no) [y/N]: ") in ["y", "Y"]
dest_folder = Path(
input("Folder to download to? (Default is pwd, will download to /datasets subdirectory): ")
)
-
print("\nPlease confirm your choices:")
- print("dataset:", "/".join([data_name] + [description[param] for param in params]))
print("attributes:", attributes)
print("force:", force)
print("dest folder:", dest_folder / "datasets")
+ print("dataset:", dataset_id)
approve = input("Would you like to continue? (Default is yes) [Y/n]: ")
if approve not in ["Y", "", "y"]:
@@ -545,14 +541,13 @@ def load_interactive():
attributes=attributes,
folder_path=dest_folder,
force=force,
- **description,
)[0]
__all__ = (
"load",
"load_interactive",
- "list_datasets",
+ "list_data_names",
"list_attributes",
"FULL",
"DEFAULT",
diff --git a/pennylane/data/data_manager/foldermap.py b/pennylane/data/data_manager/foldermap.py
index f7324fa343e..8a511375252 100644
--- a/pennylane/data/data_manager/foldermap.py
+++ b/pennylane/data/data_manager/foldermap.py
@@ -38,7 +38,7 @@ class FolderMapView(Mapping[str, Union["FolderMapView", DataPath]]):
file.
A dictionary in the folder map can optionally specify a default
- paramater using the '__default' key. This view hides that
+ parameter using the '__default' key. This view hides that
key, and allows the default parameter to be accessed.
For example, the underlying foldermap data will look like
diff --git a/pennylane/data/data_manager/graphql.py b/pennylane/data/data_manager/graphql.py
new file mode 100644
index 00000000000..c1057468ce3
--- /dev/null
+++ b/pennylane/data/data_manager/graphql.py
@@ -0,0 +1,155 @@
+"""
+Module for containing graphql functionality for interacting with the Datasets Service API.
+"""
+
+import os
+from typing import Any, Optional
+
+from requests import post
+
+GRAPHQL_URL = os.getenv("DATASETS_ENDPOINT_URL", "https://cloud.pennylane.ai/graphql")
+
+
+class GraphQLError(BaseException):
+ """Exception for GraphQL"""
+
+
+def get_graphql(url: str, query: str, variables: Optional[dict[str, Any]] = None):
+ """
+ Args:
+ url: The URL to send a query to.
+ query: The main body of the query to be sent.
+ variables: Additional input variables to the query body.
+
+ Returns:
+ string: json response.
+ GraphQLError: if there no response is received or errors are received in the json response.
+ """
+
+ json = {"query": query}
+
+ if variables:
+ json["variables"] = variables
+
+ response = post(url=url, json=json, timeout=10, headers={"content-type": "application/json"})
+ response.raise_for_status()
+ if "errors" in response.json():
+ all_errors = ",".join(error["message"] for error in response.json()["errors"])
+ raise GraphQLError(f"Errors in request: {all_errors}")
+
+ return response.json()
+
+
+def get_dataset_urls(class_id: str, parameters: dict[str, list[str]]) -> list[tuple[str, str]]:
+ """
+ Args:
+ class_id: Dataset class id e.g 'qchem', 'qspin'
+ parameters: Dataset parameters e.g 'molname', 'basis'
+
+ Returns:
+ list of tuples (dataset_id, dataset_url)
+
+ Example usage:
+ >>> get_dataset_urls("qchem", {"molname": ["H2"], "basis": ["STO-3G"], "bondlength": ["0.5"]})
+ [("H2_STO-3G_0.5", "https://cloud.pennylane.ai/datasets/h5/qchem/h2/sto-3g/0.5.h5")]
+ """
+
+ response = get_graphql(
+ GRAPHQL_URL,
+ """
+ query GetDatasetsForDownload($datasetClassId: String!, $parameters: [DatasetParameterInput!]) {
+ datasetClass(id: $datasetClassId) {
+ datasets(parameters: $parameters) {
+ id
+ downloadUrl
+ }
+ }
+ }
+ """,
+ {"datasetClassId": class_id, "parameters": parameters},
+ )
+
+ return [
+ (resp["id"], resp["downloadUrl"]) for resp in response["data"]["datasetClass"]["datasets"]
+ ]
+
+
+def list_data_names() -> list[str]:
+ """Get list of dataclass IDs."""
+ response = get_graphql(
+ GRAPHQL_URL,
+ """
+ query GetDatasetClasses {
+ datasetClasses {
+ id
+ }
+ }
+ """,
+ )
+ return [dsc["id"] for dsc in response["data"]["datasetClasses"]]
+
+
+def list_attributes(data_name) -> list[str]:
+ r"""List the attributes that exist for a specific ``data_name``.
+
+ Args:
+ data_name (str): The type of the desired data
+
+ Returns:
+ list (str): A list of accepted attributes for a given data name
+
+ .. seealso:: :func:`~.load_interactive`, :func:`~.list_data_names`, :func:`~.load`.
+
+ **Example**
+
+ >>> qml.data.list_attributes(data_name="qchem")
+ ['molname',
+ 'basis',
+ 'bondlength',
+ ...
+ 'vqe_params',
+ 'vqe_energy']
+ """
+
+ response = get_graphql(
+ GRAPHQL_URL,
+ """
+ query ListAttributes($datasetClassId: String!) {
+ datasetClass(id: $datasetClassId) {
+ attributes {
+ name
+ }
+ }
+ }
+ """,
+ {"datasetClassId": data_name},
+ )
+
+ return [attribute["name"] for attribute in response["data"]["datasetClass"]["attributes"]]
+
+
+def _get_parameter_tree(class_id) -> tuple[list[str], list[str], dict]:
+ """Returns the (parameters, attributes, parameter_tree) for a given ``class_id``."""
+
+ response = get_graphql(
+ GRAPHQL_URL,
+ """
+ query GetParameterTree($datasetClassId: String!) {
+ datasetClass(id: $datasetClassId) {
+ attributes {
+ name
+ }
+ parameters {
+ name
+ }
+ parameterTree
+ }
+ }
+ """,
+ {"datasetClassId": class_id},
+ )
+
+ parameters = [param["name"] for param in response["data"]["datasetClass"]["parameters"]]
+ attributes = [atr["name"] for atr in response["data"]["datasetClass"]["attributes"]]
+
+ return (parameters, attributes, response["data"]["datasetClass"]["parameterTree"])
diff --git a/pennylane/data/data_manager/params.py b/pennylane/data/data_manager/params.py
index 16c3fe8e5c5..de5a3be27db 100644
--- a/pennylane/data/data_manager/params.py
+++ b/pennylane/data/data_manager/params.py
@@ -126,9 +126,36 @@ def format_param_args(param: ParamName, details: Any) -> Union[ParamArg, list[Pa
return details
-def format_params(**params: Any) -> dict[ParamName, Union[ParamArg, ParamVal]]:
- """Converts params to a dictionary whose keys are parameter names and
- whose values are single ``ParamaterArg`` objects or lists of parameter values."""
- return {
+def format_params(**params: Any) -> list[dict[str:ParamName, str : Union[ParamArg, ParamVal]]]:
+ """Converts params to a list of dictionaries whose values are parameter names and
+ single ``ParamaterArg`` objects or lists of parameter values."""
+
+ input_params = {
param_name: format_param_args(param_name, param) for param_name, param in params.items()
}
+ return [{"name": k, "values": v} for k, v in input_params.items()]
+
+
+def provide_defaults(
+ data_name: str, params: list[dict[str:ParamName, str : Union[ParamArg, ParamVal]]]
+) -> list[dict[str:ParamName, str : Union[ParamArg, ParamVal]]]:
+ """
+ Provides default parameters to the qchem and qspin query parameters if the parameter
+ names are missing from the provided ``params``.
+ """
+ param_names = [param["name"] for param in params]
+ if data_name == "qchem":
+ if "basis" not in param_names:
+ params.append({"default": True, "name": "basis"})
+ if "bondlength" not in param_names:
+ params.append({"default": True, "name": "bondlength"})
+
+ if data_name == "qspin":
+ if "periodicity" not in param_names:
+ params.append({"default": True, "name": "periodicity"})
+ if "lattice" not in param_names:
+ params.append({"default": True, "name": "lattice"})
+ if "layout" not in param_names:
+ params.append({"default": True, "name": "layout"})
+
+ return params
diff --git a/pennylane/data/data_manager/progress/__init__.py b/pennylane/data/data_manager/progress/__init__.py
index f11d8c2595f..3e9df7d8274 100644
--- a/pennylane/data/data_manager/progress/__init__.py
+++ b/pennylane/data/data_manager/progress/__init__.py
@@ -15,14 +15,10 @@
from typing import Any, Optional
-from pennylane.data.data_manager.progress._default import (
- make_progress as make_progress_default,
-)
+from pennylane.data.data_manager.progress._default import make_progress as make_progress_default
try:
- from pennylane.data.data_manager.progress._rich import (
- make_progress as make_progress_rich,
- )
+ from pennylane.data.data_manager.progress._rich import make_progress as make_progress_rich
except ImportError: # pragma: no cover
make_progress_rich = None
diff --git a/tests/data/data_manager/__init__.py b/tests/data/data_manager/__init__.py
new file mode 100644
index 00000000000..e69de29bb2d
diff --git a/tests/data/data_manager/support.py b/tests/data/data_manager/support.py
new file mode 100644
index 00000000000..d7bea1532bf
--- /dev/null
+++ b/tests/data/data_manager/support.py
@@ -0,0 +1,1483 @@
+"""Test support for mocking GraphQL queries"""
+
+_list_attrs_resp = {
+ "data": {
+ "datasetClass": {
+ "attributes": [
+ {"name": "basis_rot_groupings"},
+ {"name": "basis_rot_samples"},
+ {"name": "dipole_op"},
+ {"name": "fci_energy"},
+ {"name": "fci_spectrum"},
+ {"name": "hamiltonian"},
+ {"name": "hf_state"},
+ {"name": "molecule"},
+ {"name": "number_op"},
+ {"name": "optimal_sector"},
+ {"name": "paulix_ops"},
+ {"name": "qwc_groupings"},
+ {"name": "qwc_samples"},
+ {"name": "sparse_hamiltonian"},
+ {"name": "spin2_op"},
+ {"name": "spinz_op"},
+ {"name": "symmetries"},
+ {"name": "tapered_dipole_op"},
+ {"name": "tapered_hamiltonian"},
+ {"name": "tapered_hf_state"},
+ {"name": "tapered_num_op"},
+ {"name": "tapered_spin2_op"},
+ {"name": "tapered_spinz_op"},
+ {"name": "vqe_energy"},
+ {"name": "vqe_gates"},
+ {"name": "vqe_params"},
+ ]
+ }
+ }
+}
+
+_get_urls_resp = {
+ "data": {
+ "datasetClass": {
+ "datasets": [
+ {
+ "id": "h2_sto-3g_0.46",
+ "downloadUrl": "https://cloud.pennylane.ai/datasets/download/h2_sto-3g_0.46",
+ },
+ {
+ "id": "h2_sto-3g_1.16",
+ "downloadUrl": "https://cloud.pennylane.ai/datasets/download/h2_sto-3g_1.16",
+ },
+ {
+ "id": "h2_sto-3g_1.0",
+ "downloadUrl": "https://cloud.pennylane.ai/datasets/download/h2_sto-3g_1.0",
+ },
+ ]
+ }
+ }
+}
+
+_rydberggpt_url_resp = {
+ "data": {
+ "datasetClass": {
+ "id": "rydberggpt",
+ "datasets": [
+ {
+ "id": "rydberggpt",
+ "downloadUrl": "https://cloud.pennylane.ai/datasets/v2/download/rydberggpt",
+ }
+ ],
+ }
+ }
+}
+
+_dataclass_ids = {"data": {"datasetClasses": [{"id": "other"}, {"id": "qchem"}, {"id": "qspin"}]}}
+
+_error_response = {"data": None, "errors": [{"message": "Mock error message."}]}
+
+_parameter_tree = {
+ "data": {
+ "datasetClass": {
+ "attributes": [
+ {"name": "ground_energies"},
+ {"name": "ground_states"},
+ {"name": "hamiltonians"},
+ {"name": "num_phases"},
+ {"name": "order_params"},
+ {"name": "parameters"},
+ {"name": "shadow_basis"},
+ {"name": "shadow_meas"},
+ {"name": "spin_system"},
+ ],
+ "parameters": [
+ {"name": "sysname"},
+ {"name": "periodicity"},
+ {"name": "lattice"},
+ {"name": "layout"},
+ ],
+ "parameterTree": {
+ "next": {
+ "Ising": {
+ "next": {
+ "open": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "transverse-field-ising-model-ising-open-chain-1x4",
+ "1x8": "transverse-field-ising-model-ising-open-chain-1x8",
+ "1x16": "transverse-field-ising-model-ising-open-chain-1x16",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "transverse-field-ising-model-ising-open-rectangular-2x2",
+ "2x4": "transverse-field-ising-model-ising-open-rectangular-2x4",
+ "2x8": "transverse-field-ising-model-ising-open-rectangular-2x8",
+ "4x4": "transverse-field-ising-model-ising-open-rectangular-4x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ "closed": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "transverse-field-ising-model-ising-closed-chain-1x4",
+ "1x8": "transverse-field-ising-model-ising-closed-chain-1x8",
+ "1x16": "transverse-field-ising-model-ising-closed-chain-1x16",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "transverse-field-ising-model-ising-closed-rectangular-2x2",
+ "2x4": "transverse-field-ising-model-ising-closed-rectangular-2x4",
+ "2x8": "transverse-field-ising-model-ising-closed-rectangular-2x8",
+ "4x4": "transverse-field-ising-model-ising-closed-rectangular-4x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ },
+ "default": "open",
+ },
+ "Heisenberg": {
+ "next": {
+ "open": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "xxz-heisenberg-model-heisenberg-open-chain-1x4",
+ "1x8": "xxz-heisenberg-model-heisenberg-open-chain-1x8",
+ "1x16": "xxz-heisenberg-model-heisenberg-open-chain-1x16",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "xxz-heisenberg-model-heisenberg-open-rectangular-2x2",
+ "2x4": "xxz-heisenberg-model-heisenberg-open-rectangular-2x4",
+ "2x8": "xxz-heisenberg-model-heisenberg-open-rectangular-2x8",
+ "4x4": "xxz-heisenberg-model-heisenberg-open-rectangular-4x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ "closed": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "xxz-heisenberg-model-heisenberg-closed-chain-1x4",
+ "1x8": "xxz-heisenberg-model-heisenberg-closed-chain-1x8",
+ "1x16": "xxz-heisenberg-model-heisenberg-closed-chain-1x16",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "xxz-heisenberg-model-heisenberg-closed-rectangular-2x2",
+ "2x4": "xxz-heisenberg-model-heisenberg-closed-rectangular-2x4",
+ "2x8": "xxz-heisenberg-model-heisenberg-closed-rectangular-2x8",
+ "4x4": "xxz-heisenberg-model-heisenberg-closed-rectangular-4x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ },
+ "default": "open",
+ },
+ "BoseHubbard": {
+ "next": {
+ "open": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "bose-hubbard-model-bosehubbard-open-chain-1x4",
+ "1x8": "bose-hubbard-model-bosehubbard-open-chain-1x8",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "bose-hubbard-model-bosehubbard-open-rectangular-2x2",
+ "2x4": "bose-hubbard-model-bosehubbard-open-rectangular-2x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ "closed": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "bose-hubbard-model-bosehubbard-closed-chain-1x4",
+ "1x8": "bose-hubbard-model-bosehubbard-closed-chain-1x8",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "bose-hubbard-model-bosehubbard-closed-rectangular-2x2",
+ "2x4": "bose-hubbard-model-bosehubbard-closed-rectangular-2x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ },
+ "default": "open",
+ },
+ "FermiHubbard": {
+ "next": {
+ "open": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "fermi-hubbard-model-fermihubbard-open-chain-1x4",
+ "1x8": "fermi-hubbard-model-fermihubbard-open-chain-1x8",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "fermi-hubbard-model-fermihubbard-open-rectangular-2x2",
+ "2x4": "fermi-hubbard-model-fermihubbard-open-rectangular-2x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ "closed": {
+ "next": {
+ "chain": {
+ "next": {
+ "1x4": "fermi-hubbard-model-fermihubbard-closed-chain-1x4",
+ "1x8": "fermi-hubbard-model-fermihubbard-closed-chain-1x8",
+ },
+ "default": "1x4",
+ },
+ "rectangular": {
+ "next": {
+ "2x2": "fermi-hubbard-model-fermihubbard-closed-rectangular-2x2",
+ "2x4": "fermi-hubbard-model-fermihubbard-closed-rectangular-2x4",
+ },
+ "default": "2x2",
+ },
+ },
+ "default": "chain",
+ },
+ },
+ "default": "open",
+ },
+ },
+ "default": None,
+ },
+ }
+ }
+}
+
+
+_qchem_parameter_tree = {
+ "data": {
+ "datasetClass": {
+ "attributes": [
+ {"name": "basis_rot_groupings"},
+ {"name": "basis_rot_samples"},
+ {"name": "dipole_op"},
+ {"name": "fci_energy"},
+ {"name": "fci_spectrum"},
+ {"name": "hamiltonian"},
+ {"name": "hf_state"},
+ {"name": "molecule"},
+ {"name": "number_op"},
+ {"name": "optimal_sector"},
+ {"name": "paulix_ops"},
+ {"name": "qwc_groupings"},
+ {"name": "qwc_samples"},
+ {"name": "sparse_hamiltonian"},
+ {"name": "spin2_op"},
+ {"name": "spinz_op"},
+ {"name": "symmetries"},
+ {"name": "tapered_dipole_op"},
+ {"name": "tapered_hamiltonian"},
+ {"name": "tapered_hf_state"},
+ {"name": "tapered_num_op"},
+ {"name": "tapered_spin2_op"},
+ {"name": "tapered_spinz_op"},
+ {"name": "vqe_energy"},
+ {"name": "vqe_gates"},
+ {"name": "vqe_params"},
+ ],
+ "parameters": [
+ {"name": "molname"},
+ {"name": "basis"},
+ {"name": "bondlength"},
+ {"name": "bondangle"},
+ {"name": "number_of_spin_orbitals"},
+ ],
+ "parameterTree": {
+ "next": {
+ "C2": {
+ "next": {
+ "STO-3G": {
+ "next": {
+ "0.5": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-0.5-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.7": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-0.7-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.9": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-0.9-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.1": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-1.1-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.3": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-1.3-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.5": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-1.5-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.7": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-1.7-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.9": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-1.9-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.1": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-2.1-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.3": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-2.3-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.5": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "c2-molecule-c2-sto-3g-2.5-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.246": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "c2-molecule-c2-sto-3g-1.246-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ },
+ "default": "1.246",
+ }
+ },
+ "default": "STO-3G",
+ },
+ "CO": {
+ "next": {
+ "STO-3G": {
+ "next": {
+ "0.5": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-0.5-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.7": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-0.7-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.9": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-0.9-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.1": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-1.1-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.3": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-1.3-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.5": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-1.5-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.7": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-1.7-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.9": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-1.9-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.1": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-2.1-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.3": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-2.3-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.5": {
+ "next": {
+ "N\\A": {
+ "next": {"20": "co-molecule-co-sto-3g-2.5-n\\a-20"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.128": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "co-molecule-co-sto-3g-1.128-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ },
+ "default": "1.128",
+ }
+ },
+ "default": "STO-3G",
+ },
+ "H2": {
+ "next": {
+ "6-31G": {
+ "next": {
+ "0.5": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.5-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.7": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.7-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.9": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.9-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.1": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.1-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.3": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.3-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.5": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.5-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.7": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.7-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.9": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.9-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.1": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-2.1-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.54": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.54-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.58": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.58-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.62": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.62-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.66": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.66-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.74": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.74-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.78": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.78-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.82": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.82-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.86": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.86-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.94": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.94-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.98": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.98-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.02": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.02-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.06": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.06-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.14": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.14-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.18": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.18-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.22": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.22-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.26": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.26-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.34": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.34-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.38": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.38-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.42": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.42-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.46": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.46-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.54": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.54-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.58": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.58-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.62": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.62-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.66": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.66-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.74": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.74-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.78": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.78-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.82": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.82-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.86": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.86-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.94": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.94-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.98": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-1.98-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.02": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-2.02-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.06": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-2.06-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.742": {
+ "next": {
+ "N\\A": {
+ "next": {"8": "h2-molecule-h2-6-31g-0.742-n\\a-8"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ },
+ "default": "0.742",
+ },
+ "STO-3G": {
+ "next": {
+ "0.5": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.5-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.7": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.7-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.9": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.9-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.1": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.1-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.3": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.3-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.5": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.5-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.7": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.7-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.9": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.9-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.1": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-2.1-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.54": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.54-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.58": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.58-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.62": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.62-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.66": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.66-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.74": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.74-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.78": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.78-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.82": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.82-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.86": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.86-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.94": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.94-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.98": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.98-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.02": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.02-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.06": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.06-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.14": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.14-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.18": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.18-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.22": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.22-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.26": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.26-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.34": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.34-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.38": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.38-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.42": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.42-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.46": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.46-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.54": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.54-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.58": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.58-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.62": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.62-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.66": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.66-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.74": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.74-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.78": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.78-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.82": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.82-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.86": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.86-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.94": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.94-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.98": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-1.98-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.02": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-2.02-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.06": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-2.06-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.742": {
+ "next": {
+ "N\\A": {
+ "next": {"4": "h2-molecule-h2-sto-3g-0.742-n\\a-4"},
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ },
+ "default": "0.742",
+ },
+ "CC-PVDZ": {
+ "next": {
+ "0.5": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-0.5-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.7": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-0.7-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.9": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-0.9-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.1": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-1.1-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.3": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-1.3-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.5": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-1.5-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.7": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-1.7-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "1.9": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-1.9-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.1": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-2.1-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.3": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-2.3-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "2.5": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-2.5-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ "0.742": {
+ "next": {
+ "N\\A": {
+ "next": {
+ "20": "h2-molecule-h2-cc-pvdz-0.742-n\\a-20"
+ },
+ "default": None,
+ }
+ },
+ "default": None,
+ },
+ },
+ "default": "0.742",
+ },
+ },
+ "default": "STO-3G",
+ },
+ }
+ },
+ }
+ }
+}
diff --git a/tests/data/data_manager/test_dataset_access.py b/tests/data/data_manager/test_dataset_access.py
index 7157c0cd62a..b0b3fdcdc06 100644
--- a/tests/data/data_manager/test_dataset_access.py
+++ b/tests/data/data_manager/test_dataset_access.py
@@ -15,6 +15,7 @@
Unit tests for the :class:`pennylane.data.data_manager` functions.
"""
import os
+import re
from pathlib import Path, PosixPath
from typing import NamedTuple
from unittest.mock import MagicMock, call, patch
@@ -25,7 +26,18 @@
import pennylane as qml
import pennylane.data.data_manager
from pennylane.data import Dataset
-from pennylane.data.data_manager import S3_URL, _validate_attributes
+from pennylane.data.data_manager import _validate_attributes
+from pennylane.data.data_manager.graphql import GRAPHQL_URL
+
+from .support import (
+ _dataclass_ids,
+ _error_response,
+ _get_urls_resp,
+ _list_attrs_resp,
+ _parameter_tree,
+ _qchem_parameter_tree,
+ _rydberggpt_url_resp,
+)
has_rich = False
try:
@@ -76,11 +88,6 @@
}
-@pytest.fixture(scope="session")
-def httpserver_listen_address():
- return ("localhost", 8888)
-
-
# pylint:disable=unused-argument
def get_mock(url, timeout=1.0):
"""Return the foldermap or data_struct according to URL"""
@@ -89,18 +96,6 @@ def get_mock(url, timeout=1.0):
return resp
-def head_mock(url):
- """Return a fake header stating content-length is 1."""
- return NamedTuple("Head", headers=dict)(headers={"Content-Length": 10000})
-
-
-@pytest.fixture
-def mock_get_args():
- """A Mock object that tracks the arguments passed to ``mock_requests_get``."""
-
- return MagicMock()
-
-
@pytest.fixture(autouse=True)
def mock_requests_get(request, monkeypatch, mock_get_args):
"""Patches `requests.get()` in the data_manager module so that
@@ -136,6 +131,68 @@ def mock_iter_content(chunk_size: int):
return mock_get
+@pytest.fixture(scope="session")
+def httpserver_listen_address():
+ return ("localhost", 8888)
+
+
+# pylint:disable=unused-argument
+# pylint:disable=dangerous-default-value
+def post_mock(url, json, timeout=1.0, headers={"content-type": "application/json"}):
+ """Return mocked get response depending on json content."""
+ resp = MagicMock(ok=True)
+ if "ErrorQuery" in json["query"]:
+ resp.json.return_value = _error_response
+ elif "ListAttributes" in json["query"][0]:
+ resp.json.return_value = _list_attrs_resp
+ return resp
+
+
+# pylint:disable=unused-argument
+def graphql_mock(url, query, variables=None):
+ """Return the JSON according to the query."""
+ if "ListAttributes" in query:
+ json_data = _list_attrs_resp
+ elif variables is not None and variables["datasetClassId"] == "rydberggpt":
+ json_data = _rydberggpt_url_resp
+ elif "GetDatasetsForDownload" in query:
+ json_data = _get_urls_resp
+ elif "GetParameterTree" in query:
+ json_data = _parameter_tree
+ elif "GetDatasetClasses" in query:
+ json_data = _dataclass_ids
+ return json_data
+
+
+# pylint:disable=unused-argument
+def graphql_mock_qchem(url, query, variables=None):
+ """Return the JSON according to the query."""
+ if "ListAttributes" in query:
+ json_data = _list_attrs_resp
+ elif "GetParameterTree" in query:
+ json_data = _qchem_parameter_tree
+ elif "GetDatasetClasses" in query:
+ json_data = _dataclass_ids
+ return json_data
+
+
+def get_dataset_urls_mock(class_id, parameters):
+ """Returns an empty response for the ``get_dataset_urls`` function."""
+ return []
+
+
+def head_mock(url):
+ """Return a fake header stating content-length is 1."""
+ return NamedTuple("Head", headers=dict)(headers={"Content-Length": 10000})
+
+
+@pytest.fixture
+def mock_get_args():
+ """A Mock object that tracks the arguments passed to ``mock_requests_get``."""
+
+ return MagicMock()
+
+
def submit_download_mock(_self, _fetch_and_save, filename, dest_folder):
"""Patch to write a nonsense dataset rather than a downloaded one."""
# If filename == foo/bar/x_y_z_attr.dat, content == "x_y_z_attr"
@@ -159,7 +216,6 @@ def mock_load(monkeypatch):
return mock
-@patch.object(requests, "get", get_mock)
@patch.object(pennylane.data.data_manager, "head", head_mock)
@patch("pennylane.data.data_manager.sleep")
@patch("builtins.input")
@@ -169,63 +225,83 @@ class TestLoadInteractive:
[data name, *params, attributes, Force, Folder, continue]
"""
+ @patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@pytest.mark.parametrize(
- ("side_effect", "data_name", "kwargs", "sleep_call_count"),
+ ("side_effect"),
[
(
- ["1", "1", "2", "", "", ""],
- "qchem",
- {
- "attributes": ["hamiltonian"],
- "folder_path": PosixPath(""),
- "force": False,
- "molname": "H2",
- "basis": "6-31G",
- "bondlength": "0.46",
- },
- 2,
+ [
+ "qspin",
+ "Heisenberg",
+ "open",
+ "chain",
+ "1x4",
+ "full",
+ True,
+ PosixPath("/my/path"),
+ "Y",
+ ]
),
(
- ["2", "1, 4", "Y", "/my/path", "y"],
- "qspin",
- {
- "attributes": ["parameters", "full"],
- "folder_path": PosixPath("/my/path"),
- "force": True,
- "sysname": "Heisenberg",
- "periodicity": "closed",
- "lattice": "chain",
- "layout": "1x4",
- },
- 4,
+ [
+ "qspin",
+ "Heisenberg",
+ "open",
+ "chain",
+ "1x4",
+ "[parameters, shadow_basis, shadow_meas]",
+ True,
+ PosixPath("/my/path"),
+ "Y",
+ ]
),
],
)
def test_load_interactive_success(
- self, mock_input, mock_sleep, mock_load, side_effect, data_name, kwargs, sleep_call_count
+ self,
+ mock_input,
+ mock_sleep,
+ mock_load,
+ side_effect,
): # pylint:disable=too-many-arguments, redefined-outer-name
"""Test that load_interactive succeeds."""
mock_input.side_effect = side_effect
assert isinstance(qml.data.load_interactive(), qml.data.Dataset)
- mock_load.assert_called_once_with(data_name, **kwargs)
- assert mock_sleep.call_count == sleep_call_count
+ @patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
def test_load_interactive_without_confirm(
self, mock_input, _mock_sleep, mock_load
): # pylint:disable=redefined-outer-name
"""Test that load_interactive returns None if the user doesn't confirm."""
- mock_input.side_effect = ["1", "1", "2", "", "", "n"]
+ mock_input.side_effect = [
+ "qspin",
+ "Heisenberg",
+ "open",
+ "chain",
+ "1x4",
+ "full",
+ True,
+ PosixPath("/my/path"),
+ "n",
+ ]
assert qml.data.load_interactive() is None
mock_load.assert_not_called()
+ @patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@pytest.mark.parametrize(
("side_effect", "error_message"),
[
- (["foo"], "Must enter an integer between 1 and 2"),
- (["0"], "Must enter an integer between 1 and 2"),
- (["3"], "Must enter an integer between 1 and 2"),
- (["1", "1", "0"], "Must enter a list of integers between 1 and 5"),
- (["1", "1", "1 2"], "Must enter a list of integers between 1 and 5"),
+ (["foo"], re.escape("Must select a single data name from ['other', 'qchem', 'qspin']")),
+ (["qspin", "foo"], "Must enter a valid sysname:"),
+ (["qspin", "Ising", "foo"], "Must enter a valid periodicity:"),
+ (["qspin", "Ising", "open", "foo"], "Must enter a valid lattice:"),
+ (["qspin", "Ising", "open", "chain", "foo"], "Must enter a valid layout:"),
+ (
+ ["qspin", "Ising", "open", "chain", "1x4", "foo"],
+ re.escape(
+ "Must select a list of attributes from ['ground_energies', 'ground_states', 'hamiltonians', 'num_phases', 'order_params', 'parameters', 'shadow_basis', 'shadow_meas', 'spin_system']"
+ ),
+ ),
],
)
def test_load_interactive_invalid_inputs(
@@ -236,11 +312,45 @@ def test_load_interactive_invalid_inputs(
with pytest.raises(ValueError, match=error_message):
qml.data.load_interactive()
+ @patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock_qchem)
+ @pytest.mark.parametrize(
+ ("side_effect"),
+ [
+ (
+ [
+ "qchem",
+ "H2",
+ "STO-3G",
+ "0.742",
+ "full",
+ True,
+ PosixPath("/my/path"),
+ "Y",
+ ]
+ ),
+ ],
+ )
+ def test_load_interactive_qchem(
+ self,
+ mock_input,
+ mock_sleep,
+ mock_load,
+ side_effect,
+ ):
+ """Test that load_interactive succeeds."""
+ mock_input.side_effect = side_effect
+ assert isinstance(qml.data.load_interactive(), qml.data.Dataset)
+
-@patch.object(requests, "get", get_mock)
class TestMiscHelpers:
"""Test miscellaneous helper functions in data_manager."""
+ @patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
+ def test_list_data_names(self):
+ """Test list_data_names."""
+ assert qml.data.list_data_names() == ["other", "qchem", "qspin"]
+
+ @patch.object(requests, "get", get_mock)
def test_list_datasets(self, tmp_path):
"""Test that list_datasets returns either the S3 foldermap, or the local tree."""
assert qml.data.list_datasets() == {
@@ -248,11 +358,37 @@ def test_list_datasets(self, tmp_path):
"qchem": {"H2": {"6-31G": ["0.46", "1.0", "1.16"]}},
}
+ @patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
def test_list_attributes(self):
- """Test list_attributes"""
- assert qml.data.list_attributes("qchem") == _data_struct["qchem"]["attributes"]
- with pytest.raises(ValueError, match="Currently the hosted datasets are of types"):
- qml.data.list_attributes("invalid_data_name")
+ """Test list_attributes."""
+ assert qml.data.list_attributes("qchem") == [
+ "basis_rot_groupings",
+ "basis_rot_samples",
+ "dipole_op",
+ "fci_energy",
+ "fci_spectrum",
+ "hamiltonian",
+ "hf_state",
+ "molecule",
+ "number_op",
+ "optimal_sector",
+ "paulix_ops",
+ "qwc_groupings",
+ "qwc_samples",
+ "sparse_hamiltonian",
+ "spin2_op",
+ "spinz_op",
+ "symmetries",
+ "tapered_dipole_op",
+ "tapered_hamiltonian",
+ "tapered_hf_state",
+ "tapered_num_op",
+ "tapered_spin2_op",
+ "tapered_spinz_op",
+ "vqe_energy",
+ "vqe_gates",
+ "vqe_params",
+ ]
@pytest.fixture
@@ -269,15 +405,17 @@ def mock(data_path, dest, attributes, force, block_size, pbar_task):
# pylint: disable=too-many-arguments
@patch.object(pennylane.data.data_manager, "head", head_mock)
+@patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@pytest.mark.usefixtures("mock_download_dataset")
@pytest.mark.parametrize(
"data_name, params, expect_paths",
[
(
"qchem",
- {"molname": "H2", "basis": "6-31G", "bondlength": ["0.46", "1.16"]},
- ["qchem/H2/6-31G/0.46.h5", "qchem/H2/6-31G/1.16.h5"],
- )
+ {"molname": "H2", "basis": "STO-3G", "bondlength": ["1.0", "0.46", "1.16"]},
+ ["qchem/h2_sto-3g_1.0.h5", "qchem/h2_sto-3g_0.46.h5", "qchem/h2_sto-3g_1.16.h5"],
+ ),
+ ("other", {"name": "rydberggpt"}, ["rydberggpt/rydberggpt.h5"]),
],
)
@pytest.mark.parametrize("progress_bar", [True, False])
@@ -295,12 +433,21 @@ def test_load(tmp_path, data_name, params, expect_paths, progress_bar, attribute
attributes=attributes,
**params,
)
-
assert {Path(dset.bind.filename) for dset in dsets} == {
Path(tmp_path, path) for path in expect_paths
}
+@patch.object(pennylane.data.data_manager, "get_dataset_urls", get_dataset_urls_mock)
+def test_load_bad_config():
+ msg = re.escape(
+ """No datasets exist for the provided configuration.\nPlease check the available datasets by using the ``qml.data.list_datasets()`` function."""
+ )
+ with pytest.raises(ValueError, match=msg):
+ pennylane.data.data_manager.load(data_name="qchem", molname="bad_name")
+
+
+@patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@patch.object(pennylane.data.data_manager, "head", head_mock)
def test_load_except(monkeypatch, tmp_path):
"""Test that an exception raised by _download_dataset is propagated."""
@@ -340,6 +487,7 @@ def test_download_dataset_full_or_partial(
assert download_full.called is not called_partial
+@patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@pytest.mark.parametrize("force", (True, False))
@patch("pennylane.data.data_manager._download_full")
def test_download_dataset_full_call(download_full, force):
@@ -351,7 +499,7 @@ def test_download_dataset_full_call(download_full, force):
pbar_task = MagicMock()
pennylane.data.data_manager._download_dataset(
- f"{S3_URL}/dataset/path",
+ f"{GRAPHQL_URL}/dataset/path",
attributes=None,
dest=dest,
force=force,
@@ -360,10 +508,11 @@ def test_download_dataset_full_call(download_full, force):
)
download_full.assert_called_once_with(
- f"{S3_URL}/dataset/path", block_size=1, dest=dest, pbar_task=pbar_task
+ f"{GRAPHQL_URL}/dataset/path", block_size=1, dest=dest, pbar_task=pbar_task
)
+@patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@pytest.mark.parametrize("attributes", [None, ["x"]])
@pytest.mark.parametrize("force", (True, False))
@patch("pennylane.data.data_manager._download_partial")
@@ -376,7 +525,7 @@ def test_download_dataset_partial_call(download_partial, attributes, force):
pbar_task = MagicMock()
pennylane.data.data_manager._download_dataset(
- f"{S3_URL}/dataset/path",
+ f"{GRAPHQL_URL}/dataset/path",
attributes=attributes,
dest=dest,
force=force,
@@ -385,7 +534,7 @@ def test_download_dataset_partial_call(download_partial, attributes, force):
)
download_partial.assert_called_once_with(
- f"{S3_URL}/dataset/path",
+ f"{GRAPHQL_URL}/dataset/path",
dest=dest,
attributes=attributes,
overwrite=force,
@@ -400,7 +549,7 @@ def test_download_full(tmp_path):
"""Tests that _download_dataset will fetch the dataset file
at ``s3_url`` into ``dest``."""
pennylane.data.data_manager._download_full(
- "dataset/path", tmp_path / "dataset", block_size=1, pbar_task=None
+ f"{GRAPHQL_URL}/dataset/path", tmp_path / "dataset", block_size=1, pbar_task=None
)
with open(tmp_path / "dataset", "rb") as f:
@@ -521,78 +670,17 @@ def test_download_partial_no_check_remote(open_hdf5_s3, tmp_path):
open_hdf5_s3.assert_not_called()
-@patch("builtins.open")
-@patch.object(pennylane.data.data_manager, "head", head_mock)
-@pytest.mark.parametrize(
- "datapath, escaped",
- [("data/NH3+/data.h5", "data/NH3%2B/data.h5"), ("data/CA$H/money.h5", "data/CA%24H/money.h5")],
-)
-def test_download_datasets_escapes_url(_, tmp_path, mock_get_args, datapath, escaped):
- """Tests that _download_datasets escapes special characters in a URL when doing a full download."""
-
- dest = MagicMock()
- dest.exists.return_value = False
-
- pennylane.data.data_manager._download_datasets(
- S3_URL,
- folder_path=tmp_path,
- data_paths=[datapath],
- attributes=None,
- force=True,
- block_size=1,
- num_threads=1,
- pbar=MagicMock(),
- )
-
- mock_get_args.assert_called_once()
- assert mock_get_args.call_args[0] == (f"{S3_URL}/{escaped}",)
-
-
-@patch("pennylane.data.data_manager._download_partial")
-@pytest.mark.parametrize(
- "datapath, escaped",
- [("data/NH3+/data.h5", "data/NH3%2B/data.h5"), ("data/CA$H/money.h5", "data/CA%24H/money.h5")],
-)
-def test_download_datasets_escapes_url_partial(download_partial, tmp_path, datapath, escaped):
- """Tests that _download_datasets escapes special characters in a URL when doing a partial
- download."""
- attributes = ["attr"]
- force = False
- pbar = MagicMock()
- pbar_task = MagicMock()
- pbar.add_task.return_value = pbar_task
-
- pennylane.data.data_manager._download_datasets(
- S3_URL,
- folder_path=tmp_path,
- data_paths=[datapath],
- attributes=attributes,
- force=force,
- block_size=1,
- num_threads=1,
- pbar=pbar,
- )
-
- download_partial.assert_called_once_with(
- f"{S3_URL}/{escaped}",
- dest=tmp_path / datapath,
- attributes=attributes,
- overwrite=force,
- block_size=1,
- pbar_task=pbar_task,
- )
-
-
+@patch.object(pennylane.data.data_manager.graphql, "get_graphql", graphql_mock)
@pytest.mark.parametrize(
"attributes,msg",
[
(
- ["x", "y", "z", "foo"],
- r"'foo' is an invalid attribute for 'my_dataset'. Valid attributes are: \['x', 'y', 'z'\]",
+ ["basis_rot_groupings", "basis_rot_samples", "dipole_op", "fci_energy", "foo"],
+ r"'foo' is an invalid attribute for 'my_dataset'. Valid attributes are: \['basis_rot_groupings', 'basis_rot_samples', 'dipole_op', 'fci_energy', 'fci_spectrum', 'hamiltonian', 'hf_state', 'molecule', 'number_op', 'optimal_sector', 'paulix_ops', 'qwc_groupings', 'qwc_samples', 'sparse_hamiltonian', 'spin2_op', 'spinz_op', 'symmetries', 'tapered_dipole_op', 'tapered_hamiltonian', 'tapered_hf_state', 'tapered_num_op', 'tapered_spin2_op', 'tapered_spinz_op', 'vqe_energy', 'vqe_gates', 'vqe_params'\]",
),
(
- ["x", "y", "z", "foo", "bar"],
- r"\['foo', 'bar'\] are invalid attributes for 'my_dataset'. Valid attributes are: \['x', 'y', 'z'\]",
+ ["basis_rot_groupings", "basis_rot_samples", "dipole_op", "fci_energy", "foo", "bar"],
+ r"\['foo', 'bar'\] are invalid attributes for 'my_dataset'. Valid attributes are: \['basis_rot_groupings', 'basis_rot_samples', 'dipole_op', 'fci_energy', 'fci_spectrum', 'hamiltonian', 'hf_state', 'molecule', 'number_op', 'optimal_sector', 'paulix_ops', 'qwc_groupings', 'qwc_samples', 'sparse_hamiltonian', 'spin2_op', 'spinz_op', 'symmetries', 'tapered_dipole_op', 'tapered_hamiltonian', 'tapered_hf_state', 'tapered_num_op', 'tapered_spin2_op', 'tapered_spinz_op', 'vqe_energy', 'vqe_gates', 'vqe_params'\]",
),
],
)
@@ -600,7 +688,54 @@ def test_validate_attributes_except(attributes, msg):
"""Test that ``_validate_attributes()`` raises a ValueError when passed
invalid attributes."""
- data_struct = {"my_dataset": {"attributes": ["x", "y", "z"]}}
-
with pytest.raises(ValueError, match=msg):
- _validate_attributes(data_struct, "my_dataset", attributes)
+ _validate_attributes("my_dataset", attributes)
+
+
+class TestGetGraphql:
+ """Tests for the ``get_graphql()`` function."""
+
+ query = (
+ """
+ query ListAttributes($datasetClassId: String!) {
+ datasetClass($datasetClassId: String!) {
+ attributes {
+ name
+ }
+ }
+ }
+ """,
+ )
+ inputs = {"input": {"datasetClassId": "qspin"}}
+
+ @patch.object(pennylane.data.data_manager.graphql, "post", post_mock)
+ def test_return_json(self):
+ """Tests that an expected json response is returned for a valid query and url."""
+ response = pennylane.data.data_manager.graphql.get_graphql(
+ GRAPHQL_URL,
+ self.query,
+ self.inputs,
+ )
+ assert response == _list_attrs_resp
+
+ @patch.object(pennylane.data.data_manager.graphql, "post", post_mock)
+ def test_error_response(self):
+ """Tests that GraphQLError is raised with error messages when
+ the returned json contains an error message.
+ """
+ error_query = """
+ query ErrorQuery {
+ errorQuery {
+ field
+ }
+ }
+ """
+
+ with pytest.raises(
+ pennylane.data.data_manager.graphql.GraphQLError,
+ match="Errors in request: Mock error message.",
+ ):
+ pennylane.data.data_manager.graphql.get_graphql(
+ GRAPHQL_URL,
+ error_query,
+ )
diff --git a/tests/data/data_manager/test_graphql.py b/tests/data/data_manager/test_graphql.py
new file mode 100644
index 00000000000..da43d20930f
--- /dev/null
+++ b/tests/data/data_manager/test_graphql.py
@@ -0,0 +1,55 @@
+"""Basic integration tests for the Datasets Service API"""
+
+import pytest
+import requests
+
+import pennylane.data.data_manager
+from pennylane.data.data_manager.graphql import GRAPHQL_URL
+
+
+# pylint: disable=protected-access
+class TestGetGraphql:
+ """Tests for the ``get_graphql()`` function."""
+
+ query = """
+ query DatasetClass {
+ datasetClasses {
+ id
+ }
+ }
+ """
+
+ def test_return_json(self):
+ """Tests that a dictionary representation of a json response is returned for a
+ valid query and url."""
+ response = pennylane.data.data_manager.graphql.get_graphql(
+ GRAPHQL_URL,
+ self.query,
+ )
+ assert isinstance(response, dict)
+
+ def test_bad_url(self):
+ """Tests that a ``ConnectionError`` is returned for a valid query and invalid url."""
+
+ with pytest.raises(requests.exceptions.ConnectionError):
+ pennylane.data.data_manager.graphql.get_graphql(
+ "https://bad/url/graphql",
+ self.query,
+ )
+
+ def test_bad_query(self):
+ """Tests that a ``HTTPError`` is returned for a invalid query and valid url."""
+
+ bad_query = """
+ query BadQuery {
+ badQuery {
+ field
+ }
+ }
+ """
+
+ with pytest.raises(requests.exceptions.HTTPError):
+ pennylane.data.data_manager.graphql.get_graphql(
+ GRAPHQL_URL,
+ bad_query,
+ )
diff --git a/tests/data/data_manager/test_params.py b/tests/data/data_manager/test_params.py
index 009e30dc292..9ca581ece66 100644
--- a/tests/data/data_manager/test_params.py
+++ b/tests/data/data_manager/test_params.py
@@ -23,6 +23,7 @@
ParamArg,
format_param_args,
format_params,
+ provide_defaults,
)
pytestmark = pytest.mark.data
@@ -106,12 +107,12 @@ def test_format_params():
"""Test that format_params calls format_param_args with each parameter."""
assert format_params(
layout=[1, 4], bondlength=["0.5", "0.6"], z="full", y=ParamArg.DEFAULT
- ) == {
- "bondlength": ["0.5", "0.6"],
- "layout": ["1x4"],
- "y": ParamArg.DEFAULT,
- "z": ParamArg.FULL,
- }
+ ) == [
+ {"name": "layout", "values": ["1x4"]},
+ {"name": "bondlength", "values": ["0.5", "0.6"]},
+ {"name": "z", "values": ParamArg.FULL},
+ {"name": "y", "values": ParamArg.DEFAULT},
+ ]
class TestDescription:
@@ -126,3 +127,68 @@ def test_repr(self):
"""Test that __repr__ is equivalent to dict __repr__."""
params = {"foo": "bar", "x": "y"}
assert repr(Description(params)) == f"Description({repr(params)})"
+
+
+@pytest.mark.parametrize(
+ "data_name, params, expected_params",
+ [
+ (
+ "qchem",
+ [{"name": "molname", "values": ["H2"]}],
+ [
+ {"name": "molname", "values": ["H2"]},
+ {"default": True, "name": "basis"},
+ {"default": True, "name": "bondlength"},
+ ],
+ ),
+ (
+ "qchem",
+ [{"name": "molname", "values": ["H2"]}, {"name": "bondlength", "values": ["0.82"]}],
+ [
+ {"name": "molname", "values": ["H2"]},
+ {"name": "bondlength", "values": ["0.82"]},
+ {"default": True, "name": "basis"},
+ ],
+ ),
+ (
+ "qspin",
+ [{"name": "sysname", "values": ["BoseHubbard"]}],
+ [
+ {"name": "sysname", "values": ["BoseHubbard"]},
+ {"default": True, "name": "periodicity"},
+ {"default": True, "name": "lattice"},
+ {"default": True, "name": "layout"},
+ ],
+ ),
+ (
+ "qspin",
+ [
+ {"name": "sysname", "values": ["BoseHubbard"]},
+ {"name": "periodicity", "values": ["closed"]},
+ ],
+ [
+ {"name": "sysname", "values": ["BoseHubbard"]},
+ {"name": "periodicity", "values": ["closed"]},
+ {"default": True, "name": "lattice"},
+ {"default": True, "name": "layout"},
+ ],
+ ),
+ (
+ "qspin",
+ [
+ {"name": "sysname", "values": ["BoseHubbard"]},
+ {"name": "periodicity", "values": ["closed"]},
+ {"name": "lattice", "values": ["chain"]},
+ ],
+ [
+ {"name": "sysname", "values": ["BoseHubbard"]},
+ {"name": "periodicity", "values": ["closed"]},
+ {"name": "lattice", "values": ["chain"]},
+ {"default": True, "name": "layout"},
+ ],
+ ),
+ ("other", [], []),
+ ],
+)
+def test_provide_defaults(data_name, params, expected_params):
+ assert provide_defaults(data_name, params) == expected_params