pennylane-qrack 0.20.3__tar.gz → 0.21.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pennylane-qrack might be problematic. Click here for more details.
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/Makefile +1 -1
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/PKG-INFO +1 -1
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/_version.py +1 -1
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/qrack_ace_device.py +9 -5
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/qrack_device.cpp +4 -22
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/qrack_device.py +3 -1
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/PKG-INFO +1 -1
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/SOURCES.txt +0 -7
- pennylane_qrack-0.20.3/catalyst/runtime/include/DataView.hpp +0 -148
- pennylane_qrack-0.20.3/catalyst/runtime/include/DynamicLibraryLoader.hpp +0 -79
- pennylane_qrack-0.20.3/catalyst/runtime/include/Exception.hpp +0 -87
- pennylane_qrack-0.20.3/catalyst/runtime/include/QuantumDevice.hpp +0 -364
- pennylane_qrack-0.20.3/catalyst/runtime/include/RuntimeCAPI.h +0 -112
- pennylane_qrack-0.20.3/catalyst/runtime/include/Types.h +0 -165
- pennylane_qrack-0.20.3/pennylane_qrack/libqrack_device.so +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/CHANGELOG.md +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/CMakeLists.txt +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/LICENSE +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/MANIFEST.in +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/README.rst +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/QrackAceDeviceConfig.toml +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/QrackDeviceConfig.toml +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack/__init__.py +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/dependency_links.txt +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/entry_points.txt +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/requires.txt +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/top_level.txt +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/requirements.txt +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/setup.cfg +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/setup.py +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/tests/test_apply.py +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/tests/test_integration.py +0 -0
- {pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/tests/test_units.py +0 -0
|
@@ -24,7 +24,7 @@ help:
|
|
|
24
24
|
build-deps:
|
|
25
25
|
ifneq ($(OS),Windows_NT)
|
|
26
26
|
ifeq ($(QRACK_PRESENT),)
|
|
27
|
-
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout
|
|
27
|
+
git clone https://github.com/unitaryfund/qrack.git; cd qrack; git checkout 9bbd10bbadf800d7604dc73f0315e84180f3939c; cd ..
|
|
28
28
|
endif
|
|
29
29
|
mkdir -p qrack/build
|
|
30
30
|
ifeq ($(UNAME_S),Linux)
|
|
@@ -134,11 +134,11 @@ class QrackAceDevice(QubitDevice):
|
|
|
134
134
|
# Noise parameter. (Default is "0"; depolarizing noise intensity can also be controlled by "QRACK_GATE_DEPOLARIZATION" environment variable)
|
|
135
135
|
noise = 0
|
|
136
136
|
# How many full simulation columns, between border columns
|
|
137
|
-
long_range_columns=4
|
|
137
|
+
long_range_columns = 4
|
|
138
138
|
# How many full simulation rows, between border rows
|
|
139
|
-
long_range_rows=4
|
|
139
|
+
long_range_rows = 4
|
|
140
140
|
# Whether to transpose rows and columns
|
|
141
|
-
is_transpose=False
|
|
141
|
+
is_transpose = False
|
|
142
142
|
|
|
143
143
|
def __init__(self, wires=0, shots=None, **kwargs):
|
|
144
144
|
options = dict(kwargs)
|
|
@@ -376,7 +376,9 @@ class QrackAceDevice(QubitDevice):
|
|
|
376
376
|
raise DeviceError(f"Operation {opname} is not supported on a {self.short_name} device.")
|
|
377
377
|
|
|
378
378
|
def analytic_probability(self, wires=None):
|
|
379
|
-
raise DeviceError(
|
|
379
|
+
raise DeviceError(
|
|
380
|
+
f"analytic_probability is not supported on a {self.short_name} device. (Specify a finite number of shots, instead.)"
|
|
381
|
+
)
|
|
380
382
|
|
|
381
383
|
def expval(self, observable, **kwargs):
|
|
382
384
|
if self.shots is None:
|
|
@@ -433,7 +435,9 @@ class QrackAceDevice(QubitDevice):
|
|
|
433
435
|
|
|
434
436
|
# QubitDevice.states_to_binary() doesn't work for >64qb. (Fix by Elara, the custom OpenAI GPT)
|
|
435
437
|
samples = self._state.measure_shots(list(range(self.num_wires - 1, -1, -1)), self.shots)
|
|
436
|
-
self._samples = np.array(
|
|
438
|
+
self._samples = np.array(
|
|
439
|
+
[list(format(b, f"0{self.num_wires}b")) for b in samples], dtype=np.int8
|
|
440
|
+
)
|
|
437
441
|
|
|
438
442
|
return self._samples
|
|
439
443
|
|
|
@@ -483,8 +483,6 @@ struct QrackDevice final : public Catalyst::Runtime::QuantumDevice {
|
|
|
483
483
|
}
|
|
484
484
|
return ids;
|
|
485
485
|
}
|
|
486
|
-
[[nodiscard]] auto Zero() const -> Result override { return const_cast<Result>(&QRACK_RESULT_FALSE_CONST); }
|
|
487
|
-
[[nodiscard]] auto One() const -> Result override { return const_cast<Result>(&QRACK_RESULT_TRUE_CONST); }
|
|
488
486
|
auto Observable(ObsId id, const std::vector<std::complex<double>> &matrix,
|
|
489
487
|
const std::vector<QubitIdType> &wires) -> ObsIdType override
|
|
490
488
|
{
|
|
@@ -576,21 +574,6 @@ struct QrackDevice final : public Catalyst::Runtime::QuantumDevice {
|
|
|
576
574
|
[[nodiscard]] auto GetDeviceShots() const -> size_t override { return shots; }
|
|
577
575
|
void StartTapeRecording() override { tapeRecording = true; }
|
|
578
576
|
void StopTapeRecording() override { tapeRecording = false; }
|
|
579
|
-
void PrintState() override
|
|
580
|
-
{
|
|
581
|
-
const size_t numQubits = qsim->GetQubitCount();
|
|
582
|
-
const size_t maxQPower = (size_t)((uint64_t)qsim->GetMaxQPower());
|
|
583
|
-
const size_t maxLcv = maxQPower - 1U;
|
|
584
|
-
size_t idx = 0U;
|
|
585
|
-
std::cout << "*** State-Vector of Size " << maxQPower << " ***" << std::endl;
|
|
586
|
-
std::cout << "[";
|
|
587
|
-
std::unique_ptr<Qrack::complex> sv(new Qrack::complex[maxQPower]);
|
|
588
|
-
qsim->GetQuantumState(sv.get());
|
|
589
|
-
for (; idx < maxLcv; ++idx) {
|
|
590
|
-
std::cout << sv.get()[idx] << ", ";
|
|
591
|
-
}
|
|
592
|
-
std::cout << sv.get()[idx] << "]" << std::endl;
|
|
593
|
-
}
|
|
594
577
|
void NamedOperation(const std::string &name, const std::vector<double> ¶ms,
|
|
595
578
|
const std::vector<QubitIdType> &wires, bool inverse,
|
|
596
579
|
const std::vector<QubitIdType> &controlled_wires,
|
|
@@ -735,7 +718,7 @@ struct QrackDevice final : public Catalyst::Runtime::QuantumDevice {
|
|
|
735
718
|
}
|
|
736
719
|
}
|
|
737
720
|
}
|
|
738
|
-
void Sample(DataView<double, 2> &samples
|
|
721
|
+
void Sample(DataView<double, 2> &samples) override
|
|
739
722
|
{
|
|
740
723
|
RT_FAIL_IF(samples.size() != shots * qsim->GetQubitCount(), "Invalid size for the pre-allocated samples");
|
|
741
724
|
|
|
@@ -764,7 +747,7 @@ struct QrackDevice final : public Catalyst::Runtime::QuantumDevice {
|
|
|
764
747
|
const std::map<bitCapInt, int> q_samples = qsim->MultiShotMeasureMask(qPowers, shots);
|
|
765
748
|
_SampleBody(qPowers.size(), q_samples, samples);
|
|
766
749
|
}
|
|
767
|
-
void PartialSample(DataView<double, 2> &samples, const std::vector<QubitIdType> &wires
|
|
750
|
+
void PartialSample(DataView<double, 2> &samples, const std::vector<QubitIdType> &wires) override
|
|
768
751
|
{
|
|
769
752
|
RT_FAIL_IF(samples.size() != shots * wires.size(), "Invalid size for the pre-allocated samples");
|
|
770
753
|
|
|
@@ -809,8 +792,7 @@ struct QrackDevice final : public Catalyst::Runtime::QuantumDevice {
|
|
|
809
792
|
}
|
|
810
793
|
}
|
|
811
794
|
}
|
|
812
|
-
void Counts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts
|
|
813
|
-
size_t shots) override
|
|
795
|
+
void Counts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts) override
|
|
814
796
|
{
|
|
815
797
|
const size_t numQubits = qsim->GetQubitCount();
|
|
816
798
|
const size_t numElements = 1U << numQubits;
|
|
@@ -844,7 +826,7 @@ struct QrackDevice final : public Catalyst::Runtime::QuantumDevice {
|
|
|
844
826
|
}
|
|
845
827
|
|
|
846
828
|
void PartialCounts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts,
|
|
847
|
-
const std::vector<QubitIdType> &wires
|
|
829
|
+
const std::vector<QubitIdType> &wires) override
|
|
848
830
|
{
|
|
849
831
|
const size_t numQubits = wires.size();
|
|
850
832
|
const size_t numElements = 1U << numQubits;
|
|
@@ -720,7 +720,9 @@ class QrackDevice(QubitDevice):
|
|
|
720
720
|
|
|
721
721
|
# QubitDevice.states_to_binary() doesn't work for >64qb. (Fix by Elara, the custom OpenAI GPT)
|
|
722
722
|
samples = self._state.measure_shots(list(range(self.num_wires - 1, -1, -1)), self.shots)
|
|
723
|
-
self._samples = np.array(
|
|
723
|
+
self._samples = np.array(
|
|
724
|
+
[list(format(b, f"0{self.num_wires}b")) for b in samples], dtype=np.int8
|
|
725
|
+
)
|
|
724
726
|
|
|
725
727
|
return self._samples
|
|
726
728
|
|
|
@@ -6,17 +6,10 @@ Makefile
|
|
|
6
6
|
README.rst
|
|
7
7
|
requirements.txt
|
|
8
8
|
setup.py
|
|
9
|
-
catalyst/runtime/include/DataView.hpp
|
|
10
|
-
catalyst/runtime/include/DynamicLibraryLoader.hpp
|
|
11
|
-
catalyst/runtime/include/Exception.hpp
|
|
12
|
-
catalyst/runtime/include/QuantumDevice.hpp
|
|
13
|
-
catalyst/runtime/include/RuntimeCAPI.h
|
|
14
|
-
catalyst/runtime/include/Types.h
|
|
15
9
|
pennylane_qrack/QrackAceDeviceConfig.toml
|
|
16
10
|
pennylane_qrack/QrackDeviceConfig.toml
|
|
17
11
|
pennylane_qrack/__init__.py
|
|
18
12
|
pennylane_qrack/_version.py
|
|
19
|
-
pennylane_qrack/libqrack_device.so
|
|
20
13
|
pennylane_qrack/qrack_ace_device.py
|
|
21
14
|
pennylane_qrack/qrack_device.cpp
|
|
22
15
|
pennylane_qrack/qrack_device.py
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 Xanadu Quantum Technologies Inc.
|
|
2
|
-
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
#pragma once
|
|
16
|
-
|
|
17
|
-
#include <Exception.hpp>
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* A multi-dimensional view for MemRef-like and std::vector<T> types.
|
|
21
|
-
*
|
|
22
|
-
* @tparam T The underlying data type
|
|
23
|
-
* @tparam R The Rank (R > 0)
|
|
24
|
-
*
|
|
25
|
-
* @note A forward iterator is implemented in this view for traversing over the entire
|
|
26
|
-
* elements of MemRef types rank-by-rank starting from the last dimension (R-1). For example,
|
|
27
|
-
* The DataView iterator for MemRef<T, 2> starts from index (0, 0) and traverses elements
|
|
28
|
-
* in the following order:
|
|
29
|
-
* (0, 0), ..., (0, sizes[1]-1), (1, 0), ..., (1, sizes[1]-1), ... (sizes[0]-1, sizes[1]-1).
|
|
30
|
-
*/
|
|
31
|
-
template <typename T, size_t R> class DataView {
|
|
32
|
-
private:
|
|
33
|
-
T *data_aligned;
|
|
34
|
-
size_t offset;
|
|
35
|
-
size_t sizes[R] = {0};
|
|
36
|
-
size_t strides[R] = {0};
|
|
37
|
-
|
|
38
|
-
public:
|
|
39
|
-
class iterator {
|
|
40
|
-
private:
|
|
41
|
-
const DataView<T, R> &view;
|
|
42
|
-
|
|
43
|
-
int64_t loc; // physical index
|
|
44
|
-
size_t indices[R] = {0};
|
|
45
|
-
|
|
46
|
-
public:
|
|
47
|
-
using iterator_category = std::forward_iterator_tag; // LCOV_EXCL_LINE
|
|
48
|
-
using value_type = T; // LCOV_EXCL_LINE
|
|
49
|
-
using difference_type = std::ptrdiff_t; // LCOV_EXCL_LINE
|
|
50
|
-
using pointer = T *; // LCOV_EXCL_LINE
|
|
51
|
-
using reference = T &; // LCOV_EXCL_LINE
|
|
52
|
-
|
|
53
|
-
iterator(const DataView<T, R> &_view, int64_t begin_idx) : view(_view), loc(begin_idx) {}
|
|
54
|
-
pointer operator->() const { return &view.data_aligned[loc]; }
|
|
55
|
-
reference operator*() const { return view.data_aligned[loc]; }
|
|
56
|
-
iterator &operator++()
|
|
57
|
-
{
|
|
58
|
-
int64_t next_axis = -1;
|
|
59
|
-
int64_t idx;
|
|
60
|
-
for (int64_t i = R; i > 0; --i) {
|
|
61
|
-
idx = i - 1;
|
|
62
|
-
if (indices[idx]++ < view.sizes[idx] - 1) {
|
|
63
|
-
next_axis = idx;
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
indices[idx] = 0;
|
|
67
|
-
loc -= (view.sizes[idx] - 1) * view.strides[idx];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
loc = next_axis == -1 ? -1 : loc + view.strides[next_axis];
|
|
71
|
-
return *this;
|
|
72
|
-
}
|
|
73
|
-
iterator operator++(int)
|
|
74
|
-
{
|
|
75
|
-
auto tmp = *this;
|
|
76
|
-
int64_t next_axis = -1;
|
|
77
|
-
int64_t idx;
|
|
78
|
-
for (int64_t i = R; i > 0; --i) {
|
|
79
|
-
idx = i - 1;
|
|
80
|
-
if (indices[idx]++ < view.sizes[idx] - 1) {
|
|
81
|
-
next_axis = idx;
|
|
82
|
-
break;
|
|
83
|
-
}
|
|
84
|
-
indices[idx] = 0;
|
|
85
|
-
loc -= (view.sizes[idx] - 1) * view.strides[idx];
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
loc = next_axis == -1 ? -1 : loc + view.strides[next_axis];
|
|
89
|
-
return tmp;
|
|
90
|
-
}
|
|
91
|
-
bool operator==(const iterator &other) const
|
|
92
|
-
{
|
|
93
|
-
return (loc == other.loc && view.data_aligned == other.view.data_aligned);
|
|
94
|
-
}
|
|
95
|
-
bool operator!=(const iterator &other) const { return !(*this == other); }
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
explicit DataView(std::vector<T> &buffer) : data_aligned(buffer.data()), offset(0)
|
|
99
|
-
{
|
|
100
|
-
static_assert(R == 1, "[Class: DataView] Assertion: R == 1");
|
|
101
|
-
sizes[0] = buffer.size();
|
|
102
|
-
strides[0] = 1;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
explicit DataView(T *_data_aligned, size_t _offset, const size_t *_sizes,
|
|
106
|
-
const size_t *_strides)
|
|
107
|
-
: data_aligned(_data_aligned), offset(_offset)
|
|
108
|
-
{
|
|
109
|
-
static_assert(R > 0, "[Class: DataView] Assertion: R > 0");
|
|
110
|
-
if (_sizes != nullptr && _strides != nullptr) {
|
|
111
|
-
for (size_t i = 0; i < R; i++) {
|
|
112
|
-
sizes[i] = _sizes[i];
|
|
113
|
-
strides[i] = _strides[i];
|
|
114
|
-
}
|
|
115
|
-
} // else sizes = {0}, strides = {0}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
[[nodiscard]] auto size() const -> size_t
|
|
119
|
-
{
|
|
120
|
-
if (!data_aligned) {
|
|
121
|
-
return 0;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
size_t tsize = 1;
|
|
125
|
-
for (size_t i = 0; i < R; i++) {
|
|
126
|
-
tsize *= sizes[i];
|
|
127
|
-
}
|
|
128
|
-
return tsize;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
template <typename... I> T &operator()(I... idxs) const
|
|
132
|
-
{
|
|
133
|
-
static_assert(sizeof...(idxs) == R,
|
|
134
|
-
"[Class: DataView] Error in Catalyst Runtime: Wrong number of indices");
|
|
135
|
-
size_t indices[] = {static_cast<size_t>(idxs)...};
|
|
136
|
-
|
|
137
|
-
size_t loc = offset;
|
|
138
|
-
for (size_t axis = 0; axis < R; axis++) {
|
|
139
|
-
RT_ASSERT(indices[axis] < sizes[axis]);
|
|
140
|
-
loc += indices[axis] * strides[axis];
|
|
141
|
-
}
|
|
142
|
-
return data_aligned[loc];
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
iterator begin() { return iterator{*this, static_cast<int64_t>(offset)}; }
|
|
146
|
-
|
|
147
|
-
iterator end() { return iterator{*this, -1}; }
|
|
148
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
// Copyright 2024 Xanadu Quantum Technologies Inc.
|
|
2
|
-
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
#pragma once
|
|
16
|
-
|
|
17
|
-
#include <dlfcn.h>
|
|
18
|
-
#include <string_view>
|
|
19
|
-
|
|
20
|
-
#include "Exception.hpp"
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* @brief A utility struct to handle opening, closing and retrieving symbols
|
|
24
|
-
* from dynamic shared objects.
|
|
25
|
-
*/
|
|
26
|
-
struct DynamicLibraryLoader {
|
|
27
|
-
void *handle;
|
|
28
|
-
|
|
29
|
-
DynamicLibraryLoader(std::string_view library_name, int mode = RTLD_LAZY | RTLD_NODELETE)
|
|
30
|
-
{
|
|
31
|
-
// Load the shared library
|
|
32
|
-
handle = dlopen(library_name.data(), mode);
|
|
33
|
-
if (!handle) {
|
|
34
|
-
const char *err_msg = dlerror();
|
|
35
|
-
RT_FAIL(err_msg);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
~DynamicLibraryLoader()
|
|
40
|
-
{
|
|
41
|
-
if (handle) {
|
|
42
|
-
// TODO: This is non-sensical.
|
|
43
|
-
// We are using RTLD_NODELETE, why would calling dlclose have a side-effect?
|
|
44
|
-
// Worst of all, the side-effect is not in our code.
|
|
45
|
-
// When we have dlclose, everything works well the first time.
|
|
46
|
-
// However, when trying to compile a second time, we will find that jaxlib will now
|
|
47
|
-
// raise a StopIteration exception. This doesn't really make any sense.
|
|
48
|
-
// My guess is that somehow dlclosing here will unload a the StopIteration symbol (?)
|
|
49
|
-
// rebind it with another equivalent (but with different id?)
|
|
50
|
-
// and then the MLIR python bindings are unable to catch it and stop the iteration and
|
|
51
|
-
// it gets propagated upwards.
|
|
52
|
-
//
|
|
53
|
-
// Is not calling dlclose bad?
|
|
54
|
-
// A little bit, although dlclose implies intent and does not create any requirements
|
|
55
|
-
// upon the implementation. See here:
|
|
56
|
-
// https://pubs.opengroup.org/onlinepubs/000095399/functions/dlclose.html
|
|
57
|
-
// https://github.com/pybind/pybind11/blob/75e48c5f959b4f0a49d8c664e059b6fb4b497102/include/pybind11/detail/internals.h#L108-L113
|
|
58
|
-
//
|
|
59
|
-
#ifndef __APPLE__
|
|
60
|
-
dlclose(handle);
|
|
61
|
-
#endif
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
// Get symbol from library
|
|
66
|
-
template <typename T> T getSymbol(std::string_view symbol_name)
|
|
67
|
-
{
|
|
68
|
-
// Clear any existing errors
|
|
69
|
-
dlerror();
|
|
70
|
-
|
|
71
|
-
// Retrieve symbol
|
|
72
|
-
T symbol = reinterpret_cast<T>(dlsym(handle, symbol_name.data()));
|
|
73
|
-
const char *err_msg = dlerror();
|
|
74
|
-
if (err_msg != nullptr) {
|
|
75
|
-
RT_FAIL(err_msg);
|
|
76
|
-
}
|
|
77
|
-
return symbol;
|
|
78
|
-
}
|
|
79
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
// Copyright 2023 Xanadu Quantum Technologies Inc.
|
|
2
|
-
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
#pragma once
|
|
16
|
-
|
|
17
|
-
#include <exception>
|
|
18
|
-
#include <iostream>
|
|
19
|
-
|
|
20
|
-
#include <sstream>
|
|
21
|
-
#include <string>
|
|
22
|
-
#include <type_traits>
|
|
23
|
-
#include <utility>
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @brief Macro that throws `RuntimeException` with given message.
|
|
27
|
-
*/
|
|
28
|
-
#define RT_FAIL(message) Catalyst::Runtime::_abort((message), __FILE__, __LINE__, __func__)
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @brief Macro that throws `RuntimeException` if expression evaluates
|
|
32
|
-
* to true.
|
|
33
|
-
*/
|
|
34
|
-
#define RT_FAIL_IF(expression, message) \
|
|
35
|
-
if ((expression)) { \
|
|
36
|
-
RT_FAIL(message); \
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* @brief Macro that throws `RuntimeException` with the given expression
|
|
41
|
-
* and source location if expression evaluates to false.
|
|
42
|
-
*/
|
|
43
|
-
#define RT_ASSERT(expression) RT_FAIL_IF(!(expression), "Assertion: " #expression)
|
|
44
|
-
|
|
45
|
-
namespace Catalyst::Runtime {
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* @brief This is the general exception thrown by Catalyst for runtime errors
|
|
49
|
-
* that is derived from `std::exception`.
|
|
50
|
-
*/
|
|
51
|
-
class RuntimeException : public std::exception {
|
|
52
|
-
private:
|
|
53
|
-
const std::string err_msg;
|
|
54
|
-
|
|
55
|
-
public:
|
|
56
|
-
explicit RuntimeException(std::string msg) noexcept
|
|
57
|
-
: err_msg{std::move(msg)} {} // LCOV_EXCL_LINE
|
|
58
|
-
~RuntimeException() override = default; // LCOV_EXCL_LINE
|
|
59
|
-
|
|
60
|
-
RuntimeException(const RuntimeException &) = default;
|
|
61
|
-
RuntimeException(RuntimeException &&) noexcept = default;
|
|
62
|
-
|
|
63
|
-
RuntimeException &operator=(const RuntimeException &) = delete;
|
|
64
|
-
RuntimeException &operator=(RuntimeException &&) = delete;
|
|
65
|
-
|
|
66
|
-
[[nodiscard]] auto what() const noexcept -> const char * override
|
|
67
|
-
{
|
|
68
|
-
return err_msg.c_str();
|
|
69
|
-
} // LCOV_EXCL_LINE
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* @brief Throws a `RuntimeException` with the given error message.
|
|
74
|
-
*
|
|
75
|
-
* @note This is not supposed to be called directly.
|
|
76
|
-
*/
|
|
77
|
-
[[noreturn]] inline void _abort(const char *message, const char *file_name, size_t line,
|
|
78
|
-
const char *function_name)
|
|
79
|
-
{
|
|
80
|
-
std::stringstream sstream;
|
|
81
|
-
sstream << "[" << file_name << "][Line:" << line << "][Function:" << function_name
|
|
82
|
-
<< "] Error in Catalyst Runtime: " << message;
|
|
83
|
-
|
|
84
|
-
throw RuntimeException(sstream.str());
|
|
85
|
-
} // LCOV_EXCL_LINE
|
|
86
|
-
|
|
87
|
-
} // namespace Catalyst::Runtime
|
|
@@ -1,364 +0,0 @@
|
|
|
1
|
-
// Copyright 2022-2023 Xanadu Quantum Technologies Inc.
|
|
2
|
-
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
#pragma once
|
|
16
|
-
|
|
17
|
-
#include <complex>
|
|
18
|
-
#include <memory>
|
|
19
|
-
#include <optional>
|
|
20
|
-
#include <random>
|
|
21
|
-
#include <vector>
|
|
22
|
-
|
|
23
|
-
#include "DataView.hpp"
|
|
24
|
-
#include "Types.h"
|
|
25
|
-
|
|
26
|
-
// A helper template macro to generate the <IDENTIFIER>Factory method by
|
|
27
|
-
// calling <CONSTRUCTOR>(kwargs). Check the Custom Devices guideline for details:
|
|
28
|
-
// https://docs.pennylane.ai/projects/catalyst/en/stable/dev/custom_devices.html
|
|
29
|
-
#define GENERATE_DEVICE_FACTORY(IDENTIFIER, CONSTRUCTOR) \
|
|
30
|
-
extern "C" Catalyst::Runtime::QuantumDevice *IDENTIFIER##Factory(const char *kwargs) \
|
|
31
|
-
{ \
|
|
32
|
-
return new CONSTRUCTOR(std::string(kwargs)); \
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
namespace Catalyst::Runtime {
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* @brief struct API for backend quantum devices.
|
|
39
|
-
*
|
|
40
|
-
* This device API contains,
|
|
41
|
-
* - a set of methods to manage qubit allocations and deallocations, device shot
|
|
42
|
-
* noise, and quantum tape recording as well as reference values for the result
|
|
43
|
-
* data-type; these are used to implement Quantum Runtime (QR) instructions.
|
|
44
|
-
*
|
|
45
|
-
* - a set of methods for quantum operations, observables, measurements, and gradient
|
|
46
|
-
* of the device; these are used to implement Quantum Instruction Set (QIS) instructions.
|
|
47
|
-
*
|
|
48
|
-
*/
|
|
49
|
-
struct QuantumDevice {
|
|
50
|
-
QuantumDevice() = default; // LCOV_EXCL_LINE
|
|
51
|
-
virtual ~QuantumDevice() = default; // LCOV_EXCL_LINE
|
|
52
|
-
|
|
53
|
-
QuantumDevice &operator=(const QuantumDevice &) = delete;
|
|
54
|
-
QuantumDevice(const QuantumDevice &) = delete;
|
|
55
|
-
QuantumDevice(QuantumDevice &&) = delete;
|
|
56
|
-
QuantumDevice &operator=(QuantumDevice &&) = delete;
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* @brief Allocate a qubit.
|
|
60
|
-
*
|
|
61
|
-
* @return `QubitIdType`
|
|
62
|
-
*/
|
|
63
|
-
virtual auto AllocateQubit() -> QubitIdType = 0;
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* @brief Allocate a vector of qubits.
|
|
67
|
-
*
|
|
68
|
-
* @param num_qubits The number of qubits to allocate.
|
|
69
|
-
*
|
|
70
|
-
* @return `std::vector<QubitIdType>`
|
|
71
|
-
*/
|
|
72
|
-
virtual auto AllocateQubits(size_t num_qubits) -> std::vector<QubitIdType> = 0;
|
|
73
|
-
|
|
74
|
-
/**
|
|
75
|
-
* @brief Release a qubit.
|
|
76
|
-
*
|
|
77
|
-
* @param qubit The id of the qubit
|
|
78
|
-
*/
|
|
79
|
-
virtual void ReleaseQubit(QubitIdType qubit) = 0;
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* @brief Release all qubits.
|
|
83
|
-
*/
|
|
84
|
-
virtual void ReleaseAllQubits() = 0;
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* @brief Get the number of allocated qubits.
|
|
88
|
-
*
|
|
89
|
-
* @return `size_t`
|
|
90
|
-
*/
|
|
91
|
-
[[nodiscard]] virtual auto GetNumQubits() const -> size_t = 0;
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* @brief Set the number of device shots.
|
|
95
|
-
*
|
|
96
|
-
* @param shots The number of noise shots
|
|
97
|
-
*/
|
|
98
|
-
virtual void SetDeviceShots(size_t shots) = 0;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* @brief Get the number of device shots.
|
|
102
|
-
*
|
|
103
|
-
* @return `size_t`
|
|
104
|
-
*/
|
|
105
|
-
[[nodiscard]] virtual auto GetDeviceShots() const -> size_t = 0;
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* @brief Set the PRNG of the device.
|
|
109
|
-
*
|
|
110
|
-
* The Catalyst runtime enables seeded program execution on non-hardware devices.
|
|
111
|
-
* A random number generator instance is managed by the runtime to predictably
|
|
112
|
-
* generate results for non-deterministic programs, such as those involving `Measure`
|
|
113
|
-
* calls.
|
|
114
|
-
* Devices implementing support for this feature do not need to use the provided
|
|
115
|
-
* PRNG instance as their sole source of random numbers, but it is expected that the
|
|
116
|
-
* the same instance state will predictable and reproducibly generate the same
|
|
117
|
-
* program results. It is also expected that the provided PRNG state is evolved
|
|
118
|
-
* sufficiently so that two device executions sharing the same instance do not produce
|
|
119
|
-
* identical results.
|
|
120
|
-
* The provided PRNG instance is not thread-locked, and devices wishing to share it
|
|
121
|
-
* across threads will need to provide their own thread-safety.
|
|
122
|
-
*
|
|
123
|
-
* @param gen The std::mt19937 PRNG object.
|
|
124
|
-
*/
|
|
125
|
-
virtual void SetDevicePRNG([[maybe_unused]] std::mt19937 *gen){};
|
|
126
|
-
|
|
127
|
-
/**
|
|
128
|
-
* @brief Start recording a quantum tape if provided.
|
|
129
|
-
*
|
|
130
|
-
* @note This is backed by the `Catalyst::Runtime::CacheManager<ComplexT>` property in
|
|
131
|
-
* the device implementation.
|
|
132
|
-
*/
|
|
133
|
-
virtual void StartTapeRecording() = 0;
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* @brief Stop recording a quantum tape if provided.
|
|
137
|
-
*
|
|
138
|
-
* @note This is backed by the `Catalyst::Runtime::CacheManager<ComplexT>` property in
|
|
139
|
-
* the device implementation.
|
|
140
|
-
*/
|
|
141
|
-
virtual void StopTapeRecording() = 0;
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* @brief Result value for "Zero" used in the measurement process.
|
|
145
|
-
*
|
|
146
|
-
* @return `Result`
|
|
147
|
-
*/
|
|
148
|
-
[[nodiscard]] virtual auto Zero() const -> Result = 0;
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* @brief Result value for "One" used in the measurement process.
|
|
152
|
-
*
|
|
153
|
-
* @return `Result`
|
|
154
|
-
*/
|
|
155
|
-
[[nodiscard]] virtual auto One() const -> Result = 0;
|
|
156
|
-
|
|
157
|
-
/**
|
|
158
|
-
* @brief A helper method to print the state vector of a device.
|
|
159
|
-
*/
|
|
160
|
-
virtual void PrintState() = 0;
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* @brief Prepare subsystems using the given ket vector in the computational basis.
|
|
164
|
-
*
|
|
165
|
-
* @param state A state vector of size 2**len(wires)
|
|
166
|
-
* @param wires The wire(s) the operation acts on
|
|
167
|
-
*/
|
|
168
|
-
virtual void SetState([[maybe_unused]] DataView<std::complex<double>, 1> &state,
|
|
169
|
-
[[maybe_unused]] std::vector<QubitIdType> &wires)
|
|
170
|
-
{
|
|
171
|
-
RT_FAIL("Unsupported functionality");
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* @brief Prepares a single computational basis state.
|
|
176
|
-
*
|
|
177
|
-
* @param n Prepares the basis state |n>, where n is an array of integers from the set {0, 1}
|
|
178
|
-
* @param wires The wire(s) the operation acts on
|
|
179
|
-
*/
|
|
180
|
-
virtual void SetBasisState([[maybe_unused]] DataView<int8_t, 1> &n,
|
|
181
|
-
[[maybe_unused]] std::vector<QubitIdType> &wires)
|
|
182
|
-
{
|
|
183
|
-
RT_FAIL("Unsupported functionality");
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* @brief Apply a single gate to the state vector of a device with its name if this is
|
|
188
|
-
* supported.
|
|
189
|
-
*
|
|
190
|
-
* @param name The name of the gate to apply
|
|
191
|
-
* @param params Optional parameter list for parametric gates
|
|
192
|
-
* @param wires Wires to apply gate to
|
|
193
|
-
* @param inverse Indicates whether to use inverse of gate
|
|
194
|
-
* @param controlled_wires Optional controlled wires applied to the operation
|
|
195
|
-
* @param controlled_values Optional controlled values applied to the operation
|
|
196
|
-
*/
|
|
197
|
-
virtual void
|
|
198
|
-
NamedOperation(const std::string &name, const std::vector<double> ¶ms,
|
|
199
|
-
const std::vector<QubitIdType> &wires, [[maybe_unused]] bool inverse = false,
|
|
200
|
-
[[maybe_unused]] const std::vector<QubitIdType> &controlled_wires = {},
|
|
201
|
-
[[maybe_unused]] const std::vector<bool> &controlled_values = {}) = 0;
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* @brief Apply a given matrix directly to the state vector of a device.
|
|
205
|
-
*
|
|
206
|
-
* @param matrix The matrix of data in row-major format
|
|
207
|
-
* @param wires Wires to apply gate to
|
|
208
|
-
* @param inverse Indicates whether to use inverse of gate
|
|
209
|
-
* @param controlled_wires Controlled wires applied to the operation
|
|
210
|
-
* @param controlled_values Controlled values applied to the operation
|
|
211
|
-
*/
|
|
212
|
-
virtual void
|
|
213
|
-
MatrixOperation(const std::vector<std::complex<double>> &matrix,
|
|
214
|
-
const std::vector<QubitIdType> &wires, [[maybe_unused]] bool inverse = false,
|
|
215
|
-
[[maybe_unused]] const std::vector<QubitIdType> &controlled_wires = {},
|
|
216
|
-
[[maybe_unused]] const std::vector<bool> &controlled_values = {}) = 0;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* @brief Construct a named (Identity, PauliX, PauliY, PauliZ, and Hadamard)
|
|
220
|
-
* or Hermitian observable.
|
|
221
|
-
*
|
|
222
|
-
* @param id The type of the observable
|
|
223
|
-
* @param matrix The matrix of data to construct a hermitian observable
|
|
224
|
-
* @param wires Wires to apply observable to
|
|
225
|
-
*
|
|
226
|
-
* @return `ObsIdType` Index of the constructed observable
|
|
227
|
-
*/
|
|
228
|
-
virtual auto Observable(ObsId id, const std::vector<std::complex<double>> &matrix,
|
|
229
|
-
const std::vector<QubitIdType> &wires) -> ObsIdType = 0;
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* @brief Construct a tensor product of observables.
|
|
233
|
-
*
|
|
234
|
-
* @param obs The vector of observables indices of type ObsIdType
|
|
235
|
-
*
|
|
236
|
-
* @return `ObsIdType` Index of the constructed observable
|
|
237
|
-
*/
|
|
238
|
-
virtual auto TensorObservable(const std::vector<ObsIdType> &obs) -> ObsIdType = 0;
|
|
239
|
-
|
|
240
|
-
/**
|
|
241
|
-
* @brief Construct a Hamiltonian observable.
|
|
242
|
-
*
|
|
243
|
-
* @param coeffs The vector of coefficients
|
|
244
|
-
* @param obs The vector of observables indices of size `coeffs`
|
|
245
|
-
*
|
|
246
|
-
* @return `ObsIdType` Index of the constructed observable
|
|
247
|
-
*/
|
|
248
|
-
virtual auto HamiltonianObservable(const std::vector<double> &coeffs,
|
|
249
|
-
const std::vector<ObsIdType> &obs) -> ObsIdType = 0;
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* @brief Compute the expected value of an observable.
|
|
253
|
-
*
|
|
254
|
-
* @param obsKey The index of the constructed observable
|
|
255
|
-
*
|
|
256
|
-
* @return `double` The expected value
|
|
257
|
-
*/
|
|
258
|
-
virtual auto Expval(ObsIdType obsKey) -> double = 0;
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* @brief Compute the variance of an observable.
|
|
262
|
-
*
|
|
263
|
-
* @param obsKey The index of the constructed observable
|
|
264
|
-
*
|
|
265
|
-
* @return `double` The variance
|
|
266
|
-
*/
|
|
267
|
-
virtual auto Var(ObsIdType obsKey) -> double = 0;
|
|
268
|
-
|
|
269
|
-
/**
|
|
270
|
-
* @brief Get the state-vector of a device.
|
|
271
|
-
*
|
|
272
|
-
* @param state The pre-allocated `DataView<complex<double>, 1>`
|
|
273
|
-
*/
|
|
274
|
-
virtual void State(DataView<std::complex<double>, 1> &state) = 0;
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* @brief Compute the probabilities of each computational basis state.
|
|
278
|
-
|
|
279
|
-
* @param probs The pre-allocated `DataView<double, 1>`
|
|
280
|
-
*/
|
|
281
|
-
virtual void Probs(DataView<double, 1> &probs) = 0;
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* @brief Compute the probabilities for a subset of the full system.
|
|
285
|
-
*
|
|
286
|
-
* @param probs The pre-allocated `DataView<double, 1>`
|
|
287
|
-
* @param wires Wires will restrict probabilities to a subset of the full system
|
|
288
|
-
*/
|
|
289
|
-
virtual void PartialProbs(DataView<double, 1> &probs,
|
|
290
|
-
const std::vector<QubitIdType> &wires) = 0;
|
|
291
|
-
|
|
292
|
-
/**
|
|
293
|
-
* @brief Compute samples with the number of shots on the entire wires,
|
|
294
|
-
* returing raw samples.
|
|
295
|
-
*
|
|
296
|
-
* @param samples The pre-allocated `DataView<double, 2>`representing a matrix of
|
|
297
|
-
* shape `shots * numQubits`. The built-in iterator in `DataView<double, 2>`
|
|
298
|
-
* iterates over all elements of `samples` row-wise.
|
|
299
|
-
* @param shots The number of shots
|
|
300
|
-
*/
|
|
301
|
-
virtual void Sample(DataView<double, 2> &samples, size_t shots) = 0;
|
|
302
|
-
|
|
303
|
-
/**
|
|
304
|
-
* @brief Compute partial samples with the number of shots on `wires`,
|
|
305
|
-
* returing raw samples.
|
|
306
|
-
*
|
|
307
|
-
* @param samples The pre-allocated `DataView<double, 2>`representing a matrix of
|
|
308
|
-
* shape `shots * numWires`. The built-in iterator in `DataView<double, 2>`
|
|
309
|
-
* iterates over all elements of `samples` row-wise.
|
|
310
|
-
* @param wires Wires to compute samples on
|
|
311
|
-
* @param shots The number of shots
|
|
312
|
-
*/
|
|
313
|
-
virtual void PartialSample(DataView<double, 2> &samples, const std::vector<QubitIdType> &wires,
|
|
314
|
-
size_t shots) = 0;
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* @brief Sample with the number of shots on the entire wires, returning the
|
|
318
|
-
* number of counts for each sample.
|
|
319
|
-
*
|
|
320
|
-
* @param eigvals The pre-allocated `DataView<double, 1>`
|
|
321
|
-
* @param counts The pre-allocated `DataView<int64_t, 1>`
|
|
322
|
-
* @param shots The number of shots
|
|
323
|
-
*/
|
|
324
|
-
virtual void Counts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts,
|
|
325
|
-
size_t shots) = 0;
|
|
326
|
-
|
|
327
|
-
/**
|
|
328
|
-
* @brief Partial sample with the number of shots on `wires`, returning the
|
|
329
|
-
* number of counts for each sample.
|
|
330
|
-
*
|
|
331
|
-
* @param eigvals The pre-allocated `DataView<double, 1>`
|
|
332
|
-
* @param counts The pre-allocated `DataView<int64_t, 1>`
|
|
333
|
-
* @param wires Wires to compute samples on
|
|
334
|
-
* @param shots The number of shots
|
|
335
|
-
*/
|
|
336
|
-
virtual void PartialCounts(DataView<double, 1> &eigvals, DataView<int64_t, 1> &counts,
|
|
337
|
-
const std::vector<QubitIdType> &wires, size_t shots) = 0;
|
|
338
|
-
|
|
339
|
-
/**
|
|
340
|
-
* @brief A general measurement method that acts on a single wire.
|
|
341
|
-
*
|
|
342
|
-
* @param wire The wire to compute Measure on
|
|
343
|
-
* @param postselect Which basis state to postselect after a mid-circuit measurement (-1 denotes
|
|
344
|
-
no post-selection)
|
|
345
|
-
|
|
346
|
-
* @return `Result` The measurement result
|
|
347
|
-
*/
|
|
348
|
-
virtual auto Measure(QubitIdType wire, std::optional<int32_t> postselect) -> Result = 0;
|
|
349
|
-
|
|
350
|
-
/**
|
|
351
|
-
* @brief Compute the gradient of a quantum tape, that is cached using
|
|
352
|
-
* `Catalyst::Runtime::Simulator::CacheManager`, for a specific set of trainable
|
|
353
|
-
* parameters.
|
|
354
|
-
*
|
|
355
|
-
* @param gradients The vector of pre-allocated `DataView<double, 1>*`
|
|
356
|
-
* to store gradients resutls for the list of cached observables.
|
|
357
|
-
* @param trainParams The vector of trainable parameters; if none, all parameters
|
|
358
|
-
* would be assumed trainable
|
|
359
|
-
*
|
|
360
|
-
*/
|
|
361
|
-
virtual void Gradient(std::vector<DataView<double, 1>> &gradients,
|
|
362
|
-
const std::vector<size_t> &trainParams) = 0;
|
|
363
|
-
};
|
|
364
|
-
} // namespace Catalyst::Runtime
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
// Copyright 2022-2023 Xanadu Quantum Technologies Inc.
|
|
2
|
-
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
#pragma once
|
|
16
|
-
#ifndef RUNTIMECAPI_H
|
|
17
|
-
#define RUNTIMECAPI_H
|
|
18
|
-
|
|
19
|
-
#include "Types.h"
|
|
20
|
-
|
|
21
|
-
#ifdef __cplusplus
|
|
22
|
-
extern "C" {
|
|
23
|
-
#endif
|
|
24
|
-
|
|
25
|
-
// Quantum Runtime Instructions
|
|
26
|
-
void __catalyst__rt__fail_cstr(const char *);
|
|
27
|
-
void __catalyst__rt__initialize(uint32_t *seed);
|
|
28
|
-
void __catalyst__rt__device_init(int8_t *, int8_t *, int8_t *);
|
|
29
|
-
void __catalyst__rt__device_release();
|
|
30
|
-
void __catalyst__rt__finalize();
|
|
31
|
-
void __catalyst__rt__toggle_recorder(bool);
|
|
32
|
-
void __catalyst__rt__print_state();
|
|
33
|
-
void __catalyst__rt__print_tensor(OpaqueMemRefT *, bool);
|
|
34
|
-
void __catalyst__rt__print_string(char *);
|
|
35
|
-
void __catalyst__rt__assert_bool(bool, char *);
|
|
36
|
-
int64_t __catalyst__rt__array_get_size_1d(QirArray *);
|
|
37
|
-
int8_t *__catalyst__rt__array_get_element_ptr_1d(QirArray *, int64_t);
|
|
38
|
-
|
|
39
|
-
QUBIT *__catalyst__rt__qubit_allocate();
|
|
40
|
-
QirArray *__catalyst__rt__qubit_allocate_array(int64_t);
|
|
41
|
-
void __catalyst__rt__qubit_release(QUBIT *);
|
|
42
|
-
void __catalyst__rt__qubit_release_array(QirArray *);
|
|
43
|
-
|
|
44
|
-
int64_t __catalyst__rt__num_qubits();
|
|
45
|
-
|
|
46
|
-
bool __catalyst__rt__result_equal(RESULT *, RESULT *);
|
|
47
|
-
RESULT *__catalyst__rt__result_get_one();
|
|
48
|
-
RESULT *__catalyst__rt__result_get_zero();
|
|
49
|
-
|
|
50
|
-
// Quantum Gate Set Instructions
|
|
51
|
-
void __catalyst__qis__SetState(MemRefT_CplxT_double_1d *, uint64_t, ...);
|
|
52
|
-
void __catalyst__qis__SetBasisState(MemRefT_int8_1d *, uint64_t, ...);
|
|
53
|
-
void __catalyst__qis__Identity(QUBIT *, const Modifiers *);
|
|
54
|
-
void __catalyst__qis__PauliX(QUBIT *, const Modifiers *);
|
|
55
|
-
void __catalyst__qis__PauliY(QUBIT *, const Modifiers *);
|
|
56
|
-
void __catalyst__qis__PauliZ(QUBIT *, const Modifiers *);
|
|
57
|
-
void __catalyst__qis__Hadamard(QUBIT *, const Modifiers *);
|
|
58
|
-
void __catalyst__qis__S(QUBIT *, const Modifiers *);
|
|
59
|
-
void __catalyst__qis__T(QUBIT *, const Modifiers *);
|
|
60
|
-
void __catalyst__qis__PhaseShift(double, QUBIT *, const Modifiers *);
|
|
61
|
-
void __catalyst__qis__RX(double, QUBIT *, const Modifiers *);
|
|
62
|
-
void __catalyst__qis__RY(double, QUBIT *, const Modifiers *);
|
|
63
|
-
void __catalyst__qis__RZ(double, QUBIT *, const Modifiers *);
|
|
64
|
-
void __catalyst__qis__Rot(double, double, double, QUBIT *, const Modifiers *);
|
|
65
|
-
void __catalyst__qis__CNOT(QUBIT *, QUBIT *, const Modifiers *);
|
|
66
|
-
void __catalyst__qis__CY(QUBIT *, QUBIT *, const Modifiers *);
|
|
67
|
-
void __catalyst__qis__CZ(QUBIT *, QUBIT *, const Modifiers *);
|
|
68
|
-
void __catalyst__qis__SWAP(QUBIT *, QUBIT *, const Modifiers *);
|
|
69
|
-
void __catalyst__qis__IsingXX(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
70
|
-
void __catalyst__qis__IsingYY(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
71
|
-
void __catalyst__qis__IsingXY(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
72
|
-
void __catalyst__qis__IsingZZ(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
73
|
-
void __catalyst__qis__ControlledPhaseShift(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
74
|
-
void __catalyst__qis__CRX(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
75
|
-
void __catalyst__qis__CRY(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
76
|
-
void __catalyst__qis__CRZ(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
77
|
-
void __catalyst__qis__CRot(double, double, double, QUBIT *, QUBIT *, const Modifiers *);
|
|
78
|
-
void __catalyst__qis__CSWAP(QUBIT *, QUBIT *, QUBIT *, const Modifiers *);
|
|
79
|
-
void __catalyst__qis__Toffoli(QUBIT *, QUBIT *, QUBIT *, const Modifiers *);
|
|
80
|
-
void __catalyst__qis__MultiRZ(double, const Modifiers *, int64_t, /*qubits*/...);
|
|
81
|
-
void __catalyst__qis__GlobalPhase(double, const Modifiers *);
|
|
82
|
-
void __catalyst__qis__ISWAP(QUBIT *, QUBIT *, const Modifiers *);
|
|
83
|
-
void __catalyst__qis__PSWAP(double, QUBIT *, QUBIT *, const Modifiers *);
|
|
84
|
-
|
|
85
|
-
// Struct pointer arguments for these instructions represent real arguments,
|
|
86
|
-
// as passing structs by value is too unreliable / compiler dependant.
|
|
87
|
-
void __catalyst__qis__QubitUnitary(MemRefT_CplxT_double_2d *, const Modifiers *, int64_t,
|
|
88
|
-
/*qubits*/...);
|
|
89
|
-
|
|
90
|
-
ObsIdType __catalyst__qis__NamedObs(int64_t, QUBIT *);
|
|
91
|
-
ObsIdType __catalyst__qis__HermitianObs(MemRefT_CplxT_double_2d *, int64_t, /*qubits*/...);
|
|
92
|
-
ObsIdType __catalyst__qis__TensorObs(int64_t, /*obsKeys*/...);
|
|
93
|
-
ObsIdType __catalyst__qis__HamiltonianObs(MemRefT_double_1d *, int64_t, /*obsKeys*/...);
|
|
94
|
-
|
|
95
|
-
// Struct pointers arguments here represent return values.
|
|
96
|
-
RESULT *__catalyst__qis__Measure(QUBIT *, int32_t);
|
|
97
|
-
double __catalyst__qis__Expval(ObsIdType);
|
|
98
|
-
double __catalyst__qis__Variance(ObsIdType);
|
|
99
|
-
void __catalyst__qis__Probs(MemRefT_double_1d *, int64_t, /*qubits*/...);
|
|
100
|
-
void __catalyst__qis__Sample(MemRefT_double_2d *, int64_t, int64_t, /*qubits*/...);
|
|
101
|
-
void __catalyst__qis__Counts(PairT_MemRefT_double_int64_1d *, int64_t, int64_t, /*qubits*/...);
|
|
102
|
-
void __catalyst__qis__State(MemRefT_CplxT_double_1d *, int64_t, /*qubits*/...);
|
|
103
|
-
void __catalyst__qis__Gradient(int64_t, /*results*/...);
|
|
104
|
-
void __catalyst__qis__Gradient_params(MemRefT_int64_1d *, int64_t, /*results*/...);
|
|
105
|
-
|
|
106
|
-
void __catalyst__host__rt__unrecoverable_error();
|
|
107
|
-
|
|
108
|
-
#ifdef __cplusplus
|
|
109
|
-
} // extern "C"
|
|
110
|
-
#endif
|
|
111
|
-
|
|
112
|
-
#endif
|
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
// Copyright 2022-2023 Xanadu Quantum Technologies Inc.
|
|
2
|
-
|
|
3
|
-
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
// you may not use this file except in compliance with the License.
|
|
5
|
-
// You may obtain a copy of the License at
|
|
6
|
-
|
|
7
|
-
// http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
|
|
9
|
-
// Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
// See the License for the specific language governing permissions and
|
|
13
|
-
// limitations under the License.
|
|
14
|
-
|
|
15
|
-
#pragma once
|
|
16
|
-
#ifndef TYPES_H
|
|
17
|
-
#define TYPES_H
|
|
18
|
-
|
|
19
|
-
#include <cmath>
|
|
20
|
-
#include <cstdint>
|
|
21
|
-
#include <limits>
|
|
22
|
-
|
|
23
|
-
#ifdef __cplusplus
|
|
24
|
-
extern "C" {
|
|
25
|
-
#endif
|
|
26
|
-
|
|
27
|
-
// Qubit, Result and Observable types
|
|
28
|
-
struct QUBIT;
|
|
29
|
-
using QubitIdType = intptr_t;
|
|
30
|
-
|
|
31
|
-
using RESULT = bool;
|
|
32
|
-
using Result = RESULT *;
|
|
33
|
-
using QirArray = void *;
|
|
34
|
-
|
|
35
|
-
using ObsIdType = intptr_t;
|
|
36
|
-
|
|
37
|
-
enum ObsId : int8_t {
|
|
38
|
-
Identity = 0,
|
|
39
|
-
PauliX,
|
|
40
|
-
PauliY,
|
|
41
|
-
PauliZ,
|
|
42
|
-
Hadamard,
|
|
43
|
-
Hermitian,
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
enum ObsType : int8_t {
|
|
47
|
-
Basic = 0,
|
|
48
|
-
TensorProd,
|
|
49
|
-
Hamiltonian,
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
// complex<float> type
|
|
53
|
-
struct CplxT_float {
|
|
54
|
-
float real;
|
|
55
|
-
float imag;
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
// complex<double> type
|
|
59
|
-
struct CplxT_double {
|
|
60
|
-
double real;
|
|
61
|
-
double imag;
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
enum NumericType : int8_t {
|
|
65
|
-
idx = 0,
|
|
66
|
-
i1,
|
|
67
|
-
i8,
|
|
68
|
-
i16,
|
|
69
|
-
i32,
|
|
70
|
-
i64,
|
|
71
|
-
f32,
|
|
72
|
-
f64,
|
|
73
|
-
c64,
|
|
74
|
-
c128,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
// MemRefT<datatype, dimension=rank> type
|
|
78
|
-
struct OpaqueMemRefT {
|
|
79
|
-
int64_t rank;
|
|
80
|
-
void *descriptor;
|
|
81
|
-
NumericType datatype;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// MemRefT<complex<double>, dimension=1> type
|
|
85
|
-
struct MemRefT_CplxT_double_1d {
|
|
86
|
-
CplxT_double *data_allocated;
|
|
87
|
-
CplxT_double *data_aligned;
|
|
88
|
-
size_t offset;
|
|
89
|
-
size_t sizes[1];
|
|
90
|
-
size_t strides[1];
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
// MemRefT<complex<double>, dimension=2> type
|
|
94
|
-
struct MemRefT_CplxT_double_2d {
|
|
95
|
-
CplxT_double *data_allocated;
|
|
96
|
-
CplxT_double *data_aligned;
|
|
97
|
-
size_t offset;
|
|
98
|
-
size_t sizes[2];
|
|
99
|
-
size_t strides[2];
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
// MemRefT<double, dimension=1> type
|
|
103
|
-
struct MemRefT_double_1d {
|
|
104
|
-
double *data_allocated;
|
|
105
|
-
double *data_aligned;
|
|
106
|
-
size_t offset;
|
|
107
|
-
size_t sizes[1];
|
|
108
|
-
size_t strides[1];
|
|
109
|
-
};
|
|
110
|
-
|
|
111
|
-
// MemRefT<double, dimension=2> type
|
|
112
|
-
struct MemRefT_double_2d {
|
|
113
|
-
double *data_allocated;
|
|
114
|
-
double *data_aligned;
|
|
115
|
-
size_t offset;
|
|
116
|
-
size_t sizes[2];
|
|
117
|
-
size_t strides[2];
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
// MemRefT<int64_t, dimension=1> type
|
|
121
|
-
struct MemRefT_int64_1d {
|
|
122
|
-
int64_t *data_allocated;
|
|
123
|
-
int64_t *data_aligned;
|
|
124
|
-
size_t offset;
|
|
125
|
-
size_t sizes[1];
|
|
126
|
-
size_t strides[1];
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// MemRefT<int64_t, dimension=1> type
|
|
130
|
-
struct MemRefT_int8_1d {
|
|
131
|
-
int8_t *data_allocated;
|
|
132
|
-
int8_t *data_aligned;
|
|
133
|
-
size_t offset;
|
|
134
|
-
size_t sizes[1];
|
|
135
|
-
size_t strides[1];
|
|
136
|
-
};
|
|
137
|
-
|
|
138
|
-
// PairT<MemRefT<double, dimension=1>, MemRefT<int64, dimension=2>> type
|
|
139
|
-
struct PairT_MemRefT_double_int64_1d {
|
|
140
|
-
struct MemRefT_double_1d first;
|
|
141
|
-
struct MemRefT_int64_1d second;
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
// Quantum operation modifiers
|
|
145
|
-
struct Modifiers {
|
|
146
|
-
bool adjoint;
|
|
147
|
-
size_t num_controlled;
|
|
148
|
-
QUBIT *controlled_wires;
|
|
149
|
-
bool *controlled_values;
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
using CplxT_double = struct CplxT_double;
|
|
153
|
-
using MemRefT_CplxT_double_1d = struct MemRefT_CplxT_double_1d;
|
|
154
|
-
using MemRefT_CplxT_double_2d = struct MemRefT_CplxT_double_2d;
|
|
155
|
-
using MemRefT_double_1d = struct MemRefT_double_1d;
|
|
156
|
-
using MemRefT_double_2d = struct MemRefT_double_2d;
|
|
157
|
-
using MemRefT_int64_1d = struct MemRefT_int64_1d;
|
|
158
|
-
using PairT_MemRefT_double_int64_1d = struct PairT_MemRefT_double_int64_1d;
|
|
159
|
-
using Modifiers = struct Modifiers;
|
|
160
|
-
|
|
161
|
-
#ifdef __cplusplus
|
|
162
|
-
} // extern "C"
|
|
163
|
-
#endif
|
|
164
|
-
|
|
165
|
-
#endif
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pennylane_qrack-0.20.3 → pennylane_qrack-0.21.1}/pennylane_qrack.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|