Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 12 additions & 18 deletions crates/qpy/src/params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use binrw::Endian;
use num_complex::Complex64;
use pyo3::prelude::*;
use pyo3::types::IntoPyDict;
use qiskit_circuit::imports;
use qiskit_circuit::operations::Param;
use qiskit_circuit::parameter::parameter_expression::{
Expand Down Expand Up @@ -546,33 +547,26 @@ pub(crate) fn unpack_parameter_vector(
Some(value) => value,
None => Python::attach(|py| -> Result<_, QpyError> {
// we use python-space to create a new parameter vector
let py_uuid = {
let kwargs = [("int", root_uuid_int)].into_py_dict(py)?;
py.import("uuid")?
.getattr("UUID")?
.call((), Some(&kwargs))?
Comment on lines +552 to +554
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the import done this way and not through the imports module with a OnceCell?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly, because it gets deleted in two PRs' time (#16228), and this was just me patching together a functional intermediate state to make review clearer.

};
let vector = imports::PARAMETER_VECTOR
.get_bound(py)
.call1((name.clone(), parameter_vector_pack.vector_size))?
.call1((name.clone(), parameter_vector_pack.vector_size, py_uuid))?
.unbind();
qpy_data.vectors.insert(root_uuid, (vector, Vec::new()));
qpy_data
.vectors
.insert(root_uuid, (vector, Default::default()));
qpy_data.vectors.get_mut(&root_uuid).ok_or_else(|| {
QpyError::MissingData("Parameter vector creation failed".to_string())
})
})?,
};
let vector = vector_data.0.bind(py);
let vector_name = vector.getattr("name")?.extract::<String>()?;
let vector_element = vector.get_item(index)?.extract::<Symbol>()?;
if vector_element.uuid != uuid {
// we need to create a new parameter vector element and hack it into the vector
vector_data.1.push(index);
// let param_vector_element = PyParameterVectorElement::py_new(py, vector, index, parameter_vector_pack.uuid)
let param_vector_element = Symbol::py_new(
&vector_name,
Some(uuid.as_u128()),
Some(index),
Some(vector.clone().unbind()),
)?;
vector
.getattr("_params")?
.set_item(index, param_vector_element)?;
}
vector_data.1.insert(index);
Ok(vector.clone().unbind())
})?;

Expand Down
4 changes: 2 additions & 2 deletions crates/qpy/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::sync::Arc;

use binrw::meta::{ReadEndian, WriteEndian};
use binrw::{BinRead, BinWrite, Endian, binrw};
use hashbrown::HashMap;
use hashbrown::{HashMap, HashSet};
use pyo3::prelude::*;
use pyo3::types::PyAny;

Expand Down Expand Up @@ -126,7 +126,7 @@ pub struct QPYReadData<'a> {
pub use_symengine: bool,
pub standalone_vars: HashMap<u16, qiskit_circuit::Var>,
pub standalone_stretches: HashMap<u16, qiskit_circuit::Stretch>,
pub vectors: HashMap<Uuid, (Py<PyAny>, Vec<u32>)>, // Parameter expression vectors, which are a python-only elements for now
pub vectors: HashMap<Uuid, (Py<PyAny>, HashSet<u32>)>, // Parameter expression vectors, which are a python-only elements for now
pub annotation_handler: AnnotationHandler<'a>,
}

Expand Down
9 changes: 2 additions & 7 deletions qiskit/qpy/binary_io/value.py
Original file line number Diff line number Diff line change
Expand Up @@ -460,14 +460,9 @@ def _read_parameter_vec(file_obj, vectors):
name = file_obj.read(data.vector_name_size).decode(common.ENCODE)

if root_uuid not in vectors:
vectors[root_uuid] = (ParameterVector(name, data.vector_size), set())
vectors[root_uuid] = (ParameterVector(name, data.vector_size, uuid=root_uuid), set())
vector = vectors[root_uuid][0]

if vector[data.index].uuid != uuid.UUID(bytes=data.uuid):
vectors[root_uuid][1].add(data.index)
vector._params[data.index] = ParameterVectorElement(
vector, data.index, uuid=uuid.UUID(int=root_uuid_int + data.index)
)
vectors[root_uuid][1].add(data.index)
return vector[data.index]


Expand Down
2 changes: 0 additions & 2 deletions test/python/circuit/test_circuit_load_from_qpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1171,8 +1171,6 @@ def dump_load_param_vec(qc):
self.assertTrue(all(p == q for p, q in zip(params, new_params)))
# vector[0] is part of the circuit
self.assertTrue(vector[0] == new_vector[0])
# vector[1] is not part of the circuit
self.assertTrue(vector[1] != new_vector[1])
Comment on lines -1174 to -1175
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is removed because it's generated equal even though it's not used. It was never an API contract that unused values must be different - that was an undesirable consequence.


with self.subTest("real_amplitudes"):
qc = real_amplitudes(2, reps=1)
Expand Down
Loading