Serialization
Serialization
SerializationModel(d=dict())
dataclass
A serialization model class to serialize data from QuantumModel
s,.
torch.nn.Module
and similar structures. The data included in the
serialization logic includes: the AbstractBlock
and its children
classes, QuantumCircuit
, Register
, and sympy
expressions
(including Parameter
class from qadence.parameters
).
A children class must define the value
attribute type and how to
handle it, since it is the main property for the class to be used
by the serialization process. For instance:
@dataclass
class QuantumCircuitSerialization(SerializationModel):
value: QuantumCircuit = dataclass_field(init=False)
def __post_init__(self) -> None:
self.value = (
QuantumCircuit._from_dict(self.d)
if isinstance(self.d, dict)
else self.d
)
deserialize(d, as_torch=False)
Supported Types:
AbstractBlock | QuantumCircuit | QuantumModel | Register | torch.nn.Module Deserializes a dict to one of the supported types.
PARAMETER | DESCRIPTION |
---|---|
d |
A dict containing a serialized object.
TYPE:
|
as_torch |
Whether to transform to torch for the deserialized object.
TYPE:
|
Returns: AbstractBlock, QuantumCircuit, QuantumModel, Register, torch.nn.Module.
Examples:
import torch
from qadence import serialize, deserialize, hea, hamiltonian_factory, Z
from qadence import QuantumCircuit, QuantumModel
n_qubits = 2
myblock = hea(n_qubits=n_qubits, depth=1)
block_dict = serialize(myblock)
print(block_dict)
## Lets use myblock in a QuantumCircuit and serialize it.
qc = QuantumCircuit(n_qubits, myblock)
qc_dict = serialize(qc)
qc_deserialized = deserialize(qc_dict)
assert qc == qc_deserialized
## Finally, let's wrap it in a QuantumModel
obs = hamiltonian_factory(n_qubits, detuning = Z)
qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
qm_dict = serialize(qm)
qm_deserialized = deserialize(qm_dict)
# Lets check if the loaded QuantumModel returns the same expectation
assert torch.isclose(qm.expectation({}), qm_deserialized.expectation({}))
{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': 'HEA', 'blocks': [{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('de662a19-8e32-4cc5-9ca0-09c9fb2ca89a', {'name': 'theta_0', 'expression': "Parameter('theta_0')", 'symbols': {'theta_0': {'name': 'theta_0', 'trainable': 'True', 'value': '0.620736061095401'}}})}}, 'noise': None}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('af21d875-e2e5-4054-9efc-f646218915dd', {'name': 'theta_1', 'expression': "Parameter('theta_1')", 'symbols': {'theta_1': {'name': 'theta_1', 'trainable': 'True', 'value': '0.04291442556341951'}}})}}, 'noise': None}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RY', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('825f1064-3552-4ebb-8694-24ab18857862', {'name': 'theta_2', 'expression': "Parameter('theta_2')", 'symbols': {'theta_2': {'name': 'theta_2', 'trainable': 'True', 'value': '0.7220381976961204'}}})}}, 'noise': None}, {'type': 'RY', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('5f9ac13f-1a46-4c82-a645-6db1d51b6d85', {'name': 'theta_3', 'expression': "Parameter('theta_3')", 'symbols': {'theta_3': {'name': 'theta_3', 'trainable': 'True', 'value': '0.5784008616264743'}}})}}, 'noise': None}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('ad6e508b-9161-4049-a7de-2cf363517493', {'name': 'theta_4', 'expression': "Parameter('theta_4')", 'symbols': {'theta_4': {'name': 'theta_4', 'trainable': 'True', 'value': '0.5955369557850538'}}})}}, 'noise': None}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('7c60129a-1907-4e26-a89d-adf228d27e72', {'name': 'theta_5', 'expression': "Parameter('theta_5')", 'symbols': {'theta_5': {'name': 'theta_5', 'trainable': 'True', 'value': '0.7862519072367645'}}})}}, 'noise': None}]}]}, {'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'CNOT', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'X', 'qubit_support': (1,), 'tag': None, 'noise': None}], 'noise': None}]}]}]}
Source code in qadence/serialization.py
load(file_path, map_location='cpu')
Same as serialize/deserialize but for storing/loading files.
Supported types: AbstractBlock | QuantumCircuit | QuantumModel | Register Loads a .json or .pt file to one of the supported types.
PARAMETER | DESCRIPTION |
---|---|
file_path |
The name of the file.
TYPE:
|
map_location |
In case of a .pt file, on which device to load the object (cpu,cuda).
TYPE:
|
Returns: A object of type AbstractBlock, QuantumCircuit, QuantumModel, Register.
Examples:
import torch
from pathlib import Path
import os
from qadence import save, load, hea, hamiltonian_factory, Z
from qadence import QuantumCircuit, QuantumModel
n_qubits = 2
myblock = hea(n_qubits=n_qubits, depth=1)
qc = QuantumCircuit(n_qubits, myblock)
# Lets store the circuit in a json file
save(qc, '.', 'circ')
loaded_qc = load(Path('circ.json'))
qc == loaded_qc
os.remove('circ.json')
## Let's wrap it in a QuantumModel and store that
obs = hamiltonian_factory(n_qubits, detuning = Z)
qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
save(qm, folder= '.',file_name= 'quantum_model')
qm_loaded = load('quantum_model.json')
os.remove('quantum_model.json')
Source code in qadence/serialization.py
parse_expr_fn(code)
A parsing expressions function that checks whether a given code is valid on.
the parsing grammar. The grammar is defined to be compatible with sympy
expressions, such as Float('-0.33261030434342942', precision=53)
, while
avoiding code injection such as 2*3
or __import__('os').system('ls -la')
.
PARAMETER | DESCRIPTION |
---|---|
code |
code to be parsed and checked.
TYPE:
|
RETURNS | DESCRIPTION |
---|---|
|
Boolean indicating whether the code matches the defined grammar or not. |
Source code in qadence/serialization.py
save(obj, folder, file_name='', format=SerializationFormat.JSON)
Same as serialize/deserialize but for storing/loading files.
Supported types: AbstractBlock | QuantumCircuit | QuantumModel | Register | torch.nn.Module Saves a qadence object to a json/.pt.
PARAMETER | DESCRIPTION |
---|---|
obj |
TYPE:
|
file_name |
The name of the file.
TYPE:
|
format |
The type of file to save.
TYPE:
|
Returns: None.
Examples:
import torch
from pathlib import Path
import os
from qadence import save, load, hea, hamiltonian_factory, Z
from qadence import QuantumCircuit, QuantumModel
n_qubits = 2
myblock = hea(n_qubits=n_qubits, depth=1)
qc = QuantumCircuit(n_qubits, myblock)
# Lets store the circuit in a json file
save(qc, '.', 'circ')
loaded_qc = load(Path('circ.json'))
qc == loaded_qc
os.remove('circ.json')
## Let's wrap it in a QuantumModel and store that
obs = hamiltonian_factory(n_qubits, detuning = Z)
qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
save(qm, folder= '.',file_name= 'quantum_model')
qm_loaded = load('quantum_model.json')
os.remove('quantum_model.json')
Source code in qadence/serialization.py
serialize(obj, save_params=False)
Supported Types:
AbstractBlock | QuantumCircuit | QuantumModel | torch.nn.Module | Register | Module Serializes a qadence object to a dictionary.
PARAMETER | DESCRIPTION |
---|---|
obj |
TYPE:
|
Returns: A dict.
Examples:
import torch
from qadence import serialize, deserialize, hea, hamiltonian_factory, Z
from qadence import QuantumCircuit, QuantumModel
n_qubits = 2
myblock = hea(n_qubits=n_qubits, depth=1)
block_dict = serialize(myblock)
print(block_dict)
## Lets use myblock in a QuantumCircuit and serialize it.
qc = QuantumCircuit(n_qubits, myblock)
qc_dict = serialize(qc)
qc_deserialized = deserialize(qc_dict)
assert qc == qc_deserialized
## Finally, let's wrap it in a QuantumModel
obs = hamiltonian_factory(n_qubits, detuning = Z)
qm = QuantumModel(qc, obs, backend='pyqtorch', diff_mode='ad')
qm_dict = serialize(qm)
qm_deserialized = deserialize(qm_dict)
# Lets check if the loaded QuantumModel returns the same expectation
assert torch.isclose(qm.expectation({}), qm_deserialized.expectation({}))
{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': 'HEA', 'blocks': [{'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('8b0351cf-91dc-4c48-ace2-f69f71e5d557', {'name': 'theta_0', 'expression': "Parameter('theta_0')", 'symbols': {'theta_0': {'name': 'theta_0', 'trainable': 'True', 'value': '0.840006113719292'}}})}}, 'noise': None}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('f4af2fd8-e623-48b2-bc7a-1f9da2755724', {'name': 'theta_1', 'expression': "Parameter('theta_1')", 'symbols': {'theta_1': {'name': 'theta_1', 'trainable': 'True', 'value': '0.02233239619773042'}}})}}, 'noise': None}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RY', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('56131368-0f5e-4494-b58c-39fe9569427b', {'name': 'theta_2', 'expression': "Parameter('theta_2')", 'symbols': {'theta_2': {'name': 'theta_2', 'trainable': 'True', 'value': '0.7047195415206462'}}})}}, 'noise': None}, {'type': 'RY', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('e7aeed04-3665-4e4c-b475-36aa8dec0806', {'name': 'theta_3', 'expression': "Parameter('theta_3')", 'symbols': {'theta_3': {'name': 'theta_3', 'trainable': 'True', 'value': '0.8489728940974804'}}})}}, 'noise': None}]}, {'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'RX', 'qubit_support': (0,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('22097ddd-e3cc-44d5-9fa4-eb273184b317', {'name': 'theta_4', 'expression': "Parameter('theta_4')", 'symbols': {'theta_4': {'name': 'theta_4', 'trainable': 'True', 'value': '0.7838260242719712'}}})}}, 'noise': None}, {'type': 'RX', 'qubit_support': (1,), 'tag': None, 'parameters': {'_name_dict': {'parameter': ('1d986818-79ad-4eed-8f18-7f425742ee93', {'name': 'theta_5', 'expression': "Parameter('theta_5')", 'symbols': {'theta_5': {'name': 'theta_5', 'trainable': 'True', 'value': '0.4498233918464615'}}})}}, 'noise': None}]}]}, {'type': 'ChainBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'KronBlock', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'CNOT', 'qubit_support': (0, 1), 'tag': None, 'blocks': [{'type': 'X', 'qubit_support': (1,), 'tag': None, 'noise': None}], 'noise': None}]}]}]}