Builtin Ecto Cells¶
Ecto contains a few cells that are generally useful for Ecto graph construction.
Convenience cells¶
The are cells that may be generally useful in your ecto graphs and tend to be weakly typed.
Constant¶
This cell takes a python parameter that becomes a constant
output. As long as this python type is convertable to a c++ type
(through python
bindings or basic types), it may be connected
to cells written in c++.
Brief doc
Constant node always outputs same value.
Parameters
value
boost::python::api::object
None
Value to output
Outputs
out
boost::python::api::object
Any type, constant.
Passthrough¶
Passthrough is mostly useful from within a BlackBox to connect multiple inputs to one cell, which then becomes a singular input for the BlackBox.
Brief doc
Passes through any type.
Inputs
in
ecto::tendril::none
Any type
Outputs
out
ecto::tendril::none
Any type
TrueEveryN¶
Brief doc
Will give a true result every n executions.
Parameters
count
int
0
Initial value of counter, will be incremented at every call to process.
n
int
2
Will be true at every iteration where count%n == 0
Outputs
flag
bool
If¶
The If cell enables you to conditionally execute a single cell based on an input flag.
An example of using the If cell for condition execution of a
cell. Notice that cell that is encased in an If is not added to the
graph, it is passed to the If
cell as a parameter.
#!/usr/bin/env python
import ecto
from ecto import If, TrueEveryN
from ecto.ecto_test import Generate
plasm = ecto.Plasm()
g = Generate("Generator", step=1.0, start=1.0)
if_g = If(cell=g)
truer = TrueEveryN(n=3,count=3)
plasm.connect(truer['flag'] >> if_g['__test__']
)
plasm.execute(niter=9)
assert g.outputs.out == 3 #should have only called execute 3 times.
The above sample uses the built in cell TrueEveryN
Brief doc
If true, process, else, don’t.
Parameters
cell
boost::shared_ptr<ecto::cell>
Cell to conditionally execute. The inputs and outputs of this cell will be replicated to the If cell.
input_tendril_name
std::string
__test__
Name to use for the conditional input tendril.
Inputs
__test__
bool
The test value. If this is true then cell::process() is called.
Entanglement¶
To support feedback loops, asynchronous execution of graphs, and conditional execution, ecto supplies a concept of entangled cells, which allow communication of values without breaking the acyclic or synchronous nature of graph execution.
-
ecto.
EntangledPair
((Tendril)value[, (str)source_name[, (str)sink_name]]) → tuple :¶ Constructs a pair of entangled cells. Useful for teleportation of tendrils without constructing edges in a graph.
- C++ signature :
- boost::python::tuple EntangledPair(boost::shared_ptr<ecto::tendril> [,std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > [,std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >]])
EntangledPair is useful when you would like to feed the output of one cell into the input of another cell, without creating a cycle in the graph. Keep in mind that the first execution of the graph will result in the default value of the whatever the source is connected to being used.
Here is an example of using the EntangledPair for feedback in a graph.
#!/usr/bin/env python
import ecto
from ecto.ecto_test import Generate, Add
g = Generate("Generator", step=1.0, start=1.0)
add = Add()
source, sink = ecto.EntangledPair(value=add.inputs.at('left'))
plasm = ecto.Plasm()
plasm.connect(source[:] >> add['left'],
g[:] >> add['right'],
add[:] >> sink[:]
)
for i in range(0, 5):
plasm.execute(niter=1)
print add.outputs.out
The output is:
No module named PySide.QtCore
1.0
3.0
6.0
10.0
15.0
And the graph looks like the following. Notice that there is no cycle:
Dealer¶
It may be that you have some iterable in python that you would like to pay out to your graph, one item at a time. Enter the Dealer, think blackjack.
-
ecto.
Dealer
(*args, **kwargs)¶ Emit values of python iterable
- Parameters:
- iterable [boost::python::api::object] REQUIRED
iterable python object... values to be output
- tendril [boost::shared_ptr<ecto::tendril>] REQUIRED
Destination tendril... used to set output type
- Outputs:
- out [ecto::tendril::none]
Any type
The argument
typer
should be a tendril, which already has a type associated with it. This is used to prime the dealer’s type erasure, so that boost python objects are converted immediately to this type.
Here is an example of using the Dealer.
#!/usr/bin/env python
import ecto
import ecto.ecto_test as ecto_test
plasm = ecto.Plasm()
printer = ecto_test.Printer()
cards = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
dealer = ecto.Dealer(tendril=printer.inputs.at('in'), iterable=cards)
plasm.connect(dealer['out'] >> printer['in'])
if __name__ == '__main__':
Scheduler = ecto.Scheduler
sched = Scheduler(plasm)
sched.execute()
assert dealer.outputs.at('out').type_name == 'double'
assert dealer.outputs.out == 10
The output is:
No module named PySide.QtCore
***** 1 ***** 0x1a01e60
***** 2 ***** 0x1a01e60
***** 3 ***** 0x1a01e60
***** 4 ***** 0x1a01e60
***** 5 ***** 0x1a01e60
***** 6 ***** 0x1a01e60
***** 7 ***** 0x1a01e60
***** 8 ***** 0x1a01e60
***** 9 ***** 0x1a01e60
***** 10 ***** 0x1a01e60
And the graph looks like the following. Notice that there is no cycle: