Perceval Adapter API Reference
Adapter layer isolating Merlin from Perceval internal APIs (PML-306).
MerlinProcessor and the execution units historically reached directly into
Perceval internals: RPC handler token/URL attributes, sampler command objects
(probs / sample_count / samples), remote job status fields, local
experiment private state, and RemoteConfig. Any Perceval version bump that
renames or restructures those internals could silently break Merlin at runtime.
PercevalAdapter owns every such access. The rest of Merlin talks to
this facade, so a Perceval API change is localized to this module.
The adapter is stateless (static methods) and duck-typed: it reads the same attributes Perceval exposes today, which also makes it independently testable with plain fakes.
- class merlin.core.perceval_adapter.PercevalAdapter
Bases:
objectStateless facade owning all direct Perceval-internal access.
- static build_from_session(session)
Build a fresh RemoteProcessor from a Perceval session.
- Parameters:
session (perceval.runtime.session.ISession) – Provider session (e.g. Scaleway) able to build processors.
- Returns:
Independent processor with its own handler state.
- Return type:
perceval.runtime.RemoteProcessor
- static cancel_job(job)
Request best-effort cancellation of a job, swallowing errors.
- Parameters:
job (perceval.runtime.RemoteJob) – Job to cancel. Objects without a callable
cancelare ignored; cancellation errors are suppressed by design (best-effort path).- Return type:
- static clone_remote_processor(rp, token)
Create a sibling RemoteProcessor with its own RPC handler.
Forwards the provided token so that inline-token RemoteProcessors are cloned correctly.
- Parameters:
rp (perceval.runtime.RemoteProcessor) – Processor whose platform name, URL, and proxies are copied.
token (str | None) – Authentication token forwarded to the clone.
- Returns:
Independent processor targeting the same platform.
- Return type:
perceval.runtime.RemoteProcessor
- static configure_processor(processor, circuit, input_state)
Set the circuit and, when provided, the input state and photon filter.
- Parameters:
processor (AProcessor) – Processor (local or remote) to configure.
circuit (pcvl.ACircuit) – Circuit to install.
input_state (Any) – Sequence of photon counts per mode, or falsy to skip input setup. When set,
min_detected_photons_filteris set to the total photon count.
- Return type:
- static copy_circuit(circuit)
Return an independent copy of a circuit for one execution.
- Parameters:
circuit (pcvl.ACircuit) – Circuit exported by the quantum layer.
- Returns:
Independent circuit object used by a single backend execution.
- Return type:
pcvl.ACircuit
- static create_sampler(processor, max_shots_per_call, iterations)
Create a Sampler on
processorloaded with the given iterations.- Parameters:
- Returns:
Sampler ready for command dispatch.
- Return type:
perceval.algorithm.Sampler
- static ensure_serializable_sampler_iterator(job, sampler)
Replace Perceval 1.2 iterator objects with JSON-serializable data.
- Parameters:
job (perceval.runtime.RemoteJob) – Prepared job whose private request payload may hold an iterator.
sampler (perceval.algorithm.Sampler) – Sampler used to prepare the job.
- Return type:
Notes
Perceval 1.1 stores sampler iterations as a plain list. Perceval 1.2 stores them in a
ParameterIteratorobject, but the Scaleway session handler still serializespayload["payload"]withjson.dumps. Until Perceval exposes a public serializer for that object, Merlin normalizes the remote-job payload back to the list shape accepted by the cloud side.
- static estimate_required_shots(rp, desired_samples, param_values)
Ask the remote platform estimator for the required shot count.
- Parameters:
- Returns:
Estimated shots, or
Nonewhen the platform gives no answer.- Return type:
int | None
- static execute_sync(sampler, command, max_samples=None)
Execute a sampler command synchronously and return the raw results.
- Parameters:
- Returns:
Raw Perceval results object for the executed command.
- Return type:
Any
- static extract_token(rp)
Extract the auth token from a RemoteProcessor.
Perceval stores the token on the RPC handler as
handler.tokenand also embeds it inhandler.headers['Authorization']. We probe both locations so that inline-token and global-configRemoteProcessorinstances are both handled.As a last resort, falls back to
RemoteConfig().get_token().- Parameters:
rp (perceval.runtime.RemoteProcessor) – Remote processor to probe for authentication material.
- Returns:
The resolved token, or
Noneif every strategy fails.- Return type:
str | None
Notes
get_rpc_handler()is wrapped defensively here — unlike inget_url()— precisely because this method has a downstream fallback: if the handler is unavailable it can still resolve a token from the globalRemoteConfig. Swallowing the handler error is therefore part of the control flow, not error hiding; a genuinely unresolvable token surfaces asNone(which the caller turns into aTokenExtractionError).
- static get_backend_capabilities(processor)
Return the backend platform name and available command snapshot.
- static get_results(job)
Retrieve a job’s raw results, propagating Perceval errors.
- Parameters:
job (perceval.runtime.RemoteJob) – Completed job to read.
- Returns:
Raw Perceval results object.
- Return type:
Any
- Raises:
RuntimeError – Propagated unchanged from Perceval (e.g. results not yet available, cancel requested); the polling loop interprets it.
- static get_url(rp)
Return the RPC handler URL of a RemoteProcessor, if exposed.
- Parameters:
rp (perceval.runtime.RemoteProcessor) – Remote processor whose RPC handler is inspected.
- Returns:
The handler URL, or
Nonewhen the handler has nourlattribute.- Return type:
str | None
Notes
get_rpc_handler()is intentionally left unguarded here — unlike inextract_token()— because this method has no fallback. A broken handler should fail fast at the real fault rather than yieldurl=Noneand a silently misconfigured clone downstream inclone_remote_processor().
- static job_snapshot(job)
Read a job’s status fields into a Merlin-normalized snapshot.
- Parameters:
job (perceval.runtime.RemoteJob) – Job to inspect. Missing attributes map to
None/False.- Returns:
Immutable view of the job’s id, state, and completion flags.
- Return type:
- static rebuild_local_processor(processor)
Create an isolated local Perceval processor for one execution.
Returns the fresh processor together with the
LocalExperimentSnapshotthe caller must apply (viarestore_experiment()) after installing the execution circuit. The snapshot is an explicit return value rather than hidden state on the processor, so a caller cannot silently forget to restore it.- Parameters:
processor (perceval.runtime.AProcessor) – Local processor whose experiment and backend are copied.
- Returns:
A fresh local processor (copied non-circuit experiment state and a fresh backend instance) and the experiment snapshot to restore once the execution circuit is installed.
- Return type:
tuple[perceval.runtime.AProcessor, LocalExperimentSnapshot]
- Raises:
TypeError – If the configured local processor cannot be reconstructed safely.
- static restore_experiment(experiment, snapshot)
Restore local experiment metadata after the execution circuit is set.
- Parameters:
experiment (Any) – Perceval experiment owned by the fresh local execution processor.
snapshot (LocalExperimentSnapshot) – Metadata copied from the caller’s local processor.
- Raises:
ValueError – If mode-indexed metadata cannot be applied to the execution circuit because the circuit sizes differ.
- Return type:
- static set_circuit(processor, circuit)
Install a circuit on a processor without touching its input state.
Split out from
configure_processor()so the local execution path can install the circuit, restore experiment metadata, and only then set the input — instead of passing aNoneinput-state sentinel.- Parameters:
processor (perceval.runtime.AProcessor) – Processor (local or remote) to configure.
circuit (pcvl.ACircuit) – Circuit to install.
- Return type:
- static set_input(processor, input_state)
Set the input state and matching photon filter, if provided.
Split out from
configure_processor()because the local execution path must restore experiment metadata between installing the circuit and setting the input.- Parameters:
processor (perceval.runtime.AProcessor) – Processor to receive the input state.
input_state (Any) – Sequence of photon counts per mode, or falsy to skip input setup.
- Return type:
- static snapshot_experiment(experiment)
Copy non-circuit local experiment metadata before Perceval clears it.
- Parameters:
experiment (Any) – Perceval experiment owned by the caller’s local processor.
- Returns:
Deep-copied metadata that is independent from the caller’s processor.
- Return type:
- static submit_async(sampler, command, name=None, max_samples=None)
Submit a sampler command asynchronously and return the job handle.
- Parameters:
sampler (Sampler) – Sampler prepared with circuit and iterations.
command (str) – Sampler command to dispatch:
"probs","sample_count", or"samples".name (str | None) – Remote job name to assign before submission, if any.
max_samples (int | None) – Shots to request.
Nonesubmits without a shot argument (exact probabilities).
- Returns:
Handle of the submitted asynchronous job.
- Return type:
perceval.runtime.RemoteJob
- class merlin.core.perceval_adapter.JobStatusSnapshot(job_id, state, progress, stop_message, is_complete, is_failed)
Bases:
objectMerlin-normalized view of a Perceval remote job’s status.
All
getattrguards against Perceval job internals live inPercevalAdapter.job_snapshot(); consumers only see these fields.
- class merlin.core.perceval_adapter.LocalExperimentSnapshot(circuit_size, in_ports, out_ports, detectors, detectors_injected, in_mode_type, out_mode_type, anon_herald_num, postselection)
Bases:
objectExperiment-level state that must survive local circuit replacement.
Captures the Perceval experiment private state (ports, detectors, mode types, heralds, postselection) that
clear_input_and_circuit()wipes.
- class merlin.core.perceval_adapter.TokenExtractionError
Bases:
ValueErrorSignals that no auth token could be resolved for a RemoteProcessor.
Raised by callers of
PercevalAdapter.extract_token()when it returnsNone(seeMerlinProcessor.__init__).extract_tokenitself returnsNonerather than raising, so its multi-strategy fallback (handler token, Bearer header, globalRemoteConfig) can run to completion before the caller decides the token is genuinely unresolvable.Subclasses
ValueErrorso existing callers catching the historical exception type keep working.
- class merlin.core.perceval_adapter.RemoteJobFailedError
Bases:
RuntimeErrorRaised when a remote Perceval job reports failure.
Subclasses
RuntimeErrorso existing callers catching the historical exception type keep working.