{ "cells": [ { "cell_type": "markdown", "id": "0", "metadata": {}, "source": [ "# TargetData Demo\n", "\n", "This notebook demonstrates how to use and configure `TargetData` in QAT, including:\n", "- default construction\n", "- nested qubit/resonator overrides\n", "- validation behaviour\n", "- random generation (seeded and unseeded)\n", "- serialisation and YAML loading\n", "- migration from deprecated helpers" ] }, { "cell_type": "code", "execution_count": null, "id": "1", "metadata": {}, "outputs": [], "source": [ "import tempfile\n", "import warnings\n", "from pathlib import Path\n", "\n", "from pydantic import ValidationError\n", "\n", "from qat.core.config.descriptions import CompilePipelineDescription\n", "from qat.model.target_data import (\n", " CustomTargetData,\n", " DefaultTargetData,\n", " QubitDescription,\n", " ResonatorDescription,\n", " TargetData,\n", ")\n", "\n", "warnings.simplefilter(\"always\", DeprecationWarning)" ] }, { "cell_type": "markdown", "id": "2", "metadata": {}, "source": [ "## 1) Start With Defaults\n", "\n", "`TargetData()` now directly creates a complete default instance and is the preferred entry point for new code." ] }, { "cell_type": "code", "execution_count": null, "id": "3", "metadata": {}, "outputs": [], "source": [ "target_data = TargetData()\n", "\n", "print(\"max_shots:\", target_data.max_shots)\n", "print(\"default_shots:\", target_data.default_shots)\n", "print(\"clock_cycle:\", target_data.clock_cycle)\n", "print(\"qubit passive_reset_time:\", target_data.QUBIT_DATA.passive_reset_time)\n", "print(\"qubit sample_time:\", target_data.QUBIT_DATA.sample_time)\n", "print(\"resonator sample_time:\", target_data.RESONATOR_DATA.sample_time)\n", "\n", "print(\"\\nTop-level model keys:\")\n", "print(sorted(target_data.model_dump().keys()))" ] }, { "cell_type": "markdown", "id": "4", "metadata": {}, "source": [ "## 2) Customise TargetData\n", "\n", "You can override top-level and nested values directly when constructing `TargetData`." ] }, { "cell_type": "code", "execution_count": null, "id": "5", "metadata": {}, "outputs": [], "source": [ "custom_target_data = TargetData(\n", " max_shots=20_000,\n", " default_shots=2_048,\n", " QUBIT_DATA=QubitDescription(\n", " passive_reset_time=5e-4,\n", " instruction_memory_size=60_000,\n", " ),\n", " RESONATOR_DATA=ResonatorDescription(\n", " instruction_memory_size=70_000,\n", " ),\n", ")\n", "\n", "print(\"custom default_shots:\", custom_target_data.default_shots)\n", "print(\"custom passive_reset_time:\", custom_target_data.QUBIT_DATA.passive_reset_time)\n", "print(\n", " \"custom qubit instruction_memory_size:\",\n", " custom_target_data.QUBIT_DATA.instruction_memory_size,\n", ")\n", "print(\n", " \"custom resonator instruction_memory_size:\",\n", " custom_target_data.RESONATOR_DATA.instruction_memory_size,\n", ")" ] }, { "cell_type": "markdown", "id": "6", "metadata": {}, "source": [ "## 3) Validation Behaviour\n", "\n", "`TargetData` enforces consistency and strict value constraints. The examples below show two common validation failures." ] }, { "cell_type": "code", "execution_count": null, "id": "7", "metadata": {}, "outputs": [], "source": [ "# Invalid 1: pulse_duration_min > pulse_duration_max\n", "try:\n", " _ = QubitDescription(pulse_duration_min=2e-6, pulse_duration_max=1e-6)\n", "except ValidationError as exc:\n", " print(\"Invalid duration config caught:\")\n", " print(exc)\n", "\n", "# Invalid 2: incompatible clock cycles between qubit and resonator\n", "try:\n", " _ = TargetData(\n", " QUBIT_DATA=QubitDescription(sample_time=1e-9, samples_per_clock_cycle=2),\n", " RESONATOR_DATA=ResonatorDescription(sample_time=2e-9, samples_per_clock_cycle=2),\n", " )\n", "except ValidationError as exc:\n", " print(\"\\nClock-cycle mismatch caught:\")\n", " print(exc)" ] }, { "cell_type": "markdown", "id": "8", "metadata": {}, "source": [ "## 4) Random TargetData\n", "\n", "`TargetData.random()` supports both patterns:\n", "- without a seed: convenient random examples\n", "- with a seed: deterministic examples for testing and debugging" ] }, { "cell_type": "code", "execution_count": null, "id": "9", "metadata": {}, "outputs": [], "source": [ "# Without a seed: values may differ across calls\n", "random_td_unseeded_1 = TargetData.random()\n", "random_td_unseeded_2 = TargetData.random()\n", "\n", "print(\"Unseeded call 1 clock_cycle:\", random_td_unseeded_1.clock_cycle)\n", "print(\"Unseeded call 2 clock_cycle:\", random_td_unseeded_2.clock_cycle)\n", "print(\n", " \"Unseeded reproducible:\",\n", " random_td_unseeded_1.model_dump() == random_td_unseeded_2.model_dump(),\n", ")\n", "\n", "# With a seed: deterministic across calls\n", "random_td_seeded_1 = TargetData.random(seed=123)\n", "random_td_seeded_2 = TargetData.random(seed=123)\n", "\n", "print(\"\\nSeeded call 1 clock_cycle:\", random_td_seeded_1.clock_cycle)\n", "print(\"Seeded call 2 clock_cycle:\", random_td_seeded_2.clock_cycle)\n", "print(\n", " \"Seeded reproducible:\",\n", " random_td_seeded_1.model_dump() == random_td_seeded_2.model_dump(),\n", ")\n", "\n", "compile_desc = CompilePipelineDescription(name=\"demo\")\n", "print(\"\\nCompilePipelineDescription.target_data default:\")\n", "print(compile_desc.target_data)" ] }, { "cell_type": "markdown", "id": "10", "metadata": {}, "source": [ "## 5) Serialisation, YAML Loading, and Deprecation Migration\n", "\n", "This section shows how to serialise/deserialise `TargetData` and how legacy helpers map to the preferred constructor style." ] }, { "cell_type": "code", "execution_count": null, "id": "11", "metadata": {}, "outputs": [], "source": [ "# JSON serialisation\n", "payload_json = target_data.model_dump_json(indent=2)\n", "print(\"Serialised JSON (first 250 chars):\")\n", "print(payload_json[:250] + \"...\")\n", "\n", "# YAML loading from disk via TargetData.from_yaml(...)\n", "yaml_text = \"\"\"\n", "max_shots: 12000\n", "default_shots: 512\n", "QUBIT_DATA:\n", " sample_time: 1e-09\n", " samples_per_clock_cycle: 1\n", " instruction_memory_size: 50000\n", " waveform_memory_size: 1500\n", " pulse_duration_min: 6.4e-08\n", " pulse_duration_max: 0.001\n", " pulse_channel_lo_freq_min: 1000000\n", " pulse_channel_lo_freq_max: 10000000000\n", " pulse_channel_if_freq_min: 0\n", " pulse_channel_if_freq_max: 10000000000\n", " passive_reset_time: 0.001\n", "RESONATOR_DATA:\n", " sample_time: 1e-09\n", " samples_per_clock_cycle: 1\n", " instruction_memory_size: 50000\n", " waveform_memory_size: 1500\n", " pulse_duration_min: 6.4e-08\n", " pulse_duration_max: 0.001\n", " pulse_channel_lo_freq_min: 1000000\n", " pulse_channel_lo_freq_max: 10000000000\n", " pulse_channel_if_freq_min: 0\n", " pulse_channel_if_freq_max: 10000000000\n", "\"\"\".strip()\n", "\n", "with tempfile.TemporaryDirectory() as tmp_dir:\n", " yaml_path = Path(tmp_dir) / \"target_data.yaml\"\n", " yaml_path.write_text(yaml_text)\n", " loaded_td = TargetData.from_yaml(yaml_path)\n", "\n", "print(\"\\nLoaded from YAML default_shots:\", loaded_td.default_shots)\n", "\n", "# Deprecated helpers still work, but emit DeprecationWarning.\n", "with warnings.catch_warnings(record=True) as caught:\n", " warnings.simplefilter(\"always\", DeprecationWarning)\n", " _ = TargetData.default()\n", " _ = TargetData.create_with(passive_reset_time=2e-3)\n", " _ = DefaultTargetData()\n", " _ = CustomTargetData(passive_reset_time=3e-3)\n", "\n", "dep_msgs = [str(w.message) for w in caught if issubclass(w.category, DeprecationWarning)]\n", "print(\"\\nDeprecation warnings captured:\", len(dep_msgs))\n", "for msg in dep_msgs:\n", " print(\"-\", msg)" ] }, { "cell_type": "markdown", "id": "12", "metadata": {}, "source": [ "## Summary\n", "\n", "For new code, use `TargetData(...)` directly.\n", "\n", "Migration quick reference:\n", "- `TargetData.default()` -> `TargetData()`\n", "- `TargetData.create_with(...)` -> `TargetData(...)`\n", "- `DefaultTargetData()` -> `TargetData()`\n", "- `CustomTargetData(...)` -> `TargetData(...)`" ] } ], "metadata": { "jupytext": { "main_language": "python", "notebook_metadata_filter": "-kernelspec" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.19" } }, "nbformat": 4, "nbformat_minor": 5 }