From bfc21fd4805a06274dd92ee9e264e8d216556df3 Mon Sep 17 00:00:00 2001 From: Lea Waller Date: Sat, 8 Aug 2020 13:57:55 +0200 Subject: [PATCH 1/3] [REF] Optimize _get_parameter_node performance - Traverse nested workflows in a loop - Avoid constructing the entire workflow.inputs or workflow.outputs data structure --- nipype/pipeline/engine/workflows.py | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/nipype/pipeline/engine/workflows.py b/nipype/pipeline/engine/workflows.py index 0f50b9a5aa..d7b6c11b1c 100644 --- a/nipype/pipeline/engine/workflows.py +++ b/nipype/pipeline/engine/workflows.py @@ -838,15 +838,28 @@ def _get_parameter_node(self, parameter, subtype="in"): """Returns the underlying node corresponding to an input or output parameter """ - if subtype == "in": - subobject = self.inputs - else: - subobject = self.outputs attrlist = parameter.split(".") - cur_out = subobject - for attr in attrlist[:-1]: - cur_out = getattr(cur_out, attr) - return cur_out.traits()[attrlist[-1]].node + _ = attrlist.pop() # take attribute name + nodename = attrlist.pop() + + targetworkflow = self + while attrlist: + workflowname = attrlist.pop(0) + workflow = None + for node in targetworkflow._graph.nodes(): + if node.name == workflowname and isinstance(node, Workflow): + workflow = node + break + if workflow is None: + return + targetworkflow = workflow + + for node in targetworkflow._graph.nodes(): + if node.name == nodename: + if isinstance(node, Workflow): + return + else: + return node def _check_outputs(self, parameter): return self._has_attr(parameter, subtype="out") From 84c791b9d03832a65a1c47ac1b10c9ebfec60d4c Mon Sep 17 00:00:00 2001 From: Lea Waller Date: Mon, 19 Oct 2020 22:24:31 +0200 Subject: [PATCH 2/3] Replace _get_parameter_node with get_node --- nipype/pipeline/engine/workflows.py | 31 ++--------------------------- 1 file changed, 2 insertions(+), 29 deletions(-) diff --git a/nipype/pipeline/engine/workflows.py b/nipype/pipeline/engine/workflows.py index d7b6c11b1c..30350e986d 100644 --- a/nipype/pipeline/engine/workflows.py +++ b/nipype/pipeline/engine/workflows.py @@ -834,33 +834,6 @@ def _check_is_already_connected(workflow, node, attrname): return True - def _get_parameter_node(self, parameter, subtype="in"): - """Returns the underlying node corresponding to an input or - output parameter - """ - attrlist = parameter.split(".") - _ = attrlist.pop() # take attribute name - nodename = attrlist.pop() - - targetworkflow = self - while attrlist: - workflowname = attrlist.pop(0) - workflow = None - for node in targetworkflow._graph.nodes(): - if node.name == workflowname and isinstance(node, Workflow): - workflow = node - break - if workflow is None: - return - targetworkflow = workflow - - for node in targetworkflow._graph.nodes(): - if node.name == nodename: - if isinstance(node, Workflow): - return - else: - return node - def _check_outputs(self, parameter): return self._has_attr(parameter, subtype="out") @@ -989,7 +962,7 @@ def _generate_flatgraph(self): logger.debug("in: connections-> %s", str(d["connect"])) for cd in deepcopy(d["connect"]): logger.debug("in: %s", str(cd)) - dstnode = node._get_parameter_node(cd[1], subtype="in") + dstnode = node.get_node(parameter.rsplit(".", 1)[0]) srcnode = u srcout = cd[0] dstin = cd[1].split(".")[-1] @@ -1009,7 +982,7 @@ def _generate_flatgraph(self): parameter = cd[0][0] else: parameter = cd[0] - srcnode = node._get_parameter_node(parameter, subtype="out") + srcnode = node.get_node(parameter.rsplit(".", 1)[0]) if isinstance(cd[0], tuple): srcout = list(cd[0]) srcout[0] = parameter.split(".")[-1] From d5a88de71aae60a9e6350e1c3ef2548cf058f7d0 Mon Sep 17 00:00:00 2001 From: Lea Waller Date: Tue, 20 Oct 2020 10:08:23 +0200 Subject: [PATCH 3/3] Fix pass the correct argument to get_node --- nipype/pipeline/engine/workflows.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/pipeline/engine/workflows.py b/nipype/pipeline/engine/workflows.py index 30350e986d..9b6e60ffaf 100644 --- a/nipype/pipeline/engine/workflows.py +++ b/nipype/pipeline/engine/workflows.py @@ -962,7 +962,7 @@ def _generate_flatgraph(self): logger.debug("in: connections-> %s", str(d["connect"])) for cd in deepcopy(d["connect"]): logger.debug("in: %s", str(cd)) - dstnode = node.get_node(parameter.rsplit(".", 1)[0]) + dstnode = node.get_node(cd[1].rsplit(".", 1)[0]) srcnode = u srcout = cd[0] dstin = cd[1].split(".")[-1]