Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BREAKING CHANGE: remove vestigial engagement manager and qpu client #1528

Merged
merged 10 commits into from
Feb 15, 2023
2 changes: 1 addition & 1 deletion pyquil/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@
else:
from importlib.metadata import version

pyquil_version = version(__package__)
pyquil_version = version(__package__) # type: ignore
2 changes: 0 additions & 2 deletions pyquil/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
"AbstractCompiler",
"BenchmarkConnection",
"EncryptedProgram",
"EngagementManager",
"get_qc",
"list_quantum_computers",
"local_forest_runtime",
Expand All @@ -42,7 +41,6 @@

from pyquil.api._benchmark import BenchmarkConnection
from pyquil.api._compiler import QVMCompiler, QPUCompiler, QuantumExecutable, EncryptedProgram, AbstractCompiler
from pyquil.api._engagement_manager import EngagementManager
from pyquil.api._qam import QAM, QAMExecutionResult
from pyquil.api._qpu import QPU
from pyquil.api._quantum_computer import (
Expand Down
7 changes: 3 additions & 4 deletions pyquil/api/_abstract_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@

from pyquil._memory import Memory
from pyquil._version import pyquil_version
from pyquil.api._compiler_client import CompilerClient, CompileToNativeQuilRequest
from pyquil.api._compiler_client import CompilerClient
from pyquil.external.rpcq import compiler_isa_to_target_quantum_processor
from pyquil.parser import parse_program
from pyquil.paulis import PauliTerm
from pyquil.quantum_processor import AbstractQuantumProcessor
from pyquil.quil import Program
from pyquil.quilatom import ExpressionDesignator, MemoryReference
from pyquil.quilatom import MemoryReference
from pyquil.quilbase import Gate
from qcs_api_client.client import QCSClientConfiguration
from rpcq.messages import NativeQuilMetadata, ParameterAref, ParameterSpec
from rpcq.messages import ParameterAref, ParameterSpec


class QuilcVersionMismatch(Exception):
Expand Down
5 changes: 2 additions & 3 deletions pyquil/api/_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################
import threading
from contextlib import contextmanager
from typing import Dict, Optional, Iterator
import asyncio
Expand Down Expand Up @@ -107,11 +106,11 @@ def native_quil_to_executable(self, nq_program: Program) -> QuantumExecutable:
# the event loop is available. Wrapping it in a Python async function ensures that
# the event loop is available. This is a limitation of pyo3:
# https://pyo3.rs/v0.17.1/ecosystem/async-await.html#a-note-about-asynciorun
async def _translate(*args):
async def _translate(*args): # type: ignore
return await qcs_sdk.translate(*args)

translated_program = self._event_loop.run_until_complete(
_translate(
_translate( # type: ignore
rewrite_response["program"],
nq_program.num_shots,
self.quantum_processor_id,
Expand Down
123 changes: 0 additions & 123 deletions pyquil/api/_engagement_manager.py

This file was deleted.

33 changes: 13 additions & 20 deletions pyquil/api/_qpu.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,9 @@
from qcs_api_client.client import QCSClientConfiguration
from rpcq.messages import ParameterSpec

from pyquil.api import QuantumExecutable, EncryptedProgram, EngagementManager
from pyquil.api import QuantumExecutable, EncryptedProgram

from pyquil.api._qam import QAM, QAMExecutionResult
from pyquil.api._qpu_client import QPUClient, BufferResponse
from pyquil.quilatom import (
MemoryReference,
)
Expand All @@ -40,10 +39,10 @@ def decode_buffer(buffer: "qcs_sdk.ExecutionResult") -> np.ndarray:
:return: NumPy array of decoded data
"""
if buffer["dtype"] == "complex":
buffer["data"] = [complex(re, im) for re, im in buffer["data"]] # type: ignore
buffer["dtype"] = np.complex64 # type: ignore
buffer["data"] = [complex(re, im) for re, im in buffer["data"]]
buffer["dtype"] = np.complex64
elif buffer["dtype"] == "integer":
buffer["dtype"] = np.int32 # type: ignore
buffer["dtype"] = np.int32
return np.array(buffer["data"], dtype=buffer["dtype"])


Expand Down Expand Up @@ -114,7 +113,6 @@ def __init__(
priority: int = 1,
timeout: float = 10.0,
client_configuration: Optional[QCSClientConfiguration] = None,
engagement_manager: Optional[EngagementManager] = None,
jselig-rigetti marked this conversation as resolved.
Show resolved Hide resolved
endpoint_id: Optional[str] = None,
event_loop: Optional[asyncio.AbstractEventLoop] = None,
use_gateway: bool = True,
Expand All @@ -127,24 +125,18 @@ def __init__(
correspond to higher priority.
:param timeout: Time limit for requests, in seconds.
:param client_configuration: Optional client configuration. If none is provided, a default one will be loaded.
:param endpoint_id: Optional endpoint ID to be used for engagement.
:param engagement_manager: Optional engagement manager. If none is provided, a default one will be created.
:param endpoint_id: Optional endpoint ID to be used for execution.
:param use_gateway: Disable to skip the Gateway server and perform direct execution.
"""
super().__init__()

self.priority = priority

client_configuration = client_configuration or QCSClientConfiguration.load()
engagement_manager = engagement_manager or EngagementManager(client_configuration=client_configuration)
self._qpu_client = QPUClient(
quantum_processor_id=quantum_processor_id,
endpoint_id=endpoint_id,
engagement_manager=engagement_manager,
request_timeout=timeout,
)
self._last_results: Dict[str, np.ndarray] = {}
self._memory_results: Dict[str, Optional[np.ndarray]] = defaultdict(lambda: None)
self._quantum_processor_id = quantum_processor_id
self._endpoint_id = endpoint_id

if event_loop is None:
event_loop = asyncio.get_event_loop()
Expand All @@ -154,7 +146,7 @@ def __init__(
@property
def quantum_processor_id(self) -> str:
"""ID of quantum processor targeted."""
return self._qpu_client.quantum_processor_id
return self._quantum_processor_id

def execute(self, executable: QuantumExecutable) -> QPUExecuteResponse:
"""
Expand All @@ -172,8 +164,9 @@ def execute(self, executable: QuantumExecutable) -> QPUExecuteResponse:
executable.ro_sources is not None
), "To run on a QPU, a program must include ``MEASURE``, ``CAPTURE``, and/or ``RAW-CAPTURE`` instructions"

# executable._memory.values is a dict of ParameterARef -> numbers, where ParameterARef is data class w/ name and index
# ParamterARef == Parameter on the Rust side
# executable._memory.values is a dict of ParameterARef -> numbers,
# where ParameterARef is data class w/ name and index
# ParameterARef == Parameter on the Rust side
mem_values = defaultdict(list)
for k, v in executable._memory.values.items():
mem_values[k.name].append(v)
Expand All @@ -193,11 +186,11 @@ def get_result(self, execute_response: QPUExecuteResponse) -> QAMExecutionResult
Retrieve results from execution on the QPU.
"""

async def _get_result(*args):
async def _get_result(*args): # type: ignore
return await qcs_sdk.retrieve_results(*args)

results = self._event_loop.run_until_complete(
_get_result(execute_response.job_id, self.quantum_processor_id, self._use_gateway)
_get_result(execute_response.job_id, self.quantum_processor_id, self._use_gateway) # type: ignore
)

ro_sources = execute_response._executable.ro_sources
Expand Down
Loading