From d27f889f4d91d3b1018be821884659ea9d5ffc7e Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Tue, 18 Aug 2026 16:19:28 +0200 Subject: [PATCH 1/7] change default compilation --- .../compilation/device_and_compilation.ipynb | 27 +---------- .../compilation/error_handling.ipynb | 47 ++----------------- docs/fundamentals/execution/execution.ipynb | 31 +----------- .../programming_with_qoolqit.ipynb | 17 +------ docs/tutorials/Critical_state_TFIM.ipynb | 41 +--------------- docs/tutorials/Solving_a_MWIS.ipynb | 34 +------------- docs/tutorials/solving_a_qubo.ipynb | 9 +--- qoolqit/execution/compilation_functions.py | 12 ++++- qoolqit/program.py | 13 ++--- .../test_backends_integration.py | 3 +- tests/test_program.py | 17 ++++--- 11 files changed, 46 insertions(+), 205 deletions(-) diff --git a/docs/fundamentals/compilation/device_and_compilation.ipynb b/docs/fundamentals/compilation/device_and_compilation.ipynb index 4eeb23e11..eb9336c19 100644 --- a/docs/fundamentals/compilation/device_and_compilation.ipynb +++ b/docs/fundamentals/compilation/device_and_compilation.ipynb @@ -143,26 +143,7 @@ "id": "10", "metadata": {}, "outputs": [], - "source": [ - "from qoolqit import AnalogDevice, Drive, PiecewiseLinearWaveform, QuantumProgram, Register\n", - "\n", - "# Defining the Drive\n", - "wf0 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [0.0, 0.5, 0.5, 0.0])\n", - "wf1 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [-1.0, -1.0, 1.0, 1.0])\n", - "drive = Drive(amplitude = wf0, detuning = wf1)\n", - "\n", - "# Defining the Register\n", - "coords = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]\n", - "register = Register.from_coordinates(coords)\n", - "\n", - "# Creating the Program\n", - "program = QuantumProgram(register, drive)\n", - "device = AnalogDevice()\n", - "\n", - "# Compilation to AnalogDevice\n", - "program.compile_to(device)\n", - "print(program)" - ] + "source": "from qoolqit import AnalogDevice, Drive, PiecewiseLinearWaveform, QuantumProgram, Register\n\n# Defining the Drive\nwf0 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [0.0, 0.5, 0.5, 0.0])\nwf1 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [-1.0, -1.0, 1.0, 1.0])\ndrive = Drive(amplitude = wf0, detuning = wf1)\n\n# Defining the Register\ncoords = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]\nregister = Register.from_coordinates(coords)\n\n# Creating the Program\nprogram = QuantumProgram(register, drive)\ndevice = AnalogDevice()\n\n# Compilation to AnalogDevice\nprogram.compile_to(device, profile=\"max_energy\")\nprint(program)" }, { "cell_type": "markdown", @@ -224,11 +205,7 @@ "id": "16", "metadata": {}, "outputs": [], - "source": [ - "# Compilation to AnalogDevice max duration\n", - "program.compile_to(device, device_max_duration_ratio=1.0)\n", - "program.draw(compiled = True)" - ] + "source": "# Compilation to AnalogDevice max duration\nprogram.compile_to(device, profile=\"max_energy\", device_max_duration_ratio=1.0)\nprogram.draw(compiled = True)" }, { "cell_type": "markdown", diff --git a/docs/fundamentals/compilation/error_handling.ipynb b/docs/fundamentals/compilation/error_handling.ipynb index 46cf5a3ef..5dcc5135d 100644 --- a/docs/fundamentals/compilation/error_handling.ipynb +++ b/docs/fundamentals/compilation/error_handling.ipynb @@ -64,17 +64,7 @@ "id": "4", "metadata": {}, "outputs": [], - "source": [ - "from qoolqit import AnalogDevice, QuantumProgram\n", - "\n", - "program = QuantumProgram(\n", - " register=register,\n", - " drive=drive\n", - ")\n", - "\n", - "device=AnalogDevice()\n", - "program.compile_to(device)" - ] + "source": "from qoolqit import AnalogDevice, QuantumProgram\n\nprogram = QuantumProgram(\n register=register,\n drive=drive\n)\n\ndevice=AnalogDevice()\nprogram.compile_to(device, profile=\"max_energy\")" }, { "cell_type": "markdown", @@ -144,18 +134,7 @@ "id": "10", "metadata": {}, "outputs": [], - "source": [ - "from qoolqit.exceptions import CompilationError\n", - "\n", - "L=4\n", - "amp=100\n", - "det=2\n", - "program=create_program(L,amp,det)\n", - "try:\n", - " compiled_sequence = program.compile_to(device)\n", - "except CompilationError as err:\n", - " print(err)" - ] + "source": "from qoolqit.exceptions import CompilationError\n\nL=4\namp=100\ndet=2\nprogram=create_program(L,amp,det)\ntry:\n compiled_sequence = program.compile_to(device, profile=\"max_energy\")\nexcept CompilationError as err:\n print(err)" }, { "cell_type": "markdown", @@ -180,16 +159,7 @@ "id": "13", "metadata": {}, "outputs": [], - "source": [ - "L=4\n", - "amp=1\n", - "det=20\n", - "program=create_program(L,amp,det)\n", - "try:\n", - " compiled_sequence = program.compile_to(device)\n", - "except CompilationError as err:\n", - " print(err)" - ] + "source": "L=4\namp=1\ndet=20\nprogram=create_program(L,amp,det)\ntry:\n compiled_sequence = program.compile_to(device, profile=\"max_energy\")\nexcept CompilationError as err:\n print(err)" }, { "cell_type": "markdown", @@ -214,16 +184,7 @@ "id": "16", "metadata": {}, "outputs": [], - "source": [ - "L=2\n", - "amp=10\n", - "det=1\n", - "program=create_program(L,amp,det)\n", - "try:\n", - " compiled_sequence = program.compile_to(device)\n", - "except CompilationError as err:\n", - " print(err)" - ] + "source": "L=2\namp=10\ndet=1\nprogram=create_program(L,amp,det)\ntry:\n compiled_sequence = program.compile_to(device, profile=\"max_energy\")\nexcept CompilationError as err:\n print(err)" }, { "cell_type": "markdown", diff --git a/docs/fundamentals/execution/execution.ipynb b/docs/fundamentals/execution/execution.ipynb index fa36083a0..448586196 100644 --- a/docs/fundamentals/execution/execution.ipynb +++ b/docs/fundamentals/execution/execution.ipynb @@ -36,29 +36,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from qoolqit import AnalogDevice, ConstantWaveform, Drive, QuantumProgram, RampWaveform, Register\n", - "\n", - "# Create the register\n", - "register = Register.from_coordinates([(0,1), (0,-1), (2,0)])\n", - "\n", - "# Defining the drive parameters\n", - "omega = 0.8\n", - "delta_i = -2.0 * omega\n", - "delta_f = -delta_i\n", - "T = 25.0\n", - "\n", - "# Defining the drive\n", - "wf_amp = ConstantWaveform(T, omega)\n", - "wf_det = RampWaveform(T, delta_i, delta_f)\n", - "drive = Drive(amplitude = wf_amp, detuning = wf_det)\n", - "\n", - "# Creating the program\n", - "program = QuantumProgram(register, drive)\n", - "\n", - "# Compiling the program to a device\n", - "program.compile_to(device=AnalogDevice())" - ] + "source": "from qoolqit import AnalogDevice, ConstantWaveform, Drive, QuantumProgram, RampWaveform, Register\n\n# Create the register\nregister = Register.from_coordinates([(0,1), (0,-1), (2,0)])\n\n# Defining the drive parameters\nomega = 0.8\ndelta_i = -2.0 * omega\ndelta_f = -delta_i\nT = 25.0\n\n# Defining the drive\nwf_amp = ConstantWaveform(T, omega)\nwf_det = RampWaveform(T, delta_i, delta_f)\ndrive = Drive(amplitude = wf_amp, detuning = wf_det)\n\n# Creating the program\nprogram = QuantumProgram(register, drive)\n\n# Compiling the program to a device\nprogram.compile_to(device=AnalogDevice(), profile=\"max_energy\")" }, { "cell_type": "markdown", @@ -423,12 +401,7 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": [ - "from qoolqit.devices import Device\n", - "\n", - "device = Device.from_connection(connection, \"FRESNEL\")\n", - "program.compile_to(device=device)" - ] + "source": "from qoolqit.devices import Device\n\ndevice = Device.from_connection(connection, \"FRESNEL\")\nprogram.compile_to(device=device, profile=\"max_energy\")" }, { "cell_type": "markdown", diff --git a/docs/get_started/programming_with_qoolqit.ipynb b/docs/get_started/programming_with_qoolqit.ipynb index 8055d7aec..90e4a0f13 100644 --- a/docs/get_started/programming_with_qoolqit.ipynb +++ b/docs/get_started/programming_with_qoolqit.ipynb @@ -203,12 +203,7 @@ "id": "14", "metadata": {}, "outputs": [], - "source": [ - "from qoolqit import AnalogDevice\n", - "\n", - "device = AnalogDevice()\n", - "program.compile_to(device)" - ] + "source": "from qoolqit import AnalogDevice\n\ndevice = AnalogDevice()\nprogram.compile_to(device, profile=\"max_energy\")" }, { "cell_type": "markdown", @@ -309,15 +304,7 @@ "id": "20", "metadata": {}, "outputs": [], - "source": [ - "# Build and compile programs\n", - "program_blockade = QuantumProgram(register, drive_blockade)\n", - "program_no_blockade = QuantumProgram(register, drive_no_blockade)\n", - "\n", - "device = AnalogDevice()\n", - "program_blockade.compile_to(device)\n", - "program_no_blockade.compile_to(device)" - ] + "source": "# Build and compile programs\nprogram_blockade = QuantumProgram(register, drive_blockade)\nprogram_no_blockade = QuantumProgram(register, drive_no_blockade)\n\ndevice = AnalogDevice()\nprogram_blockade.compile_to(device, profile=\"max_energy\")\nprogram_no_blockade.compile_to(device, profile=\"max_energy\")" }, { "cell_type": "code", diff --git a/docs/tutorials/Critical_state_TFIM.ipynb b/docs/tutorials/Critical_state_TFIM.ipynb index 9f5d37cf8..314727132 100644 --- a/docs/tutorials/Critical_state_TFIM.ipynb +++ b/docs/tutorials/Critical_state_TFIM.ipynb @@ -353,11 +353,7 @@ "id": "16", "metadata": {}, "outputs": [], - "source": [ - "demo = build_program(80.0)\n", - "demo.compile_to(device)\n", - "demo.draw(compiled=True)" - ] + "source": "demo = build_program(80.0)\ndemo.compile_to(device, profile=\"max_energy\")\ndemo.draw(compiled=True)" }, { "cell_type": "markdown", @@ -659,40 +655,7 @@ "id": "27", "metadata": {}, "outputs": [], - "source": [ - "# Configure observables: occupation, correlation matrix, and fidelity vs. the ED target.\n", - "config = EmulationConfig(\n", - " observables=(\n", - " Occupation(),\n", - " CorrelationMatrix(),\n", - " Fidelity(state=target_state),\n", - " ),\n", - " log_level=logging.WARN\n", - ")\n", - "\n", - "# Sweep the dimensionless total evolution time. Larger t~ => slower, more adiabatic sweep.\n", - "t_sweep = np.linspace(10.0, 120.0, 11)\n", - "fid_vs_t = np.zeros(len(t_sweep))\n", - "\n", - "for i, t in enumerate(t_sweep):\n", - " # Build the program at dimensionless duration t and compile it to the device.\n", - " prog = build_program(t)\n", - " prog.compile_to(device)\n", - "\n", - " # Run the adiabatic evolution\n", - " emulator = LocalEmulator(backend_type=SVBackend, emulation_config=config)\n", - " job = emulator.run(prog)\n", - " tagged = job.results().get_tagged_results()\n", - "\n", - " # Fidelity with the ED target, straight from the emu_sv Fidelity observable.\n", - " fid_vs_t[i] = float(np.asarray(tagged[\"fidelity\"][-1]).real)\n", - "\n", - "# Occupation and correlations from the final (largest-t~, most adiabatic) run.\n", - "occ_p = np.asarray(tagged[\"occupation\"][-1])\n", - "corr_p = np.asarray(tagged[\"correlation_matrix\"][-1])\n", - "conn_p = corr_p - np.outer(occ_p, occ_p)\n", - "fid = fid_vs_t[-1]" - ] + "source": "# Configure observables: occupation, correlation matrix, and fidelity vs. the ED target.\nconfig = EmulationConfig(\n observables=(\n Occupation(),\n CorrelationMatrix(),\n Fidelity(state=target_state),\n ),\n log_level=logging.WARN\n)\n\n# Sweep the dimensionless total evolution time. Larger t~ => slower, more adiabatic sweep.\nt_sweep = np.linspace(10.0, 120.0, 11)\nfid_vs_t = np.zeros(len(t_sweep))\n\nfor i, t in enumerate(t_sweep):\n # Build the program at dimensionless duration t and compile it to the device.\n prog = build_program(t)\n prog.compile_to(device, profile=\"max_energy\")\n\n # Run the adiabatic evolution\n emulator = LocalEmulator(backend_type=SVBackend, emulation_config=config)\n job = emulator.run(prog)\n tagged = job.results().get_tagged_results()\n\n # Fidelity with the ED target, straight from the emu_sv Fidelity observable.\n fid_vs_t[i] = float(np.asarray(tagged[\"fidelity\"][-1]).real)\n\n# Occupation and correlations from the final (largest-t~, most adiabatic) run.\nocc_p = np.asarray(tagged[\"occupation\"][-1])\ncorr_p = np.asarray(tagged[\"correlation_matrix\"][-1])\nconn_p = corr_p - np.outer(occ_p, occ_p)\nfid = fid_vs_t[-1]" }, { "cell_type": "markdown", diff --git a/docs/tutorials/Solving_a_MWIS.ipynb b/docs/tutorials/Solving_a_MWIS.ipynb index d08d84255..c7a2c4a1c 100644 --- a/docs/tutorials/Solving_a_MWIS.ipynb +++ b/docs/tutorials/Solving_a_MWIS.ipynb @@ -396,13 +396,7 @@ "id": "21", "metadata": {}, "outputs": [], - "source": [ - "from qoolqit import MockDevice, QuantumProgram\n", - "\n", - "program = QuantumProgram(register, drive)\n", - "program.compile_to(device=MockDevice())\n", - "program.draw()" - ] + "source": "from qoolqit import MockDevice, QuantumProgram\n\nprogram = QuantumProgram(register, drive)\nprogram.compile_to(device=MockDevice(), profile=\"max_energy\")\nprogram.draw()" }, { "cell_type": "markdown", @@ -495,31 +489,7 @@ "id": "27", "metadata": {}, "outputs": [], - "source": [ - "from qoolqit import AnalogDeviceWithDMM\n", - "\n", - "# Shorter schedule that fits the device's maximum pulse duration.\n", - "T_analog = 7.5\n", - "\n", - "drive_analog = Drive(\n", - " amplitude=InterpolatedWaveform(T_analog, [0.0, Omega, 0.0]),\n", - " detuning=InterpolatedWaveform(T_analog, [delta_0, 0.0, delta_f]),\n", - " dmm=DetuningMapModulator(ConstantWaveform(T_analog, -delta_f), det_map),\n", - ")\n", - "\n", - "program_analog = QuantumProgram(register, drive_analog)\n", - "program_analog.compile_to(device=AnalogDeviceWithDMM())\n", - "\n", - "results_analog = emulator.run(program_analog).results()\n", - "counts_analog = results_analog.final_bitstrings\n", - "\n", - "total = sum(counts_analog.values())\n", - "p_solution = counts_analog.get(SOLUTION, 0) / total\n", - "print(\"Most frequent bitstring:\", max(counts_analog, key=counts_analog.get))\n", - "print(f\"P({SOLUTION}) = {p_solution:.2%}\")\n", - "\n", - "plot_distribution(counts_analog, SOLUTION, top=20)" - ] + "source": "from qoolqit import AnalogDeviceWithDMM\n\n# Shorter schedule that fits the device's maximum pulse duration.\nT_analog = 7.5\n\ndrive_analog = Drive(\n amplitude=InterpolatedWaveform(T_analog, [0.0, Omega, 0.0]),\n detuning=InterpolatedWaveform(T_analog, [delta_0, 0.0, delta_f]),\n dmm=DetuningMapModulator(ConstantWaveform(T_analog, -delta_f), det_map),\n)\n\nprogram_analog = QuantumProgram(register, drive_analog)\nprogram_analog.compile_to(device=AnalogDeviceWithDMM(), profile=\"max_energy\")\n\nresults_analog = emulator.run(program_analog).results()\ncounts_analog = results_analog.final_bitstrings\n\ntotal = sum(counts_analog.values())\np_solution = counts_analog.get(SOLUTION, 0) / total\nprint(\"Most frequent bitstring:\", max(counts_analog, key=counts_analog.get))\nprint(f\"P({SOLUTION}) = {p_solution:.2%}\")\n\nplot_distribution(counts_analog, SOLUTION, top=20)" }, { "cell_type": "markdown", diff --git a/docs/tutorials/solving_a_qubo.ipynb b/docs/tutorials/solving_a_qubo.ipynb index ac01bc4f7..38f70a5ea 100644 --- a/docs/tutorials/solving_a_qubo.ipynb +++ b/docs/tutorials/solving_a_qubo.ipynb @@ -298,9 +298,7 @@ "id": "19", "metadata": {}, "outputs": [], - "source": [ - "program.compile_to(device=fresnel_device)" - ] + "source": "program.compile_to(device=fresnel_device, profile=\"max_energy\")" }, { "cell_type": "code", @@ -421,10 +419,7 @@ "id": "29", "metadata": {}, "outputs": [], - "source": [ - "program.compile_to(device=fresnel_device, device_max_duration_ratio=1)\n", - "program.compiled_sequence.draw()" - ] + "source": "program.compile_to(device=fresnel_device, profile=\"max_energy\", device_max_duration_ratio=1)\nprogram.compiled_sequence.draw()" }, { "cell_type": "markdown", diff --git a/qoolqit/execution/compilation_functions.py b/qoolqit/execution/compilation_functions.py index dff4ba245..dd57aac90 100644 --- a/qoolqit/execution/compilation_functions.py +++ b/qoolqit/execution/compilation_functions.py @@ -18,8 +18,16 @@ class CompilerProfile(Enum): """Enum for the different compilation profiles.""" - WORKING_POINT = "working_point" + DEFAULT = "default" MAX_ENERGY = "max_energy" + WORKING_POINT = DEFAULT # deprecated alias for DEFAULT + + @classmethod + def _missing_(cls, value: object) -> CompilerProfile | None: + """Resolve the deprecated "working_point" string alias to DEFAULT.""" + if value == "working_point": + return cls.DEFAULT + return None def _build_register(register: Register, device: Device, distance: float) -> PulserRegister: @@ -94,7 +102,7 @@ def basic_compilation( maximum allowed amplitude. - If the device requires a layout, it is automatically generated. """ - if profile == CompilerProfile.WORKING_POINT: + if profile == CompilerProfile.DEFAULT: TIME, ENERGY, DISTANCE = device.converter.factors _validate_program_default_profile(register, drive, device, device_max_duration_ratio) elif profile == CompilerProfile.MAX_ENERGY: diff --git a/qoolqit/program.py b/qoolqit/program.py index a8235f66c..df1f356ff 100644 --- a/qoolqit/program.py +++ b/qoolqit/program.py @@ -87,8 +87,8 @@ def compile_to( self, device: Device, profile: ( - Literal["max_energy", "working_point"] | CompilerProfile - ) = CompilerProfile.MAX_ENERGY, + Literal["default", "max_energy", "working_point"] | CompilerProfile + ) = CompilerProfile.DEFAULT, device_max_duration_ratio: float | None = None, ) -> None: """Compiles the quantum program for execution on a specific device. @@ -102,13 +102,14 @@ def compile_to( There are two compilation profiles: + - "default": Compile the program as it is. The drive and the register positions + must respect the hardware constraints of the device which can be inspected + using `device.specs()`. The string "working_point" and `CompilerProfile.WORKING_POINT` + are deprecated aliases for this profile. - "max_energy": Scale the program to utilize the device's maximum capabilities. The drive amplitude and the register positions are rescaled to achieve respectively the maximum amplitude and the minimum pairwise distance compatible with the input program and the device's constraints. - - "working_point": Compile the program as it is. The drive and the register positions - must respect the hardware constraints of the device which can be inspected - using `device.specs()`. The following option does NOT preserve the input program, but rather adapts the program to the device's constraints. Programs compiled this way are not portable across devices. @@ -120,7 +121,7 @@ def compile_to( Args: device: The target device for compilation. Must be a QoolQit Device. profile: The compilation profile used to translate the program. - Defaults to CompilerProfile.MAX_ENERGY. + Defaults to CompilerProfile.DEFAULT. device_max_duration_ratio: The fraction of the device's maximum allowed duration to set the program duration to, or None to leave it unset. Must be a number in the range (0, 1]. Can only be set if the device has a maximum allowed diff --git a/tests/test_execution/test_backends_integration.py b/tests/test_execution/test_backends_integration.py index 273073a7e..9a761c74c 100644 --- a/tests/test_execution/test_backends_integration.py +++ b/tests/test_execution/test_backends_integration.py @@ -7,6 +7,7 @@ from qoolqit import AnalogDevice, Drive, MockDevice, QuantumProgram, Register from qoolqit.devices import Device from qoolqit.execution import BackendType, EmulationConfig, JobStatus, LocalEmulator +from qoolqit.execution.compilation_functions import CompilerProfile from qoolqit.waveforms import ConstantWaveform @@ -24,7 +25,7 @@ def test_theoretical_state_vector(backend_type: Backend, rotation_angle: float) # atoms far away, no interaction register = Register.from_coordinates([(-10, -10), (10, 10)]) program = QuantumProgram(register, drive) - program.compile_to(device=MockDevice()) + program.compile_to(device=MockDevice(), profile=CompilerProfile.MAX_ENERGY) emulation_config = EmulationConfig(observables=(Occupation(),)) emulator = LocalEmulator(backend_type=backend_type, emulation_config=emulation_config) job = emulator.run(program) diff --git a/tests/test_program.py b/tests/test_program.py index aa23c57f4..97bf2f069 100644 --- a/tests/test_program.py +++ b/tests/test_program.py @@ -9,6 +9,7 @@ from qoolqit.devices import Device from qoolqit.drive import DetuningMapModulator, Drive from qoolqit.exceptions import CompilationError +from qoolqit.execution.compilation_functions import CompilerProfile from qoolqit.graphs import DataGraph from qoolqit.program import QuantumProgram from qoolqit.register import Register @@ -48,12 +49,12 @@ def test_compiler_dmm( ) -> None: program = dmm_program() if device._device.dmm_channels: - program.compile_to(device) + program.compile_to(device, profile=CompilerProfile.MAX_ENERGY) assert program.is_compiled assert isinstance(program.compiled_sequence, PulserSequence) else: with pytest.raises(CompilationError): - program.compile_to(device) + program.compile_to(device, profile=CompilerProfile.MAX_ENERGY) def test_compiled_sequence_with_small_delays() -> None: @@ -66,9 +67,9 @@ def test_compiled_sequence_with_small_delays() -> None: ) program = QuantumProgram(register=register, drive=drive) - program.compile_to(device=AnalogDevice()) + program.compile_to(device=AnalogDevice(), profile=CompilerProfile.MAX_ENERGY) program_small_delay = QuantumProgram(register=register, drive=drive_small_delay) - program_small_delay.compile_to(device=AnalogDevice()) + program_small_delay.compile_to(device=AnalogDevice(), profile=CompilerProfile.MAX_ENERGY) # check that the delay is not added to the pulser sequence if small pulser_duration = program.compiled_sequence.get_duration() @@ -91,7 +92,9 @@ def test_compile_to_max_duration_ratio(ratio: float) -> None: expected_max_duration = round(ratio * device._max_duration) - program.compile_to(device=device, device_max_duration_ratio=ratio) + program.compile_to( + device=device, profile=CompilerProfile.MAX_ENERGY, device_max_duration_ratio=ratio + ) assert program.is_compiled assert program.compiled_sequence.get_duration() == expected_max_duration @@ -103,7 +106,9 @@ def test_compile_to_max_duration(duration: float) -> None: amp = ConstantWaveform(duration=duration, value=1.0) drive = Drive(amplitude=amp) program = QuantumProgram(reg, drive) - program.compile_to(AnalogDevice(), device_max_duration_ratio=1.0) + program.compile_to( + AnalogDevice(), profile=CompilerProfile.MAX_ENERGY, device_max_duration_ratio=1.0 + ) assert program.is_compiled assert program.compiled_sequence.get_duration() == 6000 From 09af2317e7d363acec1175d0deef78b994408081 Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Tue, 18 Aug 2026 16:57:29 +0200 Subject: [PATCH 2/7] add regression tests --- tests/test_compilation/test_compile_to.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/test_compilation/test_compile_to.py b/tests/test_compilation/test_compile_to.py index 593e270b0..668278e39 100644 --- a/tests/test_compilation/test_compile_to.py +++ b/tests/test_compilation/test_compile_to.py @@ -19,10 +19,17 @@ @pytest.mark.parametrize( "profile", - [CompilerProfile.MAX_ENERGY, CompilerProfile.WORKING_POINT, "max_energy", "working_point"], + [ + CompilerProfile.MAX_ENERGY, + CompilerProfile.DEFAULT, + CompilerProfile.WORKING_POINT, + "max_energy", + "default", + "working_point", + ], ) def test_compilation_single_qubit( - profile: Literal["max_energy", "working_point"] | CompilerProfile, + profile: Literal["max_energy", "default", "working_point"] | CompilerProfile, ) -> None: """Test compilation of a single-qubit program.""" register = Register(qubits={"q0": (0.0, 0.0)}) @@ -33,6 +40,13 @@ def test_compilation_single_qubit( assert program.is_compiled +def test_compiler_profile_deprecated_working_point_alias() -> None: + """Test that WORKING_POINT and "working_point" are aliases of DEFAULT.""" + assert CompilerProfile.WORKING_POINT is CompilerProfile.DEFAULT + assert CompilerProfile("working_point") is CompilerProfile.DEFAULT + assert CompilerProfile("default") is CompilerProfile.DEFAULT + + def test_compile_to_invalid_profile_string() -> None: """Test compilation with an invalid profile string alias.""" register = Register(qubits={"q0": (0.0, 0.0)}) From c2223a26c6a793c56b95aa0c43f3667900a3205d Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Tue, 18 Aug 2026 17:43:58 +0200 Subject: [PATCH 3/7] changes moved to separate branch --- .../compilation/device_and_compilation.ipynb | 27 ++++++++++- .../compilation/error_handling.ipynb | 47 +++++++++++++++++-- docs/fundamentals/execution/execution.ipynb | 31 +++++++++++- .../programming_with_qoolqit.ipynb | 17 ++++++- docs/tutorials/Critical_state_TFIM.ipynb | 41 +++++++++++++++- docs/tutorials/Solving_a_MWIS.ipynb | 34 +++++++++++++- docs/tutorials/solving_a_qubo.ipynb | 9 +++- .../test_backends_integration.py | 3 +- tests/test_program.py | 17 +++---- 9 files changed, 197 insertions(+), 29 deletions(-) diff --git a/docs/fundamentals/compilation/device_and_compilation.ipynb b/docs/fundamentals/compilation/device_and_compilation.ipynb index eb9336c19..4eeb23e11 100644 --- a/docs/fundamentals/compilation/device_and_compilation.ipynb +++ b/docs/fundamentals/compilation/device_and_compilation.ipynb @@ -143,7 +143,26 @@ "id": "10", "metadata": {}, "outputs": [], - "source": "from qoolqit import AnalogDevice, Drive, PiecewiseLinearWaveform, QuantumProgram, Register\n\n# Defining the Drive\nwf0 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [0.0, 0.5, 0.5, 0.0])\nwf1 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [-1.0, -1.0, 1.0, 1.0])\ndrive = Drive(amplitude = wf0, detuning = wf1)\n\n# Defining the Register\ncoords = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]\nregister = Register.from_coordinates(coords)\n\n# Creating the Program\nprogram = QuantumProgram(register, drive)\ndevice = AnalogDevice()\n\n# Compilation to AnalogDevice\nprogram.compile_to(device, profile=\"max_energy\")\nprint(program)" + "source": [ + "from qoolqit import AnalogDevice, Drive, PiecewiseLinearWaveform, QuantumProgram, Register\n", + "\n", + "# Defining the Drive\n", + "wf0 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [0.0, 0.5, 0.5, 0.0])\n", + "wf1 = PiecewiseLinearWaveform([1.0, 2.0, 1.0], [-1.0, -1.0, 1.0, 1.0])\n", + "drive = Drive(amplitude = wf0, detuning = wf1)\n", + "\n", + "# Defining the Register\n", + "coords = [(0.0, 0.0), (0.0, 1.0), (1.0, 0.0), (1.0, 1.0)]\n", + "register = Register.from_coordinates(coords)\n", + "\n", + "# Creating the Program\n", + "program = QuantumProgram(register, drive)\n", + "device = AnalogDevice()\n", + "\n", + "# Compilation to AnalogDevice\n", + "program.compile_to(device)\n", + "print(program)" + ] }, { "cell_type": "markdown", @@ -205,7 +224,11 @@ "id": "16", "metadata": {}, "outputs": [], - "source": "# Compilation to AnalogDevice max duration\nprogram.compile_to(device, profile=\"max_energy\", device_max_duration_ratio=1.0)\nprogram.draw(compiled = True)" + "source": [ + "# Compilation to AnalogDevice max duration\n", + "program.compile_to(device, device_max_duration_ratio=1.0)\n", + "program.draw(compiled = True)" + ] }, { "cell_type": "markdown", diff --git a/docs/fundamentals/compilation/error_handling.ipynb b/docs/fundamentals/compilation/error_handling.ipynb index 5dcc5135d..46cf5a3ef 100644 --- a/docs/fundamentals/compilation/error_handling.ipynb +++ b/docs/fundamentals/compilation/error_handling.ipynb @@ -64,7 +64,17 @@ "id": "4", "metadata": {}, "outputs": [], - "source": "from qoolqit import AnalogDevice, QuantumProgram\n\nprogram = QuantumProgram(\n register=register,\n drive=drive\n)\n\ndevice=AnalogDevice()\nprogram.compile_to(device, profile=\"max_energy\")" + "source": [ + "from qoolqit import AnalogDevice, QuantumProgram\n", + "\n", + "program = QuantumProgram(\n", + " register=register,\n", + " drive=drive\n", + ")\n", + "\n", + "device=AnalogDevice()\n", + "program.compile_to(device)" + ] }, { "cell_type": "markdown", @@ -134,7 +144,18 @@ "id": "10", "metadata": {}, "outputs": [], - "source": "from qoolqit.exceptions import CompilationError\n\nL=4\namp=100\ndet=2\nprogram=create_program(L,amp,det)\ntry:\n compiled_sequence = program.compile_to(device, profile=\"max_energy\")\nexcept CompilationError as err:\n print(err)" + "source": [ + "from qoolqit.exceptions import CompilationError\n", + "\n", + "L=4\n", + "amp=100\n", + "det=2\n", + "program=create_program(L,amp,det)\n", + "try:\n", + " compiled_sequence = program.compile_to(device)\n", + "except CompilationError as err:\n", + " print(err)" + ] }, { "cell_type": "markdown", @@ -159,7 +180,16 @@ "id": "13", "metadata": {}, "outputs": [], - "source": "L=4\namp=1\ndet=20\nprogram=create_program(L,amp,det)\ntry:\n compiled_sequence = program.compile_to(device, profile=\"max_energy\")\nexcept CompilationError as err:\n print(err)" + "source": [ + "L=4\n", + "amp=1\n", + "det=20\n", + "program=create_program(L,amp,det)\n", + "try:\n", + " compiled_sequence = program.compile_to(device)\n", + "except CompilationError as err:\n", + " print(err)" + ] }, { "cell_type": "markdown", @@ -184,7 +214,16 @@ "id": "16", "metadata": {}, "outputs": [], - "source": "L=2\namp=10\ndet=1\nprogram=create_program(L,amp,det)\ntry:\n compiled_sequence = program.compile_to(device, profile=\"max_energy\")\nexcept CompilationError as err:\n print(err)" + "source": [ + "L=2\n", + "amp=10\n", + "det=1\n", + "program=create_program(L,amp,det)\n", + "try:\n", + " compiled_sequence = program.compile_to(device)\n", + "except CompilationError as err:\n", + " print(err)" + ] }, { "cell_type": "markdown", diff --git a/docs/fundamentals/execution/execution.ipynb b/docs/fundamentals/execution/execution.ipynb index 448586196..fa36083a0 100644 --- a/docs/fundamentals/execution/execution.ipynb +++ b/docs/fundamentals/execution/execution.ipynb @@ -36,7 +36,29 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": "from qoolqit import AnalogDevice, ConstantWaveform, Drive, QuantumProgram, RampWaveform, Register\n\n# Create the register\nregister = Register.from_coordinates([(0,1), (0,-1), (2,0)])\n\n# Defining the drive parameters\nomega = 0.8\ndelta_i = -2.0 * omega\ndelta_f = -delta_i\nT = 25.0\n\n# Defining the drive\nwf_amp = ConstantWaveform(T, omega)\nwf_det = RampWaveform(T, delta_i, delta_f)\ndrive = Drive(amplitude = wf_amp, detuning = wf_det)\n\n# Creating the program\nprogram = QuantumProgram(register, drive)\n\n# Compiling the program to a device\nprogram.compile_to(device=AnalogDevice(), profile=\"max_energy\")" + "source": [ + "from qoolqit import AnalogDevice, ConstantWaveform, Drive, QuantumProgram, RampWaveform, Register\n", + "\n", + "# Create the register\n", + "register = Register.from_coordinates([(0,1), (0,-1), (2,0)])\n", + "\n", + "# Defining the drive parameters\n", + "omega = 0.8\n", + "delta_i = -2.0 * omega\n", + "delta_f = -delta_i\n", + "T = 25.0\n", + "\n", + "# Defining the drive\n", + "wf_amp = ConstantWaveform(T, omega)\n", + "wf_det = RampWaveform(T, delta_i, delta_f)\n", + "drive = Drive(amplitude = wf_amp, detuning = wf_det)\n", + "\n", + "# Creating the program\n", + "program = QuantumProgram(register, drive)\n", + "\n", + "# Compiling the program to a device\n", + "program.compile_to(device=AnalogDevice())" + ] }, { "cell_type": "markdown", @@ -401,7 +423,12 @@ "execution_count": null, "metadata": {}, "outputs": [], - "source": "from qoolqit.devices import Device\n\ndevice = Device.from_connection(connection, \"FRESNEL\")\nprogram.compile_to(device=device, profile=\"max_energy\")" + "source": [ + "from qoolqit.devices import Device\n", + "\n", + "device = Device.from_connection(connection, \"FRESNEL\")\n", + "program.compile_to(device=device)" + ] }, { "cell_type": "markdown", diff --git a/docs/get_started/programming_with_qoolqit.ipynb b/docs/get_started/programming_with_qoolqit.ipynb index 90e4a0f13..8055d7aec 100644 --- a/docs/get_started/programming_with_qoolqit.ipynb +++ b/docs/get_started/programming_with_qoolqit.ipynb @@ -203,7 +203,12 @@ "id": "14", "metadata": {}, "outputs": [], - "source": "from qoolqit import AnalogDevice\n\ndevice = AnalogDevice()\nprogram.compile_to(device, profile=\"max_energy\")" + "source": [ + "from qoolqit import AnalogDevice\n", + "\n", + "device = AnalogDevice()\n", + "program.compile_to(device)" + ] }, { "cell_type": "markdown", @@ -304,7 +309,15 @@ "id": "20", "metadata": {}, "outputs": [], - "source": "# Build and compile programs\nprogram_blockade = QuantumProgram(register, drive_blockade)\nprogram_no_blockade = QuantumProgram(register, drive_no_blockade)\n\ndevice = AnalogDevice()\nprogram_blockade.compile_to(device, profile=\"max_energy\")\nprogram_no_blockade.compile_to(device, profile=\"max_energy\")" + "source": [ + "# Build and compile programs\n", + "program_blockade = QuantumProgram(register, drive_blockade)\n", + "program_no_blockade = QuantumProgram(register, drive_no_blockade)\n", + "\n", + "device = AnalogDevice()\n", + "program_blockade.compile_to(device)\n", + "program_no_blockade.compile_to(device)" + ] }, { "cell_type": "code", diff --git a/docs/tutorials/Critical_state_TFIM.ipynb b/docs/tutorials/Critical_state_TFIM.ipynb index 314727132..9f5d37cf8 100644 --- a/docs/tutorials/Critical_state_TFIM.ipynb +++ b/docs/tutorials/Critical_state_TFIM.ipynb @@ -353,7 +353,11 @@ "id": "16", "metadata": {}, "outputs": [], - "source": "demo = build_program(80.0)\ndemo.compile_to(device, profile=\"max_energy\")\ndemo.draw(compiled=True)" + "source": [ + "demo = build_program(80.0)\n", + "demo.compile_to(device)\n", + "demo.draw(compiled=True)" + ] }, { "cell_type": "markdown", @@ -655,7 +659,40 @@ "id": "27", "metadata": {}, "outputs": [], - "source": "# Configure observables: occupation, correlation matrix, and fidelity vs. the ED target.\nconfig = EmulationConfig(\n observables=(\n Occupation(),\n CorrelationMatrix(),\n Fidelity(state=target_state),\n ),\n log_level=logging.WARN\n)\n\n# Sweep the dimensionless total evolution time. Larger t~ => slower, more adiabatic sweep.\nt_sweep = np.linspace(10.0, 120.0, 11)\nfid_vs_t = np.zeros(len(t_sweep))\n\nfor i, t in enumerate(t_sweep):\n # Build the program at dimensionless duration t and compile it to the device.\n prog = build_program(t)\n prog.compile_to(device, profile=\"max_energy\")\n\n # Run the adiabatic evolution\n emulator = LocalEmulator(backend_type=SVBackend, emulation_config=config)\n job = emulator.run(prog)\n tagged = job.results().get_tagged_results()\n\n # Fidelity with the ED target, straight from the emu_sv Fidelity observable.\n fid_vs_t[i] = float(np.asarray(tagged[\"fidelity\"][-1]).real)\n\n# Occupation and correlations from the final (largest-t~, most adiabatic) run.\nocc_p = np.asarray(tagged[\"occupation\"][-1])\ncorr_p = np.asarray(tagged[\"correlation_matrix\"][-1])\nconn_p = corr_p - np.outer(occ_p, occ_p)\nfid = fid_vs_t[-1]" + "source": [ + "# Configure observables: occupation, correlation matrix, and fidelity vs. the ED target.\n", + "config = EmulationConfig(\n", + " observables=(\n", + " Occupation(),\n", + " CorrelationMatrix(),\n", + " Fidelity(state=target_state),\n", + " ),\n", + " log_level=logging.WARN\n", + ")\n", + "\n", + "# Sweep the dimensionless total evolution time. Larger t~ => slower, more adiabatic sweep.\n", + "t_sweep = np.linspace(10.0, 120.0, 11)\n", + "fid_vs_t = np.zeros(len(t_sweep))\n", + "\n", + "for i, t in enumerate(t_sweep):\n", + " # Build the program at dimensionless duration t and compile it to the device.\n", + " prog = build_program(t)\n", + " prog.compile_to(device)\n", + "\n", + " # Run the adiabatic evolution\n", + " emulator = LocalEmulator(backend_type=SVBackend, emulation_config=config)\n", + " job = emulator.run(prog)\n", + " tagged = job.results().get_tagged_results()\n", + "\n", + " # Fidelity with the ED target, straight from the emu_sv Fidelity observable.\n", + " fid_vs_t[i] = float(np.asarray(tagged[\"fidelity\"][-1]).real)\n", + "\n", + "# Occupation and correlations from the final (largest-t~, most adiabatic) run.\n", + "occ_p = np.asarray(tagged[\"occupation\"][-1])\n", + "corr_p = np.asarray(tagged[\"correlation_matrix\"][-1])\n", + "conn_p = corr_p - np.outer(occ_p, occ_p)\n", + "fid = fid_vs_t[-1]" + ] }, { "cell_type": "markdown", diff --git a/docs/tutorials/Solving_a_MWIS.ipynb b/docs/tutorials/Solving_a_MWIS.ipynb index c7a2c4a1c..d08d84255 100644 --- a/docs/tutorials/Solving_a_MWIS.ipynb +++ b/docs/tutorials/Solving_a_MWIS.ipynb @@ -396,7 +396,13 @@ "id": "21", "metadata": {}, "outputs": [], - "source": "from qoolqit import MockDevice, QuantumProgram\n\nprogram = QuantumProgram(register, drive)\nprogram.compile_to(device=MockDevice(), profile=\"max_energy\")\nprogram.draw()" + "source": [ + "from qoolqit import MockDevice, QuantumProgram\n", + "\n", + "program = QuantumProgram(register, drive)\n", + "program.compile_to(device=MockDevice())\n", + "program.draw()" + ] }, { "cell_type": "markdown", @@ -489,7 +495,31 @@ "id": "27", "metadata": {}, "outputs": [], - "source": "from qoolqit import AnalogDeviceWithDMM\n\n# Shorter schedule that fits the device's maximum pulse duration.\nT_analog = 7.5\n\ndrive_analog = Drive(\n amplitude=InterpolatedWaveform(T_analog, [0.0, Omega, 0.0]),\n detuning=InterpolatedWaveform(T_analog, [delta_0, 0.0, delta_f]),\n dmm=DetuningMapModulator(ConstantWaveform(T_analog, -delta_f), det_map),\n)\n\nprogram_analog = QuantumProgram(register, drive_analog)\nprogram_analog.compile_to(device=AnalogDeviceWithDMM(), profile=\"max_energy\")\n\nresults_analog = emulator.run(program_analog).results()\ncounts_analog = results_analog.final_bitstrings\n\ntotal = sum(counts_analog.values())\np_solution = counts_analog.get(SOLUTION, 0) / total\nprint(\"Most frequent bitstring:\", max(counts_analog, key=counts_analog.get))\nprint(f\"P({SOLUTION}) = {p_solution:.2%}\")\n\nplot_distribution(counts_analog, SOLUTION, top=20)" + "source": [ + "from qoolqit import AnalogDeviceWithDMM\n", + "\n", + "# Shorter schedule that fits the device's maximum pulse duration.\n", + "T_analog = 7.5\n", + "\n", + "drive_analog = Drive(\n", + " amplitude=InterpolatedWaveform(T_analog, [0.0, Omega, 0.0]),\n", + " detuning=InterpolatedWaveform(T_analog, [delta_0, 0.0, delta_f]),\n", + " dmm=DetuningMapModulator(ConstantWaveform(T_analog, -delta_f), det_map),\n", + ")\n", + "\n", + "program_analog = QuantumProgram(register, drive_analog)\n", + "program_analog.compile_to(device=AnalogDeviceWithDMM())\n", + "\n", + "results_analog = emulator.run(program_analog).results()\n", + "counts_analog = results_analog.final_bitstrings\n", + "\n", + "total = sum(counts_analog.values())\n", + "p_solution = counts_analog.get(SOLUTION, 0) / total\n", + "print(\"Most frequent bitstring:\", max(counts_analog, key=counts_analog.get))\n", + "print(f\"P({SOLUTION}) = {p_solution:.2%}\")\n", + "\n", + "plot_distribution(counts_analog, SOLUTION, top=20)" + ] }, { "cell_type": "markdown", diff --git a/docs/tutorials/solving_a_qubo.ipynb b/docs/tutorials/solving_a_qubo.ipynb index 38f70a5ea..ac01bc4f7 100644 --- a/docs/tutorials/solving_a_qubo.ipynb +++ b/docs/tutorials/solving_a_qubo.ipynb @@ -298,7 +298,9 @@ "id": "19", "metadata": {}, "outputs": [], - "source": "program.compile_to(device=fresnel_device, profile=\"max_energy\")" + "source": [ + "program.compile_to(device=fresnel_device)" + ] }, { "cell_type": "code", @@ -419,7 +421,10 @@ "id": "29", "metadata": {}, "outputs": [], - "source": "program.compile_to(device=fresnel_device, profile=\"max_energy\", device_max_duration_ratio=1)\nprogram.compiled_sequence.draw()" + "source": [ + "program.compile_to(device=fresnel_device, device_max_duration_ratio=1)\n", + "program.compiled_sequence.draw()" + ] }, { "cell_type": "markdown", diff --git a/tests/test_execution/test_backends_integration.py b/tests/test_execution/test_backends_integration.py index 9a761c74c..273073a7e 100644 --- a/tests/test_execution/test_backends_integration.py +++ b/tests/test_execution/test_backends_integration.py @@ -7,7 +7,6 @@ from qoolqit import AnalogDevice, Drive, MockDevice, QuantumProgram, Register from qoolqit.devices import Device from qoolqit.execution import BackendType, EmulationConfig, JobStatus, LocalEmulator -from qoolqit.execution.compilation_functions import CompilerProfile from qoolqit.waveforms import ConstantWaveform @@ -25,7 +24,7 @@ def test_theoretical_state_vector(backend_type: Backend, rotation_angle: float) # atoms far away, no interaction register = Register.from_coordinates([(-10, -10), (10, 10)]) program = QuantumProgram(register, drive) - program.compile_to(device=MockDevice(), profile=CompilerProfile.MAX_ENERGY) + program.compile_to(device=MockDevice()) emulation_config = EmulationConfig(observables=(Occupation(),)) emulator = LocalEmulator(backend_type=backend_type, emulation_config=emulation_config) job = emulator.run(program) diff --git a/tests/test_program.py b/tests/test_program.py index 97bf2f069..aa23c57f4 100644 --- a/tests/test_program.py +++ b/tests/test_program.py @@ -9,7 +9,6 @@ from qoolqit.devices import Device from qoolqit.drive import DetuningMapModulator, Drive from qoolqit.exceptions import CompilationError -from qoolqit.execution.compilation_functions import CompilerProfile from qoolqit.graphs import DataGraph from qoolqit.program import QuantumProgram from qoolqit.register import Register @@ -49,12 +48,12 @@ def test_compiler_dmm( ) -> None: program = dmm_program() if device._device.dmm_channels: - program.compile_to(device, profile=CompilerProfile.MAX_ENERGY) + program.compile_to(device) assert program.is_compiled assert isinstance(program.compiled_sequence, PulserSequence) else: with pytest.raises(CompilationError): - program.compile_to(device, profile=CompilerProfile.MAX_ENERGY) + program.compile_to(device) def test_compiled_sequence_with_small_delays() -> None: @@ -67,9 +66,9 @@ def test_compiled_sequence_with_small_delays() -> None: ) program = QuantumProgram(register=register, drive=drive) - program.compile_to(device=AnalogDevice(), profile=CompilerProfile.MAX_ENERGY) + program.compile_to(device=AnalogDevice()) program_small_delay = QuantumProgram(register=register, drive=drive_small_delay) - program_small_delay.compile_to(device=AnalogDevice(), profile=CompilerProfile.MAX_ENERGY) + program_small_delay.compile_to(device=AnalogDevice()) # check that the delay is not added to the pulser sequence if small pulser_duration = program.compiled_sequence.get_duration() @@ -92,9 +91,7 @@ def test_compile_to_max_duration_ratio(ratio: float) -> None: expected_max_duration = round(ratio * device._max_duration) - program.compile_to( - device=device, profile=CompilerProfile.MAX_ENERGY, device_max_duration_ratio=ratio - ) + program.compile_to(device=device, device_max_duration_ratio=ratio) assert program.is_compiled assert program.compiled_sequence.get_duration() == expected_max_duration @@ -106,9 +103,7 @@ def test_compile_to_max_duration(duration: float) -> None: amp = ConstantWaveform(duration=duration, value=1.0) drive = Drive(amplitude=amp) program = QuantumProgram(reg, drive) - program.compile_to( - AnalogDevice(), profile=CompilerProfile.MAX_ENERGY, device_max_duration_ratio=1.0 - ) + program.compile_to(AnalogDevice(), device_max_duration_ratio=1.0) assert program.is_compiled assert program.compiled_sequence.get_duration() == 6000 From 331bcb254825d59721875668b2bea1bf5d03b9b7 Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Tue, 18 Aug 2026 17:54:42 +0200 Subject: [PATCH 4/7] working point to default --- qoolqit/program.py | 8 +++----- tests/test_compilation/test_compile_to.py | 9 +++------ .../{test_working_point.py => test_default.py} | 4 ++-- 3 files changed, 8 insertions(+), 13 deletions(-) rename tests/test_compilation/{test_working_point.py => test_default.py} (98%) diff --git a/qoolqit/program.py b/qoolqit/program.py index df1f356ff..4946dd613 100644 --- a/qoolqit/program.py +++ b/qoolqit/program.py @@ -86,9 +86,7 @@ def __repr__(self) -> str: def compile_to( self, device: Device, - profile: ( - Literal["default", "max_energy", "working_point"] | CompilerProfile - ) = CompilerProfile.DEFAULT, + profile: Literal["default", "max_energy"] | CompilerProfile = CompilerProfile.DEFAULT, device_max_duration_ratio: float | None = None, ) -> None: """Compiles the quantum program for execution on a specific device. @@ -104,8 +102,8 @@ def compile_to( - "default": Compile the program as it is. The drive and the register positions must respect the hardware constraints of the device which can be inspected - using `device.specs()`. The string "working_point" and `CompilerProfile.WORKING_POINT` - are deprecated aliases for this profile. + using `device.specs()`. The `CompilerProfile.WORKING_POINT` is deprecated + aliases for this profile. - "max_energy": Scale the program to utilize the device's maximum capabilities. The drive amplitude and the register positions are rescaled to achieve respectively the maximum amplitude and the minimum pairwise distance diff --git a/tests/test_compilation/test_compile_to.py b/tests/test_compilation/test_compile_to.py index 668278e39..2c6323c80 100644 --- a/tests/test_compilation/test_compile_to.py +++ b/tests/test_compilation/test_compile_to.py @@ -22,14 +22,12 @@ [ CompilerProfile.MAX_ENERGY, CompilerProfile.DEFAULT, - CompilerProfile.WORKING_POINT, "max_energy", "default", - "working_point", ], ) def test_compilation_single_qubit( - profile: Literal["max_energy", "default", "working_point"] | CompilerProfile, + profile: Literal["max_energy", "default"] | CompilerProfile, ) -> None: """Test compilation of a single-qubit program.""" register = Register(qubits={"q0": (0.0, 0.0)}) @@ -41,9 +39,8 @@ def test_compilation_single_qubit( def test_compiler_profile_deprecated_working_point_alias() -> None: - """Test that WORKING_POINT and "working_point" are aliases of DEFAULT.""" + """Test that WORKING_POINT is aliases of DEFAULT.""" assert CompilerProfile.WORKING_POINT is CompilerProfile.DEFAULT - assert CompilerProfile("working_point") is CompilerProfile.DEFAULT assert CompilerProfile("default") is CompilerProfile.DEFAULT @@ -67,7 +64,7 @@ def test_dmm_not_supported() -> None: program.compile_to(device=AnalogDevice()) -@pytest.mark.parametrize("profile", [CompilerProfile.MAX_ENERGY, CompilerProfile.WORKING_POINT]) +@pytest.mark.parametrize("profile", [CompilerProfile.MAX_ENERGY, CompilerProfile.DEFAULT]) def test_compilation_with_dmm(profile: CompilerProfile) -> None: """Test compilation of a program with a DMM.""" register = Register(qubits={"q0": (0.0, 0.7), "q1": (-0.5, -0.5), "q2": (0.5, -0.5)}) diff --git a/tests/test_compilation/test_working_point.py b/tests/test_compilation/test_default.py similarity index 98% rename from tests/test_compilation/test_working_point.py rename to tests/test_compilation/test_default.py index e1864d09f..61424c34d 100644 --- a/tests/test_compilation/test_working_point.py +++ b/tests/test_compilation/test_default.py @@ -1,4 +1,4 @@ -"""Test the WORKING_POINT compilation profile.""" +"""Test the DEFAULT compilation profile.""" from __future__ import annotations @@ -23,7 +23,7 @@ class TestWorkingPointCompilerProfile: - profile = CompilerProfile.WORKING_POINT + profile = CompilerProfile.DEFAULT @pytest.fixture(autouse=True) def program_factory( From ceabd9b08e3c2422d1f625df8db5e7e9198d5e68 Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Wed, 19 Aug 2026 09:21:48 +0200 Subject: [PATCH 5/7] fix program tests --- tests/test_program.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_program.py b/tests/test_program.py index ad54739f5..ac1543e8a 100644 --- a/tests/test_program.py +++ b/tests/test_program.py @@ -49,7 +49,7 @@ def test_compiler_dmm( ) -> None: program = dmm_program() if device._device.dmm_channels: - program.compile_to(device) + program.compile_to(device, profile=CompilerProfile.MAX_ENERGY) assert program.is_compiled assert isinstance(program.compiled_sequence, PulserSequence) else: @@ -103,7 +103,7 @@ def test_compile_to_max_duration_ratio(ratio: float) -> None: def test_compile_to_max_duration(duration: float) -> None: """Test that the compiled sequence's duration is set to the maximum allowed by the device.""" reg = Register.from_graph(DataGraph.line(2)) - amp = ConstantWaveform(duration=duration, value=1.0) + amp = ConstantWaveform(duration=duration, value=0.2) drive = Drive(amplitude=amp) program = QuantumProgram(reg, drive) program.compile_to(AnalogDevice(), device_max_duration_ratio=1.0) From e822b8d9562f73a4e66b7d13427e622d0e0e7d90 Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Wed, 19 Aug 2026 09:28:46 +0200 Subject: [PATCH 6/7] remove unused _missing_ mechanism to deprecate "working_point" --- qoolqit/execution/compilation_functions.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/qoolqit/execution/compilation_functions.py b/qoolqit/execution/compilation_functions.py index dd57aac90..457d857d8 100644 --- a/qoolqit/execution/compilation_functions.py +++ b/qoolqit/execution/compilation_functions.py @@ -22,13 +22,6 @@ class CompilerProfile(Enum): MAX_ENERGY = "max_energy" WORKING_POINT = DEFAULT # deprecated alias for DEFAULT - @classmethod - def _missing_(cls, value: object) -> CompilerProfile | None: - """Resolve the deprecated "working_point" string alias to DEFAULT.""" - if value == "working_point": - return cls.DEFAULT - return None - def _build_register(register: Register, device: Device, distance: float) -> PulserRegister: """Builds a Pulser Register from a QoolQit Register.""" From 8687a9c67c15b5f8c2789d6988205d6b9e65fee6 Mon Sep 17 00:00:00 2001 From: Stefano Grava Date: Wed, 19 Aug 2026 10:13:22 +0200 Subject: [PATCH 7/7] update test profile --- tests/test_program.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/test_program.py b/tests/test_program.py index ac1543e8a..d5d1dd697 100644 --- a/tests/test_program.py +++ b/tests/test_program.py @@ -106,7 +106,9 @@ def test_compile_to_max_duration(duration: float) -> None: amp = ConstantWaveform(duration=duration, value=0.2) drive = Drive(amplitude=amp) program = QuantumProgram(reg, drive) - program.compile_to(AnalogDevice(), device_max_duration_ratio=1.0) + program.compile_to( + AnalogDevice(), profile=CompilerProfile.DEFAULT, device_max_duration_ratio=1.0 + ) assert program.is_compiled assert program.compiled_sequence.get_duration() == 6000