Skip to content

Commit b7859a4

Browse files
committed
2 parents 9687431 + 2471c40 commit b7859a4

File tree

3 files changed

+216
-15
lines changed

3 files changed

+216
-15
lines changed

src/backend/evaluator/layers/layer3_gateSubstituter.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,38 @@ class GateSubstituter {
400400
return;
401401
}
402402
GateWithLinkedIO& gate = gatesWithLinkedIO.at(gateId);
403+
for (middle_id_t middleId : gate.idsCreated) {
404+
std::vector<middle_id_t> referencingGates = collectReferencingTrackedGates(middleId);
405+
for (const auto& referencingGateId : referencingGates) {
406+
#ifdef TRACY_PROFILER
407+
ZoneScopedN("GateSubstituter::deleteGateWithLinkedIO - per tracked gate");
408+
#endif
409+
auto trackedGateIter = trackedGates.find(referencingGateId);
410+
if (trackedGateIter == trackedGates.end()) {
411+
continue;
412+
}
413+
TrackedGate& trackedGateRef = trackedGateIter->second;
414+
bool success = trackedGateRef.removeReferencesToId(middleId);
415+
if (!success) {
416+
continue;
417+
}
418+
BlockType newState = trackedGateRef.evaluate();
419+
if (newState != trackedGateRef.currentState) {
420+
trackedGateRef.currentState = newState;
421+
replacer.removeGate(pauseGuard, trackedGateRef.id);
422+
replacer.addGate(pauseGuard, newState, trackedGateRef.id);
423+
for (const auto& input : trackedGateRef.inputs) {
424+
replacer.makeConnection(pauseGuard, input);
425+
}
426+
for (const auto& output : trackedGateRef.outputs) {
427+
if (output.source.gateId == output.destination.gateId) {
428+
continue;
429+
}
430+
replacer.makeConnection(pauseGuard, output);
431+
}
432+
}
433+
}
434+
}
403435
for (middle_id_t middleId : gate.idsCreated) {
404436
replacer.removeGate(pauseGuard, middleId);
405437
middleIdProvider.releaseId(middleId);

src/backend/evaluator/simulator/logicSimulator.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ void LogicSimulator::processPendingStateChanges() {
158158
continue;
159159
}
160160
GateLocation& gateLocation = gateLocations.at(change.id);
161-
if (gateLocation.gateType == SimGateType::CONSTANT) {
161+
if (gateLocation.gateType == SimGateType::CONSTANT || gateLocation.gateType == SimGateType::JUNCTION) {
162162
continue;
163163
}
164164

@@ -189,7 +189,7 @@ void LogicSimulator::setState(simulator_id_t id, logic_state_t st) {
189189
return;
190190
}
191191
GateLocation& gateLocation = gateLocations.at(id);
192-
if (gateLocation.gateType == SimGateType::CONSTANT) {
192+
if (gateLocation.gateType == SimGateType::CONSTANT || gateLocation.gateType == SimGateType::JUNCTION) {
193193
return;
194194
}
195195
statesA[id] = st;

tests/evaluator/fuzzing/basic.cpp

Lines changed: 182 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,117 @@
55
#include "backend/blockData/blockDataManager.h"
66
#include "computerAPI/directoryManager.h"
77

8-
class BasicFuzzingEvaluatorTest : public ::testing::TestWithParam<uint64_t> {
8+
namespace {
9+
10+
struct BusDef {
11+
unsigned int numInputs;
12+
unsigned int numOutputs;
13+
unsigned int inputLaneWidth;
14+
unsigned int outputLaneWidth;
15+
};
16+
17+
struct RunningConfig {
18+
unsigned int numEditOperations;
19+
unsigned int numTestOperations;
20+
unsigned int numTicksBetweenTests;
21+
unsigned int numStatesSetPerTest;
22+
};
23+
24+
struct BlockTypesAllowed {
25+
std::vector<BlockType> blockTypesToUse;
26+
std::vector<BusDef> busDefinitions;
27+
std::vector<std::string> customBlockPaths;
28+
std::string hash() const {
29+
std::string h;
30+
for (BlockType bt : blockTypesToUse) {
31+
h += std::to_string(static_cast<uint16_t>(bt)) + "-";
32+
}
33+
for (const BusDef& busDef : busDefinitions) {
34+
h += "b" + std::to_string(busDef.numInputs) + "_" + std::to_string(busDef.numOutputs) + "_" +
35+
std::to_string(busDef.inputLaneWidth) + "_" + std::to_string(busDef.outputLaneWidth) + "-";
36+
}
37+
for (const std::string& path : customBlockPaths) {
38+
h += "c" + path + "-";
39+
}
40+
return h;
41+
};
42+
};
43+
44+
struct TestcaseConfig {
45+
uint64_t seed;
46+
bool realistic;
47+
RunningConfig runningConfig;
48+
BlockTypesAllowed blockTypesAllowed;
49+
int index;
50+
};
51+
52+
std::string testcase_config_to_string(const TestcaseConfig& config) {
53+
std::string str = std::string("s_") + std::to_string(config.seed);
54+
str += "_r_";
55+
str += (config.realistic ? "1" : "0");
56+
RunningConfig runConfig = config.runningConfig;
57+
str += "_eo_" + std::to_string(runConfig.numEditOperations);
58+
str += "_to_" + std::to_string(runConfig.numTestOperations);
59+
str += "_tbt_" + std::to_string(runConfig.numTicksBetweenTests);
60+
str += "_spt_" + std::to_string(runConfig.numStatesSetPerTest);
61+
str += "_bt_" + config.blockTypesAllowed.hash();
62+
return std::to_string(std::hash<std::string>{}(str));
63+
};
64+
65+
int u = 0;
66+
std::vector<TestcaseConfig> makeTestcases() {
67+
std::vector<TestcaseConfig> testcases;
68+
for (uint64_t seed = 0; seed < 5; ++seed) {
69+
for (bool realistic : {false, true}) {
70+
RunningConfig runningConfig = {5000, 100, 3, 50};
71+
BlockTypesAllowed blockTypesAllowed = {
72+
{
73+
BlockType::AND,
74+
BlockType::OR,
75+
BlockType::XOR,
76+
BlockType::NAND,
77+
BlockType::NOR,
78+
BlockType::XNOR,
79+
BlockType::BUFFER,
80+
BlockType::NOT,
81+
BlockType::TRISTATE_BUFFER,
82+
BlockType::JUNCTION,
83+
BlockType::JUNCTION_L,
84+
BlockType::JUNCTION_H,
85+
BlockType::JUNCTION_X,
86+
BlockType::LIGHT,
87+
BlockType::SWITCH,
88+
BlockType::BUTTON
89+
}, {}, {}
90+
};
91+
testcases.push_back(TestcaseConfig { seed, realistic, runningConfig, blockTypesAllowed, u++ });
92+
93+
blockTypesAllowed = {
94+
{}, {}, {}
95+
};
96+
for (unsigned int i = 1; i <= 21; ++i) {
97+
blockTypesAllowed.blockTypesToUse.push_back(BlockType(i));
98+
}
99+
blockTypesAllowed.busDefinitions.push_back(BusDef {2, 1, 1, 2});
100+
blockTypesAllowed.busDefinitions.push_back(BusDef {4, 1, 1, 4});
101+
blockTypesAllowed.busDefinitions.push_back(BusDef {2, 1, 2, 4});
102+
blockTypesAllowed.busDefinitions.push_back(BusDef {8, 1, 1, 8});
103+
blockTypesAllowed.busDefinitions.push_back(BusDef {4, 1, 2, 8});
104+
blockTypesAllowed.busDefinitions.push_back(BusDef {2, 1, 4, 8});
105+
blockTypesAllowed.busDefinitions.push_back(BusDef { 2, 4, 4, 2 });
106+
107+
blockTypesAllowed.customBlockPaths.push_back("passthrough.cir");
108+
blockTypesAllowed.customBlockPaths.push_back("full_adder.cir");
109+
blockTypesAllowed.customBlockPaths.push_back("bus_tristate_2.cir");
110+
blockTypesAllowed.customBlockPaths.push_back("nested_passthrough.cir");
111+
testcases.push_back(TestcaseConfig { seed, realistic, runningConfig, blockTypesAllowed, u++ });
112+
}
113+
}
114+
return testcases;
115+
}
116+
}; // namespace
117+
118+
class BasicFuzzingEvaluatorTest : public ::testing::TestWithParam<TestcaseConfig> {
9119
protected:
10120
void SetUp() override;
11121
void TearDown() override;
@@ -14,10 +124,17 @@ class BasicFuzzingEvaluatorTest : public ::testing::TestWithParam<uint64_t> {
14124
SharedCircuit circuit = nullptr;
15125
SharedEvaluator tEval = nullptr; // testing evaluator
16126
SharedEvaluator rEval = nullptr; // reference evaluator
127+
BlockType loadCircuit(const std::filesystem::path& path);
17128
};
18129

130+
BlockType BasicFuzzingEvaluatorTest::loadCircuit(const std::filesystem::path& path) {
131+
CircuitFileManager& circuitFileManager = environment.getCircuitFileManager();
132+
circuit_id_t circuitId = circuitFileManager.loadFromFile(path.string()).at(0);
133+
SharedCircuit circuit = environment.getBackend().getCircuitManager().getCircuit(circuitId);
134+
return circuit->getBlockType();
135+
}
136+
19137
void BasicFuzzingEvaluatorTest::SetUp() {
20-
gen.seed(GetParam());
21138
circuit_id_t circuitId = environment.getBackend().getCircuitManager().createNewCircuit(false);
22139
circuit = environment.getBackend().getCircuit(circuitId);
23140
evaluator_id_t evalId = environment.getBackend().createEvaluator(circuitId).value();
@@ -64,23 +181,40 @@ std::optional<connection_end_id_t> getRandomConnectionEnd(const BlockData* block
64181
}
65182

66183
TEST_P(BasicFuzzingEvaluatorTest, FuzzInteractions) {
67-
bool runRealistic = gen() % 2 == 0;
184+
TestcaseConfig config = GetParam();
185+
gen.seed(config.seed);
186+
bool runRealistic = config.realistic;
68187
tEval->setRealistic(runRealistic);
69188
BlockDataManager& blockDataManager = environment.getBackend().getBlockDataManager();
70189
std::uniform_int_distribution<int> distPos(-20, 20);
71190
std::vector<block_id_t> blockIds;
72-
int numEditOperations = 5000;
73-
int numTestOperations = 100;
74-
int numTicksBetweenTests = 3;
75-
int numStatesSetPerTest = 50;
191+
RunningConfig runningConfig = config.runningConfig;
192+
int numEditOperations = runningConfig.numEditOperations;
193+
int numTestOperations = runningConfig.numTestOperations;
194+
int numTicksBetweenTests = runningConfig.numTicksBetweenTests;
195+
int numStatesSetPerTest = runningConfig.numStatesSetPerTest;
196+
BlockTypesAllowed typeConfig = config.blockTypesAllowed;
197+
std::vector<BlockType> allowedBlockTypes = typeConfig.blockTypesToUse;
198+
for (BusDef& busDef : typeConfig.busDefinitions) {
199+
BlockType busBlockType = blockDataManager.getBusBlock(
200+
busDef.numInputs,
201+
busDef.numOutputs,
202+
busDef.inputLaneWidth,
203+
busDef.outputLaneWidth
204+
);
205+
allowedBlockTypes.push_back(busBlockType);
206+
}
207+
for (const std::string& customBlockPath : typeConfig.customBlockPaths) {
208+
BlockType customBlockType = loadCircuit(DirectoryManager::getResourceDirectory() / "circuits" / "evaluator" / customBlockPath);
209+
allowedBlockTypes.push_back(customBlockType);
210+
}
211+
logInfo("Fuzzing test with seed {}, realistic {}, {} edit operations, {} test operations, {} ticks between tests, {} states per test, {} allowed block types. config idx: {}", "BasicFuzzingEvaluatorTest", config.seed, runRealistic, numEditOperations, numTestOperations, numTicksBetweenTests, numStatesSetPerTest, allowedBlockTypes.size(), config.index);
76212
for (int i = 0; i < numEditOperations; ++i) {
77213
int operation = gen() % 8; // 0,1: place, 2: remove, 3,4,5: connect, 6,7: disconnect
78214
if (operation <= 1) { // place block
79215
Orientation orientation(Rotation(gen() % 4), (gen() % 2) == 0);
80-
BlockType blockType = BlockType((gen() % blockDataManager.maxBlockId()) + 1);
81-
if (!blockDataManager.blockExists(blockType)) {
82-
continue;
83-
}
216+
BlockType blockType = allowedBlockTypes[gen() % allowedBlockTypes.size()];
217+
ASSERT_TRUE(blockDataManager.blockExists(blockType));
84218
Position pos(distPos(gen), distPos(gen));
85219
bool success = circuit->tryInsertBlock(pos, orientation, blockType);
86220
if (!success) continue;
@@ -137,7 +271,7 @@ TEST_P(BasicFuzzingEvaluatorTest, FuzzInteractions) {
137271
{
138272
CircuitFileManager& circuitFileManager = environment.getCircuitFileManager();
139273
const std::filesystem::path savePath =
140-
DirectoryManager::getConfigDirectory() / "tmp" / ("BasicFuzzingCircuit_" + std::to_string(GetParam()) + ".cir");
274+
DirectoryManager::getConfigDirectory() / "tmp" / ("BasicFuzzingCircuit_" + testcase_config_to_string(config) + ".cir");
141275
std::filesystem::create_directories(savePath.parent_path());
142276
ASSERT_TRUE(circuitFileManager.saveToFile(savePath.string(), circuit->getUUID()));
143277
logInfo("Saved fuzzing circuit to " + savePath.string(), "BasicFuzzingEvaluatorTest");
@@ -286,6 +420,41 @@ TEST_P(BasicFuzzingEvaluatorTest, FuzzInteractions) {
286420
INSTANTIATE_TEST_SUITE_P(
287421
RandomSeeds,
288422
BasicFuzzingEvaluatorTest,
289-
::testing::Range(uint64_t(0), uint64_t(10))
423+
// ::testing::Range(uint64_t(0), uint64_t(10))
290424
// ::testing::Values(uint64_t(3))
425+
testing::ValuesIn(makeTestcases())
426+
// testing::Combine(
427+
// testing::Values(
428+
// uint64_t(0),
429+
// uint64_t(1),
430+
// uint64_t(2),
431+
// uint64_t(3),
432+
// uint64_t(4)
433+
// ),
434+
// testing::Values(false, true),
435+
// testing::Values(
436+
// RunningConfig{5000, 100, 3, 50},
437+
// ),
438+
// testing::Values(
439+
// BlockTypesAllowed(
440+
// {
441+
// BlockType::AND,
442+
// BlockType::OR,
443+
// BlockType::XOR,
444+
// BlockType::NAND,
445+
// BlockType::NOR,
446+
// BlockType::XNOR,
447+
// BlockType::BUFFER,
448+
// BlockType::NOT,
449+
// BlockType::JUNCTION,
450+
// BlockType::TRISTATE_BUFFER,
451+
// BlockType::BUTTON,
452+
// BlockType::SWITCH,
453+
// BlockType::CONSTANT_OFF,
454+
// BlockType::CONSTANT_ON,
455+
// BlockType::LIGHT,
456+
// }, {}, {}
457+
// )
458+
// )
459+
// )
291460
);

0 commit comments

Comments
 (0)