Skip to content
Snippets Groups Projects
Commit e02f00a3 authored by Jens Georg's avatar Jens Georg Committed by Martin Christoph Hierholzer
Browse files

Fix static circular depdendency analysis

parent 65be71eb
No related branches found
No related tags found
No related merge requests found
......@@ -159,10 +159,6 @@ namespace ChimeraTK {
template<typename UserType>
friend class ExceptionHandlingDecorator;
/** Scan for circular dependencies and mark all affected consuming nodes.
* This can only be done after all connections have been established. */
// void markCircularConsumers(VariableNetwork& variableNetwork);
/** The model of the application */
Model::RootProxy _model;
......
......@@ -7,6 +7,7 @@
#include "DeviceManager.h"
#include "Utilities.h"
#include "VariableNetworkGraphDumpingVisitor.h"
#include "VariableNetworkNode.h"
#include "XMLGeneratorVisitor.h"
#include <ChimeraTK/BackendFactory.h>
......@@ -264,22 +265,6 @@ void Application::dumpModuleConnectionGraph(const std::string& fileName) const {
visitor.dispatch(*this);
}
*/
/*********************************************************************************************************************/
/*
void Application::markCircularConsumers(VariableNetwork& variableNetwork) {
for(auto& node : variableNetwork.getConsumingNodes()) {
// A variable network is a tree-like network of VariableNetworkNodes (one feeder and one or more multiple consumers)
// A circular network is a list of modules (EntityOwners) which have a circular dependency
auto circularNetwork = node.scanForCircularDepencency();
if(not circularNetwork.empty()) {
auto circularNetworkHash = boost::hash_range(circularNetwork.begin(), circularNetwork.end());
circularDependencyNetworks[circularNetworkHash] = circularNetwork;
circularNetworkInvalidityCounters[circularNetworkHash] = 0;
}
}
}
*/
/*********************************************************************************************************************/
......
......@@ -208,6 +208,18 @@ namespace ChimeraTK {
makeConnectionForConstantFeeder(net);
}
// Mark circular networks
for(auto& node : net.consumers) {
// A variable network is a tree-like network of VariableNetworkNodes (one feeder and one or more multiple consumers)
// A circular network is a list of modules (EntityOwners) which have a circular dependency
auto circularNetwork = node.scanForCircularDepencency();
if(not circularNetwork.empty()) {
auto circularNetworkHash = boost::hash_range(circularNetwork.begin(), circularNetwork.end());
_app.circularDependencyNetworks[circularNetworkHash] = circularNetwork;
_app.circularNetworkInvalidityCounters[circularNetworkHash] = 0;
}
}
return net;
}
......
......@@ -284,6 +284,10 @@ namespace ChimeraTK {
// We are starting a new scan. Reset the indicator for already found circular dependencies.
detail::CircularDependencyDetectionRecursionStopper::startNewScan();
if(!getModel().isValid()) {
return {};
}
// find the feeder of the network
auto amProxy = getModel().visit(Model::returnApplicationModule, Model::keepPvAccess, Model::keepApplicationModules,
Model::adjacentInSearch, Model::returnFirstHit(Model::ApplicationModuleProxy{}));
......@@ -295,7 +299,11 @@ namespace ChimeraTK {
assert(getDirection().dir == VariableDirection::consuming);
Module* owningModule = &amProxy.getApplicationModule();
auto inputModuleList = owningModule->getInputModulesRecursively({owningModule});
// We do not put ourselves in the list right away. The called code will do this as well and detect a circle
// immediately, even if there is just a simple connection, we leave the marking of the already visited node
// to the recursive call.
auto inputModuleList = owningModule->getInputModulesRecursively({});
auto nInstancesFound = std::count(inputModuleList.begin(), inputModuleList.end(), owningModule);
assert(nInstancesFound >= 1); // the start list must not have been deleted in the call
......@@ -324,7 +332,7 @@ namespace ChimeraTK {
return inputModuleList;
}
// No circlular network. Return an empty list.
// No circular network. Return an empty list.
return {};
}
......
......@@ -52,7 +52,7 @@ struct TestModuleBase : ctk::ApplicationModule {
}
};
/// ModuleA has two additonal inputs to get invalidity flags. It is reading all inputs with ReadAny
/// ModuleA has two additional inputs to get invalidity flags. It is reading all inputs with ReadAny
struct ModuleA : TestModuleBase {
using TestModuleBase::TestModuleBase;
......@@ -602,7 +602,7 @@ struct TestApplication2 : ctk::Application {
/** \anchor dataValidity_test_TestCircularInputDetection2
* Tests Technical specification: data validity propagation
* * \ref dataValidity_4_1_2_1 "4.1.2.1" Entangled circles belonhg to the same circular network.
* * \ref dataValidity_4_1_2_1 "4.1.2.1" Entangled circles belong to the same circular network.
* * \ref dataValidity_4_1_2_2 "4.1.2.2" There can be multiple disconnected circular networks.
* * \ref dataValidity_4_3_2 "4.3.2" Each module and each circular input knows its circular network.
*/
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment