-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathBucketBrigadePhase.qs
117 lines (106 loc) · 4.77 KB
/
BucketBrigadePhase.qs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
namespace Tests {
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Arithmetic;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Logical;
open QsharpCommunity.Qram;
// Verify empty qRAMs are empty
@Test("QuantumSimulator")
operation BucketBrigadeOraclePhaseEmptyMatchResults() : Unit {
for addressSize in 1..3 {
let expectedValue = ConstantArray(2^addressSize, [false]);
let data = EmptyQRAM(addressSize);
let result = CreateBitQueryMeasureAllQRAM(data);
let pairs = Zipped(result, expectedValue);
Ignore(Mapped(
AllEqualityFactB(_, _, $"Expecting memory contents {expectedValue}, got {result}."),
pairs
));
}
}
// Verify full qRAMs are full
@Test("QuantumSimulator")
operation BucketBrigadeOraclePhaseFullMatchResults() : Unit {
for addressSize in 1..3 {
let expectedValue = ConstantArray(2^addressSize, [true]);
let data = FullQRAM(addressSize);
let result = CreateBitQueryMeasureAllQRAM(data);
let pairs = Zipped(result, expectedValue);
Ignore(Mapped(
AllEqualityFactB(_, _, $"Expecting memory contents {expectedValue}, got {result}."),
pairs
));
}
}
// Verify things work when only the first cell is full
@Test("QuantumSimulator")
operation BucketBrigadeOraclePhaseFirstCellFullMatchResults() : Unit {
for addressSize in 1..3 {
let expectedValue = [[true]] + ConstantArray(2^addressSize-1, [false]);
let data = FirstCellFullQRAM();
let result = CreateBitQueryMeasureAllQRAM(data);
let pairs = Zipped(result, expectedValue);
Ignore(Mapped(
AllEqualityFactB(_, _, $"Expecting memory contents {expectedValue}, got {result}."),
pairs
));
}
}
// Verify things work when only the second cell is full
@Test("QuantumSimulator")
operation BucketBrigadeOraclePhaseSecondCellFullMatchResults() : Unit {
for addressSize in 1..3 {
let expectedValue = [[false], [true]] + ConstantArray(2^addressSize-2, [false]);
let data = SecondCellFullQRAM();
let result = CreateBitQueryMeasureAllQRAM(data);
let pairs = Zipped(result, expectedValue);
Ignore(Mapped(
AllEqualityFactB(_, _, $"Expecting memory contents {expectedValue}, got {result}."),
pairs
));
}
}
// Verify things work when only the last cell is full
@Test("QuantumSimulator")
operation BucketBrigadeOraclePhaseLastCellFullMatchResults() : Unit {
for addressSize in 1..3 {
let expectedValue = ConstantArray(2^addressSize-1, [false]) + [[true]];
let data = LastCellFullQRAM(addressSize);
let result = CreateBitQueryMeasureAllQRAM(data);
let pairs = Zipped(result, expectedValue);
Ignore(Mapped(
AllEqualityFactB(_, _, $"Expecting memory contents {expectedValue}, got {result}."),
pairs
));
}
}
// Operation that creates a qRAM, and returns the contents for
// each address queried individually
internal operation CreatePhaseQueryMeasureAllQRAM(bank : MemoryBank) : Bool[][] {
mutable result = new Bool[][2^bank::AddressSize];
use (addressRegister, flatMemoryRegister, targetRegister) =
(Qubit[bank::AddressSize],
Qubit[bank::DataSize*(2^bank::AddressSize)],
Qubit[bank::DataSize]);
let memoryRegister = Most(Partitioned(ConstantArray(2^bank::AddressSize, bank::DataSize), flatMemoryRegister));
let memory = BucketBrigadeQRAMOracle(bank::DataSet, MemoryRegister(memoryRegister));
// Query each address sequentially and store in results array
for queryAddress in 0..2^bank::AddressSize-1 {
// Prepare the address register for the lookup
PrepareIntAddressRegister(queryAddress, addressRegister);
// Read out the memory at that address
memory::QueryPhase(AddressRegister(addressRegister), MemoryRegister(memoryRegister), targetRegister);
// Measure the target register and log the results
set result w/= queryAddress <- ResultArrayAsBoolArray(MultiM(targetRegister));
ResetAll(addressRegister + targetRegister);
}
// Done with the memory register now
ResetAll(flatMemoryRegister);
return result;
}
}