Example #1
0
def main():
    graph = aiocells.DependencyGraph()

    clock = aiocells.ModClock()

    variable_1 = aiocells.ModPlace(clock)
    variable_2 = aiocells.ModPlace(clock)

    printer_1 = aiocells.ModPrinter(clock, variable_1,
                                    "variable_1 changed to {value}")
    printer_2 = aiocells.ModPrinter(clock, variable_2,
                                    "variable_2 changed to {value}")

    graph.add_precedence(variable_1, printer_1)
    graph.add_precedence(variable_2, printer_2)

    print("Nothing has changed:")
    aiocells.compute_sequential(graph)

    variable_1.value = 1
    variable_2.value = 2
    print("Both variables:")
    aiocells.compute_sequential(graph)

    variable_1.value = 3
    print("variable_1 only:")
    aiocells.compute_sequential(graph)
Example #2
0
async def async_main():

    # Tests an async internal node in a flow graph

    graph = aiocells.DependencyGraph()

    time = aiocells.Place()
    printer = graph.add_node(functools.partial(async_printer, time))

    graph.add_precedence(time, printer)

    # This example will continue until it is interrupted with Ctrl-C.
    #
    # Note that marking a function to be repeater function currently only
    # affects the behaviour of 'compute_flow' and not any of the other
    # `compute` functions.

    print()
    print("Demo will complete in 10 iterations. Ctrl-C to cancel.")
    print()
    repeat_timer = functools.partial(aiocells.timer, 1, time)
    graph.add_precedence(repeat_timer, time)

    iteration_count = 0
    while await aiocells.compute_flow(graph):
        iteration_count += 1
        if iteration_count > 10:
            await aiocells.cancel_flow(graph)
Example #3
0
def create_graph(stopwatch):

    graph = aiocells.DependencyGraph()

    # The method to start the stopwatch
    start_stopwatch = stopwatch.start

    # Two sleeps. Note that they are asyncio.sleep
    sleep_1 = partial(asyncio.sleep, 1)
    sleep_2 = partial(asyncio.sleep, 2)

    # The method to stop the stopwatch
    stop_stopwatch = stopwatch.stop

    # Start the stopwatch before the first sleep
    graph.add_precedence(start_stopwatch, sleep_1)
    # Stop the stopwatch after the first sleep
    graph.add_precedence(sleep_1, stop_stopwatch)

    # Start the stopwatch before the second sleep
    graph.add_precedence(start_stopwatch, sleep_2)
    # Stop the stopwatch after the second sleep
    graph.add_precedence(sleep_2, stop_stopwatch)

    # Note that there is no precedence relationship between the two
    # sleeps.
    return graph
Example #4
0
async def async_main():

    clock = aiocells.ModClock()
    graph = aiocells.DependencyGraph()

    # Here, we simplify the previous demo by using a single variable to
    # store the time and a single printer to announce the modifications
    # when they happen. Because we are using 'compute_flow', the graph
    # is computed when any of the timers go off.
    time = aiocells.ModVariable(clock)
    printer = aiocells.ModPrinter(clock, time, "time changed to {value}")
    graph.add_precedence(time, printer)

    # Set the time after 1 second
    timer_1 = functools.partial(aiocells.timer, 1, time)
    graph.add_precedence(timer_1, time)

    # Set the time after 3 seconds
    timer_3 = functools.partial(aiocells.timer, 3, time)
    graph.add_precedence(timer_3, time)

    print()
    print("Demo will complete in 10 iterations. Ctrl-C to cancel.")
    print()

    iteration_count = 0
    while await aiocells.compute_flow(graph):
        iteration_count += 1
        if iteration_count > 10:
            await aiocells.cancel_flow(graph)
