-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
93 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,26 @@ | ||
import argparse | ||
from pathlib import Path | ||
|
||
from qupsy.spec import parse_spec | ||
from qupsy.utils import logger | ||
|
||
|
||
def main() -> None: | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("-d", "--dry-run", action="store_true", help="Dry run") | ||
parser.add_argument( | ||
"specification", type=Path, metavar="SPEC", help="Specification file" | ||
) | ||
|
||
args = parser.parse_args() | ||
|
||
logger.debug("Specification file: %s", args.specification) | ||
spec = parse_spec(args.specification) | ||
|
||
logger.info("Specification loaded: %s", args.specification) | ||
logger.debug("Specification:\n%s", spec) | ||
|
||
if args.dry_run: | ||
return | ||
|
||
print("Hello, qupsy!") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
import json | ||
from dataclasses import dataclass | ||
from pathlib import Path | ||
from typing import cast | ||
|
||
import numpy as np | ||
import numpy.typing as npt | ||
|
||
from qupsy.language import CX, CRy, Gate, H, Ry, X | ||
from qupsy.utils import logger | ||
|
||
GATE_MAP: dict[str, type[Gate]] = { | ||
"H": H, | ||
"X": X, | ||
"Ry": Ry, | ||
"CX": CX, | ||
"CRy": CRy, | ||
} | ||
|
||
|
||
@dataclass | ||
class Spec: | ||
gates: list[type[Gate]] | ||
testcases: list[tuple[npt.ArrayLike, npt.ArrayLike]] | ||
|
||
def __str__(self) -> str: | ||
testcases_string: list[str] = [] | ||
for input, output in self.testcases: | ||
input_str = str(input).splitlines() | ||
input_str = input_str[0] + " ...]" if len(input_str) > 1 else input_str[0] | ||
output_str = str(output).splitlines() | ||
output_str = ( | ||
output_str[0] + " ...]" if len(output_str) > 1 else output_str[0] | ||
) | ||
|
||
testcases_string.append( | ||
f" ( Input: {input_str},\n Output: {output_str})," | ||
) | ||
return f"""Spec( | ||
gates: [{", ".join(map(lambda g: g.__name__, self.gates))}], | ||
testcases: [ | ||
{"\n".join(testcases_string)} | ||
], | ||
)""" | ||
|
||
|
||
def parse_spec(spec: Path | str) -> Spec: | ||
if isinstance(spec, str): | ||
spec = Path(spec) | ||
data = json.loads(spec.read_text()) | ||
gates = cast(list[str], data.get("gates", ["H", "X", "Ry", "CX", "CRy"])) | ||
gates = [GATE_MAP[gate] for gate in gates] | ||
|
||
testcases: list[tuple[npt.ArrayLike, npt.ArrayLike]] = [] | ||
for tc in data["testcases"].values(): | ||
output = np.fromstring(tc["output"], dtype="complex", sep=",") | ||
input = ( | ||
tc["input"] | ||
if "input" in tc | ||
else (np.concat([[1], np.zeros_like(output[1:])])) | ||
) | ||
testcases.append((input, output)) | ||
|
||
logger.debug("Parsed output: %s", output) | ||
logger.debug("Parsed input: %s", input) | ||
|
||
return Spec(gates, testcases) |