-
Notifications
You must be signed in to change notification settings - Fork 2
Allow setting qpu mode in device #92
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
base: main
Are you sure you want to change the base?
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,6 +22,9 @@ class Device(Generic[FutureType], AuthMixin): | |
| that can be dry-run or submitted asynchronously. | ||
|
|
||
| Attributes: | ||
| qpu_mode (str | None): Explicit qlam QPU mode used by tasks created | ||
| from this device. When None, qlam-core resolves it from | ||
| configuration. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This also opens the possibility of using (Note: I am assuming that the API base URL will be different for each QPU, and that this is purely to configure the QPU mode)
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure this will error. The |
||
| future_cls (type[FutureType]): Future class used by tasks created from | ||
| this device. Defaults to `Future`. | ||
| kernel_serializer (KernelSerializer): Default serializer passed to | ||
|
|
@@ -94,6 +97,7 @@ def task( | |
|
|
||
| return self.single_kernel_task_cls( | ||
| context_name=self.context_name, | ||
| qpu_mode=self.qpu_mode, | ||
| kernel=kernel, | ||
| num_shots=num_shots, | ||
| arguments=arguments, | ||
|
|
@@ -139,6 +143,7 @@ def batch_task( | |
|
|
||
| return self.kernel_batch_task_cls( | ||
| context_name=self.context_name, | ||
| qpu_mode=self.qpu_mode, | ||
| kernels=kernels, | ||
| arguments=arguments, | ||
| num_shots=num_shots, | ||
|
|
@@ -183,6 +188,7 @@ def parameter_scan( | |
|
|
||
| return self.parameter_scan_task_cls( | ||
| context_name=self.context_name, | ||
| qpu_mode=self.qpu_mode, | ||
| kernel=kernel, | ||
| num_shots=num_shots, | ||
| arguments=arguments, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,6 +57,8 @@ class Future(AuthMixin, Generic[ResultType]): | |
| and construct result views over that storage using ``result_cls``. | ||
|
|
||
| Attributes: | ||
| qpu_mode (str | None): Explicit qlam QPU mode used for backend API | ||
| calls. When None, qlam-core resolves it from configuration. | ||
|
jasonhan3 marked this conversation as resolved.
|
||
| task_id (str): Backend task ID. | ||
| storage (StorageBackend): Storage backend used for fetched shots and | ||
| task metadata. Defaults to a fresh `DictStorage` (in-memory; not | ||
|
|
@@ -95,7 +97,10 @@ def get_task(self) -> "Task": | |
| # NOTE: typing issue in qlam-core | ||
| # every client is BaseRestApi, which doesn't have get, but it actually does | ||
| task = self.call_with_auth_refresh( | ||
| lambda: client.get(id=self.task_id) # type: ignore | ||
| lambda: client.get( # type: ignore | ||
| qpu_mode=self.qpu_mode, | ||
| id=self.task_id, | ||
| ) | ||
| ) | ||
| logger.info( | ||
| f"Fetched task with id {self.task_id}. Current status: {task.task_status}" | ||
|
|
@@ -120,7 +125,10 @@ def get_compilation(self, compilation_id: str | None = None): | |
|
|
||
| with CompilationsClient(self.app_context) as client: | ||
| return self.call_with_auth_refresh( | ||
| lambda: client.get(id=compilation_id) # type: ignore | ||
| lambda: client.get( # type: ignore | ||
| qpu_mode=self.qpu_mode, | ||
| id=compilation_id, | ||
| ) | ||
| ) | ||
|
|
||
| def fetch(self) -> None: | ||
|
|
@@ -176,7 +184,10 @@ def cancel(self): | |
| try: | ||
| # NOTE: typing issue because client is seen as BaseClient instead of TaskClient | ||
| return self.call_with_auth_refresh( | ||
| lambda: client.cancel(id=self.task_id) # type: ignore | ||
| lambda: client.cancel( # type: ignore | ||
| qpu_mode=self.qpu_mode, | ||
| id=self.task_id, | ||
| ) | ||
| ) | ||
| except Exception as e: | ||
| warn( | ||
|
|
@@ -327,6 +338,7 @@ def from_storage( | |
| task_id: str | None = None, | ||
| fetch_options: ApiFetchOptions = ApiFetchOptions(), | ||
| context_name: str | None = None, | ||
| qpu_mode: str | None = None, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We would want to override the
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I admit this is a little odd, but this is genuinely about overriding this setting. However, |
||
| ) -> Self: | ||
| """Create a future from task metadata already present in storage. | ||
|
|
||
|
|
@@ -343,6 +355,9 @@ def from_storage( | |
| context_name (str | None): Name of the qlam context to attach to | ||
| the returned future. When None, the class-level default on | ||
| `cls` is used. Defaults to None. | ||
| qpu_mode (str | None): Explicit qlam QPU mode to attach to the | ||
| returned future. When None, qlam-core resolves it from | ||
| configuration. Defaults to None. | ||
|
|
||
| Returns: | ||
| Self: A future attached to the selected task ID. | ||
|
|
@@ -382,6 +397,7 @@ def from_storage( | |
| fetch_options=fetch_options, | ||
| result_cls=cls.result_cls, | ||
| context_name=context_name, | ||
| qpu_mode=qpu_mode, | ||
| ) | ||
|
|
||
| @classmethod | ||
|
|
@@ -392,6 +408,7 @@ def from_task_id( | |
| storage: StorageBackend | None = None, | ||
| fetch_options: ApiFetchOptions = ApiFetchOptions(), | ||
| context_name: str | None = None, | ||
| qpu_mode: str | None = None, | ||
|
jasonhan3 marked this conversation as resolved.
|
||
| ) -> Self: | ||
| """Create a future from a backend task ID. | ||
|
|
||
|
|
@@ -410,6 +427,9 @@ def from_task_id( | |
| context_name (str | None): Name of the qlam context used to fetch | ||
| the task and attached to the returned future. When None, the | ||
| class-level default on `cls` is used. Defaults to None. | ||
| qpu_mode (str | None): Explicit qlam QPU mode used to fetch the | ||
| task and attached to the returned future. When None, qlam-core | ||
| resolves it from configuration. Defaults to None. | ||
|
|
||
| Returns: | ||
| Self: A future attached to `task_id`. | ||
|
|
@@ -422,17 +442,23 @@ def from_task_id( | |
| storage = DictStorage() | ||
|
|
||
| context_name = cls._resolve_context_name(context_name) | ||
| auth = AuthMixin(context_name=context_name) | ||
| auth = AuthMixin(context_name=context_name, qpu_mode=qpu_mode) | ||
| auth.authenticate() | ||
| with TasksClient(auth.app_context) as client: | ||
| task = auth.call_with_auth_refresh( | ||
| lambda: client.get(id=task_id) # type: ignore | ||
| lambda: client.get( # type: ignore | ||
| qpu_mode=qpu_mode, | ||
| id=task_id, | ||
| ) | ||
| ) | ||
|
|
||
| # fetch subtasks for metadata | ||
| with DefinitionsClient(auth.app_context) as client: | ||
| task_def = auth.call_with_auth_refresh( | ||
| lambda: client.get(id=task.definition_id) # type: ignore | ||
| lambda: client.get( # type: ignore | ||
| qpu_mode=qpu_mode, | ||
| id=task.definition_id, | ||
| ) | ||
| ) | ||
|
|
||
| storage.add_task_definition( | ||
|
|
@@ -445,6 +471,7 @@ def from_task_id( | |
| fetch_options=fetch_options, | ||
| result_cls=cls.result_cls, | ||
| context_name=context_name, | ||
| qpu_mode=qpu_mode, | ||
| ) | ||
|
|
||
| def _wait_for_completion(self, timeout: float | None = None) -> TaskStatus: | ||
|
|
@@ -513,6 +540,7 @@ def _fetch_subtask_page( | |
|
|
||
| while full_shots_page: | ||
| response = client.get( | ||
| qpu_mode=self.qpu_mode, | ||
| id=self.task_id, | ||
| page=subtask_page, | ||
| size=self.fetch_options.subtasks_per_fetch, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of passing a single qpu_mode in here, would it make sense to pass the full ConfigMixin for future proofing passing config around?