Skip to content

Commit fd0616d

Browse files
committed
Fix complex matrix assignment ownership
Signed-off-by: Minh Vu <vuhoangminh97@gmail.com>
1 parent 1b12ae9 commit fd0616d

2 files changed

Lines changed: 52 additions & 12 deletions

File tree

runtime/cudaq/operators/matrix.h

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <complex>
2121
#include <iterator>
2222
#include <optional>
23+
#include <utility>
2324
#include <vector>
2425

2526
namespace Eigen {
@@ -74,14 +75,17 @@ class complex_matrix {
7475

7576
complex_matrix(const complex_matrix &other)
7677
: dimensions{other.dimensions},
77-
data{new value_type[get_size(other.dimensions)]},
78+
data{get_size(other.dimensions)
79+
? new value_type[get_size(other.dimensions)]
80+
: nullptr},
7881
internal_order(other.internal_order) {
79-
std::copy(other.data, other.data + get_size(dimensions), data);
82+
if (data)
83+
std::copy(other.data, other.data + get_size(dimensions), data);
8084
}
8185

8286
complex_matrix(const complex_matrix &other, order order);
8387

84-
complex_matrix(complex_matrix &&other)
88+
complex_matrix(complex_matrix &&other) noexcept
8589
: dimensions{other.dimensions}, data{other.data},
8690
internal_order(other.internal_order) {
8791
other.data = nullptr;
@@ -96,18 +100,14 @@ class complex_matrix {
96100
}
97101

98102
complex_matrix &operator=(const complex_matrix &other) {
99-
dimensions = other.dimensions;
100-
data = new value_type[get_size(other.dimensions)];
101-
std::copy(other.data, other.data + get_size(dimensions), data);
102-
internal_order = other.internal_order;
103+
complex_matrix copy(other);
104+
swap(copy);
103105
return *this;
104106
}
105107

106-
complex_matrix &operator=(complex_matrix &&other) {
107-
dimensions = other.dimensions;
108-
data = other.data;
109-
other.data = nullptr;
110-
internal_order = other.internal_order;
108+
complex_matrix &operator=(complex_matrix &&other) noexcept {
109+
complex_matrix moved(std::move(other));
110+
swap(moved);
111111
return *this;
112112
}
113113

@@ -232,6 +232,13 @@ class complex_matrix {
232232

233233
static void check_size(std::size_t size, const Dimensions &dim);
234234

235+
void swap(complex_matrix &other) noexcept {
236+
using std::swap;
237+
swap(dimensions, other.dimensions);
238+
swap(data, other.data);
239+
swap(internal_order, other.internal_order);
240+
}
241+
235242
void swap(complex_matrix::value_type *new_data) {
236243
if (data)
237244
delete[] data;

unittests/utils/Matrix.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,39 @@ TEST(Tensor, initializationError) {
5555
}
5656
}
5757

58+
TEST(Tensor, assignment) {
59+
const cudaq::complex_matrix empty;
60+
const cudaq::complex_matrix small({1., 2., 3., 4.});
61+
const cudaq::complex_matrix large({1., 2., 3., 4., 5., 6.}, {2, 3},
62+
cudaq::complex_matrix::order::column_major);
63+
64+
cudaq::complex_matrix copy;
65+
for (std::size_t i = 0; i < 100; ++i) {
66+
copy = empty;
67+
EXPECT_EQ(copy, empty);
68+
copy = small;
69+
EXPECT_EQ(copy, small);
70+
copy = large;
71+
EXPECT_EQ(copy, large);
72+
}
73+
74+
copy = copy;
75+
EXPECT_EQ(copy, large);
76+
77+
cudaq::complex_matrix moved({7., 8., 9., 10.});
78+
for (std::size_t i = 0; i < 100; ++i) {
79+
moved = cudaq::complex_matrix();
80+
EXPECT_EQ(moved, empty);
81+
moved = cudaq::complex_matrix(small);
82+
EXPECT_EQ(moved, small);
83+
moved = cudaq::complex_matrix(large);
84+
EXPECT_EQ(moved, large);
85+
}
86+
87+
moved = std::move(moved);
88+
EXPECT_EQ(moved, large);
89+
}
90+
5891
TEST(Tensor, access) {
5992
{
6093
cudaq::complex_matrix m1({1., 0., 0., 1.});

0 commit comments

Comments
 (0)