Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Commit 8b42674

Browse files
troels-imdime10Chris Granadericardo-espinozabettinaheim
authored
QAT: Improving architecture and configuration management (#1134)
* Optimization example: revert PR #1100 (#1125) * Use stdin/stdout instead of TCP/IP. (#1118) * Use stdin/stdout instead of TCP/IP. * Update package-lock. Co-authored-by: Ricardo Espinoza <[email protected]> * Add QIR JIT compilation from Python example (#1124) * Add QIR JIT compilation example in Python * Add README to JIT example and update for Windows * Small fix to JIT example README * Fix NuGet instructions on Linux * More fixes for Linux Co-authored-by: bettinaheim <[email protected]> Co-authored-by: Stefan J. Wernli <[email protected]> * Update Using and Borrowing Syntax (#1099) * Adding new custom simulator example (#1120) * Initial implementation of a simple simulator for QIR. Goal: Implement an example simulator that is easy to understand and maps more or less directly to the theory. Based on the Eigen C++ linear algebra library. Untested, guide to come. * Small tweaks to QIR simulator example * Restructured version of the Simulator example to separate out components. * First portion of QIR Runtime simulator guide * Add second simulator type: trace simulator Move each simulator to its own subdirectory. * Update Simulation example readme with simulator structure and trace simulator implementation * Remove version 1 of the simulation example * Split out TraceSimulator from top-level README and add run instructions * Move headers and libraries into subfolders * Remove version number from example folder name * Add explanation of the full state simulator sample * Remove duplicate information from top-level simulation sample README * Update structure of top-level simulation sample README * Small fixes to top-level simulator readme * Use and update relative links within repo * Small formatting changes to the sample state simulator README * Add more details on including the Eigen library * Apply suggestions from code review Co-authored-by: Chris Granade <[email protected]> * Add copyright header to source files * Use unicode angle brackets for quantum states * Small fixes to top-level README of simulation example * Get QIR Runtime dependencies from NuGet package instead * Add Linux instructions to sample simulators * Better formatting of the Windows/Linux separation * Apply suggestions from code review. * Add notice about Clang requirement to compile sample * Update examples/QIR/Simulation/TraceSimulator/README.md * Update examples/QIR/Simulation/StateSimulator/README.md Co-authored-by: Chris Granade <[email protected]> Co-authored-by: Stefan J. Wernli <[email protected]> * Fixing memory leak in generated QIR (#1129) * Creating module based configuration * Adding configuration modules * More refactoring * Deprecating RuleSet profile * Refactoring * Finishing dump config * Preparing for draft PR * Cleaning * More refactoring * Preparing error logging * Fixing CI * Adding commandline tests * Refactor * Fixing issues * Minor changes * Style fixing * Update Unit Syntax (#1103) * Renaming pass * More refactor * Finalising component registration * Formatting style * Minor refactor * Fixed CI * More tests * Removing example QIR * Update Array Syntax (#1135) * Update readme links to runtime repo (#1137) * Updating test * Updating Phi tests * CI update * Removing garbage * Updating according to requests * Removing garbage * Updating config binder Co-authored-by: dime10 <[email protected]> Co-authored-by: Chris Granade <[email protected]> Co-authored-by: Ricardo Espinoza <[email protected]> Co-authored-by: bettinaheim <[email protected]> Co-authored-by: Stefan J. Wernli <[email protected]> Co-authored-by: Scott Carda <[email protected]>
1 parent f0c8227 commit 8b42674

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

62 files changed

+2943
-700
lines changed

src/Passes/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,6 @@ test-examples:
2121
clean:
2222
rm -rf Release/
2323
rm -rf Debug/
24+
find . | grep ".profraw" | xargs rm
2425
cd examples && make clean
2526

src/Passes/Source/AllocationManager/AllocationManager.cpp

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,15 @@ namespace microsoft
1212
namespace quantum
1313
{
1414

15-
AllocationManager::AllocationManagerPtr AllocationManager::createNew()
15+
BasicAllocationManager::BasicAllocationManagerPtr BasicAllocationManager::createNew()
1616
{
17-
AllocationManagerPtr ret;
18-
ret.reset(new AllocationManager());
17+
BasicAllocationManagerPtr ret;
18+
ret.reset(new BasicAllocationManager());
1919

2020
return ret;
2121
}
2222

23-
AllocationManager::Index AllocationManager::allocate(String const& name, Index const& size)
23+
BasicAllocationManager::Index BasicAllocationManager::allocate(String const& name, Index const& size)
2424
{
2525
auto ret = next_qubit_index_;
2626

@@ -44,12 +44,7 @@ namespace quantum
4444
return ret;
4545
}
4646

47-
AllocationManager::Address AllocationManager::getAddress(Address const& address, Index const& n) const
48-
{
49-
return address + n;
50-
}
51-
52-
void AllocationManager::release(Address const& address)
47+
void BasicAllocationManager::release(Address const& address)
5348
{
5449
--allocation_index_;
5550
auto it = mappings_.begin();
@@ -67,16 +62,24 @@ namespace quantum
6762
}
6863

6964
mappings_.erase(it);
70-
if (mappings_.empty())
71-
{
72-
next_qubit_index_ = 0;
73-
}
74-
else
65+
if (reuse_qubits_)
7566
{
76-
auto& b = mappings_.back();
77-
next_qubit_index_ = b.start + b.size;
67+
if (mappings_.empty())
68+
{
69+
next_qubit_index_ = 0;
70+
}
71+
else
72+
{
73+
auto& b = mappings_.back();
74+
next_qubit_index_ = b.start + b.size;
75+
}
7876
}
7977
}
8078

79+
void BasicAllocationManager::setReuseQubits(bool val)
80+
{
81+
reuse_qubits_ = val;
82+
}
83+
8184
} // namespace quantum
8285
} // namespace microsoft

src/Passes/Source/AllocationManager/AllocationManager.hpp

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// Copyright (c) Microsoft Corporation.
33
// Licensed under the MIT License.
44

5+
#include "AllocationManager/IAllocationManager.hpp"
6+
57
#include "Llvm/Llvm.hpp"
68

79
#include <memory>
@@ -13,14 +15,10 @@ namespace microsoft
1315
{
1416
namespace quantum
1517
{
16-
// TODO(QAT-private-issue-35): work out similarities and differences between resource allocation at
17-
// runtime and compile time to make common interface and/or implementation depending on what is most
18-
// suited.
19-
2018
/// AllocationManager is a simple qubit and results allocator that can be used at compile-time.
2119
/// It is based on an assumption that all qubit allocating function calls are inlined and that
2220
/// qubits/results can be allocated with strictly growing IDs.
23-
class AllocationManager
21+
class BasicAllocationManager : public IAllocationManager
2422
{
2523
public:
2624
/// Defines a named register/memory segment with start
@@ -38,15 +36,13 @@ namespace quantum
3836
Address end{0}; ///< Index not included in memory segment
3937
};
4038

41-
using Address = uint64_t;
42-
using Index = uint64_t;
43-
using String = std::string;
44-
using AllocationManagerPtr = std::shared_ptr<AllocationManager>;
45-
using Resource = std::vector<llvm::Value*>;
46-
using Resources = std::unordered_map<std::string, Resource>;
47-
using NameToIndex = std::unordered_map<String, Index>;
48-
using AddressToIndex = std::unordered_map<Address, Index>;
49-
using Mappings = std::vector<MemoryMapping>;
39+
using Address = uint64_t;
40+
using Index = uint64_t;
41+
using String = std::string;
42+
using NameToIndex = std::unordered_map<String, Index>;
43+
using AddressToIndex = std::unordered_map<Address, Index>;
44+
using Mappings = std::vector<MemoryMapping>;
45+
using BasicAllocationManagerPtr = std::shared_ptr<BasicAllocationManager>;
5046

5147
/// Construction only allowed using smart pointer allocation through static functions.
5248
/// Constructors are private to prevent
@@ -55,7 +51,7 @@ namespace quantum
5551
/// Creates a new allocation manager. The manager is kept
5652
/// as a shared pointer to enable allocation accross diffent
5753
/// passes and/or replacement rules.
58-
static AllocationManagerPtr createNew();
54+
static BasicAllocationManagerPtr createNew();
5955
/// @}
6056

6157
/// Allocation and release functions
@@ -66,23 +62,24 @@ namespace quantum
6662
/// of a larger segment, the function returns the address pointing to the first element.
6763
/// Allocation is garantueed to be sequential. Note that this assumption may change in the
6864
/// future and to be future proof, please use AllocationManager::getAddress().
69-
Address allocate(String const& name = "", Index const& size = 1);
70-
71-
/// Gets the Address of n'th element in a segment given the segments address.
72-
Address getAddress(Address const& address, Index const& n) const;
65+
Address allocate(String const& name = "", Index const& size = 1) override;
7366

7467
/// Releases the segment by address.
75-
void release(Address const& address);
68+
void release(Address const& address) override;
7669

7770
/// @}
7871

72+
/// Configuration function to set mode of qubit allocation. If function argument is true,
73+
/// the allocation manager will reuse qubits.
74+
void setReuseQubits(bool val);
75+
7976
private:
8077
/// Private constructors
8178
/// @{
8279
/// Public construction of this object is only allowed
8380
/// as a shared pointer. To create a new AllocationManager,
8481
/// use AllocationManager::createNew().
85-
AllocationManager() = default;
82+
BasicAllocationManager() = default;
8683
/// @}
8784

8885
/// Variables used for mode_ == NeverReuse
@@ -103,6 +100,9 @@ namespace quantum
103100
/// @}
104101

105102
Index allocation_index_{0};
103+
104+
/// Whether or not to reuse qubits
105+
bool reuse_qubits_{true};
106106
};
107107

108108
} // namespace quantum
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4-
#include "Profiles/IProfile.hpp"
4+
#include "AllocationManager/IAllocationManager.hpp"
55

66
namespace microsoft
77
{
88
namespace quantum
99
{
1010

11-
IProfile::~IProfile() = default;
11+
IAllocationManager::~IAllocationManager() = default;
1212

1313
} // namespace quantum
1414
} // namespace microsoft
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
// Copyright (c) Microsoft Corporation.
3+
// Licensed under the MIT License.
4+
5+
#include "Llvm/Llvm.hpp"
6+
7+
#include <memory>
8+
#include <string>
9+
#include <unordered_map>
10+
#include <vector>
11+
12+
namespace microsoft
13+
{
14+
namespace quantum
15+
{
16+
17+
class IAllocationManager
18+
{
19+
public:
20+
using Address = uint64_t;
21+
using Index = uint64_t;
22+
using String = std::string;
23+
using AllocationManagerPtr = std::shared_ptr<IAllocationManager>;
24+
25+
virtual ~IAllocationManager();
26+
virtual Address allocate(String const& name = "", Index const& size = 1) = 0;
27+
virtual void release(Address const& address) = 0;
28+
};
29+
30+
} // namespace quantum
31+
} // namespace microsoft

src/Passes/Source/AllocationManager/Tests/Unit/main.cpp

Lines changed: 89 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,99 @@
44
#include "AllocationManager/AllocationManager.hpp"
55
#include "gtest/gtest.h"
66

7-
TEST(AllocationManagerTestSuite, LinearAllocationTest)
7+
TEST(AllocationManagerTestSuite, LinearAllocationTestReuse)
88
{
9-
auto manager = microsoft::quantum::AllocationManager::createNew();
9+
auto manager = microsoft::quantum::BasicAllocationManager::createNew();
10+
manager->setReuseQubits(true);
1011

1112
// Expecting ids to be allocated linearly for single
1213
// allocations
13-
EXPECT_TRUE(manager->allocate() == 0);
14-
EXPECT_TRUE(manager->allocate() == 1);
15-
EXPECT_TRUE(manager->allocate() == 2);
16-
EXPECT_TRUE(manager->allocate() == 3);
17-
EXPECT_TRUE(manager->allocate() == 4);
14+
auto q1 = manager->allocate();
15+
EXPECT_EQ(q1, 0);
16+
auto q2 = manager->allocate();
17+
EXPECT_EQ(q2, 1);
18+
auto q3 = manager->allocate();
19+
EXPECT_EQ(q3, 2);
20+
auto q4 = manager->allocate();
21+
EXPECT_EQ(q4, 3);
22+
auto q5 = manager->allocate();
23+
EXPECT_EQ(q5, 4);
1824

1925
// We expect that allocating
20-
manager->allocate("test", 10);
21-
EXPECT_TRUE(manager->allocate() == 15);
22-
manager->allocate("test2", 10);
26+
auto arr1 = manager->allocate("test", 10);
27+
EXPECT_EQ(arr1, 5);
28+
auto arr2 = manager->allocate("test2", 10);
29+
EXPECT_EQ(arr2, 15);
30+
31+
// Testing reusing
32+
manager->release(arr2);
33+
arr2 = manager->allocate("test2", 10);
34+
EXPECT_EQ(arr2, 15);
35+
36+
manager->release(arr2);
37+
manager->release(q1);
38+
manager->release(q2);
39+
manager->release(q3);
40+
manager->release(q4);
41+
manager->release(q5);
42+
arr2 = manager->allocate("test2", 10);
43+
EXPECT_EQ(arr2, 15);
44+
45+
manager->release(arr1);
46+
manager->release(arr2);
47+
arr2 = manager->allocate("test2", 10);
48+
EXPECT_EQ(arr2, 0);
49+
}
50+
51+
TEST(AllocationManagerTestSuite, LinearAllocationTestNoReuse)
52+
{
53+
auto manager = microsoft::quantum::BasicAllocationManager::createNew();
54+
manager->setReuseQubits(false);
55+
56+
auto q1 = manager->allocate();
57+
EXPECT_EQ(q1, 0);
58+
auto q2 = manager->allocate();
59+
EXPECT_EQ(q2, 1);
60+
auto q3 = manager->allocate();
61+
EXPECT_EQ(q3, 2);
62+
auto q4 = manager->allocate();
63+
EXPECT_EQ(q4, 3);
64+
auto q5 = manager->allocate();
65+
EXPECT_EQ(q5, 4);
66+
67+
// We expect that allocating
68+
auto arr1 = manager->allocate("test", 10);
69+
EXPECT_EQ(arr1, 5);
70+
auto arr2 = manager->allocate("test2", 10);
71+
EXPECT_EQ(arr2, 15);
72+
73+
// Testing reusing
74+
manager->release(arr2);
75+
arr2 = manager->allocate("test2", 10);
76+
EXPECT_EQ(arr2, 25);
77+
78+
manager->release(arr2);
79+
manager->release(q1);
80+
manager->release(q2);
81+
manager->release(q3);
82+
manager->release(q4);
83+
manager->release(q5);
84+
arr2 = manager->allocate("test2", 10);
85+
EXPECT_EQ(arr2, 35);
86+
87+
manager->release(arr1);
88+
manager->release(arr2);
89+
arr2 = manager->allocate("test2", 10);
90+
EXPECT_EQ(arr2, 45);
91+
}
92+
93+
TEST(AllocationManagerTestSuite, InvalidRelease)
94+
{
95+
auto manager = microsoft::quantum::BasicAllocationManager::createNew();
96+
auto q1 = manager->allocate();
97+
EXPECT_EQ(q1, 0);
98+
auto q2 = manager->allocate();
99+
EXPECT_EQ(q2, 1);
100+
101+
EXPECT_THROW(manager->release(28837), std::runtime_error);
23102
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
add_executable(qat Qat/Qat.cpp Qat/LlvmAnalysis.cpp)
1+
add_executable(qat Qat/Qat.cpp Qat/LlvmAnalysis.cpp Qat/Config.cpp)
22

33
target_link_libraries(qat ${llvm_libs})
4-
target_link_libraries(qat ProfilePass Rules AllocationManager Commandline Profiles)
4+
target_link_libraries(qat RuleTransformationPass Rules AllocationManager Commandline Generators)

0 commit comments

Comments
 (0)