Example #5
0
def main():
    graph = aiocells.DependencyGraph()

    # First, we add a lambda function
    before_sleep = graph.add_node(lambda: print("Sleeping..."))

    # Second, we create a coroutine function using functools.partial. This
    # is the closest we can get to a lambda for an async function
    sleep_2 = partial(asyncio.sleep, 2)

    # Finally, another lambda function
    wake_up = graph.add_node(lambda: print("Woke up!"))

    # Here, 'sleep' will implicitly be added to the graph because it is
    # part of the precedence relationship
    graph.add_precedence(before_sleep, sleep_2)
    graph.add_precedence(sleep_2, wake_up)

    # Here, we use the `async_compute_sequential`, which, like
    # `compute_sequential`, call the nodes in a topologically correct sequence.
    # However, whereas `compute_sequential` only supports vanilla callables,
    # `async_compute_sequential` additionally supports coroutine functions,
    # as defined by `inspect.iscoroutinefunction`. However, the execution is
    # still sequential. Each coroutine function is executed using 'await' and
    # must complete before the next node is executed. The function
    # `async_compute_sequential` is a coroutine and must be awaited.  Here,
    # we simply pass it to `asyncio.run`.
    asyncio.run(aiocells.async_compute_sequential(graph))
Example #6
0
def main():
    graph = aiocells.DependencyGraph()

    # In this example, we add a instance of a callable object rather than
    # a function
    node = graph.add_node(HelloWorld())

    aiocells.compute_sequential(graph)
Example #7
0
def create_graph(stopwatch):

    graph = aiocells.DependencyGraph()

    start_stopwatch = stopwatch.start
    stop_stopwatch = stopwatch.stop

    for t in range(100000):
        sleep_1 = partial(asyncio.sleep, 1)
        graph.add_precedence(start_stopwatch, sleep_1)
        graph.add_precedence(sleep_1, stop_stopwatch)

    return graph
Example #8
0
def create_graph(stopwatch):

    graph = aiocells.DependencyGraph()

    start_stopwatch = graph.add_node(stopwatch.start)
    stop_stopwatch = graph.add_node(stopwatch.stop)

    for i in range(10):
        subgraph = graph.add_node(partial(run_subgraph, f"{i}"))
        graph.add_precedence(start_stopwatch, subgraph)
        graph.add_precedence(subgraph, stop_stopwatch)

    return graph
Example #9
0
def subgraph(name, period):

    clock = aiocells.ModClock()
    graph = aiocells.DependencyGraph(name=name)

    time = aiocells.ModPlace(clock)
    printer = aiocells.ModPrinter(clock, time,
                                  f"time in \"{name}\" changed to {{value}}")
    graph.add_precedence(time, printer)

    timer = functools.partial(aiocells.timer, period, time)
    graph.add_precedence(timer, time)

    return graph
Example #10
0
def create_graph(stopwatch):

    graph = aiocells.DependencyGraph()

    start_stopwatch = stopwatch.start
    stop_stopwatch = stopwatch.stop

    for t in range(100000):

        def null():
            pass

        graph.add_precedence(start_stopwatch, null)
        graph.add_precedence(null, stop_stopwatch)

    return graph
Example #11
0
async def async_main():

    graph = aiocells.DependencyGraph(name="async_main")

    subgraph_1 = subgraph("graph_1", 0.7)
    subgraph_2 = subgraph("graph_2", 1.5)

    graph.add_node(functools.partial(aiocells.compute_flow, subgraph_1))
    graph.add_node(functools.partial(aiocells.compute_flow, subgraph_2))

    print()
    print("Demo will complete in 10 iterations. Ctrl-C to cancel.")
    print()

    iteration_count = 0
    while await aiocells.compute_flow(graph):
        iteration_count += 1
        if iteration_count > 10:
            await aiocells.cancel_flow(graph)
Example #12
0
def main():
    graph = aiocells.DependencyGraph()

    # 'add_node' always returns the node that has just been added, in this
    # case the lambda functions. We will use this below to define precedence
    # relationships
    print_sleeping = graph.add_node(lambda: print("Sleeping..."))
    sleep = graph.add_node(lambda: time.sleep(2))
    print_woke_up = graph.add_node(lambda: print("Woke up!"))

    print("Define the precedence relationships...")
    graph.add_precedence(print_sleeping, sleep)
    graph.add_precedence(sleep, print_woke_up)

    # Now, after we've defined the precedence relationships, we use the
    # simplest computer to compute the graph. The nodes will be called in
    # an order that is consistent with the precedence relationships.
    # Specifically, the nodes are executed in topological order.
    aiocells.compute_sequential(graph)
Example #13
0
def create_graph(stopwatch):
    graph = aiocells.DependencyGraph()

    start_stopwatch = stopwatch.start

    # Note that these two sleeps are just lambdas. They are vanilla
    # callables and not coroutine functions. Thus, they cannot be run
    # concurrently. Thus, the total run time will be about 3 seconds even
    # if we use the concurrent computer.
    sleep_1 = graph.add_node(lambda: time.sleep(1))
    sleep_2 = graph.add_node(lambda: time.sleep(2))

    stop_stopwatch = stopwatch.stop

    graph.add_precedence(start_stopwatch, sleep_1)
    graph.add_precedence(sleep_1, stop_stopwatch)

    graph.add_precedence(start_stopwatch, sleep_2)
    graph.add_precedence(sleep_2, stop_stopwatch)

    return graph
Example #14
0
def main():

    graph = aiocells.DependencyGraph()

    time = aiocells.Place()

    # 'aio.timer' will put the current time in the 'time' variable when
    # one second has expired
    timer = functools.partial(aiocells.timer, 1, time)
    printer = aiocells.print_value(time, "variable changed to {value}")

    graph.add_precedence(timer, time)
    graph.add_precedence(time, printer)
    logger.debug("graph: %s", graph)

    logger.info("First computation...")
    asyncio.run(aiocells.async_compute_concurrent(graph))
    logger.debug("graph: %s", graph)

    logger.info("Second computation...")
    asyncio.run(aiocells.async_compute_concurrent(graph))
    logger.debug("graph: %s", graph)
Example #15
0
def main():

    graph = aiocells.DependencyGraph()

    time = aiocells.Place()
    timer = TimerObject(time)

    # Here, we bind the coroutine method with the object
    compute_timer = functools.partial(TimerObject.compute, timer)
    printer = aiocells.print_value(time, "variable changed to {value}")

    graph.add_precedence(compute_timer, time)
    graph.add_precedence(time, printer)
    logger.debug("graph: %s", graph)

    logger.info("First computation...")
    asyncio.run(aiocells.async_compute_concurrent(graph))
    logger.debug("graph: %s", graph)

    logger.info("Second computation...")
    asyncio.run(aiocells.async_compute_concurrent(graph))
    logger.debug("graph: %s", graph)
Example #16
0
async def async_main(iterations=None):

    iterations = iterations if iterations is not None else 10

    clock = aiocells.ModClock()
    graph = aiocells.DependencyGraph(name="demo_1")

    # Two completely unrelated sequences are added to the graph. They
    # run concurrently.

    time_1 = aiocells.ModPlace(clock)
    timer_1 = functools.partial(aiocells.timer, 1, time_1)
    printer_1 = aiocells.ModPrinter(clock, time_1, "time_1 changed to {value}")
    graph.add_precedence(timer_1, time_1)
    graph.add_precedence(time_1, printer_1)

    time_3 = aiocells.ModPlace(clock)
    timer_3 = functools.partial(aiocells.timer, 3, time_3)
    printer_3 = aiocells.ModPrinter(clock, time_3, "time_3 changed to {value}")
    graph.add_precedence(timer_3, time_3)
    graph.add_precedence(time_3, printer_3)

    # With a flow computation, when any of the input nodes returns, all
    # non-input nodes are computed in topological order.  When this happens, we
    # are generally only interested in nodes that change as a result of the
    # input node returning. So, in this case, we see a message from "time_1"
    # every second and a message from "time_3" every 3 seconds

    print()
    print("Demo will complete in 10 iterations. Ctrl-C to cancel.")
    print()

    iteration_count = 0
    while await aiocells.compute_flow(graph):
        iteration_count += 1
        if iteration_count > iterations:
            await aiocells.cancel_flow(graph)
Example #17
0
def main():
    graph = aiocells.DependencyGraph()

    # The node can be any callable, in this case a function.
    graph.add_node(hello_world)
    aiocells.compute_sequential(graph)
Example #18
0
async def run_subgraph(name):
    graph = aiocells.DependencyGraph()
    sleep_2 = partial(asyncio.sleep, 2)
    graph.add_node(sleep_2)
    print(f"Running subgraph {name}")
    await aiocells.async_compute_concurrent(graph)
Example #19
0
def main():
    graph = aiocells.DependencyGraph()
    graph.add_node(lambda: time.sleep(2))
    print("This computation will take about 2 seconds because of the sleep")
    aiocells.compute_sequential(graph)