Skip to content
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
1 change: 1 addition & 0 deletions .env.q8s
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export MLFLOW_TRACKING_URI="http://mlflow-service:5000"
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
.ipynb_checkpoints
.q8s_cache
.venv
.venv
kubeconfig.yaml
2 changes: 1 addition & 1 deletion Q8Sproject
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ docker:
username: qubernetes-dev
registry: ghcr.io

kubeconfig: config.vlad.yaml
kubeconfig: kubeconfig.yaml
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,39 @@ Initialize the Q8S project:
```bash
q8sctl init --images
```

### Getting the cluster configurations

Login into the Qubernetes [Console](https://console.em4qs.qubernetes.dev) select the Settings -> General option and download the kubeconfig file for your cluster. Save it as `kubeconfig.yaml` in the project root directory.

### Getting a PAT for GitHub Container Registry

To execute workloads that have images in GitHub Container Registry (GHCR), you need a Personal Access Token (PAT) with the `read:packages` scope. Follow [GitHub’s guide on creating a Personal Access Token (classic)](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/managing-your-personal-access-tokens#creating-a-personal-access-token-classic) to create one.

## Execute workloads from command line

To execute workloads in your Qubernetes cluster, use the following command:

```bash
q8sctl execute --registry_pat YOUR_GHCR_PAT --target cpu /src/workloads/sample_workload.py
```

## Execute workloads from Jupyter Lab notebooks

Install Jupyter Lab if you haven't already:

```bash
pip install jupyter
```

To execute workloads from notebooks, start Jupyter Lab with the following command:

```bash
q8sctl jupyter --registry_pat YOUR_GHCR_PAT --target cpu --install
```

Open the `notebook.ipynb` file in Jupyter Lab. Select the kernel `Q8s kernel`.

## Building Images with CI

The image build workflow is defined in `.github/workflows/build-images.yaml`. It is triggered when a new branch is created or when a commit with a modified `Q8Sproject` file is pushed.
142 changes: 142 additions & 0 deletions notebook.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 4,
"id": "d08f086a-a30a-4be7-8edd-6eb2e72940e5",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
" ┌───┐ ┌─┐ "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"q_0: ┤ H ├──■──┤M├───"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
" └───┘┌─┴─┐└╥┘┌─┐"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"q_1: ─────┤ X ├─╫─┤M├"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
" └───┘ ║ └╥┘"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"c: 2/═══════════╩══╩═"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
" 0 1 "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"{'00': 497, '11': 503}"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": []
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"import logging\n",
"\n",
"from qiskit import QuantumCircuit, transpile\n",
"from qiskit_aer import AerSimulator\n",
"\n",
"logger = logging.getLogger(__name__)\n",
"\n",
"\n",
"def demo_function(shotsAmount=1000, device=\"CPU\"):\n",
" simulator = AerSimulator(method=\"statevector\", device=device)\n",
"\n",
" circuit = QuantumCircuit(2, 2)\n",
" circuit.h(0)\n",
" circuit.cx(0, 1)\n",
" circuit.measure([0, 1], [0, 1])\n",
"\n",
" compiled_circuit = transpile(circuit, simulator)\n",
" job = simulator.run(compiled_circuit, shots=shotsAmount)\n",
" result = job.result()\n",
" counts = result.get_counts()\n",
" print(circuit)\n",
" return counts\n",
"\n",
"counts = demo_function()\n",
"print(counts)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c25eba4c-983b-4932-baf1-fa4f67d346e9",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Q8s kernel",
"language": "python",
"name": "q8s"
},
"language_info": {
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "Any text",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
14 changes: 14 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[build-system]
requires = ["setuptools>=61.0"]
build-backend = "setuptools.build_meta"

[project]
name = "workloads"
version = "0.1.0"
description = "A minimal Python package"
readme = "README.md"
requires-python = ">=3.10"

# Optional but recommended when using src layout
[tool.setuptools.packages.find]
where = ["src"]
2 changes: 1 addition & 1 deletion requirements-dev.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
q8s>=0.8.0
q8s>=0.9.0
28 changes: 28 additions & 0 deletions src/workloads/sample_workload.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import logging

from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator

logger = logging.getLogger(__name__)


def demo_function(shotsAmount=1000, device="GPU"):
simulator = AerSimulator(method="statevector", device=device)

circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])

compiled_circuit = transpile(circuit, simulator)
job = simulator.run(compiled_circuit, shots=shotsAmount)
result = job.result()
counts = result.get_counts()
logger.debug(circuit)
return counts


if __name__ == "__main__":
logging.basicConfig(level=logging.DEBUG)
output = demo_function()
print("Simulation result:", output)
49 changes: 49 additions & 0 deletions src/workloads/sample_workload_with_mlflow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import logging
import os
import mlflow

from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator

logger = logging.getLogger(__name__)


def demo_function(shotsAmount=1000, device="CPU"):
simulator = AerSimulator(method="statevector", device=device)

circuit = QuantumCircuit(2, 2)
circuit.h(0)
circuit.cx(0, 1)
circuit.measure([0, 1], [0, 1])

compiled_circuit = transpile(circuit, simulator)
job = simulator.run(compiled_circuit, shots=shotsAmount)
result = job.result()
counts = result.get_counts()
logger.debug(circuit)
return counts


if __name__ == "__main__":
mlflow.set_experiment("Sample Workload Experiment")

with mlflow.start_run():
# Set Git-related tags for traceability
mlflow.set_tag(
"mlflow.source.git.commit", os.getenv("MLFLOW_GIT_COMMIT", "unknown")
)
mlflow.set_tag(
"mlflow.source.git.branch", os.getenv("MLFLOW_GIT_BRANCH", "unknown")
)
mlflow.set_tag(
"mlflow.source.git.repoURL", os.getenv("MLFLOW_GIT_REPO_URL", "unknown")
)

# logging.basicConfig(level=logging.DEBUG)

shots = 1000
device = "GPU"
mlflow.log_param("shots", shots)
mlflow.log_param("device", device)
counts = demo_function(shotsAmount=shots, device=device)
mlflow.log_dict(counts, "simulation_counts.json")