From 50042dae3ef8af35e19e4ffbf6d9b3e6c6019a67 Mon Sep 17 00:00:00 2001 From: John Lapeyre Date: Tue, 21 Jul 2020 14:14:56 -0700 Subject: [PATCH] Be more memory efficient converting SummedOp to MatrixOp Before, all summands were converted to MatrixOp and then summed. This PR instead converts them one by one and accumulates the result, thereby avoiding building a large intermediate list. Closes #1027 * Add release note --- qiskit/aqua/operators/list_ops/summed_op.py | 9 +++++++++ .../efficient-summedop-tomatrix-op-b2650bccb5273d20.yaml | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 releasenotes/notes/efficient-summedop-tomatrix-op-b2650bccb5273d20.yaml diff --git a/qiskit/aqua/operators/list_ops/summed_op.py b/qiskit/aqua/operators/list_ops/summed_op.py index d8bacf07ef..9f585da8c1 100644 --- a/qiskit/aqua/operators/list_ops/summed_op.py +++ b/qiskit/aqua/operators/list_ops/summed_op.py @@ -131,6 +131,15 @@ def reduce(self) -> OperatorBase: else: return cast(OperatorBase, reduced_ops) + def to_matrix_op(self, massive: bool = False) -> OperatorBase: + """ Returns an equivalent Operator composed of only NumPy-based primitives, such as + ``MatrixOp`` and ``VectorStateFn``. """ + accum = self.oplist[0].to_matrix_op(massive=massive) # type: ignore + for i in range(1, len(self.oplist)): + accum += self.oplist[i].to_matrix_op(massive=massive) # type: ignore + + return accum * self.coeff + def to_legacy_op(self, massive: bool = False) -> LegacyBaseOperator: # We do this recursively in case there are SummedOps of PauliOps in oplist. legacy_ops = [op.to_legacy_op(massive=massive) for op in self.oplist] diff --git a/releasenotes/notes/efficient-summedop-tomatrix-op-b2650bccb5273d20.yaml b/releasenotes/notes/efficient-summedop-tomatrix-op-b2650bccb5273d20.yaml new file mode 100644 index 0000000000..2565d81b9c --- /dev/null +++ b/releasenotes/notes/efficient-summedop-tomatrix-op-b2650bccb5273d20.yaml @@ -0,0 +1,9 @@ +--- +fixes: + - | + Previously, SummedOp.to_matrix_op built a list MatrixOp's (with numpy + matrices) and then summed them, returning a single MatrixOp. Some + algorithms (for example vqe) require summing thousands of matrices, which + exhausts memory when building the list of matrices. With this change, + no list is constructed. Rather, each operand in the sum is converted to + a matrix, added to an accumulator, and discarded.