diff --git a/setup.cfg b/setup.cfg index 88483b24..8376fb18 100644 --- a/setup.cfg +++ b/setup.cfg @@ -9,3 +9,11 @@ env= addopts = --verbose -n logical --durations=0 --durations-min=0.5 testpaths = test/unit_tests +filterwarnings = + # Many existing tests deliberately exercise the JaqcdProgram code path + # (e.g. parametrized tests that compare JAQCD vs OpenQASM behavior). The + # JAQCD deprecation warning is expected on those paths; ignore it here. + # Tests that specifically assert the warning fires use + # `pytest.warns(UserWarning, match="JaqcdProgram")` directly and are + # unaffected by this filter. + ignore:Submitting JaqcdProgram to LocalSimulator is deprecated:UserWarning diff --git a/src/braket/default_simulator/simulator.py b/src/braket/default_simulator/simulator.py index 9f2675e7..cc522cf1 100644 --- a/src/braket/default_simulator/simulator.py +++ b/src/braket/default_simulator/simulator.py @@ -138,6 +138,15 @@ def run( """ Simulate a program using either OpenQASM or Jaqcd. + .. deprecated:: 1.39.4 + Submitting a ``JaqcdProgram`` to a local simulator is deprecated + and emits a ``UserWarning``. Submit an ``OpenQASMProgram`` (or a + ``ProgramSet``) instead. Amazon Braket service devices no longer + accept JAQCD program submissions; see MCM-150287739. Local + simulators continue to accept JAQCD programs in this release so + historical notebooks keep working during the migration window; + JAQCD support will be removed in a future release. + Args: circuit_ir (OpenQASMProgram | ProgramSet | JaqcdProgram): Program specification. @@ -161,6 +170,14 @@ def run( return self.run_openqasm(circuit_ir, *args, **kwargs) elif isinstance(circuit_ir, ProgramSet): return self.run_program_set(circuit_ir, *args, **kwargs) + if isinstance(circuit_ir, JaqcdProgram): + warnings.warn( + "Submitting JaqcdProgram to LocalSimulator is deprecated and " + "will be removed in a future release. Submit OpenQASMProgram " + "instead. Amazon Braket service devices no longer accept " + "JAQCD program submissions. See MCM-150287739.", + stacklevel=2, + ) return self.run_jaqcd(circuit_ir, *args, **kwargs) def create_program_context(self) -> AbstractProgramContext: diff --git a/test/unit_tests/braket/default_simulator/test_simulator.py b/test/unit_tests/braket/default_simulator/test_simulator.py index 308f8a0b..70d1e187 100644 --- a/test/unit_tests/braket/default_simulator/test_simulator.py +++ b/test/unit_tests/braket/default_simulator/test_simulator.py @@ -11,12 +11,18 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +import json +import warnings + import numpy as np import pytest +from braket.ir.jaqcd import Program as JaqcdProgram +from braket.ir.openqasm import Program as OpenQASMProgram from braket.default_simulator import observables from braket.default_simulator.result_types import DensityMatrix, Expectation, Probability, Variance from braket.default_simulator.simulator import BaseLocalSimulator +from braket.default_simulator.state_vector_simulator import StateVectorSimulator @pytest.mark.parametrize( @@ -60,3 +66,50 @@ def test_observable_hash_tensor_product(): def test_base_local_simulator_abstract(): with pytest.raises(TypeError, match="Can't instantiate abstract class BaseLocalSimulator"): BaseLocalSimulator() + + +def _minimal_jaqcd_program() -> JaqcdProgram: + """Build a minimal JaqcdProgram for warning-assertion tests.""" + return JaqcdProgram.parse_raw( + json.dumps( + { + "instructions": [{"type": "h", "target": 0}], + "results": [{"type": "probability", "targets": [0]}], + } + ) + ) + + +def _minimal_openqasm_program() -> OpenQASMProgram: + """Build a minimal OpenQASMProgram for warning-assertion tests.""" + return OpenQASMProgram( + source=""" + qubit q; + h q; + #pragma braket result probability q + """ + ) + + +def test_run_jaqcd_emits_warning(): + """Submitting a JaqcdProgram via BaseLocalSimulator.run should emit a + UserWarning telling the customer to migrate to OpenQASMProgram. The + program still executes — this is a soft deprecation.""" + simulator = StateVectorSimulator() + with pytest.warns(UserWarning, match="JaqcdProgram"): + result = simulator.run(_minimal_jaqcd_program(), qubit_count=1, shots=10) + assert result is not None + + +def test_run_openqasm_no_jaqcd_warning(): + """The OpenQASM path must not emit the JAQCD deprecation warning. Assert + specifically on JAQCD-message warnings rather than erroring on all + UserWarnings, since other unrelated warnings (e.g. the density-matrix + noise advisory) are legitimate.""" + simulator = StateVectorSimulator() + with warnings.catch_warnings(record=True) as w: + warnings.simplefilter("always") + result = simulator.run(_minimal_openqasm_program(), shots=10) + jaqcd_warnings = [x for x in w if "JaqcdProgram" in str(x.message)] + assert jaqcd_warnings == [] + assert result is not None