Skip to content
Snippets Groups Projects
Commit 61afd225 authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

replaces commit cf640e0c:

Instead of making the DeviceModule return the same VariableNetworkNode for the same register, an optimisation step before realising the connections (but after all connections have been defined) is performed. In this step, all networks sharing the same (device-type) feeder will be merged. This is more flexible and avoids problems with (potentially different) triggers etc.
parent 29894667
No related branches found
No related tags found
No related merge requests found
......@@ -153,6 +153,9 @@ namespace ChimeraTK {
/** Make the connections between accessors as requested in the initialise() function. */
void makeConnections();
/** Apply optimisations to the VariableNetworks, e.g. by merging networks sharing the same feeder. */
void optimiseConnections();
/** Make the connections for a single network */
void makeConnectionsForNetwork(VariableNetwork &network);
......
......@@ -53,10 +53,6 @@ namespace ChimeraTK {
// List of sub modules accessed through the operator[]. This is mutable since it is little more than a cache and
// thus does not change the logical state of this module
mutable std::list<DeviceModule> subModules;
// List of variables accessed through the operator(). This is mutable since it is little more than a cache and
// thus does not change the logical state of this module
mutable std::map<std::string, VariableNetworkNode> variables;
};
......
......@@ -77,6 +77,9 @@ namespace ChimeraTK {
/** Set the owner network of this node. If an owner network is already set, an assertion will be raised */
void setOwner(VariableNetwork *network);
/** Clear the owner network of this node. */
void clearOwner();
/** Set the value type for this node. Only possible of the current value type is undecided (i.e. AnyType). */
void setValueType(const std::type_info& newType) const;
......
......@@ -347,6 +347,12 @@ void Application::makeConnections() {
// run checks first
checkConnections();
// apply optimisations
optimiseConnections();
// run checks again to make sure the optimisations didn't create corrupted networks
checkConnections();
// make the connections for all networks
for(auto &network : networkList) {
......@@ -357,6 +363,73 @@ void Application::makeConnections() {
/*********************************************************************************************************************/
void Application::optimiseConnections() {
// list of iterators of networks to be removed from the networkList after the merge operation
std::list<VariableNetwork*> deleteNetworks;
// search for networks with the same feeder
for(auto it1 = networkList.begin(); it1 != networkList.end(); ++it1) {
for(auto it2 = it1; it2 != networkList.end(); ++it2) {
if(it1 == it2) continue;
auto feeder1 = it1->getFeedingNode();
auto feeder2 = it2->getFeedingNode();
// this optimisation is only necessary for device-type nodes, since application and control-system nodes will
// automatically create merged networks when having the same feeder
/// @todo check if this assumtion is true! control-system nodes can be created with different types, too!
if(feeder1.getType() != NodeType::Device || feeder2.getType() != NodeType::Device) continue;
// check if referrring to same register
if(feeder1.getDeviceAlias() != feeder2.getDeviceAlias()) continue;
if(feeder1.getRegisterName() != feeder2.getRegisterName()) continue;
// check if directions are the same
if(feeder1.getDirection() != feeder2.getDirection()) continue;
// check if value types and number of elements are compatible
if(feeder1.getValueType() != feeder2.getValueType()) continue;
if(feeder1.getNumberOfElements() != feeder2.getNumberOfElements()) continue;
// check if transfer mode is the same
if(feeder1.getMode() != feeder2.getMode()) continue;
// check if triggers are compatible, if present
if(feeder1.hasExternalTrigger() != feeder2.hasExternalTrigger()) continue;
if(feeder1.hasExternalTrigger()) {
if(feeder1.getExternalTrigger() != feeder2.getExternalTrigger()) continue;
}
// everything should be compatible at this point: merge the networks. We will merge the network of the outer
// loop into the network of the inner loop, since the network of the outer loop will not be found a second time
// in the inner loop.
std::cout << "HIER merging networks" << std::endl;
it1->dump();
it2->dump();
for(auto consumer : it1->getConsumingNodes()) {
consumer.clearOwner();
it2->addNode(consumer);
}
it2->dump();
// schedule the outer loop network for deletion and stop processing it
deleteNetworks.push_back(&(*it1));
break;
}
}
// remove networks from the network list
for(auto net : deleteNetworks) {
networkList.remove(*net);
}
dumpConnections();
}
/*********************************************************************************************************************/
void Application::dumpConnections() {
std::cout << "==== List of all variable connections of the current Application ====" << std::endl;
for(auto &network : networkList) {
......
......@@ -22,10 +22,7 @@ namespace ChimeraTK {
VariableNetworkNode DeviceModule::operator()(const std::string& registerName, UpdateMode mode,
const std::type_info &valueType, size_t nElements) const {
if(variables.count(registerName) == 0) {
variables[registerName] = {deviceAliasOrURI, registerNamePrefix/registerName, mode, VariableDirection::invalid, valueType, nElements};
}
return variables[registerName];
return {deviceAliasOrURI, registerNamePrefix/registerName, mode, VariableDirection::invalid, valueType, nElements};
}
/*********************************************************************************************************************/
......
......@@ -97,6 +97,12 @@ namespace ChimeraTK {
/*********************************************************************************************************************/
void VariableNetworkNode::clearOwner() {
pdata->network = nullptr;
}
/*********************************************************************************************************************/
bool VariableNetworkNode::hasImplementation() const {
return pdata->type == NodeType::Device || pdata->type == NodeType::ControlSystem || pdata->type == NodeType::Constant;
}
......
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