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
7 changes: 7 additions & 0 deletions azure-quantum/azure/quantum/cirq/service.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,13 @@ def targets(
cirq_targets.append(target)
continue

# Only apply the generic QIR fallback to targets that advertise a QIR
# target profile. Providers like Pasqal use pulse-level input formats
# (e.g. pasqal.pulser.v1) that are incompatible with QIR submission.
# target_profile is None for non-QIR targets.
if not status.target_profile:
continue

cirq_targets.append(
AzureGenericQirCirqTarget.from_target_status(
self._workspace, pid, status, **kwargs
Expand Down
6 changes: 6 additions & 0 deletions azure-quantum/azure/quantum/qiskit/provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,12 @@ def backends(self, name=None, **kwargs):
if (target_id, pid) in existing_pairs:
continue
status = status_by_target.get((target_id, pid))
# Only create a generic QIR backend for targets that advertise a QIR
# target profile. Providers like Pasqal use pulse-level input formats
# (e.g. pasqal.pulser.v1) that are incompatible with QIR submission.
# target_profile is None for non-QIR targets.
if status is not None and not status.target_profile:
continue
backend_list.append(
AzureGenericQirBackend(
name=target_id,
Expand Down
15 changes: 15 additions & 0 deletions azure-quantum/tests/mock_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,21 @@ def _target(
],
}
),
# A non-QIR provider (no target_profile) that should never get a generic
# QIR backend/target wrapper — mirrors real-world Pasqal behavior.
ProviderStatus(
{
"id": "pasqal",
"currentAvailability": "Available",
"targets": [
_target(
target_id="pasqal.sim.emu-tn",
num_qubits=100,
target_profile=None,
)
],
}
),
]

ws._client.services.providers._store[:] = providers
Expand Down
32 changes: 32 additions & 0 deletions azure-quantum/tests/test_cirq.py
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,38 @@ def test_cirq_generic_to_cirq_result_drops_non_binary_shots_and_exposes_raw():
)


def test_cirq_service_targets_excludes_non_qir_target():
"""Targets without a target_profile (e.g. Pasqal) must not be wrapped as
AzureGenericQirCirqTarget — they use pulse-level input formats incompatible
with QIR submission.
"""
pytest.importorskip("cirq")
pytest.importorskip("cirq_ionq")

from azure.quantum.cirq.service import AzureQuantumService
from azure.quantum.cirq.targets.generic import AzureGenericQirCirqTarget

from mock_client import create_default_workspace

ws = create_default_workspace()
_freeze_workspace_client_recreation(ws)
service = AzureQuantumService(workspace=ws)

targets = service.targets()
target_names = [t.name for t in targets]

# The Pasqal target (target_profile=None) should be completely absent.
assert not any(
"pasqal" in name for name in target_names
), f"Non-QIR Pasqal target unexpectedly appeared in service.targets(): {target_names}"
# Specifically, no AzureGenericQirCirqTarget should have been created for it.
assert not any(
isinstance(t, AzureGenericQirCirqTarget) and "pasqal" in t.name for t in targets
)
# QIR-capable targets should still be present.
assert any("microsoft.estimator" in name for name in target_names)


def test_cirq_service_targets_discovers_provider_specific_and_generic_wrappers(
monkeypatch: pytest.MonkeyPatch,
):
Expand Down
17 changes: 17 additions & 0 deletions azure-quantum/tests/test_qiskit.py
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,23 @@ def test_qir_target_profile_from_deprecated_target_capability():
assert "target_profile" not in input_params


def test_generic_qir_backend_not_created_for_non_qir_target():
"""Targets without a target_profile (e.g. Pasqal) must not receive an
AzureGenericQirBackend — they use pulse-level input formats incompatible
with QIR submission.

The default mock workspace already includes pasqal.sim.emu-tn with
target_profile=None via seed_providers in mock_client.py.
"""
from qiskit.providers.exceptions import QiskitBackendNotFoundError

ws = create_default_workspace()
provider = AzureQuantumProvider(workspace=ws)

with pytest.raises(QiskitBackendNotFoundError):
provider.get_backend("pasqal.sim.emu-tn")


def test_generic_qir_backend_created_for_unknown_workspace_target(
monkeypatch: pytest.MonkeyPatch,
):
Expand Down
Loading