Skip to content

Commit 10eba27

Browse files
2 parents 16096e4 + 33a61be commit 10eba27

File tree

14 files changed

+753
-401
lines changed

14 files changed

+753
-401
lines changed

src/backend/backend.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "backend.h"
22

3-
circuit_id_t Backend::createCircuit() { return circuitManager.createNewCircuit(); }
3+
circuit_id_t Backend::createCircuit(const std::string& uuid, const std::string& name) { return circuitManager.createNewCircuit(uuid, name); }
44

55
std::optional<evaluator_id_t> Backend::createEvaluator(circuit_id_t circuitId) {
66
SharedCircuit circuit = circuitManager.getCircuit(circuitId);

src/backend/backend.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
#include "evaluator/evaluatorManager.h"
66
#include "circuit/circuitManager.h"
77
#include "tools/toolManagerManager.h"
8+
#include "util/uuid.h"
89

910
class Backend {
1011
public:
1112
Backend() : toolManagerManager(&circuitViews) {}
1213

1314
// Creates a new Circuit. Returns circuit_id_t.
14-
circuit_id_t createCircuit();
15+
circuit_id_t createCircuit(const std::string& uuid = generate_uuid_v4(), const std::string& name = "Circuit");
1516
// Attempts to create a Evaluator for a Circuit. Returns evaluator_id_t if successful.
1617
std::optional<evaluator_id_t> createEvaluator(circuit_id_t circuitId);
1718

src/backend/circuit/circuit.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,13 @@ typedef unsigned int circuit_update_count;
1414

1515
class Circuit {
1616
public:
17-
inline Circuit(circuit_id_t circuitId, BlockDataManager* blockDataManager ) : circuitId(circuitId), blockContainer(blockDataManager) { }
17+
inline Circuit(circuit_id_t circuitId, BlockDataManager* blockDataManager, const std::string& uuid, const std::string& name) :
18+
circuitId(circuitId), blockContainer(blockDataManager), circuitUUID(uuid), circuitName(name) { }
1819

20+
inline const std::string& getUUID() const { return circuitUUID; }
1921
inline circuit_id_t getCircuitId() const { return circuitId; }
20-
inline std::string getCircuitName() const { return "Circuit " + std::to_string(circuitId); }
22+
inline std::string getCircuitNameNumber() const { return circuitName + " : " + std::to_string(circuitId); }
23+
inline const std::string& getCircuitName() const { return circuitName; }
2124

2225
inline bool isSaved() const { return saved; }
2326
inline void setSaved() { saved = true; }
@@ -102,6 +105,8 @@ class Circuit {
102105

103106
void sendDifference(DifferenceSharedPtr difference) { if (difference->empty()) return; saved = false; if (!midUndo) undoSystem.addDifference(difference); for (auto pair : listenerFunctions) pair.second(difference, circuitId); }
104107

108+
std::string circuitName;
109+
std::string circuitUUID;
105110
circuit_id_t circuitId;
106111
BlockContainer blockContainer;
107112
CircuitBlockData circuitBlockData;

src/backend/circuit/circuitManager.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class CircuitManager {
1818
return iter->second;
1919
}
2020

21-
inline circuit_id_t createNewCircuit() {
21+
inline circuit_id_t createNewCircuit(const std::string& uuid, const std::string& name) {
2222
circuit_id_t id = getNewCircuitId();
23-
circuits.emplace(id, std::make_shared<Circuit>(id, &blockDataManager));
23+
circuits.emplace(id, std::make_shared<Circuit>(id, &blockDataManager, uuid, name));
2424
return id;
2525
}
2626

src/backend/circuit/parsedCircuit.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,19 @@ class ParsedCircuit {
8181
void setFilePath(const std::string& fpath) { fullFilePath = fpath; }
8282
const std::string& getFilePath() const { return fullFilePath; }
8383

84+
void setName(const std::string& name) { importedCircuitName = name; }
85+
const std::string& getName() const { return importedCircuitName; }
86+
87+
void setUUID(const std::string& uuid) { uuidFromLoad = uuid; }
88+
const std::string& getUUID() const { return uuidFromLoad; }
89+
90+
void addCircuitNameUUID(const std::string& name, const std::string& uuid) {
91+
circuitNameToUUID[name] = uuid;
92+
}
93+
const std::unordered_map<std::string, std::string>& getCircuitNameToUUID() const {
94+
return circuitNameToUUID;
95+
}
96+
8497
bool isValid() const { return valid; }
8598
const Vector& getMinPos() const { return minPos; }
8699

@@ -98,9 +111,14 @@ class ParsedCircuit {
98111
private:
99112
Vector minPos = Vector(std::numeric_limits<int>::max(), std::numeric_limits<int>::max());
100113
Vector maxPos = Vector(std::numeric_limits<int>::min(), std::numeric_limits<int>::min());
114+
101115
std::unordered_map<block_id_t, BlockData> blocks;
102116
std::vector<ConnectionData> connections;
117+
103118
std::string fullFilePath;
119+
std::string uuidFromLoad;
120+
std::string importedCircuitName;
121+
std::unordered_map<std::string, std::string> circuitNameToUUID;
104122
bool valid = true;
105123

106124
std::unordered_map<std::string, SharedParsedCircuit> dependencies;

src/backend/circuit/validateCircuit.cpp

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -123,10 +123,40 @@ bool CircuitValidator::setOverlapsUnpositioned() {
123123
return true;
124124
}
125125

126+
127+
// iterative dfs
128+
template <class PreVisit, class PostVisit>
129+
void depthFirstSearch(const std::unordered_map<block_id_t, std::vector<block_id_t>>& adj, block_id_t start, std::unordered_set<block_id_t>& visited, PreVisit preVisit, PostVisit postVisit) {
130+
std::stack<block_id_t> stack;
131+
stack.push(start);
132+
visited.insert(start);
133+
preVisit(start);
134+
while (!stack.empty()) {
135+
block_id_t node = stack.top();
136+
bool hasUnvisited = false;
137+
if (adj.count(node)){
138+
for (block_id_t neighbor : adj.at(node)) {
139+
if (visited.count(neighbor)) continue;
140+
visited.insert(neighbor);
141+
preVisit(neighbor);
142+
stack.push(neighbor);
143+
hasUnvisited = true;
144+
break;
145+
}
146+
}
147+
148+
if (!hasUnvisited) {
149+
stack.pop();
150+
postVisit(node);
151+
}
152+
}
153+
}
154+
126155
// SCC META GRAPH TOPOLOGICAL SORT
127156
bool CircuitValidator::handleUnpositionedBlocks() {
128157
// Separate components so that we can place down disconnected components independently
129158
std::unordered_map<block_id_t, std::vector<block_id_t>> undirectedAdj;
159+
undirectedAdj.reserve(parsedCircuit.blocks.size());
130160
for (const ParsedCircuit::ConnectionData& conn : parsedCircuit.connections) {
131161
block_id_t u = conn.inputBlockId;
132162
block_id_t v = conn.outputBlockId;
@@ -136,94 +166,64 @@ bool CircuitValidator::handleUnpositionedBlocks() {
136166

137167
// find cc's by dfs
138168
std::vector<std::unordered_set<block_id_t>> components;
169+
std::unordered_map<block_id_t, int> blockToComponent;
139170
std::unordered_set<block_id_t> visited;
140-
std::function<void(block_id_t)> dfsComponent = [&](block_id_t node) {
141-
visited.insert(node);
142-
components.back().insert(node);
143-
for (block_id_t neighbor : undirectedAdj[node]) {
144-
if (!visited.count(neighbor)) {
145-
dfsComponent(neighbor);
146-
}
147-
}
148-
};
149171
for (const auto& [id, block] : parsedCircuit.blocks) {
150172
if (!visited.count(id)) {
151173
components.push_back({});
152-
dfsComponent(id);
174+
depthFirstSearch(undirectedAdj, id, visited, [&](block_id_t node){components.back().insert(node); blockToComponent[node] = components.size()-1;}, [&](block_id_t){});
153175
}
154176
}
155177

156-
const int componentSpacing = 5;
157-
int currentYOffset = 0;
158-
int ccIndex = 0;
159-
for (const std::unordered_set<block_id_t>& cc: components){
160-
logInfo("Parsing CC " + std::to_string(++ccIndex));
161-
162-
// adjacency list
163-
std::unordered_map<block_id_t, std::vector<block_id_t>> adj;
164-
for (const auto& conn : parsedCircuit.connections) {
165-
if (cc.count(conn.inputBlockId) && cc.count(conn.outputBlockId)) {
166-
block_id_t to = conn.outputBlockId;
167-
block_id_t from = conn.inputBlockId;
168-
//logInfo("From: " + std::to_string(from) + "("+std::to_string(conn.outputId)+")" +
169-
// ", To: " + std::to_string(to) + "("+std::to_string(conn.inputId)+")");
170-
if (blockDataManager->isConnectionInput(parsedCircuit.blocks.at(conn.outputBlockId).type, conn.outputId)){
171-
adj[from].push_back(to);
172-
}
173-
}
178+
// preprocess connected component connections
179+
std::vector<std::unordered_map<block_id_t,std::vector<block_id_t>>> componentAdjs(components.size());
180+
for (const ParsedCircuit::ConnectionData& conn : parsedCircuit.connections) {
181+
if (blockDataManager->isConnectionInput(parsedCircuit.blocks.at(conn.outputBlockId).type,conn.outputId)){
182+
int cc = blockToComponent[conn.inputBlockId];
183+
componentAdjs[cc][conn.inputBlockId].push_back(conn.outputBlockId);
174184
}
185+
}
175186

176-
// find SCC metagraph DAG for topological sort using kosaraju's
177-
std::unordered_map<block_id_t, std::vector<block_id_t>> revAdj;
178-
std::stack<block_id_t> postNumber; // highest post number node is a part of a source SCC, run on G^R
179-
std::vector<std::vector<block_id_t>> sccs;
187+
// precompute input connections for each block for layer placement
188+
std::unordered_map<block_id_t, std::vector<block_id_t>> inputConnections;
189+
for (const auto& conn : parsedCircuit.connections) {
190+
inputConnections[conn.inputBlockId].push_back(conn.outputBlockId);
191+
}
180192

181-
std::function<void(block_id_t)> dfs =
182-
[&](block_id_t node) -> void {
183-
visited.insert(node);
184-
for (block_id_t v : adj[node]) {
185-
if (!visited.count(v)) {
186-
dfs(v);
187-
}
188-
}
189-
postNumber.push(node); // post visit
190-
};
191-
192-
std::function<void(block_id_t, std::vector<block_id_t>&)> dfsRev =
193-
[&](block_id_t node, std::vector<block_id_t>& component) -> void {
194-
visited.insert(node);
195-
component.push_back(node);
196-
for (block_id_t v : revAdj[node]) {
197-
if (!visited.count(v)) {
198-
dfsRev(v, component);
199-
}
200-
}
201-
};
193+
const int componentSpacing = 5;
194+
int currentYOffset = 0;
195+
for (int ccIndex=0; ccIndex<componentAdjs.size(); ++ccIndex){
196+
const std::unordered_map<block_id_t, std::vector<block_id_t>>& adj = componentAdjs[ccIndex];
197+
logInfo("Parsing CC " + std::to_string(ccIndex));
202198

199+
// find SCC metagraph DAG for topological sort using kosaraju's
203200
// gather stack that shows decreasing post visit numbers
201+
std::stack<block_id_t> postNumber; // highest post number node is a part of a source SCC, run on G^R
204202
visited.clear();
205-
for (block_id_t id : cc) {
203+
for (block_id_t id : components[ccIndex]) {
206204
if (!visited.count(id)) {
207-
dfs(id);
205+
depthFirstSearch(adj, id, visited, [&](block_id_t){}, [&](block_id_t node){postNumber.push(node);});
208206
}
209207
}
210208

211209
// make reverse graph in adjacency list
210+
std::unordered_map<block_id_t, std::vector<block_id_t>> revAdj;
212211
for (const auto& [u, adjs] : adj) {
213212
for (block_id_t v : adjs) {
214213
revAdj[v].push_back(u);
215214
}
216215
}
217216

218217
// run dfs from source SCC's in reverse graph, sink SCCs of regular
218+
std::vector<std::vector<block_id_t>> sccs;
219219
visited.clear();
220220
while (!postNumber.empty()) {
221221
block_id_t node = postNumber.top();
222222
postNumber.pop();
223223
if (!visited.count(node)) {
224-
std::vector<block_id_t> component;
225-
dfsRev(node, component);
226-
sccs.push_back(component);
224+
std::vector<block_id_t> revCC;
225+
depthFirstSearch(adj, node, visited, [&](block_id_t node){revCC.push_back(node);}, [&](block_id_t){});
226+
sccs.push_back(revCC);
227227
}
228228
}
229229

@@ -275,12 +275,13 @@ bool CircuitValidator::handleUnpositionedBlocks() {
275275
}
276276

277277
std::unordered_map<block_id_t, int> layers;
278-
for (int sccIndex : sccOrder) {
279-
for (block_id_t id : sccs[sccIndex]) {
278+
for (int sccIdx : sccOrder) {
279+
for (block_id_t id : sccs[sccIdx]) {
280280
int maxLayer = 0;
281-
for (const auto& conn : parsedCircuit.connections) {
282-
if (conn.inputBlockId == id) {
283-
maxLayer = std::max(maxLayer, layers[conn.outputBlockId] + 1);
281+
auto it = inputConnections.find(id);
282+
if (it != inputConnections.end()) {
283+
for (block_id_t outputBlock : it->second) {
284+
maxLayer = std::max(maxLayer, layers[outputBlock] + 1);
284285
}
285286
}
286287
layers[id] = maxLayer;

src/backend/circuit/validateCircuit.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
#ifndef validateCircuit_h
22
#define validateCircuit_h
33
#include "backend/circuit/parsedCircuit.h"
4-
#include "backend/circuit/circuit.h"
5-
#include <vector>
4+
#include "backend/container/block/blockDataManager.h"
65

76
// Will take in a ParsedCircuit and modify its "valid" state to whether or not it is valid.
87
// The parsed circuit is only considered to be valid or invalid relative to itself,

0 commit comments

Comments
 (0)