rigetti / qcs-sdk-rust

Rust SDK for Rigetti Quantum Cloud Services (QCS)
https://docs.rs/qcs
12 stars 5 forks source link

Negative Integer Values are improperly returned on `ExecutionResults` #466

Open erichulburd opened 4 months ago

erichulburd commented 4 months ago

The following test fails:

from typing import Dict, List, Union

import pytest
from pyquil.quil import Program
from qcs_sdk.qpu.api import ConnectionStrategy, ExecutionOptions, retrieve_results
from quil.program import FrameSet

def _clean_frames(calibration_program: Program) -> None:
    frames = FrameSet()
    for frame_id, attributes in calibration_program._program.frames.get_all_frames().items():
        if frame_id.name != "ro_rx":
            frames.insert(frame_id, attributes)
    calibration_program._program.frames = frames

def test_example(live_quantum_processor_id: str, quantum_processor_calibration_program: Program):
    program = Program()
    program.declare("SOURCE", "INTEGER", 1)
    program.declare("DEST", "INTEGER", 1)
    program.declare("INDEX", "INTEGER", 1)
    program += Program("LOAD DEST[0] SOURCE INDEX[0]")
    _clean_frames(quantum_processor_calibration_program)
    program += quantum_processor_calibration_program.copy_everything_except_instructions()

    translation_output = translate_for_pyquil(program.out(), live_quantum_processor_id, None)
    execution_options = ExecutionOptions.builder()
    execution_options.timeout_seconds = 60 * 3
    execution_options.connection_strategy = ConnectionStrategy.direct_access()
    memory_values: Dict[str, List[Union[int, float]]] = {
        "SOURCE": [-57835426011472],
        "DEST": [0],
        "INDEX": [0],
    }
    job_id = execute_for_pyquil(live_quantum_processor_id, translation_output, memory_values)
    results = retrieve_results(
        job_id,
        quantum_processor_id=live_quantum_processor_id,
        execution_options=execution_options.build(),
    )
    assert results.memory["SOURCE"].inner() == [-57835426011472]
    assert results.memory["DEST"].inner() == [-57835426011472]

Output:

FAILED tests/test_example.py::test_example - assert [-82902062343856] == [-57835426011472

If you wrap the final value in _handle_readout_bug below, the test will pass.

def _handle_readout_bug(final_value: int):
    if final_value < 0:
        # somewhere up the stack, values are being interpreted as signed-magnitude.
        # Here we correct that by flipping the bits and adding 1 to get the correct
        # two's complement value.
        return (final_value ^ (2**47 - 1)) + 1
    return final_value

Info:

$ poetry run python --version
Python 3.9.19
$ poetry show pyquil
 name         : pyquil
 version      : 4.9.2
 description  : A Python library for creating Quantum Instruction Language (Quil) programs.
$ poetry show qcs-sdk-python
 name         : qcs-sdk-python
 version      : 0.17.6
 description  : Python interface for the QCS Rust SDK