-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Refactor get sampler #7672
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?
Refactor get sampler #7672
Changes from all commits
d2d1b3b
5494ef7
396438a
fcf006d
36fc45d
a7eec34
2a7cf4a
95e1046
74ac05a
158c77b
c0fe0ad
3c019ac
22d9832
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 |
---|---|---|
|
@@ -590,15 +590,14 @@ def get_processor(self, processor_id: str) -> engine_processor.EngineProcessor: | |
""" | ||
return engine_processor.EngineProcessor(self.project_id, processor_id, self.context) | ||
|
||
def get_sampler( | ||
def get_sampler_from_run_name( | ||
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. The methods in The style guide suggests that defaults are useful to avoid "lots of functions for the rare exceptions", and @eliottrosenberg made it sound like these specialized versions are exceptional. Would it suffice to just check for mutual exclusivity of the arguments and raise an exception if that's violated? Alternatively, if you find it important to bake this check into the interface, you could alternatively do it with the type system, e.g.:
WDYT? 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. @hoisinberg and I were discussing this exact pattern. Yes this is better I think. |
||
self, | ||
processor_id: str | list[str], | ||
run_name: str = "", | ||
device_config_name: str = "", | ||
snapshot_id: str = "", | ||
processor_id: str, | ||
run_name: str, | ||
device_config_name: str | None = None, | ||
max_concurrent_jobs: int = 100, | ||
) -> cirq_google.ProcessorSampler: | ||
"""Returns a sampler backed by the engine. | ||
"""Returns a sampler backed by the engine and given `run_name`. | ||
|
||
Args: | ||
processor_id: String identifier of which processor should be used to sample. | ||
|
@@ -608,8 +607,67 @@ def get_sampler( | |
device_config_name: An identifier used to select the processor configuration | ||
utilized to run the job. A configuration identifies the set of | ||
available qubits, couplers, and supported gates in the processor. | ||
snapshot_id: A unique identifier for an immutable snapshot reference. A | ||
snapshot contains a collection of device configurations for the processor. | ||
max_concurrent_jobs: The maximum number of jobs to be sent | ||
simultaneously to the Engine. This client-side throttle can be | ||
used to proactively reduce load to the backends and avoid quota | ||
violations when pipelining circuit executions. | ||
|
||
Returns: | ||
A `cirq.Sampler` instance (specifically a `engine_sampler.ProcessorSampler` | ||
that will send circuits to the Quantum Computing Service | ||
when sampled. | ||
""" | ||
return self.get_processor(processor_id).get_sampler_from_run_name( | ||
run_name=run_name, | ||
device_config_name=device_config_name, | ||
max_concurrent_jobs=max_concurrent_jobs, | ||
) | ||
|
||
def get_sampler_from_snapshot_id( | ||
self, | ||
processor_id: str, | ||
snapshot_id: str, | ||
device_config_name: str | None, | ||
max_concurrent_jobs: int = 100, | ||
) -> cirq_google.ProcessorSampler: | ||
"""Returns a sampler backed by the engine. | ||
Args: | ||
processor_id: String identifier of which processor should be used to sample. | ||
device_config_name: An identifier used to select the processor configuration | ||
utilized to run the job. A configuration identifies the set of | ||
available qubits, couplers, and supported gates in the processor. | ||
snapshot_id: A unique identifier for an immutable snapshot reference. | ||
A snapshot contains a collection of device configurations for the | ||
processor. | ||
max_concurrent_jobs: The maximum number of jobs to be sent | ||
simultaneously to the Engine. This client-side throttle can be | ||
used to proactively reduce load to the backends and avoid quota | ||
violations when pipelining circuit executions. | ||
|
||
Returns: | ||
A `cirq.Sampler` instance (specifically a `engine_sampler.ProcessorSampler` | ||
that will send circuits to the Quantum Computing Service | ||
when sampled. | ||
""" | ||
return self.get_processor(processor_id).get_sampler_from_snapshot_id( | ||
snapshot_id=snapshot_id, | ||
device_config_name=device_config_name, | ||
max_concurrent_jobs=max_concurrent_jobs, | ||
) | ||
|
||
def get_sampler( | ||
self, | ||
processor_id: str | list[str], | ||
device_config_name: str | None = None, | ||
max_concurrent_jobs: int = 100, | ||
) -> cirq_google.ProcessorSampler: | ||
"""Returns a sampler backed by the engine. | ||
|
||
Args: | ||
processor_id: String identifier of which processor should be used to sample. | ||
device_config_name: An identifier used to select the processor configuration | ||
utilized to run the job. A configuration identifies the set of | ||
available qubits, couplers, and supported gates in the processor. | ||
max_concurrent_jobs: The maximum number of jobs to be sent | ||
concurrently to the Engine. This client-side throttle can be | ||
used to proactively reduce load to the backends and avoid quota | ||
|
@@ -629,11 +687,9 @@ def get_sampler( | |
'to get_sampler() no longer supported. Use Engine.run() instead if ' | ||
'you need to specify a list.' | ||
) | ||
|
||
return self.get_processor(processor_id).get_sampler( | ||
run_name=run_name, | ||
device_config_name=device_config_name, | ||
snapshot_id=snapshot_id, | ||
max_concurrent_jobs=max_concurrent_jobs, | ||
device_config_name=device_config_name, max_concurrent_jobs=max_concurrent_jobs | ||
) | ||
|
||
async def get_processor_config_from_snapshot_async( | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -99,18 +99,48 @@ def engine(self) -> engine_base.Engine: | |
|
||
return engine_base.Engine(self.project_id, context=self.context) | ||
|
||
def get_sampler( | ||
self, | ||
run_name: str = "", | ||
device_config_name: str = "", | ||
snapshot_id: str = "", | ||
max_concurrent_jobs: int = 100, | ||
def get_sampler_from_run_name( | ||
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. Could this be simplified by adding a
This or something like it should probably the the canonical form of retrieval because a sampler should always refer to a fully-qualified config even if the user used defaults to construct it. 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 like Will's suggestion. |
||
self, run_name: str, device_config_name: str | None = None, max_concurrent_jobs: int = 100 | ||
) -> cg.engine.ProcessorSampler: | ||
"""Returns a sampler backed by the engine. | ||
"""Returns a sampler backed by the engine and given `run_name`. | ||
|
||
Args: | ||
run_name: A unique identifier representing an automation run for the | ||
processor. An Automation Run contains a collection of device | ||
configurations for the processor. | ||
device_config_name: An identifier used to select the processor configuration | ||
utilized to run the job. A configuration identifies the set of | ||
available qubits, couplers, and supported gates in the processor. | ||
max_concurrent_jobs: The maximum number of jobs to be sent | ||
simultaneously to the Engine. This client-side throttle can be | ||
used to proactively reduce load to the backends and avoid quota | ||
violations when pipelining circuit executions. | ||
|
||
Returns: | ||
A `cirq.Sampler` instance (specifically a `engine_sampler.ProcessorSampler` | ||
that will send circuits to the Quantum Computing Service | ||
when sampled. | ||
""" | ||
processor = self._inner_processor() | ||
return processor_sampler.ProcessorSampler( | ||
processor=self, | ||
run_name=run_name, | ||
device_config_name=( | ||
device_config_name | ||
if device_config_name | ||
else processor.default_device_config_key.config_alias | ||
), | ||
max_concurrent_jobs=max_concurrent_jobs, | ||
) | ||
|
||
def get_sampler_from_snapshot_id( | ||
self, | ||
snapshot_id: str, | ||
device_config_name: str | None = None, | ||
max_concurrent_jobs: int = 100, | ||
) -> cg.engine.ProcessorSampler: | ||
"""Returns a sampler backed by the engine. | ||
Args: | ||
device_config_name: An identifier used to select the processor configuration | ||
utilized to run the job. A configuration identifies the set of | ||
available qubits, couplers, and supported gates in the processor. | ||
|
@@ -126,29 +156,50 @@ def get_sampler( | |
A `cirq.Sampler` instance (specifically a `engine_sampler.ProcessorSampler` | ||
that will send circuits to the Quantum Computing Service | ||
when sampled. | ||
""" | ||
processor = self._inner_processor() | ||
return processor_sampler.ProcessorSampler( | ||
processor=self, | ||
snapshot_id=snapshot_id, | ||
device_config_name=( | ||
device_config_name | ||
if device_config_name | ||
else processor.default_device_config_key.config_alias | ||
), | ||
max_concurrent_jobs=max_concurrent_jobs, | ||
) | ||
|
||
Raises: | ||
ValueError: If only one of `run_name` and `device_config_name` are specified. | ||
ValueError: If both `run_name` and `snapshot_id` are specified. | ||
def get_sampler( | ||
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. Following on from the above comment regarding the requirement of a device config to build a sampler, should we remove 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 agree with Will about removing the |
||
self, device_config_name: str | None = None, max_concurrent_jobs: int = 100 | ||
) -> cg.engine.ProcessorSampler: | ||
"""Returns the default sampler backed by the engine. | ||
|
||
Args: | ||
device_config_name: An identifier used to select the processor configuration | ||
utilized to run the job. A configuration identifies the set of | ||
available qubits, couplers, and supported gates in the processor. | ||
max_concurrent_jobs: The maximum number of jobs to be sent | ||
simultaneously to the Engine. This client-side throttle can be | ||
used to proactively reduce load to the backends and avoid quota | ||
violations when pipelining circuit executions. | ||
|
||
Returns: | ||
A `cirq.Sampler` instance (specifically a `engine_sampler.ProcessorSampler` | ||
that will send circuits to the Quantum Computing Service | ||
when sampled. | ||
|
||
""" | ||
processor = self._inner_processor() | ||
if run_name and snapshot_id: | ||
raise ValueError('Cannot specify both `run_name` and `snapshot_id`') | ||
if (bool(run_name) or bool(snapshot_id)) ^ bool(device_config_name): | ||
raise ValueError( | ||
'Cannot specify only one of top level identifier and `device_config_name`' | ||
) | ||
# If not provided, initialize the sampler with the Processor's default values. | ||
if not run_name and not device_config_name and not snapshot_id: | ||
run_name = processor.default_device_config_key.run | ||
device_config_name = processor.default_device_config_key.config_alias | ||
snapshot_id = processor.default_device_config_key.snapshot_id | ||
|
||
return processor_sampler.ProcessorSampler( | ||
processor=self, | ||
run_name=run_name, | ||
snapshot_id=snapshot_id, | ||
device_config_name=device_config_name, | ||
run_name=processor.default_device_config_key.run, | ||
snapshot_id=processor.default_device_config_key.snapshot_id, | ||
device_config_name=( | ||
device_config_name | ||
if device_config_name | ||
else processor.default_device_config_key.config_alias | ||
), | ||
max_concurrent_jobs=max_concurrent_jobs, | ||
) | ||
|
||
|
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.
This removes what I would expect to be the most common use case: specify only a device config name, but not the version (run or snapshot).
@eliottrosenberg - do we really want to support a default config name ("config alias") at all? While defaults make sense to get the "latest" version, a default grid seem more risky and I think are worth forcing explicit selection.