From e5e846b88c1dca13b5cba9d0969c7dc9811bee39 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Wed, 26 Feb 2025 20:04:49 -0500 Subject: [PATCH 01/15] Use uv in docker build, add new dependencies --- docker/.dockerignore | 92 ++++++++++++++++++++++++++++++++++++++ docker/Dockerfile | 51 +++++++-------------- docker/docker-compose.yaml | 37 ++++++++++++--- docker/requirements.txt | 3 -- pyproject.toml | 10 ++++- src/oqd_cloud/client.py | 2 +- src/oqd_cloud/provider.py | 2 +- 7 files changed, 150 insertions(+), 47 deletions(-) create mode 100644 docker/.dockerignore diff --git a/docker/.dockerignore b/docker/.dockerignore new file mode 100644 index 0000000..a12670d --- /dev/null +++ b/docker/.dockerignore @@ -0,0 +1,92 @@ +# Git +.git +.gitignore +.gitattributes + + +# CI +.codeclimate.yml +.travis.yml +.taskcluster.yml + +# Docker +docker-compose.yml +Dockerfile +.docker +.dockerignore + +# Byte-compiled / optimized / DLL files +**/__pycache__/ +**/*.py[cod] + +# C extensions +*.so + +# Distribution / packaging +.Python +env/ +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +*.egg-info/ +.installed.cfg +*.egg + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.cache +nosetests.xml +coverage.xml + +# Translations +*.mo +*.pot + +# Django stuff: +*.log + +# Sphinx documentation +docs/_build/ + +# PyBuilder +target/ + +# Virtual environment +.env +.venv/ +venv/ + +# PyCharm +.idea + +# Python mode for VIM +.ropeproject +**/.ropeproject + +# Vim swap files +**/*.swp + +# VS Code +.vscode/ + + +.venv \ No newline at end of file diff --git a/docker/Dockerfile b/docker/Dockerfile index c659f77..b1ffa9e 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,62 +1,41 @@ -FROM python:3.10.13-slim-bookworm as build - +FROM python:3.12-slim-bookworm as build +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ RUN apt-get update && \ apt-get upgrade -y && \ apt-get install -y --no-install-recommends build-essential gcc && \ - apt-get install -y git # for installing directly from git - -ARG PIP_DISABLE_PIP_VERSION_CHECK=1 -ARG PIP_NO_CACHE_DIR=1 + apt-get install -y git # for installing directly from git WORKDIR /python - -RUN python -m venv /python/venv - -ENV PATH="/python/venv/bin:$PATH" - +RUN uv venv /python/.venv +ENV PATH="/python/.venv/bin:$PATH" COPY docker/requirements.txt . -RUN pip install -r requirements.txt -RUN pip install oqd-compiler-infrastructure -RUN pip install oqd-core -RUN pip install oqd-analog-emulator +RUN uv pip install -r requirements.txt +RUN uv pip install "oqd-analog-emulator@git+https://github.com/openquantumdesign/oqd-analog-emulator" +RUN uv pip install "oqd-trical@git+https://github.com/openquantumdesign/oqd-trical" ######################################################################################## -FROM python:3.10.13-slim-bookworm as app +FROM python:3.12-slim-bookworm as app +COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ RUN apt update && \ apt install -y --no-install-recommends supervisor && \ apt-get install -y gcc g++ # needed from Cython +COPY --from=build /python/.venv /python/.venv -ARG PIP_DISABLE_PIP_VERSION_CHECK=1 -ARG PIP_NO_CACHE_DIR=1 - -COPY --from=build /python/venv /python/venv - -ENV PATH="/python/venv/bin:$PATH" +ENV PATH="/python/.venv/bin:$PATH" ENV PYTHONPATH="/app/src" COPY . ./app WORKDIR /app -RUN pip install . -#RUN pip install .[all] +RUN uv pip install .[server] -#COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf +# COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] -######################################################################################## - -# RUN \ -# apt update \ -# && apt install wget -y \ -# && wget https://julialang-s3.julialang.org/bin/linux/x64/1.9/julia-1.9.3-linux-x86_64.tar.gz -P /opt \ -# && tar zxvf /opt/julia-1.9.3-linux-x86_64.tar.gz -C /opt - -# ENV PATH "$PATH:/opt/julia-1.9.3/bin" - -# RUN julia -e 'using Pkg; Pkg.add(["QuantumOptics", "Configurations", "StatsBase", "DataStructures", "JSON3", "IonSim"])' +######################################################################################## \ No newline at end of file diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index e52f159..4e2d091 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -5,10 +5,39 @@ version: "3.9" networks: internal: name: oqd-cloud-server-internal + # minionetwork: + # driver: bridge + + +volumes: + redis_volume: + driver: local + postgres_volume: + driver: local + minio_volume: + driver: local + ################################################################################ services: + minio: + image: docker.io/bitnami/minio:2022 + container_name: oqd-cloud-server-minio + ports: + - '9000:9000' + - '9001:9001' + networks: + # - minionetwork + internal: + volumes: + - 'minio_volume:/data' + environment: + - MINIO_ROOT_USER=${MINIO_ROOT_USER} + - MINIO_ROOT_PASSWORD=${REDIS_PASSWORD} + - MINIO_DEFAULT_BUCKETS=${REDIS_BUCKET_NAME} + + redis: image: redis container_name: oqd-cloud-server-redis @@ -70,6 +99,9 @@ services: JWT_ALGORITHM: ${JWT_ALGORITHM} JWT_ACCESS_TOKEN_EXPIRE_MINUTES: ${JWT_ACCESS_TOKEN_EXPIRE_MINUTES} RQ_WORKERS: 4 + MINIO_ROOT_USER: ${MINIO_ROOT_USER} + MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + MINIO_DEFAULT_BUCKETS: ${MINIO_DEFAULT_BUCKETS} ports: - "8000:8000" networks: @@ -80,8 +112,3 @@ services: postgres: condition: service_healthy -volumes: - redis_volume: - driver: local - postgres_volume: - driver: local diff --git a/docker/requirements.txt b/docker/requirements.txt index 0468d34..38eb276 100644 --- a/docker/requirements.txt +++ b/docker/requirements.txt @@ -1,7 +1,4 @@ -qutip~=5.0.1 -numpy~=1.0 pydantic>=2.4 - sqlalchemy fastapi redis diff --git a/pyproject.toml b/pyproject.toml index 7518e11..859bb61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,10 +49,18 @@ server = [ "python-jose", "passlib", "python-multipart", + "pydantic>=2.4", + "sqlalchemy", + "fastapi", + "redis", + "rq", + "python-dotenv", + "minio", # "oqd-compiler-infrastructure@git+https://github.com/openquantumdesign/oqd-compiler-infrastructure", "oqd-core@git+https://github.com/openquantumdesign/oqd-core", - "oqd-compiler-infrastructure@git+https://github.com/openquantumdesign/oqd-analog-emulator", + "oqd-analog-emulator@git+https://github.com/openquantumdesign/oqd-analog-emulator", + "oqd-trical@git+https://github.com/openquantumdesign/oqd-trical", ] diff --git a/src/oqd_cloud/client.py b/src/oqd_cloud/client.py index 7a2467e..117fb66 100644 --- a/src/oqd_cloud/client.py +++ b/src/oqd_cloud/client.py @@ -52,7 +52,7 @@ class Client: user="user", password="password" ) - job = client.submit_job(task=task, backend="analog-qutip") + job = client.submit_job(task=task, backend="oqd-analog-emulator") ``` """ diff --git a/src/oqd_cloud/provider.py b/src/oqd_cloud/provider.py index 8bc583e..dfbefdd 100644 --- a/src/oqd_cloud/provider.py +++ b/src/oqd_cloud/provider.py @@ -29,7 +29,7 @@ def available_backends(self): return self._available_backends else: return [ - "analog-qutip", + "oqd-analog-emulator", ] @property From 655c289889afb9c2e3687c12b77fac4c95d07294 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Wed, 26 Feb 2025 20:31:51 -0500 Subject: [PATCH 02/15] Remove requirements.txt, add to pyproject.toml instead, simplfiy Docker --- pyproject.toml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 859bb61..48b6ecb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -29,7 +29,7 @@ classifiers = [ dependencies = [ "requests", "pydantic>=2.4", - "oqd-core@git+https://github.com/openquantumdesign/oqd-core", + "oqd-core@git+https://github.com/OpenQuantumDesign/oqd-core", ] [project.optional-dependencies] @@ -57,10 +57,8 @@ server = [ "python-dotenv", "minio", # - "oqd-compiler-infrastructure@git+https://github.com/openquantumdesign/oqd-compiler-infrastructure", - "oqd-core@git+https://github.com/openquantumdesign/oqd-core", - "oqd-analog-emulator@git+https://github.com/openquantumdesign/oqd-analog-emulator", - "oqd-trical@git+https://github.com/openquantumdesign/oqd-trical", + "oqd-analog-emulator@git+https://github.com/OpenQuantumDesign/oqd-analog-emulator", + "oqd-trical@git+https://github.com/OpenQuantumDesign/oqd-trical", ] From 05ea1f7aa0d6f21bec8e01f29b41ed59e7489db0 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Wed, 26 Feb 2025 22:31:34 -0500 Subject: [PATCH 03/15] Add route for getting available backends --- .gitignore | 3 +- docker/Dockerfile | 33 ++++----------- docker/docker-compose.yaml | 54 ++++++++++++++++++++---- docker/requirements.txt | 6 --- src/oqd_cloud/client.py | 15 +++++-- src/oqd_cloud/provider.py | 20 ++++++--- src/oqd_cloud/server/model.py | 6 ++- src/oqd_cloud/server/route/job.py | 38 ++++++++++------- tests/test_client.py | 70 ++++++++++++++++--------------- 9 files changed, 145 insertions(+), 100 deletions(-) delete mode 100644 docker/requirements.txt diff --git a/.gitignore b/.gitignore index fafbe0d..874aba0 100644 --- a/.gitignore +++ b/.gitignore @@ -165,4 +165,5 @@ cython_debug/ *.code-workspace .github/workflows/_*.yml -uv.lock \ No newline at end of file +uv.lock +docker/.env copy diff --git a/docker/Dockerfile b/docker/Dockerfile index b1ffa9e..997ea3f 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,38 +3,19 @@ COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ RUN apt-get update && \ apt-get upgrade -y && \ - apt-get install -y --no-install-recommends build-essential gcc && \ - apt-get install -y git # for installing directly from git - -WORKDIR /python -RUN uv venv /python/.venv -ENV PATH="/python/.venv/bin:$PATH" -COPY docker/requirements.txt . - -RUN uv pip install -r requirements.txt - -RUN uv pip install "oqd-analog-emulator@git+https://github.com/openquantumdesign/oqd-analog-emulator" -RUN uv pip install "oqd-trical@git+https://github.com/openquantumdesign/oqd-trical" - -######################################################################################## - -FROM python:3.12-slim-bookworm as app -COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/ - -RUN apt update && \ apt install -y --no-install-recommends supervisor && \ + apt-get install -y git && \ apt-get install -y gcc g++ # needed from Cython -COPY --from=build /python/.venv /python/.venv - -ENV PATH="/python/.venv/bin:$PATH" -ENV PYTHONPATH="/app/src" - COPY . ./app +ENV PYTHONPATH="/app/src" WORKDIR /app -RUN uv pip install .[server] -# COPY ./supervisord.conf /etc/supervisor/conf.d/supervisord.conf +RUN uv venv +ENV PATH=".venv/bin:$PATH" + +RUN uv pip install ".[server]" + COPY ./docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"] diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 4e2d091..905bddc 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -5,9 +5,6 @@ version: "3.9" networks: internal: name: oqd-cloud-server-internal - # minionetwork: - # driver: bridge - volumes: redis_volume: @@ -22,21 +19,22 @@ volumes: services: minio: - image: docker.io/bitnami/minio:2022 + image: minio/minio container_name: oqd-cloud-server-minio + restart: always ports: - '9000:9000' - '9001:9001' + # network_mode: "host" networks: - # - minionetwork internal: volumes: - 'minio_volume:/data' environment: - MINIO_ROOT_USER=${MINIO_ROOT_USER} - - MINIO_ROOT_PASSWORD=${REDIS_PASSWORD} - - MINIO_DEFAULT_BUCKETS=${REDIS_BUCKET_NAME} - + - MINIO_ROOT_PASSWORD=${MINIO_ROOT_PASSWORD} + - MINIO_DEFAULT_BUCKETS=${MINIO_DEFAULT_BUCKETS} + command: server /data --console-address ":9001" redis: image: redis @@ -53,6 +51,7 @@ services: command: ["sh", "-c", "redis-server --requirepass $${REDIS_PASSWORD} --save 20 1 --loglevel notice --appendonly yes --appendfsync everysec"] expose: - "6379" + # network_mode: "host" networks: internal: volumes: @@ -74,11 +73,50 @@ services: retries: 5 expose: - "5432" + # network_mode: "host" networks: internal: volumes: - postgres_volume:/var/lib/postgres/data + + # app: + # image: oqd-cloud-server # Use existing built image + # container_name: oqd-cloud-server + # restart: always + # environment: + # REDIS_HOST: ${REDIS_HOST} + # REDIS_PASSWORD: ${REDIS_PASSWORD} + # POSTGRES_HOST: ${POSTGRES_HOST} + # POSTGRES_USER: ${POSTGRES_USER} + # POSTGRES_DB: ${POSTGRES_DB} + # POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + # JWT_SECRET_KEY: ${JWT_SECRET_KEY} + # JWT_ALGORITHM: ${JWT_ALGORITHM} + # JWT_ACCESS_TOKEN_EXPIRE_MINUTES: ${JWT_ACCESS_TOKEN_EXPIRE_MINUTES} + # RQ_WORKERS: 4 + # MINIO_ROOT_USER: ${MINIO_ROOT_USER} + # MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + # MINIO_DEFAULT_BUCKETS: ${MINIO_DEFAULT_BUCKETS} + # ports: + # - "8000:8000" + # networks: + # - internal + # volumes: + # - ../:/app # Bind-mount your code + # working_dir: /app # Set working directory inside container + # command: > + # /bin/sh -c " + # source .venv/bin/activate + # uvicorn main:app --host 0.0.0.0 --port 8000 --reload + # " + # depends_on: + # redis: + # condition: service_healthy + # postgres: + # condition: service_healthy + + app: build: context: ../ diff --git a/docker/requirements.txt b/docker/requirements.txt deleted file mode 100644 index 38eb276..0000000 --- a/docker/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -pydantic>=2.4 -sqlalchemy -fastapi -redis -rq -python-dotenv \ No newline at end of file diff --git a/src/oqd_cloud/client.py b/src/oqd_cloud/client.py index 117fb66..b0dc840 100644 --- a/src/oqd_cloud/client.py +++ b/src/oqd_cloud/client.py @@ -13,7 +13,7 @@ # limitations under the License. -from typing import Literal, Optional +from typing import Literal, Optional, Sequence import requests from oqd_core.backend.task import Task @@ -21,7 +21,11 @@ from oqd_cloud.provider import Provider -__all__ = ["Job", "Client"] +__all__ = ["Job", "Client", "Backends"] + + +class Backends(BaseModel): + available: Sequence[str] class Job(BaseModel): @@ -129,13 +133,18 @@ def connect(self, provider: Provider, username: str, password: str): # self.connect(self, self.provider) # pass - def submit_job(self, task: Task, backend: Literal["analog-qutip",]): + def submit_job( + self, + task: Task, + backend: str + ): """Submit a Task as an AnalogCircuit, DigitalCircuit, or AtomicCircuit to a backend.""" response = requests.post( self.provider.job_submission_url(backend=backend), json=task.model_dump(), headers=self.authorization_header, ) + print(response) job = Job.model_validate(response.json()) if response.status_code == 200: diff --git a/src/oqd_cloud/provider.py b/src/oqd_cloud/provider.py index dfbefdd..86be27a 100644 --- a/src/oqd_cloud/provider.py +++ b/src/oqd_cloud/provider.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +import requests + class Provider: def __init__(self, url: str = "http://localhost:8000"): @@ -25,12 +27,18 @@ def __init__(self, url: str = "http://localhost:8000"): @property def available_backends(self): # todo: get available backends from url - if hasattr(self, "_available_backends"): - return self._available_backends - else: - return [ - "oqd-analog-emulator", - ] + response = requests.post( + self.url + "/available_backends" + ) + if response.status_code == 200: + return response['backends'] + + # if hasattr(self, "_available_backends"): + # return self._available_backends + # else: + # return [ + # "oqd-analog-emulator", + # ] @property def registration_url(self): diff --git a/src/oqd_cloud/server/model.py b/src/oqd_cloud/server/model.py index 9a2212d..98ed279 100644 --- a/src/oqd_cloud/server/model.py +++ b/src/oqd_cloud/server/model.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Optional +from typing import Optional, Sequence from pydantic import BaseModel, ConfigDict @@ -44,3 +44,7 @@ class Job(BaseModel): status: str result: Optional[str] = None user_id: str + + +class Backends(BaseModel): + available: Sequence[str] \ No newline at end of file diff --git a/src/oqd_cloud/server/route/job.py b/src/oqd_cloud/server/route/job.py index dd6175e..76d6531 100644 --- a/src/oqd_cloud/server/route/job.py +++ b/src/oqd_cloud/server/route/job.py @@ -18,7 +18,8 @@ from fastapi import status as http_status ######################################################################################## -from oqd_analog_emulator.qutip_backend import QutipBackend +import oqd_analog_emulator #.qutip_backend import QutipBackend +import oqd_trical from oqd_core.backend.task import Task from rq.job import Callback from rq.job import Job as RQJob @@ -32,38 +33,43 @@ report_stopped, report_success, ) -from oqd_cloud.server.model import Job +from oqd_cloud.server.model import Job, Backends from oqd_cloud.server.route.auth import user_dependency ######################################################################################## -job_router = APIRouter(tags=["Job"]) +# _backends = ["oqd-analog-emulator-qutip", "oqd-trical-qutip", "oqd-trical-dynamiqs"] +_backends = { + "oqd-analog-emulator-qutip": oqd_analog_emulator.qutip_backend.QutipBackend(), + "oqd-trical-qutip": oqd_trical.backend.qutip.QutipBackend(), + "oqd-trical-dynamiqs": oqd_trical.backend.dynamiqs.DynamiqsBackend(), +} +backends = Backends(available=list(_backends.keys())) +job_router = APIRouter(tags=["Job"]) +@job_router.post("/available_backends", tags=["Job"]) +async def available_backends(): + return backends + + @job_router.post("/submit/{backend}", tags=["Job"]) async def submit_job( task: Task, - backend: Literal["analog-qutip",], + # backend: Literal["oqd-analog-emulator-qutip", "oqd-trical-qutip", "oqd-trical-dynamiqs"], + backend: Literal[tuple(backends.available)], user: user_dependency, db: db_dependency, ): print(task) print(f"Queueing {task} on server {backend} backend. {len(queue)} jobs in queue.") - backends = { - "analog-qutip": QutipBackend(), - # "tensorcircuit": TensorCircuitBackend() - } - # backends_run = { - # "analog-qutip": lambda task: backends["analog-qutip"].run(task=task) + # backends = { + # "oqd-analog-emulator-qutip": oqd_analog_emulator.qutip_backend.QutipBackend(), + # "oqd-trical-qutip": oqd_trical.backend.qutip.QutipBackend(), + # "oqd-trical-dynamiqs": oqd_trical.backend.dynamiqs.DynamiqsBackend(), # } - if backend == "analog-qutip": - try: - expt, args = backends[backend].compile(task=task) - except Exception: - raise Exception("Cannot properly compile to the QutipBackend.") - job = queue.enqueue( backends[backend].run, task, diff --git a/tests/test_client.py b/tests/test_client.py index 1312220..4d0e419 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -14,10 +14,10 @@ # %% -import matplotlib.pyplot as plt -import numpy as np -import seaborn as sns -from oqd_analog_emulator.qutip_backend import QutipBackend +# import matplotlib.pyplot as plt +# import numpy as np +# import seaborn as sns +# from oqd_analog_emulator.qutip_backend import QutipBackend from oqd_core.backend.metric import Expectation from oqd_core.backend.task import Task, TaskArgsAnalog from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate @@ -70,46 +70,46 @@ task.model_dump_json() # %% -backend = QutipBackend() -expt, args = backend.compile(task=task) +# backend = QutipBackend() +# expt, args = backend.compile(task=task) # results = backend.run(experiment=expt, args=args) -a = {"experiment": expt, "args": args} -results = backend.run(task=task) +# a = {"experiment": expt, "args": args} +# results = backend.run(task=task) # %% -fig, ax = plt.subplots(1, 1, figsize=[6, 3]) -colors = sns.color_palette(palette="crest", n_colors=4) +# fig, ax = plt.subplots(1, 1, figsize=[6, 3]) +# colors = sns.color_palette(palette="crest", n_colors=4) -for k, (name, metric) in enumerate(results.metrics.items()): - ax.plot(results.times, metric, label=f"$\\langle {name} \\rangle$", color=colors[k]) -ax.legend() -# plt.show() +# for k, (name, metric) in enumerate(results.metrics.items()): +# ax.plot(results.times, metric, label=f"$\\langle {name} \\rangle$", color=colors[k]) +# ax.legend() +# # plt.show() -# %% -fig, axs = plt.subplots(4, 1, sharex=True, figsize=[5, 9]) +# # %% +# fig, axs = plt.subplots(4, 1, sharex=True, figsize=[5, 9]) -state = np.array([basis.real + 1j * basis.imag for basis in results.state]) -bases = ["0", "1"] -counts = {basis: results.counts.get(basis, 0) for basis in bases} +# state = np.array([basis.real + 1j * basis.imag for basis in results.state]) +# bases = ["0", "1"] +# counts = {basis: results.counts.get(basis, 0) for basis in bases} -ax = axs[0] -ax.bar(x=bases, height=np.abs(state) ** 2, color=colors[0]) -ax.set(ylabel="Probability") +# ax = axs[0] +# ax.bar(x=bases, height=np.abs(state) ** 2, color=colors[0]) +# ax.set(ylabel="Probability") -ax = axs[1] -ax.bar(x=bases, height=list(counts.values()), color=colors[1]) -ax.set(ylabel="Count") +# ax = axs[1] +# ax.bar(x=bases, height=list(counts.values()), color=colors[1]) +# ax.set(ylabel="Count") -ax = axs[2] -ax.bar(x=bases, height=state.real, color=colors[2]) -ax.set(ylabel="Amplitude (real)") +# ax = axs[2] +# ax.bar(x=bases, height=state.real, color=colors[2]) +# ax.set(ylabel="Amplitude (real)") -ax = axs[3] -ax.bar(x=bases, height=state.imag, color=colors[3]) -ax.set(xlabel="Basis state", ylabel="Amplitude (imag)", ylim=[-np.pi, np.pi]) +# ax = axs[3] +# ax.bar(x=bases, height=state.imag, color=colors[3]) +# ax.set(xlabel="Basis state", ylabel="Amplitude (imag)", ylim=[-np.pi, np.pi]) -# plt.show() +# # plt.show() # %% client = Client() @@ -117,9 +117,13 @@ client.connect(provider=provider, username="ben", password="pwd") client.status_report +#%% +backends = provider.available_backends +print(backends) + # %% print(client.jobs) -job = client.submit_job(task=task, backend="analog-qutip") +job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip") # %% client.retrieve_job(job_id=job.job_id) From f5ebb6b07e73c8fef9af53f58ab10797b3b6159e Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Wed, 26 Feb 2025 22:51:49 -0500 Subject: [PATCH 04/15] Get available backends from server route, add atomic JSON example --- src/oqd_cloud/provider.py | 20 ++- tests/atomic.json | 266 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 275 insertions(+), 11 deletions(-) create mode 100644 tests/atomic.json diff --git a/src/oqd_cloud/provider.py b/src/oqd_cloud/provider.py index 86be27a..d6a60f1 100644 --- a/src/oqd_cloud/provider.py +++ b/src/oqd_cloud/provider.py @@ -13,6 +13,7 @@ # limitations under the License. import requests +from oqd_cloud.server.model import Backends class Provider: @@ -24,22 +25,19 @@ def __init__(self, url: str = "http://localhost:8000"): """ self.url = url - @property - def available_backends(self): - # todo: get available backends from url + # get available backends + self.backends = Backends(available=[]) response = requests.post( self.url + "/available_backends" ) + backends = Backends.model_validate(response.json()) if response.status_code == 200: - return response['backends'] - - # if hasattr(self, "_available_backends"): - # return self._available_backends - # else: - # return [ - # "oqd-analog-emulator", - # ] + self.backends = backends + @property + def available_backends(self): + return self.backends.available + @property def registration_url(self): return self.url + "/auth/register" diff --git a/tests/atomic.json b/tests/atomic.json new file mode 100644 index 0000000..a2e3b90 --- /dev/null +++ b/tests/atomic.json @@ -0,0 +1,266 @@ +{ + "class_": "AtomicCircuit", + "system": { + "class_": "System", + "ions": [ + { + "class_": "Ion", + "mass": 171.0, + "charge": 1.0, + "levels": [ + { + "class_": "Level", + "label": "q0", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 0.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 0.0 + }, + { + "class_": "Level", + "label": "q1", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 62.83185307179586 + }, + { + "class_": "Level", + "label": "e0", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": -1.0, + "energy": 628.3185307179587 + }, + { + "class_": "Level", + "label": "e1", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": 1.0, + "energy": 691.1503837897545 + } + ], + "transitions": [ + { + "class_": "Transition", + "label": "q0->e0", + "level1": { + "class_": "Level", + "label": "q0", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 0.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 0.0 + }, + "level2": { + "class_": "Level", + "label": "e0", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": -1.0, + "energy": 628.3185307179587 + }, + "einsteinA": 1.0, + "multipole": "E1" + }, + { + "class_": "Transition", + "label": "q0->e1", + "level1": { + "class_": "Level", + "label": "q0", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 0.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 0.0 + }, + "level2": { + "class_": "Level", + "label": "e1", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": 1.0, + "energy": 691.1503837897545 + }, + "einsteinA": 1.0, + "multipole": "E1" + }, + { + "class_": "Transition", + "label": "q1->e0", + "level1": { + "class_": "Level", + "label": "q1", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 62.83185307179586 + }, + "level2": { + "class_": "Level", + "label": "e0", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": -1.0, + "energy": 628.3185307179587 + }, + "einsteinA": 1.0, + "multipole": "E1" + }, + { + "class_": "Transition", + "label": "q1->e1", + "level1": { + "class_": "Level", + "label": "q1", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 62.83185307179586 + }, + "level2": { + "class_": "Level", + "label": "e1", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": 1.0, + "energy": 691.1503837897545 + }, + "einsteinA": 1.0, + "multipole": "E1" + } + ], + "position": [ + 0.0, + 0.0, + 0.0 + ] + } + ], + "modes": [ + { + "class_": "Phonon", + "energy": 0.1, + "eigenvector": [ + 1.0, + 0.0, + 0.0 + ] + } + ] + }, + "protocol": { + "class_": "SequentialProtocol", + "sequence": [ + { + "class_": "Pulse", + "beam": { + "class_": "Beam", + "transition": { + "class_": "Transition", + "label": "q0->e0", + "level1": { + "class_": "Level", + "label": "q0", + "principal": 6, + "spin": 0.5, + "orbital": 0.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 0.0, + "spin_orbital_nuclear_magnetization": 0.0, + "energy": 0.0 + }, + "level2": { + "class_": "Level", + "label": "e0", + "principal": 5, + "spin": 0.5, + "orbital": 1.0, + "nuclear": 0.5, + "spin_orbital": 0.5, + "spin_orbital_nuclear": 1.0, + "spin_orbital_nuclear_magnetization": -1.0, + "energy": 628.3185307179587 + }, + "einsteinA": 1.0, + "multipole": "E1" + }, + "rabi": { + "class_": "MathNum", + "value": 6.283185307179586 + }, + "detuning": { + "class_": "MathNum", + "value": 0 + }, + "phase": { + "class_": "MathNum", + "value": 0 + }, + "polarization": [ + 1.0, + 0.0, + 0.0 + ], + "wavevector": [ + 0.0, + 1.0, + 0.0 + ], + "target": 0 + }, + "duration": 10.0 + } + ] + } + } \ No newline at end of file From 6c9eecc1763017a26fc867b7c279f1027c1cfa41 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Thu, 27 Feb 2025 09:53:39 -0500 Subject: [PATCH 05/15] Set up local development --- docker/docker-compose.yaml | 94 ++++++++++++++++-------------- pyproject.toml | 16 +++++ src/oqd_cloud/provider.py | 3 +- src/oqd_cloud/server/main.py | 2 +- src/oqd_cloud/server/route/job.py | 2 +- src/oqd_cloud/server/route/user.py | 2 +- tests/test_client.py | 34 ++++++++++- 7 files changed, 104 insertions(+), 49 deletions(-) diff --git a/docker/docker-compose.yaml b/docker/docker-compose.yaml index 905bddc..184085b 100644 --- a/docker/docker-compose.yaml +++ b/docker/docker-compose.yaml @@ -20,7 +20,7 @@ volumes: services: minio: image: minio/minio - container_name: oqd-cloud-server-minio + container_name: minio restart: always ports: - '9000:9000' @@ -38,7 +38,7 @@ services: redis: image: redis - container_name: oqd-cloud-server-redis + container_name: redis restart: always healthcheck: test: ["CMD-SHELL", "redis-cli -a $${REDIS_PASSWORD} --raw incr _docker_healthcheck"] @@ -49,8 +49,10 @@ services: environment: REDIS_PASSWORD: ${REDIS_PASSWORD} # Replace command: ["sh", "-c", "redis-server --requirepass $${REDIS_PASSWORD} --save 20 1 --loglevel notice --appendonly yes --appendfsync everysec"] - expose: - - "6379" + ports: + - "6379:6379" + # expose: + # - "6379" # network_mode: "host" networks: internal: @@ -59,7 +61,7 @@ services: postgres: image: postgres - container_name: oqd-cloud-server-postgres + container_name: postgres restart: always environment: POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} # Replace @@ -71,8 +73,10 @@ services: interval: 5s timeout: 25s retries: 5 - expose: - - "5432" + # expose: + # - "5432" + ports: + - "5432:5432" # network_mode: "host" networks: internal: @@ -105,11 +109,13 @@ services: # volumes: # - ../:/app # Bind-mount your code # working_dir: /app # Set working directory inside container - # command: > - # /bin/sh -c " - # source .venv/bin/activate - # uvicorn main:app --host 0.0.0.0 --port 8000 --reload - # " + # # command: uv run src/oqd_cloud/server/main.py + # command: uv run src/oqd_cloud/server/main.py + # # command: > + # # /bin/sh -c " + # # source .venv/bin/activate + # # uvicorn main:app --host 0.0.0.0 --port 8000 --reload + # # " # depends_on: # redis: # condition: service_healthy @@ -117,36 +123,36 @@ services: # condition: service_healthy - app: - build: - context: ../ - dockerfile: docker/Dockerfile - args: - GITHUB_TOKEN: ${GITHUB_TOKEN} - image: oqd-cloud-server - container_name: oqd-cloud-server - restart: always - environment: - REDIS_HOST: ${REDIS_HOST} - REDIS_PASSWORD: ${REDIS_PASSWORD} - POSTGRES_HOST: ${POSTGRES_HOST} - POSTGRES_USER: ${POSTGRES_USER} - POSTGRES_DB: ${POSTGRES_DB} - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} - JWT_SECRET_KEY: ${JWT_SECRET_KEY} - JWT_ALGORITHM: ${JWT_ALGORITHM} - JWT_ACCESS_TOKEN_EXPIRE_MINUTES: ${JWT_ACCESS_TOKEN_EXPIRE_MINUTES} - RQ_WORKERS: 4 - MINIO_ROOT_USER: ${MINIO_ROOT_USER} - MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} - MINIO_DEFAULT_BUCKETS: ${MINIO_DEFAULT_BUCKETS} - ports: - - "8000:8000" - networks: - internal: - depends_on: - redis: - condition: service_healthy - postgres: - condition: service_healthy + # app: + # build: + # context: ../ + # dockerfile: docker/Dockerfile + # args: + # GITHUB_TOKEN: ${GITHUB_TOKEN} + # image: oqd-cloud-server + # container_name: oqd-cloud-server + # restart: always + # environment: + # REDIS_HOST: ${REDIS_HOST} + # REDIS_PASSWORD: ${REDIS_PASSWORD} + # POSTGRES_HOST: ${POSTGRES_HOST} + # POSTGRES_USER: ${POSTGRES_USER} + # POSTGRES_DB: ${POSTGRES_DB} + # POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + # JWT_SECRET_KEY: ${JWT_SECRET_KEY} + # JWT_ALGORITHM: ${JWT_ALGORITHM} + # JWT_ACCESS_TOKEN_EXPIRE_MINUTES: ${JWT_ACCESS_TOKEN_EXPIRE_MINUTES} + # RQ_WORKERS: 4 + # MINIO_ROOT_USER: ${MINIO_ROOT_USER} + # MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD} + # MINIO_DEFAULT_BUCKETS: ${MINIO_DEFAULT_BUCKETS} + # ports: + # - "8000:8000" + # networks: + # internal: + # depends_on: + # redis: + # condition: service_healthy + # postgres: + # condition: service_healthy diff --git a/pyproject.toml b/pyproject.toml index 48b6ecb..4297849 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,6 +30,22 @@ dependencies = [ "requests", "pydantic>=2.4", "oqd-core@git+https://github.com/OpenQuantumDesign/oqd-core", + # + "asyncpg", + "uvicorn", + "python-jose", + "passlib", + "python-multipart", + "pydantic>=2.4", + "sqlalchemy", + "fastapi", + "redis", + "rq", + "python-dotenv", + "minio", + # + "oqd-analog-emulator@git+https://github.com/OpenQuantumDesign/oqd-analog-emulator", + "oqd-trical@git+https://github.com/OpenQuantumDesign/oqd-trical", ] [project.optional-dependencies] diff --git a/src/oqd_cloud/provider.py b/src/oqd_cloud/provider.py index d6a60f1..f569bef 100644 --- a/src/oqd_cloud/provider.py +++ b/src/oqd_cloud/provider.py @@ -17,12 +17,13 @@ class Provider: - def __init__(self, url: str = "http://localhost:8000"): + def __init__(self, host: str = "http://localhost", port: int = 8000): """ Args: url: URL for the server """ + url = f"{host}:{port}" self.url = url # get available backends diff --git a/src/oqd_cloud/server/main.py b/src/oqd_cloud/server/main.py index 29465e2..4d1a22e 100644 --- a/src/oqd_cloud/server/main.py +++ b/src/oqd_cloud/server/main.py @@ -15,4 +15,4 @@ if __name__ == "__main__": import uvicorn - uvicorn.run("app:app", host="0.0.0.0", port=8000) + uvicorn.run("app:app", host="0.0.0.0", port=8007) diff --git a/src/oqd_cloud/server/route/job.py b/src/oqd_cloud/server/route/job.py index 76d6531..e4d90ed 100644 --- a/src/oqd_cloud/server/route/job.py +++ b/src/oqd_cloud/server/route/job.py @@ -71,7 +71,7 @@ async def submit_job( # } job = queue.enqueue( - backends[backend].run, + _backends[backend].run, task, on_success=Callback(report_success), on_failure=Callback(report_failure), diff --git a/src/oqd_cloud/server/route/user.py b/src/oqd_cloud/server/route/user.py index c752503..8ceb431 100644 --- a/src/oqd_cloud/server/route/user.py +++ b/src/oqd_cloud/server/route/user.py @@ -21,7 +21,7 @@ from oqd_cloud.server.database import JobInDB, UserInDB, db_dependency from oqd_cloud.server.model import ( Job, # todo: proper import - UserRegistrationForm, # , Job + UserRegistrationForm, ) ######################################################################################## diff --git a/tests/test_client.py b/tests/test_client.py index 4d0e419..981cb8e 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -23,6 +23,8 @@ from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate from oqd_core.interface.analog.operator import PauliX, PauliZ +from oqd_core.interface.atomic.circuit import AtomicCircuit + from oqd_cloud.client import Client from oqd_cloud.provider import Provider @@ -113,7 +115,7 @@ # %% client = Client() -provider = Provider() +provider = Provider(port=8007) client.connect(provider=provider, username="ben", password="pwd") client.status_report @@ -127,3 +129,33 @@ # %% client.retrieve_job(job_id=job.job_id) + +# %% + +with open("./tests/atomic.json", "r") as f: + circuit = AtomicCircuit.model_validate_json(f.read()) + +print(circuit) + +# %% +from minio import Minio +import os + +os.getenv("127.0.0.1:9000") + +client = Minio( + "127.0.0.1:9000", + access_key="admin", + secret_key="password", + secure=False +) + +# %% +source_file = "./tests/atomic.json" +bucket_name = "oqd-cloud-bucket" +destination_file = "my-test-file.txt" + +client.fput_object( + bucket_name, destination_file, source_file, +) +# %% From 1bcb57de11b626599ad426eed00a7b3584552f24 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Thu, 27 Feb 2025 21:34:12 -0500 Subject: [PATCH 06/15] Ad tags as body arg for submit_job route --- src/oqd_cloud/client.py | 6 +++- src/oqd_cloud/provider.py | 2 +- src/oqd_cloud/server/database.py | 1 + src/oqd_cloud/server/main.py | 2 +- src/oqd_cloud/server/model.py | 3 +- src/oqd_cloud/server/route/job.py | 27 +++++++++------- src/oqd_cloud/server/storage.py | 50 +++++++++++++++++++++++++++++ tests/test_client.py | 52 ++----------------------------- 8 files changed, 77 insertions(+), 66 deletions(-) create mode 100644 src/oqd_cloud/server/storage.py diff --git a/src/oqd_cloud/client.py b/src/oqd_cloud/client.py index b0dc840..cd44c0c 100644 --- a/src/oqd_cloud/client.py +++ b/src/oqd_cloud/client.py @@ -16,6 +16,7 @@ from typing import Literal, Optional, Sequence import requests +import json from oqd_core.backend.task import Task from pydantic import BaseModel, ConfigDict @@ -41,6 +42,7 @@ class Job(BaseModel): status: str result: Optional[str] = None user_id: str + # tags: Optional[Sequence[str]] class Client: @@ -136,12 +138,14 @@ def connect(self, provider: Provider, username: str, password: str): def submit_job( self, task: Task, - backend: str + backend: str, + tags: Sequence[str] ): """Submit a Task as an AnalogCircuit, DigitalCircuit, or AtomicCircuit to a backend.""" response = requests.post( self.provider.job_submission_url(backend=backend), json=task.model_dump(), + # json={"task": task.model_dump(), "tags": tags}, headers=self.authorization_header, ) print(response) diff --git a/src/oqd_cloud/provider.py b/src/oqd_cloud/provider.py index f569bef..7415b2a 100644 --- a/src/oqd_cloud/provider.py +++ b/src/oqd_cloud/provider.py @@ -28,7 +28,7 @@ def __init__(self, host: str = "http://localhost", port: int = 8000): # get available backends self.backends = Backends(available=[]) - response = requests.post( + response = requests.get( self.url + "/available_backends" ) backends = Backends.model_validate(response.json()) diff --git a/src/oqd_cloud/server/database.py b/src/oqd_cloud/server/database.py index 751e819..a6ff01b 100644 --- a/src/oqd_cloud/server/database.py +++ b/src/oqd_cloud/server/database.py @@ -65,6 +65,7 @@ class JobInDB(Base): backend: Mapped[str] status: Mapped[str] result: Mapped[Optional[str]] + tags: Mapped[Optional[str]] user_id: Mapped[int] = mapped_column(ForeignKey("users.user_id")) user: Mapped["UserInDB"] = relationship(back_populates="jobs") diff --git a/src/oqd_cloud/server/main.py b/src/oqd_cloud/server/main.py index 4d1a22e..41b47f7 100644 --- a/src/oqd_cloud/server/main.py +++ b/src/oqd_cloud/server/main.py @@ -15,4 +15,4 @@ if __name__ == "__main__": import uvicorn - uvicorn.run("app:app", host="0.0.0.0", port=8007) + uvicorn.run("app:app", host="0.0.0.0", port=8007, log_level='debug') diff --git a/src/oqd_cloud/server/model.py b/src/oqd_cloud/server/model.py index 98ed279..c7eefc1 100644 --- a/src/oqd_cloud/server/model.py +++ b/src/oqd_cloud/server/model.py @@ -44,7 +44,8 @@ class Job(BaseModel): status: str result: Optional[str] = None user_id: str - + # tags: Optional[Sequence[str]] + class Backends(BaseModel): available: Sequence[str] \ No newline at end of file diff --git a/src/oqd_cloud/server/route/job.py b/src/oqd_cloud/server/route/job.py index e4d90ed..7f7d2de 100644 --- a/src/oqd_cloud/server/route/job.py +++ b/src/oqd_cloud/server/route/job.py @@ -12,11 +12,12 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Literal +from typing import Literal, Sequence, Optional from fastapi import APIRouter, HTTPException from fastapi import status as http_status - +import logging +logger = logging.getLogger('uvicorn.error') ######################################################################################## import oqd_analog_emulator #.qutip_backend import QutipBackend import oqd_trical @@ -38,7 +39,6 @@ ######################################################################################## -# _backends = ["oqd-analog-emulator-qutip", "oqd-trical-qutip", "oqd-trical-dynamiqs"] _backends = { "oqd-analog-emulator-qutip": oqd_analog_emulator.qutip_backend.QutipBackend(), "oqd-trical-qutip": oqd_trical.backend.qutip.QutipBackend(), @@ -48,7 +48,8 @@ job_router = APIRouter(tags=["Job"]) -@job_router.post("/available_backends", tags=["Job"]) + +@job_router.get("/available_backends") async def available_backends(): return backends @@ -56,20 +57,21 @@ async def available_backends(): @job_router.post("/submit/{backend}", tags=["Job"]) async def submit_job( task: Task, - # backend: Literal["oqd-analog-emulator-qutip", "oqd-trical-qutip", "oqd-trical-dynamiqs"], backend: Literal[tuple(backends.available)], + # tags: Optional[Sequence[str]], user: user_dependency, db: db_dependency, ): print(task) print(f"Queueing {task} on server {backend} backend. {len(queue)} jobs in queue.") - - # backends = { - # "oqd-analog-emulator-qutip": oqd_analog_emulator.qutip_backend.QutipBackend(), - # "oqd-trical-qutip": oqd_trical.backend.qutip.QutipBackend(), - # "oqd-trical-dynamiqs": oqd_trical.backend.dynamiqs.DynamiqsBackend(), - # } - + # logger.debug(f'debug message {tags}') + + _backends = { + "oqd-analog-emulator-qutip": oqd_analog_emulator.qutip_backend.QutipBackend(), + "oqd-trical-qutip": oqd_trical.backend.qutip.QutipBackend(), + "oqd-trical-dynamiqs": oqd_trical.backend.dynamiqs.DynamiqsBackend(), + } + job = queue.enqueue( _backends[backend].run, task, @@ -84,6 +86,7 @@ async def submit_job( backend=backend, status=job.get_status(), result=None, + # tags=tags, user_id=user.user_id, ) db.add(job_in_db) diff --git a/src/oqd_cloud/server/storage.py b/src/oqd_cloud/server/storage.py new file mode 100644 index 0000000..2143d97 --- /dev/null +++ b/src/oqd_cloud/server/storage.py @@ -0,0 +1,50 @@ +# Copyright 2024-2025 Open Quantum Design + +# 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. + +from typing import Literal +from minio import Minio +import os + +from fastapi import APIRouter, HTTPException +from fastapi import status as http_status + +######################################################################################## +import oqd_analog_emulator #.qutip_backend import QutipBackend +import oqd_trical +from oqd_core.backend.task import Task +from rq.job import Callback +from rq.job import Job as RQJob +from sqlalchemy import select + +from oqd_cloud.server.database import JobInDB, db_dependency +from oqd_cloud.server.model import Job, Backends +from oqd_cloud.server.route.auth import user_dependency + +######################################################################################## + +minio_client = Minio( + "127.0.0.1:9000", + access_key="admin", + secret_key="password", + secure=False +) + +# %% +source_file = "./tests/atomic.json" +bucket_name = "oqd-cloud-bucket" +destination_file = "my-test-file.txt" + +minio_client.fput_object( + bucket_name, destination_file, source_file, +) \ No newline at end of file diff --git a/tests/test_client.py b/tests/test_client.py index 981cb8e..4072212 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -28,7 +28,6 @@ from oqd_cloud.client import Client from oqd_cloud.provider import Provider -# %% X = PauliX() Z = PauliZ() @@ -36,17 +35,14 @@ Hx = AnalogGate(hamiltonian=(2 * X + Z)) -# %% op = 2 * X + Z print(op.model_dump_json()) -# %% print(Hx) print(Hx.model_dump_json()) print(AnalogGate.model_validate_json(Hx.model_dump_json())) -# %% circuit = AnalogCircuit() circuit.evolve(duration=10, gate=Hx) @@ -54,10 +50,8 @@ print(circuit.model_dump_json()) print(AnalogCircuit.model_validate_json(circuit.model_dump_json())) -# %% circuit.model_json_schema() -# %% # define task args args = TaskArgsAnalog( n_shots=100, @@ -71,49 +65,8 @@ task = Task(program=circuit, args=args) task.model_dump_json() -# %% -# backend = QutipBackend() -# expt, args = backend.compile(task=task) -# results = backend.run(experiment=expt, args=args) -# a = {"experiment": expt, "args": args} -# results = backend.run(task=task) - -# %% -# fig, ax = plt.subplots(1, 1, figsize=[6, 3]) -# colors = sns.color_palette(palette="crest", n_colors=4) - -# for k, (name, metric) in enumerate(results.metrics.items()): -# ax.plot(results.times, metric, label=f"$\\langle {name} \\rangle$", color=colors[k]) -# ax.legend() -# # plt.show() - -# # %% -# fig, axs = plt.subplots(4, 1, sharex=True, figsize=[5, 9]) -# state = np.array([basis.real + 1j * basis.imag for basis in results.state]) -# bases = ["0", "1"] -# counts = {basis: results.counts.get(basis, 0) for basis in bases} - -# ax = axs[0] -# ax.bar(x=bases, height=np.abs(state) ** 2, color=colors[0]) -# ax.set(ylabel="Probability") - - -# ax = axs[1] -# ax.bar(x=bases, height=list(counts.values()), color=colors[1]) -# ax.set(ylabel="Count") - -# ax = axs[2] -# ax.bar(x=bases, height=state.real, color=colors[2]) -# ax.set(ylabel="Amplitude (real)") - -# ax = axs[3] -# ax.bar(x=bases, height=state.imag, color=colors[3]) -# ax.set(xlabel="Basis state", ylabel="Amplitude (imag)", ylim=[-np.pi, np.pi]) - -# # plt.show() - -# %% +#%% client = Client() provider = Provider(port=8007) client.connect(provider=provider, username="ben", password="pwd") @@ -125,13 +78,12 @@ # %% print(client.jobs) -job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip") +job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip", tags=['a', 'b']) # %% client.retrieve_job(job_id=job.job_id) # %% - with open("./tests/atomic.json", "r") as f: circuit = AtomicCircuit.model_validate_json(f.read()) From 48d4b98c37d36552a274a63740f8ba2b25db30bc Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Thu, 27 Feb 2025 22:47:33 -0500 Subject: [PATCH 07/15] Add tags --- src/oqd_cloud/client.py | 8 ++++---- src/oqd_cloud/server/model.py | 2 +- src/oqd_cloud/server/route/job.py | 23 +++++++-------------- tests/test_client.py | 33 +++---------------------------- 4 files changed, 15 insertions(+), 51 deletions(-) diff --git a/src/oqd_cloud/client.py b/src/oqd_cloud/client.py index cd44c0c..6190055 100644 --- a/src/oqd_cloud/client.py +++ b/src/oqd_cloud/client.py @@ -42,7 +42,7 @@ class Job(BaseModel): status: str result: Optional[str] = None user_id: str - # tags: Optional[Sequence[str]] + tags: Optional[str] = None class Client: @@ -139,13 +139,13 @@ def submit_job( self, task: Task, backend: str, - tags: Sequence[str] + tags: str ): """Submit a Task as an AnalogCircuit, DigitalCircuit, or AtomicCircuit to a backend.""" response = requests.post( self.provider.job_submission_url(backend=backend), - json=task.model_dump(), - # json={"task": task.model_dump(), "tags": tags}, + # json=task.model_dump(), + json={"task": task.model_dump(), "tags": tags}, headers=self.authorization_header, ) print(response) diff --git a/src/oqd_cloud/server/model.py b/src/oqd_cloud/server/model.py index c7eefc1..e545ddc 100644 --- a/src/oqd_cloud/server/model.py +++ b/src/oqd_cloud/server/model.py @@ -44,7 +44,7 @@ class Job(BaseModel): status: str result: Optional[str] = None user_id: str - # tags: Optional[Sequence[str]] + tags: Optional[str] = None class Backends(BaseModel): diff --git a/src/oqd_cloud/server/route/job.py b/src/oqd_cloud/server/route/job.py index 7f7d2de..583c147 100644 --- a/src/oqd_cloud/server/route/job.py +++ b/src/oqd_cloud/server/route/job.py @@ -12,12 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Literal, Sequence, Optional +from typing import Literal, Sequence, Optional, Annotated -from fastapi import APIRouter, HTTPException +from fastapi import APIRouter, HTTPException, Body from fastapi import status as http_status -import logging -logger = logging.getLogger('uvicorn.error') + ######################################################################################## import oqd_analog_emulator #.qutip_backend import QutipBackend import oqd_trical @@ -56,22 +55,14 @@ async def available_backends(): @job_router.post("/submit/{backend}", tags=["Job"]) async def submit_job( - task: Task, backend: Literal[tuple(backends.available)], - # tags: Optional[Sequence[str]], + task: Task, + tags: Annotated[str, Body()], user: user_dependency, db: db_dependency, ): - print(task) print(f"Queueing {task} on server {backend} backend. {len(queue)} jobs in queue.") - # logger.debug(f'debug message {tags}') - - _backends = { - "oqd-analog-emulator-qutip": oqd_analog_emulator.qutip_backend.QutipBackend(), - "oqd-trical-qutip": oqd_trical.backend.qutip.QutipBackend(), - "oqd-trical-dynamiqs": oqd_trical.backend.dynamiqs.DynamiqsBackend(), - } - + job = queue.enqueue( _backends[backend].run, task, @@ -86,7 +77,7 @@ async def submit_job( backend=backend, status=job.get_status(), result=None, - # tags=tags, + tags=tags, user_id=user.user_id, ) db.add(job_in_db) diff --git a/tests/test_client.py b/tests/test_client.py index 4072212..dc6e424 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -27,6 +27,7 @@ from oqd_cloud.client import Client from oqd_cloud.provider import Provider +from rich.pretty import pprint X = PauliX() Z = PauliZ() @@ -78,36 +79,8 @@ # %% print(client.jobs) -job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip", tags=['a', 'b']) +job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip", tags='a') +pprint(job) # %% client.retrieve_job(job_id=job.job_id) - -# %% -with open("./tests/atomic.json", "r") as f: - circuit = AtomicCircuit.model_validate_json(f.read()) - -print(circuit) - -# %% -from minio import Minio -import os - -os.getenv("127.0.0.1:9000") - -client = Minio( - "127.0.0.1:9000", - access_key="admin", - secret_key="password", - secure=False -) - -# %% -source_file = "./tests/atomic.json" -bucket_name = "oqd-cloud-bucket" -destination_file = "my-test-file.txt" - -client.fput_object( - bucket_name, destination_file, source_file, -) -# %% From b3a9fc862a41c7a696213850289708f6ca716401 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Sat, 1 Mar 2025 15:41:51 -0500 Subject: [PATCH 08/15] Add s3 storage functions --- src/oqd_cloud/server/jobqueue.py | 7 +++- src/oqd_cloud/server/storage.py | 62 +++++++++++++++++++------------- 2 files changed, 43 insertions(+), 26 deletions(-) diff --git a/src/oqd_cloud/server/jobqueue.py b/src/oqd_cloud/server/jobqueue.py index a0a5398..ddcbcbb 100644 --- a/src/oqd_cloud/server/jobqueue.py +++ b/src/oqd_cloud/server/jobqueue.py @@ -23,6 +23,7 @@ ######################################################################################## from oqd_cloud.server.database import JobInDB, get_db +from oqd_cloud.server.storage import save_obj, get_temp_link ######################################################################################## REDIS_HOST = os.environ["REDIS_HOST"] @@ -38,7 +39,11 @@ async def _report_success(job, connection, result, *args, **kwargs): async with asynccontextmanager(get_db)() as db: - status_update = dict(status="finished", result=result.model_dump_json()) + + save_obj(job, result) + url = get_temp_link(job) + status_update = dict(status="finished", result=url) + # status_update = dict(status="finished", result=result.model_dump_json()) query = await db.execute(select(JobInDB).filter(JobInDB.job_id == job.id)) job_in_db = query.scalars().first() for k, v in status_update.items(): diff --git a/src/oqd_cloud/server/storage.py b/src/oqd_cloud/server/storage.py index 2143d97..15f9b23 100644 --- a/src/oqd_cloud/server/storage.py +++ b/src/oqd_cloud/server/storage.py @@ -15,36 +15,48 @@ from typing import Literal from minio import Minio import os +import io +from datetime import timedelta -from fastapi import APIRouter, HTTPException -from fastapi import status as http_status - -######################################################################################## -import oqd_analog_emulator #.qutip_backend import QutipBackend -import oqd_trical -from oqd_core.backend.task import Task -from rq.job import Callback -from rq.job import Job as RQJob -from sqlalchemy import select - -from oqd_cloud.server.database import JobInDB, db_dependency -from oqd_cloud.server.model import Job, Backends -from oqd_cloud.server.route.auth import user_dependency +from oqd_cloud.server.database import JobInDB, get_db ######################################################################################## minio_client = Minio( - "127.0.0.1:9000", - access_key="admin", - secret_key="password", + f"{os.getenv("MINIO_ENDPOINT")}:9000", + access_key=os.getenv("MINIO_ROOT_USER"), + secret_key=os.getenv("MINIO_ROOT_PASSWORD"), secure=False ) -# %% -source_file = "./tests/atomic.json" -bucket_name = "oqd-cloud-bucket" -destination_file = "my-test-file.txt" - -minio_client.fput_object( - bucket_name, destination_file, source_file, -) \ No newline at end of file +DEFAULT_MINIO_BUCKET = os.getenv("MINIO_DEFAULT_BUCKETS") +RESULT_FILENAME = "result.json" + +def save_obj(job: JobInDB, result): + # if the file is already saved, fput can be used + # minio_client.fput_object( + # BUCKET, destination_file, source_file, + # ) + + # here we dump to json, todo: future version should dump to HDF5 + json_bytes = result.model_dump_json().encode('utf-8') + buffer = io.BytesIO(json_bytes) + + minio_client.put_object( + DEFAULT_MINIO_BUCKET, + f"{job.id}/{RESULT_FILENAME}", + data=buffer, + length=len(json_bytes), + content_type='application/json' + ) + + return + + +def get_temp_link(job: JobInDB): + return minio_client.get_presigned_url( + "GET", + DEFAULT_MINIO_BUCKET, + f"{job.id}/{RESULT_FILENAME}", + expires=timedelta(hours=2), + ) From 1e1e1ab480bfa0169dfd84aef0edaaa19e598a26 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Sat, 1 Mar 2025 16:33:57 -0500 Subject: [PATCH 09/15] Test job result retrieval and storage --- src/oqd_cloud/client.py | 5 +++++ src/oqd_cloud/server/jobqueue.py | 1 - src/oqd_cloud/server/route/job.py | 3 ++- src/oqd_cloud/server/storage.py | 10 +++++++++- tests/test_client.py | 5 ++++- 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/oqd_cloud/client.py b/src/oqd_cloud/client.py index 6190055..4af5873 100644 --- a/src/oqd_cloud/client.py +++ b/src/oqd_cloud/client.py @@ -14,6 +14,7 @@ from typing import Literal, Optional, Sequence +import urllib.request import requests import json @@ -167,6 +168,10 @@ def retrieve_job(self, job_id): job = Job.model_validate(response.json()) if response.status_code == 200: + # download result file from temporary link + with urllib.request.urlopen(job.result) as f: + job.result = f.read().decode('utf-8') + self._jobs[job_id] = job return self.jobs[job_id] diff --git a/src/oqd_cloud/server/jobqueue.py b/src/oqd_cloud/server/jobqueue.py index ddcbcbb..401ead4 100644 --- a/src/oqd_cloud/server/jobqueue.py +++ b/src/oqd_cloud/server/jobqueue.py @@ -39,7 +39,6 @@ async def _report_success(job, connection, result, *args, **kwargs): async with asynccontextmanager(get_db)() as db: - save_obj(job, result) url = get_temp_link(job) status_update = dict(status="finished", result=url) diff --git a/src/oqd_cloud/server/route/job.py b/src/oqd_cloud/server/route/job.py index 583c147..11f0ef2 100644 --- a/src/oqd_cloud/server/route/job.py +++ b/src/oqd_cloud/server/route/job.py @@ -61,7 +61,8 @@ async def submit_job( user: user_dependency, db: db_dependency, ): - print(f"Queueing {task} on server {backend} backend. {len(queue)} jobs in queue.") + print(f"Queueing task on server {backend} backend. {len(queue)} jobs in queue.") + # print(f"Queueing {task} on server {backend} backend. {len(queue)} jobs in queue.") job = queue.enqueue( _backends[backend].run, diff --git a/src/oqd_cloud/server/storage.py b/src/oqd_cloud/server/storage.py index 15f9b23..7828f54 100644 --- a/src/oqd_cloud/server/storage.py +++ b/src/oqd_cloud/server/storage.py @@ -23,7 +23,7 @@ ######################################################################################## minio_client = Minio( - f"{os.getenv("MINIO_ENDPOINT")}:9000", + f"localhost:9000", access_key=os.getenv("MINIO_ROOT_USER"), secret_key=os.getenv("MINIO_ROOT_PASSWORD"), secure=False @@ -32,6 +32,14 @@ DEFAULT_MINIO_BUCKET = os.getenv("MINIO_DEFAULT_BUCKETS") RESULT_FILENAME = "result.json" +if not minio_client.bucket_exists(DEFAULT_MINIO_BUCKET): + minio_client.make_bucket(DEFAULT_MINIO_BUCKET) + print("Created bucket", DEFAULT_MINIO_BUCKET) +else: + print("Bucket", DEFAULT_MINIO_BUCKET, "already exists") + + + def save_obj(job: JobInDB, result): # if the file is already saved, fput can be used # minio_client.fput_object( diff --git a/tests/test_client.py b/tests/test_client.py index dc6e424..c4aae38 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -83,4 +83,7 @@ pprint(job) # %% -client.retrieve_job(job_id=job.job_id) +job = client.retrieve_job(job_id=job.job_id) +pprint(job) + +# %% From 5d1bee18e32d991db9f02e4747913d45d6976c50 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Sat, 1 Mar 2025 16:34:44 -0500 Subject: [PATCH 10/15] Ruff format and check --- src/oqd_cloud/client.py | 14 ++++---------- src/oqd_cloud/provider.py | 8 +++----- src/oqd_cloud/server/jobqueue.py | 4 ++-- src/oqd_cloud/server/main.py | 2 +- src/oqd_cloud/server/model.py | 4 ++-- src/oqd_cloud/server/route/job.py | 8 ++++---- src/oqd_cloud/server/storage.py | 24 +++++++++++------------- tests/test_client.py | 9 ++++----- 8 files changed, 31 insertions(+), 42 deletions(-) diff --git a/src/oqd_cloud/client.py b/src/oqd_cloud/client.py index 4af5873..7ea3a85 100644 --- a/src/oqd_cloud/client.py +++ b/src/oqd_cloud/client.py @@ -13,11 +13,10 @@ # limitations under the License. -from typing import Literal, Optional, Sequence +from typing import Optional, Sequence import urllib.request import requests -import json from oqd_core.backend.task import Task from pydantic import BaseModel, ConfigDict @@ -136,12 +135,7 @@ def connect(self, provider: Provider, username: str, password: str): # self.connect(self, self.provider) # pass - def submit_job( - self, - task: Task, - backend: str, - tags: str - ): + def submit_job(self, task: Task, backend: str, tags: str): """Submit a Task as an AnalogCircuit, DigitalCircuit, or AtomicCircuit to a backend.""" response = requests.post( self.provider.job_submission_url(backend=backend), @@ -170,8 +164,8 @@ def retrieve_job(self, job_id): if response.status_code == 200: # download result file from temporary link with urllib.request.urlopen(job.result) as f: - job.result = f.read().decode('utf-8') - + job.result = f.read().decode("utf-8") + self._jobs[job_id] = job return self.jobs[job_id] diff --git a/src/oqd_cloud/provider.py b/src/oqd_cloud/provider.py index 7415b2a..cd0e44b 100644 --- a/src/oqd_cloud/provider.py +++ b/src/oqd_cloud/provider.py @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -import requests +import requests from oqd_cloud.server.model import Backends @@ -28,9 +28,7 @@ def __init__(self, host: str = "http://localhost", port: int = 8000): # get available backends self.backends = Backends(available=[]) - response = requests.get( - self.url + "/available_backends" - ) + response = requests.get(self.url + "/available_backends") backends = Backends.model_validate(response.json()) if response.status_code == 200: self.backends = backends @@ -38,7 +36,7 @@ def __init__(self, host: str = "http://localhost", port: int = 8000): @property def available_backends(self): return self.backends.available - + @property def registration_url(self): return self.url + "/auth/register" diff --git a/src/oqd_cloud/server/jobqueue.py b/src/oqd_cloud/server/jobqueue.py index 401ead4..fd71c6b 100644 --- a/src/oqd_cloud/server/jobqueue.py +++ b/src/oqd_cloud/server/jobqueue.py @@ -41,8 +41,8 @@ async def _report_success(job, connection, result, *args, **kwargs): async with asynccontextmanager(get_db)() as db: save_obj(job, result) url = get_temp_link(job) - status_update = dict(status="finished", result=url) - # status_update = dict(status="finished", result=result.model_dump_json()) + status_update = dict(status="finished", result=url) + # status_update = dict(status="finished", result=result.model_dump_json()) query = await db.execute(select(JobInDB).filter(JobInDB.job_id == job.id)) job_in_db = query.scalars().first() for k, v in status_update.items(): diff --git a/src/oqd_cloud/server/main.py b/src/oqd_cloud/server/main.py index 41b47f7..379c69c 100644 --- a/src/oqd_cloud/server/main.py +++ b/src/oqd_cloud/server/main.py @@ -15,4 +15,4 @@ if __name__ == "__main__": import uvicorn - uvicorn.run("app:app", host="0.0.0.0", port=8007, log_level='debug') + uvicorn.run("app:app", host="0.0.0.0", port=8007, log_level="debug") diff --git a/src/oqd_cloud/server/model.py b/src/oqd_cloud/server/model.py index e545ddc..e82bc2a 100644 --- a/src/oqd_cloud/server/model.py +++ b/src/oqd_cloud/server/model.py @@ -45,7 +45,7 @@ class Job(BaseModel): result: Optional[str] = None user_id: str tags: Optional[str] = None - + class Backends(BaseModel): - available: Sequence[str] \ No newline at end of file + available: Sequence[str] diff --git a/src/oqd_cloud/server/route/job.py b/src/oqd_cloud/server/route/job.py index 11f0ef2..dad3e25 100644 --- a/src/oqd_cloud/server/route/job.py +++ b/src/oqd_cloud/server/route/job.py @@ -12,13 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Literal, Sequence, Optional, Annotated +from typing import Literal, Annotated from fastapi import APIRouter, HTTPException, Body from fastapi import status as http_status ######################################################################################## -import oqd_analog_emulator #.qutip_backend import QutipBackend +import oqd_analog_emulator # .qutip_backend import QutipBackend import oqd_trical from oqd_core.backend.task import Task from rq.job import Callback @@ -51,8 +51,8 @@ @job_router.get("/available_backends") async def available_backends(): return backends - - + + @job_router.post("/submit/{backend}", tags=["Job"]) async def submit_job( backend: Literal[tuple(backends.available)], diff --git a/src/oqd_cloud/server/storage.py b/src/oqd_cloud/server/storage.py index 7828f54..0770e94 100644 --- a/src/oqd_cloud/server/storage.py +++ b/src/oqd_cloud/server/storage.py @@ -12,21 +12,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -from typing import Literal from minio import Minio import os import io from datetime import timedelta -from oqd_cloud.server.database import JobInDB, get_db +from oqd_cloud.server.database import JobInDB ######################################################################################## minio_client = Minio( - f"localhost:9000", + "localhost:9000", access_key=os.getenv("MINIO_ROOT_USER"), secret_key=os.getenv("MINIO_ROOT_PASSWORD"), - secure=False + secure=False, ) DEFAULT_MINIO_BUCKET = os.getenv("MINIO_DEFAULT_BUCKETS") @@ -39,23 +38,22 @@ print("Bucket", DEFAULT_MINIO_BUCKET, "already exists") - def save_obj(job: JobInDB, result): # if the file is already saved, fput can be used # minio_client.fput_object( # BUCKET, destination_file, source_file, # ) - - # here we dump to json, todo: future version should dump to HDF5 - json_bytes = result.model_dump_json().encode('utf-8') + + # here we dump to json, todo: future version should dump to HDF5 + json_bytes = result.model_dump_json().encode("utf-8") buffer = io.BytesIO(json_bytes) minio_client.put_object( - DEFAULT_MINIO_BUCKET, - f"{job.id}/{RESULT_FILENAME}", - data=buffer, - length=len(json_bytes), - content_type='application/json' + DEFAULT_MINIO_BUCKET, + f"{job.id}/{RESULT_FILENAME}", + data=buffer, + length=len(json_bytes), + content_type="application/json", ) return diff --git a/tests/test_client.py b/tests/test_client.py index c4aae38..c4acd72 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -23,11 +23,10 @@ from oqd_core.interface.analog.operation import AnalogCircuit, AnalogGate from oqd_core.interface.analog.operator import PauliX, PauliZ -from oqd_core.interface.atomic.circuit import AtomicCircuit from oqd_cloud.client import Client from oqd_cloud.provider import Provider -from rich.pretty import pprint +from rich.pretty import pprint X = PauliX() Z = PauliZ() @@ -67,19 +66,19 @@ task.model_dump_json() -#%% +# %% client = Client() provider = Provider(port=8007) client.connect(provider=provider, username="ben", password="pwd") client.status_report -#%% +# %% backends = provider.available_backends print(backends) # %% print(client.jobs) -job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip", tags='a') +job = client.submit_job(task=task, backend="oqd-analog-emulator-qutip", tags="a") pprint(job) # %% From 3451f5d0cdcde21ecde8225339d96609a7af2577 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Fri, 16 May 2025 13:15:19 -0400 Subject: [PATCH 11/15] Test hdf format --- .gitignore | 2 + tests/test_h5.py | 50 ++++++++++++++++++++++++ tests/test_storage.py | 90 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) create mode 100644 tests/test_h5.py create mode 100644 tests/test_storage.py diff --git a/.gitignore b/.gitignore index 874aba0..81d28c8 100644 --- a/.gitignore +++ b/.gitignore @@ -167,3 +167,5 @@ cython_debug/ uv.lock docker/.env copy + +*.DS_Store \ No newline at end of file diff --git a/tests/test_h5.py b/tests/test_h5.py new file mode 100644 index 0000000..ed25e86 --- /dev/null +++ b/tests/test_h5.py @@ -0,0 +1,50 @@ +# %% +from h5pydantic import H5Dataset, H5Group, H5Int64 + + +class Baseline(H5Group): + temperature: float + humidity: float + + +class Metadata(H5Group): + start: Baseline + end: Baseline + + +class Acquisition(H5Dataset, shape=(3, 5), dtype=H5Int64): + beamstop: H5Int64 + + +class Experiment(H5Group): + metadata: Metadata + data: list[Acquisition] = [] + + +# %% +# from model import Experiment, Acquisition, Baseline, Metadata + +import numpy as np +from pathlib import Path +from rich.pretty import pprint + +experiment = Experiment( + data=[Acquisition(beamstop=11), Acquisition(beamstop=12)], + metadata=Metadata( + start=Baseline(temperature=25.0, humidity=0.4), + end=Baseline(temperature=26.0, humidity=0.4), + ), +) + +with experiment.dump(Path("experiment.hdf")): + experiment.data[0][()] = np.random.randint(255, size=(3, 5)) + experiment.data[1][()] = np.random.randint(255, size=(3, 5)) + +pprint(experiment) + +# %% +experiment + + + +# %% diff --git a/tests/test_storage.py b/tests/test_storage.py new file mode 100644 index 0000000..4b0fed6 --- /dev/null +++ b/tests/test_storage.py @@ -0,0 +1,90 @@ +# %% +# with open("./tests/atomic.json", "r") as f: +# circuit = AtomicCircuit.model_validate_json(f.read()) + +# print(circuit) + +# %% +from minio import Minio +import os + +os.getenv("127.0.0.1:9000") + +user_id = '1234' +job_id = '4321' + +client = Minio( + "127.0.0.1:9000", + access_key="admin", + secret_key="password", + secure=False +) + +# %% +source_file = "./tests/atomic.json" +bucket_name = f"{user_id}" +destination_file = f"{job_id}/artifact1.txt" + +#%% +import io +from oqd_core.interface.atomic import AtomicCircuit + +circuit = AtomicCircuit.parse_file(source_file) +#%% + + + +json_bytes = circuit.model_dump_json().encode('utf-8') +buffer = io.BytesIO(json_bytes) + +client.put_object( + "oqd-cloud-bucket", + "result.txt", + data=buffer, + length=len(json_bytes), + content_type='application/json' +) + +#%% +# Make the bucket if it doesn't exist. +found = client.bucket_exists(bucket_name) +if not found: + client.make_bucket(bucket_name) + print("Created bucket", bucket_name) +else: + print("Bucket", bucket_name, "already exists") + + +client.fput_object( + bucket_name, destination_file, source_file, +) +print( + source_file, "successfully uploaded as object", + destination_file, "to bucket", bucket_name, +) + +#%% +# Server should: +# 1. Run the job, submitting to the requested backend +# 2. The backend returns the result as a HDF5/Pydantic model, which is dumped to as a Minio artifact [jobid.hdf5] +# 3. When client requests results, the server checks if successful, generates a temporary link, and returns the url +# 4. The Client class will automatically + +# %% [SERVER] creates a minio link for the file, with a expiry time +from datetime import timedelta + +url = client.get_presigned_url( + "GET", + bucket_name, + destination_file, + expires=timedelta(hours=2), +) + +#%% [CLIENT] saves to provided filename +import urllib.request +file = urllib.request.urlretrieve(url, "result.txt") + +#%% [CLIENT] loads directly to memory +with urllib.request.urlopen(url) as f: + html = f.read()#.decode('utf-8') +# %% From c82262925a422ec8b0b199cc5393ec2e436e1723 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Fri, 16 May 2025 14:10:37 -0400 Subject: [PATCH 12/15] [docs] Add updated brand CSS for docs --- docs/stylesheets/brand.css | 115 +++++++++++++++++++++++++++++++++++++ mkdocs.yaml | 10 ++-- 2 files changed, 120 insertions(+), 5 deletions(-) create mode 100644 docs/stylesheets/brand.css diff --git a/docs/stylesheets/brand.css b/docs/stylesheets/brand.css new file mode 100644 index 0000000..a5d7985 --- /dev/null +++ b/docs/stylesheets/brand.css @@ -0,0 +1,115 @@ +/* Load custom fonts from Google Fonts */ +@import url('https://fonts.googleapis.com/css2?family=Raleway:wght@600;700&family=Source+Serif+Pro&display=swap'); + +/* Base typography */ +body, .md-typeset { + font-family: 'Source Serif Pro', serif; +} + +/* Headings */ +h1, h2, h3, h4, h5, h6, +.md-typeset h1, .md-typeset h2, .md-typeset h3, +.md-typeset h4, .md-typeset h5, .md-typeset h6 { + font-family: 'Raleway', sans-serif; + font-weight: 700; /* Bold for headings */ +} + +/* Subheadings */ +.md-typeset h2, .md-typeset h3 { + font-weight: 600; /* SemiBold for subheadings */ +} + +/* Light mode overrides */ +[data-md-color-scheme="default"] { + --md-default-bg-color: #FFFFFF; + --md-primary-fg-color: #23627D; /* blue accent */ + --md-accent-fg-color: #23627D; +} + +/* Dark mode overrides */ +[data-md-color-scheme="slate"] { + --md-default-bg-color: #141414; + --md-primary-fg-color: #23627D; + --md-accent-fg-color: #23627D; +} + + + +/* Apply Raleway to all navigation and sidebar elements */ +.md-nav, +.md-nav__title, +.md-nav__link, +.md-header, +.md-tabs, +.md-sidebar, +.md-sidebar__inner, +.md-nav__item, +.md-footer, +.md-footer__inner { + font-family: 'Raleway', sans-serif; + font-weight: 600; /* SemiBold for ToC/nav for clarity */ +} + + + + +/* Page heading accent color for light mode */ +[data-md-color-scheme="default"] .md-typeset h1, +[data-md-color-scheme="default"] .md-typeset h2, +[data-md-color-scheme="default"] .md-typeset h3, +[data-md-color-scheme="default"] .md-typeset h4, +[data-md-color-scheme="default"] .md-typeset h5, +[data-md-color-scheme="default"] .md-typeset h6 { + color: #7B2328; /* Warm yellow/orange for light mode */ +} + +/* Page heading accent color for dark mode */ +[data-md-color-scheme="slate"] .md-typeset h1, +[data-md-color-scheme="slate"] .md-typeset h2, +[data-md-color-scheme="slate"] .md-typeset h3, +[data-md-color-scheme="slate"] .md-typeset h4, +[data-md-color-scheme="slate"] .md-typeset h5, +[data-md-color-scheme="slate"] .md-typeset h6 { + color: #F19D19; /* Deep red for dark mode */ +} + + + + + +/* Light mode nav/ToC font color */ +[data-md-color-scheme="default"] .md-nav, +[data-md-color-scheme="default"] .md-nav__link, +[data-md-color-scheme="default"] .md-header, +[data-md-color-scheme="default"] .md-tabs { + /*color: #222; /* Dark gray or your preferred shade */ + color: #141414; +} + +/* Dark mode nav/ToC font color */ +[data-md-color-scheme="slate"] .md-nav, +[data-md-color-scheme="slate"] .md-nav__link, +[data-md-color-scheme="slate"] .md-header, +[data-md-color-scheme="slate"] .md-tabs { + color: #f0f0f0; /* Light gray or white */ +} + + + +/* Top navigation bar text and icons should be light-colored */ +.md-header, +.md-header .md-header__title, +.md-header .md-header__button, +.md-header .md-tabs, +.md-header .md-tabs__link, +.md-header .md-header__topic, +.md-header .md-header__option { + color: #f0f0f0 !important; /* Light gray or white text */ + fill: #f0f0f0 !important; /* Icons (SVG) */ +} + +/* Hover state for links in header */ +.md-header .md-tabs__link:hover { + color: #ffffff !important; + text-decoration: underline; +} \ No newline at end of file diff --git a/mkdocs.yaml b/mkdocs.yaml index 9ba3209..10e714c 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -27,22 +27,21 @@ nav: theme: name: material - logo: img/oqd-logo.png favicon: img/oqd-logo.png palette: - media: "(prefers-color-scheme: light)" scheme: default - primary: teal - accent: pink + primary: custom + accent: custom toggle: icon: material/weather-sunny name: Switch to dark mode - media: "(prefers-color-scheme: dark)" scheme: slate - primary: teal - accent: pink + primary: custom + accent: custom toggle: icon: material/weather-night name: Switch to light mode @@ -126,3 +125,4 @@ extra_javascript: extra_css: - stylesheets/headers.css - stylesheets/admonitions.css + - stylesheets/brand.css From 9b545ad23c28586f3a95f5ef9c565938a4df29df Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Fri, 16 May 2025 15:02:40 -0400 Subject: [PATCH 13/15] [docs] New branding --- docs/img/oqd-icon.png | Bin 0 -> 91320 bytes docs/img/oqd-logo-black.png | Bin 0 -> 67518 bytes docs/img/oqd-logo-text.png | Bin 14701 -> 0 bytes docs/img/oqd-logo-white.png | Bin 0 -> 63349 bytes docs/img/oqd-logo.png | Bin 7826 -> 0 bytes docs/index.md | 19 +++++++++++++++---- docs/stylesheets/brand.css | 3 ++- 7 files changed, 17 insertions(+), 5 deletions(-) create mode 100755 docs/img/oqd-icon.png create mode 100755 docs/img/oqd-logo-black.png delete mode 100644 docs/img/oqd-logo-text.png create mode 100755 docs/img/oqd-logo-white.png delete mode 100644 docs/img/oqd-logo.png diff --git a/docs/img/oqd-icon.png b/docs/img/oqd-icon.png new file mode 100755 index 0000000000000000000000000000000000000000..5571ea8766e923a6932859a6d7790614f29dbc3f GIT binary patch literal 91320 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[q>`56>2ZiU`pybA7gm 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�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%0Ar5zh&rgE-r~{0-2=P5|z6JjUchANFz8fHPjeen{ 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⋙e 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 NXk=OC+8=@%t;E~6twee}!Tj=rq>3d?G?v;3a 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 z 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 literal 0 HcmV?d00001 diff --git a/docs/img/oqd-logo-text.png b/docs/img/oqd-logo-text.png deleted file mode 100644 index 8ae1e94fcfd1f1483523482f1ebaa2e2ab8671ee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14701 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 diff --git a/docs/img/oqd-logo-white.png b/docs/img/oqd-logo-white.png new file mode 100755 index 0000000000000000000000000000000000000000..c9ae0621474c9999ccb88116263ff9c097f797fa GIT binary patch literal 63349 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 W&Muc}M#z3p9p~xl=d#Wzp$PymI9DbB literal 0 HcmV?d00001 diff --git a/docs/img/oqd-logo.png b/docs/img/oqd-logo.png deleted file mode 100644 index e3aaf16f57ca44ea012b07723d99fcd9f693ddce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7826 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 BfrbD8 diff --git a/docs/index.md b/docs/index.md index f6f5888..6e6eb5a 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,13 +1,24 @@ -# ![Open Quantum Design](./img/oqd-logo-text.png) +# + +

