Created
September 17, 2016 18:11
-
-
Save mcg1969/5b6ae95ff16cfe1c751285451ebc679d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 1, | |
"metadata": { | |
"collapsed": true | |
}, | |
"outputs": [], | |
"source": [ | |
"import inspect\n", | |
"import dask\n", | |
"from operator import getitem\n", | |
"from collections import namedtuple\n", | |
"from graphviz import Digraph\n", | |
"from dask import delayed\n", | |
"from dask.delayed import Delayed, to_task_dasks\n", | |
"from dask.dot import dot_graph, to_graphviz\n", | |
"from dask.async import get_sync\n", | |
"from dask.base import tokenize, visualize" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 11, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"class SimpleDelayed(object):\n", | |
" def __init__(self, func, nout):\n", | |
" if nout == 0:\n", | |
" raise RuntimeError('SimpleDelayed functions must have at least one output')\n", | |
" self.nout = nout\n", | |
" self.func = func\n", | |
" self.dfunc = delayed(func)\n", | |
" if func.__doc__:\n", | |
" self.__doc__ = 'This is a SimpleDelayed wrapper around the following function:\\n--------\\n%s' % func.__doc__\n", | |
" \n", | |
" def __call__(self, *args, **kwargs):\n", | |
" delayed = kwargs.pop('delayed', None)\n", | |
" if (delayed or any(isinstance(arg, Delayed) for arg in args) or\n", | |
" kwargs and any(isinstance(arg, Delayed) for arg in kwargs.values())):\n", | |
" res = self.dfunc(*args, **kwargs)\n", | |
" if delayed is not None and not delayed:\n", | |
" res = res.compute()\n", | |
" elif kwargs:\n", | |
" res = self.func(*args, **kwargs)\n", | |
" else:\n", | |
" res = self.func(*args)\n", | |
" if self.nout == 1 or type(res) is tuple:\n", | |
" return res\n", | |
" else:\n", | |
" return tuple(res[k] for k in range(self.nout))\n", | |
" \n", | |
" def visualize(self):\n", | |
" graph = Digraph(graph_attr={'rankdir':'BT'})\n", | |
" fname = self.func.__name__\n", | |
" argspec = inspect.getargspec(self.func)\n", | |
" graph.node(fname, shape='circle')\n", | |
" args = list(argspec.args)\n", | |
" if argspec.varargs:\n", | |
" args.append('*' + argspec.varargs)\n", | |
" if argspec.keywords:\n", | |
" args.append('**' + argspec.keywords)\n", | |
" for k_name in args:\n", | |
" graph.node(k_name, shape='box')\n", | |
" graph.edge(k_name, fname)\n", | |
" for k in range(self.nout):\n", | |
" k_name = '%s_out[%d]' % (fname, k)\n", | |
" graph.node(k_name, shape='box')\n", | |
" graph.edge(fname, k_name)\n", | |
" return graph\n", | |
"\n", | |
" def __repr__(self):\n", | |
" return 'SimpleDelayed: name=%s, nout=%d' % (self.func.__name__, self.nout)\n", | |
"\n", | |
" def _repr_svg_(self):\n", | |
" return self.visualize()._repr_svg_()\n", | |
"\n", | |
"def simple_delayed(nout):\n", | |
" def decorator(function):\n", | |
" return SimpleDelayed(function, nout)\n", | |
" return decorator" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 25, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"@simple_delayed(2)\n", | |
"def f(x, y, z, *args, **kwargs):\n", | |
" \"\"\"Testing\"\"\"\n", | |
" return x + y, y + z" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 26, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": [ | |
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", | |
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", | |
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", | |
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", | |
" -->\n", | |
"<!-- Title: %3 Pages: 1 -->\n", | |
"<svg width=\"366pt\" height=\"188pt\"\n", | |
" viewBox=\"0.00 0.00 366.09 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", | |
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n", | |
"<title>%3</title>\n", | |
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 362.094,-184 362.094,4 -4,4\"/>\n", | |
"<!-- f -->\n", | |
"<g id=\"node1\" class=\"node\"><title>f</title>\n", | |
"<ellipse fill=\"none\" stroke=\"black\" cx=\"171\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n", | |
"<text text-anchor=\"middle\" x=\"171\" y=\"-85.8\" font-family=\"Times,serif\" font-size=\"14.00\">f</text>\n", | |
"</g>\n", | |
"<!-- f_out[0] -->\n", | |
"<g id=\"node7\" class=\"node\"><title>f_out[0]</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"161.876,-180 100.124,-180 100.124,-144 161.876,-144 161.876,-180\"/>\n", | |
"<text text-anchor=\"middle\" x=\"131\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">f_out[0]</text>\n", | |
"</g>\n", | |
"<!-- f->f_out[0] -->\n", | |
"<g id=\"edge6\" class=\"edge\"><title>f->f_out[0]</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M162.321,-106.189C157.515,-114.599 151.409,-125.285 145.867,-134.984\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"142.709,-133.454 140.787,-143.873 148.787,-136.927 142.709,-133.454\"/>\n", | |
"</g>\n", | |
"<!-- f_out[1] -->\n", | |
"<g id=\"node8\" class=\"node\"><title>f_out[1]</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"241.876,-180 180.124,-180 180.124,-144 241.876,-144 241.876,-180\"/>\n", | |
"<text text-anchor=\"middle\" x=\"211\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">f_out[1]</text>\n", | |
"</g>\n", | |
"<!-- f->f_out[1] -->\n", | |
"<g id=\"edge7\" class=\"edge\"><title>f->f_out[1]</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M179.679,-106.189C184.485,-114.599 190.591,-125.285 196.133,-134.984\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"193.213,-136.927 201.213,-143.873 199.291,-133.454 193.213,-136.927\"/>\n", | |
"</g>\n", | |
"<!-- x -->\n", | |
"<g id=\"node2\" class=\"node\"><title>x</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-36 0,-36 0,-0 54,-0 54,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"27\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">x</text>\n", | |
"</g>\n", | |
"<!-- x->f -->\n", | |
"<g id=\"edge1\" class=\"edge\"><title>x->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M54.0853,-32.1665C80.5259,-45.0195 120.422,-64.4133 146.091,-76.8917\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"144.652,-80.0833 155.175,-81.3075 147.712,-73.7877 144.652,-80.0833\"/>\n", | |
"</g>\n", | |
"<!-- y -->\n", | |
"<g id=\"node3\" class=\"node\"><title>y</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"126,-36 72,-36 72,-0 126,-0 126,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"99\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">y</text>\n", | |
"</g>\n", | |
"<!-- y->f -->\n", | |
"<g id=\"edge2\" class=\"edge\"><title>y->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M116.798,-36.3034C127.253,-46.468 140.487,-59.3349 151.262,-69.8099\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"148.987,-72.4804 158.597,-76.9417 153.867,-67.4614 148.987,-72.4804\"/>\n", | |
"</g>\n", | |
"<!-- z -->\n", | |
"<g id=\"node4\" class=\"node\"><title>z</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"198,-36 144,-36 144,-0 198,-0 198,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"171\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">z</text>\n", | |
"</g>\n", | |
"<!-- z->f -->\n", | |
"<g id=\"edge3\" class=\"edge\"><title>z->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M171,-36.3034C171,-44.0173 171,-53.2875 171,-61.8876\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"167.5,-61.8956 171,-71.8957 174.5,-61.8957 167.5,-61.8956\"/>\n", | |
"</g>\n", | |
"<!-- *args -->\n", | |
"<g id=\"node5\" class=\"node\"><title>*args</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"270,-36 216,-36 216,-0 270,-0 270,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"243\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">*args</text>\n", | |
"</g>\n", | |
"<!-- *args->f -->\n", | |
"<g id=\"edge4\" class=\"edge\"><title>*args->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M225.202,-36.3034C214.747,-46.468 201.513,-59.3349 190.738,-69.8099\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"188.133,-67.4614 183.403,-76.9417 193.013,-72.4804 188.133,-67.4614\"/>\n", | |
"</g>\n", | |
"<!-- **kwargs -->\n", | |
"<g id=\"node6\" class=\"node\"><title>**kwargs</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"358.189,-36 287.811,-36 287.811,-0 358.189,-0 358.189,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"323\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">**kwargs</text>\n", | |
"</g>\n", | |
"<!-- **kwargs->f -->\n", | |
"<g id=\"edge5\" class=\"edge\"><title>**kwargs->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M287.746,-35.2354C259.719,-48.1425 221.196,-65.8835 196.199,-77.3954\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"194.634,-74.2624 187.015,-81.6246 197.562,-80.6206 194.634,-74.2624\"/>\n", | |
"</g>\n", | |
"</g>\n", | |
"</svg>\n" | |
], | |
"text/plain": [ | |
"<graphviz.dot.Digraph at 0x113d32b10>" | |
] | |
}, | |
"execution_count": 26, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"f.visualize()" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"### Calling a SimpleDelayed function" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Calling the function with non-delayed arguments produces an immediate result." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 27, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(3, 5)" | |
] | |
}, | |
"execution_count": 27, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"a, b = f(1,2,3)\n", | |
"(a, b)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Calling the function with a `delayed` input produces `delayed` output. However, because the number of outputs is _known_, the function can return a tuple of each separate output." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 28, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(Delayed('getitem-6d75232e95c9de2b282c1908c88d0e7a'),\n", | |
" Delayed('getitem-7de94c591141577a8a8d2392873273b4'))" | |
] | |
}, | |
"execution_count": 28, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"a, b = f(delayed(1), 2, 3)\n", | |
"(a, b)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Adding `delayed=True` forces delayed computation, even with constant inputs." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 29, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(Delayed('getitem-41867693f5e3b7907b6689055a15a460'),\n", | |
" Delayed('getitem-d48445505b3c5219bde203afdccf3e1f'))" | |
] | |
}, | |
"execution_count": 29, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"a, b = f(1, 2, 3, delayed=True)\n", | |
"(a, b)" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Adding `delayed=False` forces immediate computation even with delayed input." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 30, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"text/plain": [ | |
"(3, 5)" | |
] | |
}, | |
"execution_count": 30, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"f(delayed(1), 2, 3, delayed=False)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 31, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [], | |
"source": [ | |
"class PipelineFunction:\n", | |
" \n", | |
" def __init__(self, func, outputs):\n", | |
" self.nout = len(outputs)\n", | |
" self.func = func\n", | |
" self.__name__ = func.__name__\n", | |
" self.dfunc = delayed(func)\n", | |
" self.outputs = outputs\n", | |
" self.tuple = namedtuple(self.__name__ + '_out', outputs)._make\n", | |
" argspec = inspect.getargspec(func)\n", | |
" if argspec.varargs or argspec.keywords:\n", | |
" raise RuntimeError('PipelineFunctions cannot have *args or **kwargs')\n", | |
" self.inputs = argspec.args\n", | |
" \n", | |
" def __call__(self, *args, **kwargs):\n", | |
" delayed = kwargs.pop('delayed', None)\n", | |
" if delayed is False or delayed is None:\n", | |
" delay_comp = self.any_delayed(args)\n", | |
" delay_out = delay_comp and delayed is None\n", | |
" else:\n", | |
" delay_comp = delay_out = True\n", | |
" res = (self.dfunc if delay_comp else self.func)(*args)\n", | |
" if delay_comp != delay_out:\n", | |
" res = res.compute()\n", | |
" if self.nout <= 1:\n", | |
" return res\n", | |
" elif delay_out:\n", | |
" res = [res[k] for k in range(self.nout)]\n", | |
" return self.tuple(res)\n", | |
"\n", | |
" def to_dask(self, table=None):\n", | |
" if table is None:\n", | |
" table = {k: None for k in self.inputs}\n", | |
" if any(table.get(k) for k in self.outputs):\n", | |
" bad = [k for k in self.outputs if table.get(k)]\n", | |
" raise RuntimeError('The following output values are already written: %s' % (', '.join(bad),))\n", | |
" res = (self,) + tuple(self.inputs)\n", | |
" if len(self.outputs) == 1:\n", | |
" table[self.outputs[0]] = res\n", | |
" else:\n", | |
" nm = '@%s-%s' % (self.__name__,tokenize(res))\n", | |
" table[nm] = res\n", | |
" table.update({out: (getitem, nm, k) for k, out in enumerate(self.outputs)})\n", | |
" return table\n", | |
" \n", | |
" def visualize(self, graph=None):\n", | |
" if graph is None:\n", | |
" graph = Digraph(graph_attr={'rankdir':'BT'})\n", | |
" fname = self.__name__\n", | |
" graph.node(fname, shape='circle')\n", | |
" for k_name in self.inputs:\n", | |
" graph.node(k_name, shape='box')\n", | |
" graph.edge(k_name, fname)\n", | |
" for k_name in self.outputs:\n", | |
" graph.node(k_name, shape='box')\n", | |
" graph.edge(fname, k_name)\n", | |
" return graph\n", | |
"\n", | |
" def compute(self, table, delayed=None):\n", | |
" try:\n", | |
" args = [table[k] for k in self.inputs]\n", | |
" except KeyError:\n", | |
" bad = [k for k in self.inputs if table.get(k) is None]\n", | |
" raise RuntimeError('Missing inputs: %s' % (','.join(bad),))\n", | |
" res = self.__call__(*args, delayed=delayed)\n", | |
" if len(self.outputs) == 1:\n", | |
" table[self.outputs[0]] = res\n", | |
" elif isinstance(res, Delayed):\n", | |
" table.update({out: self.dextract(res, k) for k, out in enumerate(self.outputs)})\n", | |
" else:\n", | |
" table.update({out: val for out, val in zip(self.outputs, res)})\n", | |
" return table\n", | |
" \n", | |
" def __repr__(self):\n", | |
" return 'PipelineFunction: name=%s, inputs=(%s), outputs=(%s)' % (self.__name__, ','.join(self.inputs),','.join(self.outputs))\n", | |
" \n", | |
" def _repr_svg_(self):\n", | |
" return self.visualize()._repr_svg_()\n", | |
"\n", | |
"def pipe(*outputs):\n", | |
" def decorator(function):\n", | |
" return PipelineFunction(function, outputs)\n", | |
" return decorator" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 32, | |
"metadata": { | |
"collapsed": false, | |
"scrolled": true | |
}, | |
"outputs": [], | |
"source": [ | |
"@pipe('a', 'b')\n", | |
"def f(x, y, z):\n", | |
" return x + y, y + z\n", | |
"@pipe('c')\n", | |
"def g(w):\n", | |
" return 2 * w" | |
] | |
}, | |
{ | |
"cell_type": "markdown", | |
"metadata": {}, | |
"source": [ | |
"Examining the function in IPython produces a nice graph output." | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 33, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": [ | |
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", | |
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", | |
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", | |
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", | |
" -->\n", | |
"<!-- Title: %3 Pages: 1 -->\n", | |
"<svg width=\"206pt\" height=\"188pt\"\n", | |
" viewBox=\"0.00 0.00 206.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", | |
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n", | |
"<title>%3</title>\n", | |
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 202,-184 202,4 -4,4\"/>\n", | |
"<!-- f -->\n", | |
"<g id=\"node1\" class=\"node\"><title>f</title>\n", | |
"<ellipse fill=\"none\" stroke=\"black\" cx=\"99\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n", | |
"<text text-anchor=\"middle\" x=\"99\" y=\"-85.8\" font-family=\"Times,serif\" font-size=\"14.00\">f</text>\n", | |
"</g>\n", | |
"<!-- a -->\n", | |
"<g id=\"node5\" class=\"node\"><title>a</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"90,-180 36,-180 36,-144 90,-144 90,-180\"/>\n", | |
"<text text-anchor=\"middle\" x=\"63\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n", | |
"</g>\n", | |
"<!-- f->a -->\n", | |
"<g id=\"edge4\" class=\"edge\"><title>f->a</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M91.0104,-106.535C86.7846,-114.752 81.4796,-125.068 76.6261,-134.505\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"73.4409,-133.046 71.9799,-143.539 79.6659,-136.247 73.4409,-133.046\"/>\n", | |
"</g>\n", | |
"<!-- b -->\n", | |
"<g id=\"node6\" class=\"node\"><title>b</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"162,-180 108,-180 108,-144 162,-144 162,-180\"/>\n", | |
"<text text-anchor=\"middle\" x=\"135\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n", | |
"</g>\n", | |
"<!-- f->b -->\n", | |
"<g id=\"edge5\" class=\"edge\"><title>f->b</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M106.99,-106.535C111.215,-114.752 116.52,-125.068 121.374,-134.505\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"118.334,-136.247 126.02,-143.539 124.559,-133.046 118.334,-136.247\"/>\n", | |
"</g>\n", | |
"<!-- x -->\n", | |
"<g id=\"node2\" class=\"node\"><title>x</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-36 0,-36 0,-0 54,-0 54,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"27\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">x</text>\n", | |
"</g>\n", | |
"<!-- x->f -->\n", | |
"<g id=\"edge1\" class=\"edge\"><title>x->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M44.7978,-36.3034C55.2528,-46.468 68.4873,-59.3349 79.2616,-69.8099\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"76.9874,-72.4804 86.5972,-76.9417 81.867,-67.4614 76.9874,-72.4804\"/>\n", | |
"</g>\n", | |
"<!-- y -->\n", | |
"<g id=\"node3\" class=\"node\"><title>y</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"126,-36 72,-36 72,-0 126,-0 126,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"99\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">y</text>\n", | |
"</g>\n", | |
"<!-- y->f -->\n", | |
"<g id=\"edge2\" class=\"edge\"><title>y->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M99,-36.3034C99,-44.0173 99,-53.2875 99,-61.8876\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"95.5001,-61.8956 99,-71.8957 102.5,-61.8957 95.5001,-61.8956\"/>\n", | |
"</g>\n", | |
"<!-- z -->\n", | |
"<g id=\"node4\" class=\"node\"><title>z</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"198,-36 144,-36 144,-0 198,-0 198,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"171\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">z</text>\n", | |
"</g>\n", | |
"<!-- z->f -->\n", | |
"<g id=\"edge3\" class=\"edge\"><title>z->f</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M153.202,-36.3034C142.747,-46.468 129.513,-59.3349 118.738,-69.8099\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"116.133,-67.4614 111.403,-76.9417 121.013,-72.4804 116.133,-67.4614\"/>\n", | |
"</g>\n", | |
"</g>\n", | |
"</svg>\n" | |
], | |
"text/plain": [ | |
"PipelineFunction: name=f, inputs=(x,y,z), outputs=(a,b)" | |
] | |
}, | |
"execution_count": 33, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"f" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 34, | |
"metadata": { | |
"collapsed": false | |
}, | |
"outputs": [ | |
{ | |
"data": { | |
"image/svg+xml": [ | |
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n", | |
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n", | |
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n", | |
"<!-- Generated by graphviz version 2.38.0 (20140413.2041)\n", | |
" -->\n", | |
"<!-- Title: %3 Pages: 1 -->\n", | |
"<svg width=\"62pt\" height=\"188pt\"\n", | |
" viewBox=\"0.00 0.00 62.00 188.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", | |
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 184)\">\n", | |
"<title>%3</title>\n", | |
"<polygon fill=\"white\" stroke=\"none\" points=\"-4,4 -4,-184 58,-184 58,4 -4,4\"/>\n", | |
"<!-- g -->\n", | |
"<g id=\"node1\" class=\"node\"><title>g</title>\n", | |
"<ellipse fill=\"none\" stroke=\"black\" cx=\"27\" cy=\"-90\" rx=\"18\" ry=\"18\"/>\n", | |
"<text text-anchor=\"middle\" x=\"27\" y=\"-85.8\" font-family=\"Times,serif\" font-size=\"14.00\">g</text>\n", | |
"</g>\n", | |
"<!-- c -->\n", | |
"<g id=\"node3\" class=\"node\"><title>c</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-180 0,-180 0,-144 54,-144 54,-180\"/>\n", | |
"<text text-anchor=\"middle\" x=\"27\" y=\"-157.8\" font-family=\"Times,serif\" font-size=\"14.00\">c</text>\n", | |
"</g>\n", | |
"<!-- g->c -->\n", | |
"<g id=\"edge2\" class=\"edge\"><title>g->c</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M27,-108.303C27,-116.017 27,-125.288 27,-133.888\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"23.5001,-133.896 27,-143.896 30.5001,-133.896 23.5001,-133.896\"/>\n", | |
"</g>\n", | |
"<!-- w -->\n", | |
"<g id=\"node2\" class=\"node\"><title>w</title>\n", | |
"<polygon fill=\"none\" stroke=\"black\" points=\"54,-36 0,-36 0,-0 54,-0 54,-36\"/>\n", | |
"<text text-anchor=\"middle\" x=\"27\" y=\"-13.8\" font-family=\"Times,serif\" font-size=\"14.00\">w</text>\n", | |
"</g>\n", | |
"<!-- w->g -->\n", | |
"<g id=\"edge1\" class=\"edge\"><title>w->g</title>\n", | |
"<path fill=\"none\" stroke=\"black\" d=\"M27,-36.3034C27,-44.0173 27,-53.2875 27,-61.8876\"/>\n", | |
"<polygon fill=\"black\" stroke=\"black\" points=\"23.5001,-61.8956 27,-71.8957 30.5001,-61.8957 23.5001,-61.8956\"/>\n", | |
"</g>\n", | |
"</g>\n", | |
"</svg>\n" | |
], | |
"text/plain": [ | |
"PipelineFunction: name=g, inputs=(w), outputs=(c)" | |
] | |
}, | |
"execution_count": 34, | |
"metadata": {}, | |
"output_type": "execute_result" | |
} | |
], | |
"source": [ | |
"g" | |
] | |
} | |
], | |
"metadata": { | |
"kernelspec": { | |
"display_name": "Python 2", | |
"language": "python", | |
"name": "python2" | |
}, | |
"language_info": { | |
"codemirror_mode": { | |
"name": "ipython", | |
"version": 2 | |
}, | |
"file_extension": ".py", | |
"mimetype": "text/x-python", | |
"name": "python", | |
"nbconvert_exporter": "python", | |
"pygments_lexer": "ipython2", | |
"version": "2.7.12" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 0 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment