This repository was archived by the owner on Jan 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 90
T anikda/experimental #291
Merged
AniketDalvi
merged 15 commits into
feature/simulator-enhancement
from
t-anikda/experimental
Jul 30, 2020
Merged
Changes from all commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
e32e0b2
Initial wfn permute changes
f48134e
changes to reorder to fix minor bugs
3281075
rebase with clean sim branch
c3189fb
Reordering wfn to work with existing flush/fuse logic
4beea14
resolving conflicts
d6b2ca2
Added some comments
91eef28
Merge branch 'master' of https://github.com/microsoft/qsharp-runtime …
945fb33
Merge branch 'feature/simulator-enhancement' of https://github.com/mi…
1c4b977
Combining Dave's scheduling logic with reordering
97bd17c
PR changes
1c4b04f
PR changes
07bbb87
PR changes
d91fab3
PR change to avoid copying
8f3c963
PR changes
bcb37db
PR changes to undo character change in Haner
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| { | ||
| "configurations": [ | ||
| { | ||
| "name": "x64-Debug", | ||
| "generator": "Ninja", | ||
| "configurationType": "Debug", | ||
| "inheritEnvironments": [ "msvc_x64_x64" ], | ||
| "buildRoot": "${projectDir}\\out\\build\\${name}", | ||
| "installRoot": "${projectDir}\\out\\install\\${name}", | ||
| "cmakeCommandArgs": "", | ||
| "buildCommandArgs": "", | ||
| "ctestCommandArgs": "", | ||
| "variables": [] | ||
| }, | ||
| { | ||
| "name": "x64-Release", | ||
| "generator": "Ninja", | ||
| "configurationType": "RelWithDebInfo", | ||
| "buildRoot": "${projectDir}\\out\\build\\${name}", | ||
| "installRoot": "${projectDir}\\out\\install\\${name}", | ||
| "cmakeCommandArgs": "", | ||
| "buildCommandArgs": "", | ||
| "ctestCommandArgs": "", | ||
| "inheritEnvironments": [ "msvc_x64_x64" ], | ||
| "variables": [] | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -10,21 +10,28 @@ | |
| #include <iostream> | ||
| #include <cassert> | ||
| #include "util/alignedalloc.hpp" | ||
| #include <unordered_map> | ||
|
|
||
| class Item{ | ||
| public: | ||
| using Index = unsigned; | ||
| using IndexVector = std::vector<Index>; | ||
| using Complex = std::complex<double>; | ||
| using Matrix = std::vector<std::vector<Complex, Microsoft::Quantum::Simulator::AlignedAlloc<Complex, 64>>>; | ||
| Item(Matrix mat, IndexVector idx) : mat_(mat), idx_(idx) {} | ||
| Item(Matrix mat, IndexVector idx) : mat_(std::move(mat)), idx_(idx) {} | ||
| Matrix& get_matrix() { return mat_; } | ||
| IndexVector& get_indices() { return idx_; } | ||
| IndexVector& get_indices() const { return idx_; } | ||
| void remap_idx(std::unordered_map<unsigned, unsigned> elemDict) const { | ||
| for (size_t i = 0; i < idx_.size(); i++) { | ||
| idx_[i] = elemDict[idx_[i]]; | ||
| } | ||
| } | ||
| private: | ||
| Matrix mat_; | ||
| IndexVector idx_; | ||
| mutable IndexVector idx_; | ||
| }; | ||
|
|
||
| // Class handling the fusion of gates | ||
| class Fusion{ | ||
| public: | ||
| using Index = unsigned; | ||
|
|
@@ -37,7 +44,7 @@ class Fusion{ | |
| Fusion() : global_factor_(1.) {} | ||
|
|
||
| Index num_qubits() const { | ||
| return static_cast<Index>(set_.size()); | ||
| return static_cast<Index>(target_set_.size()); | ||
| } | ||
|
|
||
| Index num_controls() const { | ||
|
|
@@ -58,21 +65,58 @@ class Fusion{ | |
| handle_controls(empty_matrix, empty_vec, {}); // remove all current control qubits (this is a GLOBAL factor) | ||
| } | ||
|
|
||
| const IndexSet& get_target_set() const { | ||
| return target_set_; | ||
| } | ||
|
|
||
| const ItemVector& get_items() const { | ||
| return items_; | ||
| } | ||
|
|
||
| const IndexSet& get_ctrl_set() const { | ||
| return ctrl_set_; | ||
| } | ||
|
|
||
| const Complex& get_global_factor() const { | ||
| return global_factor_; | ||
| } | ||
|
|
||
| static void remap_qubits(std::set<Index>& qubits, const std::unordered_map<unsigned, unsigned>& mapFromOldLocToNewLoc) { | ||
| std::set<Index> tempSet; | ||
| for (unsigned elem : qubits) { | ||
| if (mapFromOldLocToNewLoc.find(elem) != mapFromOldLocToNewLoc.end()) { | ||
| tempSet.insert(mapFromOldLocToNewLoc.at(elem)); | ||
| } | ||
| } | ||
| qubits.swap(tempSet); | ||
| } | ||
|
|
||
| void remap_target_set(const std::unordered_map<unsigned, unsigned>& mapFromOldLocToNewLoc) const { | ||
| remap_qubits(target_set_, mapFromOldLocToNewLoc); | ||
| } | ||
|
|
||
| void remap_ctrl_set(const std::unordered_map<unsigned, unsigned>& mapFromOldLocToNewLoc) const { | ||
| remap_qubits(ctrl_set_, mapFromOldLocToNewLoc); | ||
| } | ||
|
|
||
| void set_items(ItemVector&& newItems) { | ||
| items_.swap(newItems); | ||
| } | ||
AniketDalvi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| // This saves a class instance create/destroy on every gate insert | ||
| // Need a quick way to decide if we're going to grow too wide | ||
| int predict(IndexVector index_list, IndexVector const& ctrl_list = {}) { | ||
| int cnt = num_qubits() + num_controls(); | ||
| for (auto idx : index_list) | ||
| if (set_.count(idx) == 0 && ctrl_set_.count(idx) == 0) cnt++; | ||
| if (target_set_.count(idx) == 0 && ctrl_set_.count(idx) == 0) cnt++; | ||
| for (auto idx : ctrl_list) | ||
| if (set_.count(idx) == 0 && ctrl_set_.count(idx) == 0) cnt++; | ||
| if (target_set_.count(idx) == 0 && ctrl_set_.count(idx) == 0) cnt++; | ||
| return cnt; | ||
| } | ||
|
|
||
| void insert(Matrix matrix, IndexVector index_list, IndexVector const& ctrl_list = {}){ | ||
| for (auto idx : index_list) | ||
| set_.emplace(idx); | ||
| target_set_.emplace(idx); | ||
|
|
||
| if (global_factor_ != 1. && ctrl_list.size() > 0){ | ||
| assert(ctrl_set_.size() == 0); | ||
|
|
@@ -85,15 +129,15 @@ class Fusion{ | |
| } | ||
|
|
||
| void get_indices(IndexVector &indices) const{ | ||
| for (auto idx : set_) | ||
| for (auto idx : target_set_) | ||
| indices.push_back(idx); | ||
| } | ||
|
|
||
| void perform_fusion(Matrix& fused_matrix, IndexVector& index_list, IndexVector& ctrl_list){ | ||
| if (global_factor_ != 1.) | ||
| assert(ctrl_set_.size() == 0); | ||
|
|
||
| for (auto idx : set_) | ||
| for (auto idx : target_set_) | ||
| index_list.push_back(idx); | ||
|
|
||
| unsigned N = num_qubits(); | ||
|
|
@@ -167,7 +211,7 @@ class Fusion{ | |
| if (ctrl_set_.count(ctrlIdx) == 0){ // need to either add it to the list or to the command | ||
| if (items_.size() > 0){ // add it to the command | ||
| add_controls(matrix, indexList, {ctrlIdx}); | ||
| set_.insert(ctrlIdx); | ||
| target_set_.insert(ctrlIdx); | ||
| } | ||
| else // add it to the list | ||
| ctrl_set_.emplace(ctrlIdx); | ||
|
|
@@ -183,17 +227,17 @@ class Fusion{ | |
| for (auto idx : unhandled_ctrl){ | ||
| new_ctrls.push_back(idx); | ||
| ctrl_set_.erase(idx); | ||
| set_.insert(idx); | ||
| target_set_.insert(idx); | ||
| } | ||
| for (auto &item : items_) | ||
| add_controls(item.get_matrix(), item.get_indices(), new_ctrls); | ||
| } | ||
| } | ||
|
|
||
| IndexSet set_; | ||
| ItemVector items_; | ||
| IndexSet ctrl_set_; | ||
| Complex global_factor_; | ||
| mutable IndexSet target_set_; //set of qubits being acted on | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still believe that it would be better to remove |
||
| mutable ItemVector items_; //queue if gates to be fused | ||
| mutable IndexSet ctrl_set_; //set of controls | ||
| mutable Complex global_factor_; | ||
| }; | ||
|
|
||
| #endif | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Declaring setters as
constdoesn't make sense: the purpose of the setter is to change the object, isn't it?Another problem with the signature is that it still does an extra unnecessary copy of
Fusionobject, first into the parameter when the function is invoked and then once again from the parameter intofusedgates. Change it tovoid set_fusedgates(const Fusion& newFusedGates) { fusedgates = newFusedGates; }There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be set as const, as I am calling it in flush() which is const. Yes, the setter is supposed to change the object - but in this case by change here we are changing the contents of the container, not the container or its location.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As a part of public class interface a const setter doesn't make much sense, whatever the implementation details of other methods might be. If clients outside of the class need to use the setter (for example, tests), make it non-const for them and inside
flush()do the assignment directly, without going through the setter.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Apologies, I did not really understand what you were trying to convey here completely. Unfortunately because the data structure fusedgates is private, I cannot make the assignments outside this class, thereby not allowing me to make assignments in flush() directly. Given this, the use of a setter is necessary to alter the datastructure. And as this setter is being called in a function which is declared const, the language does not allow me to have the setter to be non-const.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"funny" public interfaces like this usually indicate that there is an issue with design of data structures: basically, you are trying to put a square peg into a round hole. You have multiple choices to address it:
constfrom member functions that violate constness (easy, as any chickening out is, but honest :))Personally, for a quick solution I'd go with either 2 or 3.
Your call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thought about this a little. Given a couple of factors - what this branch is trying to achieve and considering that I have just a couple of weeks left, I think it will be good idea for me to create an issue outlining this very relevant issue you bring up which can be tackled later. The only reason I say that is because I feel this deviates a little from the original purpose of this branch, and that making this const change is going to take some time as it very deeply entrenched in the simulator codebase, and I am hoping to get a couple of more branches checked-in before the end of my internship, and want to leave enough time for that. Thank you!