Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce schema for Quantum Volume jobs #67

Merged
merged 4 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ _build
# MacOS
.DS_Store

# VSCode
.vscode

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
5 changes: 5 additions & 0 deletions metriq_gym/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ def parse_arguments() -> argparse.Namespace:
Parsed arguments as an argparse.Namespace object.
"""
parser = argparse.ArgumentParser(description="Quantum volume certification")
parser.add_argument(
"input_file",
cosenal marked this conversation as resolved.
Show resolved Hide resolved
type=str,
help="Path to the file containing the benchmark parameters",
)
parser.add_argument(
"-n", "--num_qubits", type=int, default=8, help="Number of qubits (default is 8)"
)
Expand Down
11 changes: 6 additions & 5 deletions metriq_gym/dispatch_qv.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,37 +3,38 @@
import logging
import sys


from metriq_gym.bench import dispatch_bench_job
from metriq_gym.job_manager import JobManager
from metriq_gym.cli import parse_arguments
from metriq_gym.stats import calc_stats
from metriq_gym.schema_validator import load_and_validate


logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")


def main():
args = parse_arguments()
params = load_and_validate(args.input_file)

logging.info(
f"Dispatching Quantum Volume job with n={args.num_qubits}, shots={args.shots}, trials={args.trials}, backend={args.backend}, confidence_level={args.confidence_level}, jobs_file={args.jobs_file}"
f"Dispatching {params['benchmark_name']} job with n={params["num_qubits"]}, shots={params["shots"]}, trials={params["trials"]}, backend={args.backend}, confidence_level={params["confidence_level"]}, jobs_file={args.jobs_file}"
)

job_manager = JobManager(args.jobs_file)

result = dispatch_bench_job(
args.num_qubits, args.backend, args.shots, args.trials, args.provider
params["num_qubits"], args.backend, params["shots"], params["trials"], args.provider
vprusso marked this conversation as resolved.
Show resolved Hide resolved
)

if len(result.counts) > 0:
stats = calc_stats([result], args.confidence_level)
stats = calc_stats([result], params["confidence_level"])
logging.info(f"Simulator-only job completed: {stats[0]}.")
print(stats[0])

return 0

logging.info(f"Dispatched {args.trials} trials in 1 job.")
logging.info(f"Dispatched {params["trials"]} trials in 1 job.")

job_manager.add_job(result.to_serializable())

Expand Down
2 changes: 1 addition & 1 deletion metriq_gym/job_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

DEFAULT_FILE_PATH = ".metriq_gym_jobs.jsonl"

# TODO: JobManager is not thread-safe at the moment
# TODO: https://github.com/unitaryfund/metriq-gym/issues/51


class JobManager:
Expand Down
50 changes: 50 additions & 0 deletions metriq_gym/schema_validator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import json
import os
from jsonschema import validate


CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
DEFAULT_SCHEMA_DIR = os.path.join(CURRENT_DIR, "schemas")

SCHEMA_MAPPING = {
"Quantum Volume": "quantum_volume.schema.json",
}


cosenal marked this conversation as resolved.
Show resolved Hide resolved
def load_json_file(file_path: str) -> dict:
"""
Load and parse a JSON file.
"""
with open(file_path, "r") as file:
return json.load(file)


def load_schema(benchmark_name: str, schema_dir: str = DEFAULT_SCHEMA_DIR) -> dict:
"""
Load a JSON schema based on the benchmark name.
"""
schema_filename = SCHEMA_MAPPING.get(benchmark_name)
if not schema_filename:
raise ValueError(f"Unsupported benchmark: {benchmark_name}")

schema_path = os.path.join(schema_dir, schema_filename)
return load_json_file(schema_path)


def validate_params(params: dict, schema_dir: str = DEFAULT_SCHEMA_DIR) -> None:
"""
Validate parameters against the corresponding JSON schema.
Raises a ValidationError if the parameters do not match the schema.
"""
schema = load_schema(params.get("benchmark_name"), schema_dir)
validate(instance=params, schema=schema)


def load_and_validate(file_path: str, schema_dir: str = DEFAULT_SCHEMA_DIR) -> dict:
"""
Load parameters from a JSON file and validate them against the corresponding schema.
Raises a ValidationError validation fails.
"""
params = load_json_file(file_path)
validate_params(params, schema_dir)
return params
37 changes: 37 additions & 0 deletions metriq_gym/schemas/quantum_volume.schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
cosenal marked this conversation as resolved.
Show resolved Hide resolved
"$id": "metriq-gym/quantum_volume.schema.json",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Quantum Volume",
cosenal marked this conversation as resolved.
Show resolved Hide resolved
"type": "object",
"properties": {
"benchmark_name": {
"type": "string",
"const": "Quantum Volume"
},
"num_qubits": {
"type": "integer",
"minimum": 1,
"examples": [5]
},
"shots": {
"type": "integer",
"default": 1000,
"minimum": 1,
"examples": [1000]
},
"trials": {
"type": "integer",
"default": 100,
"minimum": 1,
"examples": [100]
},
"confidence_level": {
"type": "number",
"minimum": 0,
"maximum": 1,
"default": 0.95,
"examples": [0.95]
}
},
"required": ["benchmark_name", "num_qubits"]
}
Loading