+ Logo + Logo +

- Open Quantum Design: Cloud + Open Quantum Design: Cloud

-![Python](https://img.shields.io/badge/Python-3.10_|_3.11_|_3.12-blue) -[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/ambv/black) +[![PyPI Version](https://img.shields.io/pypi/v/oqd-cloud)](https://pypi.org/project/oqd-cloud) +[![CI](https://github.com/OpenQuantumDesign/oqd-cloud/actions/workflows/pytest.yml/badge.svg)](https://github.com/OpenQuantumDesign/oqd-cloud/actions/workflows/pytest.yml) +![versions](https://img.shields.io/badge/python-3.10%20%7C%203.11%20%7C%203.12-blue) +[![License: Apache 2.0](https://img.shields.io/badge/license-Apache%202.0-brightgreen.svg)](https://opensource.org/licenses/Apache-2.0) +[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) + + + /// admonition | Note type: note diff --git a/docs/stylesheets/brand.css b/docs/stylesheets/brand.css index a5d7985..d2fdeeb 100644 --- a/docs/stylesheets/brand.css +++ b/docs/stylesheets/brand.css @@ -70,7 +70,8 @@ h1, h2, h3, h4, h5, h6, [data-md-color-scheme="slate"] .md-typeset h4, [data-md-color-scheme="slate"] .md-typeset h5, [data-md-color-scheme="slate"] .md-typeset h6 { - color: #F19D19; /* Deep red for dark mode */ + /* color: #F19D19; Deep red for dark mode */ + color: #E45B68; /* Deep red for dark mode */ } From 65ef9e1d990f819e6db5be5b7c53a648e7855ad1 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Fri, 16 May 2025 15:21:17 -0400 Subject: [PATCH 14/15] [docs] Fix paths --- docs/index.md | 4 ++-- mkdocs.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/index.md b/docs/index.md index 6e6eb5a..3d40517 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,8 +1,8 @@ #

- Logo - Logo + Logo + Logo

diff --git a/mkdocs.yaml b/mkdocs.yaml index 10e714c..d8b874a 100644 --- a/mkdocs.yaml +++ b/mkdocs.yaml @@ -27,8 +27,8 @@ nav: theme: name: material - logo: img/oqd-logo.png - favicon: img/oqd-logo.png + logo: img/oqd-icon.png + favicon: img/oqd-icon.png palette: - media: "(prefers-color-scheme: light)" From 55e04c454aeeaba1236e9aeebaeadf4b4c5d1d02 Mon Sep 17 00:00:00 2001 From: Benjamin MacLellan Date: Sun, 8 Jun 2025 10:27:06 -0400 Subject: [PATCH 15/15] [docs] Update stack visual and doc index --- README.md | 60 ++++++++++++++++++++++++-------------------- docs/index.md | 69 ++++++++++++++++++++++++--------------------------- 2 files changed, 65 insertions(+), 64 deletions(-) diff --git a/README.md b/README.md index 29ceeef..4b422e1 100644 --- a/README.md +++ b/README.md @@ -41,93 +41,99 @@ pip install .[docs] mkdocs serve ``` - +### Where in the stack ```mermaid block-beta columns 3 - + block:Interface columns 1 InterfaceTitle("Interfaces") - InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] + InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] space - InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] + InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] space InterfaceAtomic["Atomic Interface\nLight-matter interactions between lasers and ions"] space end - + block:IR columns 1 IRTitle("IRs") - IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] + IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] space IRAnalog["openQSIM"] space IRAtomic["openAPL"] space end - + block:Emulator columns 1 EmulatorsTitle("Classical Emulators") - - EmulatorDigital["Pennylane, Qiskit"] + + EmulatorDigital["Pennylane, Qiskit"] space EmulatorAnalog["QuTiP, QuantumOptics.jl"] space EmulatorAtomic["TrICal, QuantumIon.jl"] space end - + space block:RealTime columns 1 RealTimeTitle("Real-Time") space - RTSoftware["ARTIQ, DAX, OQDAX"] + RTSoftware["ARTIQ, DAX, OQDAX"] space RTGateware["Sinara Real-Time Control"] space RTHardware["Lasers, Modulators, Photodetection, Ion Trap"] space - RTApparatus["Trapped-Ion QPU (171Yt+, 133Ba+)"] + RTApparatus["Trapped-Ion QPU (171Yb+, 133Ba+)"] space end space - + InterfaceDigital --> IRDigital InterfaceAnalog --> IRAnalog InterfaceAtomic --> IRAtomic - + IRDigital --> IRAnalog IRAnalog --> IRAtomic - + IRDigital --> EmulatorDigital IRAnalog --> EmulatorAnalog IRAtomic --> EmulatorAtomic - + IRAtomic --> RealTimeTitle - + RTSoftware --> RTGateware RTGateware --> RTHardware RTHardware --> RTApparatus - - classDef title fill:#d6d4d4,stroke:#333,color:#333; - classDef digital fill:#E7E08B,stroke:#333,color:#333; - classDef analog fill:#E4E9B2,stroke:#333,color:#333; - classDef atomic fill:#D2E4C4,stroke:#333,color:#333; - classDef realtime fill:#B5CBB7,stroke:#333,color:#333; - - classDef highlight fill:#f2bbbb,stroke:#333,color:#333,stroke-dasharray: 5 5; - + + classDef title fill:#23627D,stroke:#141414,color:#FFFFFF; + classDef digital fill:#c3e1ee,stroke:#141414,color:#141414; + classDef analog fill:#afd7e9,stroke:#141414,color:#141414; + classDef atomic fill:#9ccee3,stroke:#141414,color:#141414; + classDef realtime fill:#88c4dd,stroke:#141414,color:#141414; + + classDef highlight fill:#F19D19,stroke:#141414,color:#141414,stroke-dasharray: 5 5; + classDef normal fill:#fcebcf,stroke:#141414,color:#141414; + class InterfaceTitle,IRTitle,EmulatorsTitle,RealTimeTitle title class InterfaceDigital,IRDigital,EmulatorDigital digital class InterfaceAnalog,IRAnalog,EmulatorAnalog analog class InterfaceAtomic,IRAtomic,EmulatorAtomic atomic class RTSoftware,RTGateware,RTHardware,RTApparatus realtime + + class Emulator highlight + + class Interface normal + class RealTime normal + class IR normal - class Emulator highlight ``` The tools in this repository allow for self-hosting a server to run quantum programs on classical emulators, highlighted in the stack diagram in red. diff --git a/docs/index.md b/docs/index.md index 3d40517..71eac93 100644 --- a/docs/index.md +++ b/docs/index.md @@ -18,107 +18,102 @@ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff) - - -/// admonition | Note - type: note -Welcome to the Open Quantum Design. -This documentation is still under development, we welcome contributions! © Open Quantum Design -/// - - ## What's Here This repository contains the software needed to submit jobs to a remote, cloud server for classical simulations of quantum programs. In addition, it provides a Docker script to self-host a simulation server of the OQD emulator backends. - - ```mermaid block-beta columns 3 - + block:Interface columns 1 InterfaceTitle("Interfaces") - InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] + InterfaceDigital["Digital Interface\nQuantum circuits with discrete gates"] space - InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] + InterfaceAnalog["Analog Interface\n Continuous-time evolution with Hamiltonians"] space InterfaceAtomic["Atomic Interface\nLight-matter interactions between lasers and ions"] space end - + block:IR columns 1 IRTitle("IRs") - IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] + IRDigital["Quantum circuit IR\nopenQASM, LLVM+QIR"] space IRAnalog["openQSIM"] space IRAtomic["openAPL"] space end - + block:Emulator columns 1 EmulatorsTitle("Classical Emulators") - - EmulatorDigital["Pennylane, Qiskit"] + + EmulatorDigital["Pennylane, Qiskit"] space EmulatorAnalog["QuTiP, QuantumOptics.jl"] space EmulatorAtomic["TrICal, QuantumIon.jl"] space end - + space block:RealTime columns 1 RealTimeTitle("Real-Time") space - RTSoftware["ARTIQ, DAX, OQDAX"] + RTSoftware["ARTIQ, DAX, OQDAX"] space RTGateware["Sinara Real-Time Control"] space RTHardware["Lasers, Modulators, Photodetection, Ion Trap"] space - RTApparatus["Trapped-Ion QPU (171Yt+, 133Ba+)"] + RTApparatus["Trapped-Ion QPU (171Yb+, 133Ba+)"] space end space - + InterfaceDigital --> IRDigital InterfaceAnalog --> IRAnalog InterfaceAtomic --> IRAtomic - + IRDigital --> IRAnalog IRAnalog --> IRAtomic - + IRDigital --> EmulatorDigital IRAnalog --> EmulatorAnalog IRAtomic --> EmulatorAtomic - + IRAtomic --> RealTimeTitle - + RTSoftware --> RTGateware RTGateware --> RTHardware RTHardware --> RTApparatus - - classDef title fill:#d6d4d4,stroke:#333,color:#333; - classDef digital fill:#E7E08B,stroke:#333,color:#333; - classDef analog fill:#E4E9B2,stroke:#333,color:#333; - classDef atomic fill:#D2E4C4,stroke:#333,color:#333; - classDef realtime fill:#B5CBB7,stroke:#333,color:#333; - - classDef highlight fill:#f2bbbb,stroke:#333,color:#333,stroke-dasharray: 5 5; - + + classDef title fill:#23627D,stroke:#141414,color:#FFFFFF; + classDef digital fill:#c3e1ee,stroke:#141414,color:#141414; + classDef analog fill:#afd7e9,stroke:#141414,color:#141414; + classDef atomic fill:#9ccee3,stroke:#141414,color:#141414; + classDef realtime fill:#88c4dd,stroke:#141414,color:#141414; + + classDef highlight fill:#F19D19,stroke:#141414,color:#141414,stroke-dasharray: 5 5; + classDef normal fill:#fcebcf,stroke:#141414,color:#141414; + class InterfaceTitle,IRTitle,EmulatorsTitle,RealTimeTitle title class InterfaceDigital,IRDigital,EmulatorDigital digital class InterfaceAnalog,IRAnalog,EmulatorAnalog analog class InterfaceAtomic,IRAtomic,EmulatorAtomic atomic class RTSoftware,RTGateware,RTHardware,RTApparatus realtime + + class Emulator highlight + + class Interface normal + class RealTime normal + class IR normal - class Emulator highlight ``` The tools in this repository allow for self-hosting a server to run quantum programs on classical emulators, highlighted in the stack diagram in red.