// change the node associated with nodeName to newNode; used in the KL-reg based adaptation to reduce feature copy // need to update all the mappings as well childrens void ComputationNetwork::ChangeNode(wstring nodeName, ComputationNodeBasePtr newNode) { InvalidateCompiledNetwork(); ComputationNodeBasePtr oldNode = GetNodeFromName(nodeName); if (oldNode->OperationName() != newNode->OperationName()) InvalidArgument("newNode must have the same type as the old node."); // change children for (auto nodeIter = m_nameToNodeMap.begin(); nodeIter != m_nameToNodeMap.end(); nodeIter++) { ComputationNodeBasePtr node = nodeIter->second; for (int i = 0; i < node->GetNumInputs(); i++) if (node->GetInputs()[i] == oldNode) node->SetInput(i, newNode); } // change name map m_nameToNodeMap[nodeName] = newNode; for (int i = 0; i < oldNode->GetNumInputs(); i++) newNode->SetInput(i, oldNode->GetInputs()[i]); // change other maps for (auto groupIter : GetAllNodeGroups()) { auto& group = *groupIter; for (int i = 0; i < group.size(); i++) if (group[i] == oldNode) group[i] = newNode; } }
// replace a named node by newNode of the same type under the same name, including moving over all network links // This is used in // 1. Update nodes to quantized versions. // 2. The KL-reg based adaptation to reduce feature copy (deprecated) // need to update all the mappings as well childrens. void ComputationNetwork::ReplaceNode(wstring nodeName, ComputationNodeBasePtr newNode) { ComputationNodeBasePtr oldNode = GetNodeFromName(nodeName); if (newNode->NodeName() != nodeName) // TODO: This was not tested for earlier; I hope no code depends on this. InvalidArgument("ChangeNode: newNode must have the same name as the old node."); InvalidateCompiledNetwork(); // change all nodes that have old node as input to point to the new node instead ChangeNodeInputs(oldNode, newNode); // change all inputs of this new node to share the old one's inputs for (int i = 0; i < oldNode->GetNumInputs(); i++) { newNode->SetInput(i, oldNode->GetInputs()[i]); // TODO: use AttachInput()? //oldNode->SetInput(i, nullptr); // BUGBUG: old node should no longer point into the network } // replace the node in the network RemoveNodeFromNet(oldNode); AddNodeToNet(newNode); // also update node groups for (auto groupIter : GetAllNodeGroups()) { auto& group = *groupIter; for (int i = 0; i < group.size(); i++) if (group[i] == oldNode) group[i] = newNode; } }
void ComputationNetwork::DeleteNode(const std::wstring& nodeName) { InvalidateCompiledNetwork(); ComputationNodeBasePtr nodeToDelete = GetNodeFromName(nodeName); // first delete links, if this node is involved, the whole connection will be removed for (auto nodeIter = m_nameToNodeMap.begin(); nodeIter != m_nameToNodeMap.end(); nodeIter++) { ComputationNodeBasePtr node = nodeIter->second; for (size_t i = 0; i < node->GetNumInputs(); i++) { ComputationNodeBasePtr child = node->GetInputs()[i]; // nodeToDelete is a child if (child == nodeToDelete) { // this used to call DetatchInputs(), but it's better for MEL to retain other inputs node->SetInput(i, nullptr); break; } } } // nodeToDelete is a parent nodeToDelete->DetachInputs(); // deref all its inputs; if we don't do that, we might end up with a mem leak due to a circular reference // unlink from all node-group sets for (auto groupIter : GetAllNodeGroups()) { auto search = std::find(groupIter->begin(), groupIter->end(), nodeToDelete); if (search != groupIter->end()) groupIter->erase(search); } // Note: the necessary update of m_allSEQNodes is hanlded by the InvalidateCompiledNetwork() call above // delete the node itself m_nameToNodeMap.erase(nodeName); // this will deref the node and possibly deallocate it }