Euler#

This is a toy example that proves Euler’s identity using Tango. You can use this to play with the concept of a Step and see how Tango runs things without getting distracted by the details of what you’re running.

Running the experiment#

If you haven’t already, clone the tango repository and then change directories into examples/euler.

You can then run the experiment with:

tango run euler_general.jsonnet -i complex_arithmetic -w workspace

This will leave its results in a subdirectory of workspace/runs/ corresponding to the name of the run. The output it prints should look something like this:

Starting new run comic-heron
Server started at http://localhost:8080/run/comic-heron
[step i_times_pi] ● Starting step "i_times_pi"...
[step i_times_pi] βœ“ Finished step "i_times_pi"
[step cos] ● Starting step "cos"...
[step cos] βœ“ Finished step "cos"
[step sin] ● Starting step "sin"...
[step sin] βœ“ Finished step "sin"
[step pow_e] βœ“ Found output for step "i_times_pi" in cache (needed by "pow_e")...
[step pow_e] ● Starting step "pow_e"...
[step pow_e] βœ“ Finished step "pow_e"
[step i_times_sin] βœ“ Found output for step "sin" in cache (needed by "i_times_sin")...
[step i_times_sin] ● Starting step "i_times_sin"...
[step i_times_sin] βœ“ Finished step "i_times_sin"
[step sum] βœ“ Found output for step "cos" in cache (needed by "sum")...
[step sum] βœ“ Found output for step "i_times_sin" in cache (needed by "sum")...
[step sum] ● Starting step "sum"...
[step sum] βœ“ Finished step "sum"
[step sub] βœ“ Found output for step "sum" in cache (needed by "sub")...
[step sub] βœ“ Found output for step "pow_e" in cache (needed by "sub")...
[step sub] ● Starting step "sub"...
[step sub] βœ“ Finished step "sub"
[step print] βœ“ Found output for step "sub" in cache (needed by "print")...
[step print] ● Starting step "print"...
[step print] 0j
[step print] βœ“ Finished step "print"
βœ“ Finished run comic-heron

 ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 ┃ Step Name   ┃ Status      ┃ Cached Result                                                     ┃
 ┑━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
 β”‚ cos         β”‚ βœ“ succeeded β”‚ workspace/cache/CosineStep-5aes9CUTRmkz5gJ5J6JSRbJZ4qkFu4kk       β”‚
 β”‚ i_times_pi  β”‚ βœ“ succeeded β”‚ workspace/cache/MultiplyStep-4SRzHCCqYGs2PLeT8LeL5ukrCWGJoiae     β”‚
 β”‚ i_times_sin β”‚ βœ“ succeeded β”‚ workspace/cache/MultiplyStep-2ZG7wPj9WLn5PgpYyPVHw9Qg7VM1mhwf     β”‚
 β”‚ pow_e       β”‚ βœ“ succeeded β”‚ workspace/cache/ExponentiateStep-1swPpNipP6HBSP5rKdNjEqbYAWNf4CdG β”‚
 β”‚ print       β”‚ βœ“ succeeded β”‚ N/A                                                               β”‚
 β”‚ sin         β”‚ βœ“ succeeded β”‚ workspace/cache/SineStep-5aes9CUTRmkz5gJ5J6JSRbJZ4qkFu4kk         β”‚
 β”‚ sub         β”‚ βœ“ succeeded β”‚ workspace/cache/SubtractionStep-4ygj1UyLk6TCVBxN7DWTCccbMa7M1C5v  β”‚
 β”‚ sum         β”‚ βœ“ succeeded β”‚ workspace/cache/AdditionStep-34AiXoyiPKADMUnhcBzFYd6JeMcgx4DP     β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                                 βœ“ 8 succeeded

Use your workspace to get the cached result of a step, e.g.

 >>> from tango import Workspace
 >>> workspace = Workspace.from_url(...)
 >>> workspace.step_result_for_run("comic-heron", "sum")

A few things are of note here:

  1. Tango assigns a name to your run. In this case, the name is β€œcomic-heron”.

  2. Tango starts a web server while it runs. You can connect to this server to follow along with the progress.

  3. In this configuration, the β€œprint” step prints the output (”0j”). Most of the time though, you will look for the output in the output directories that are given in the table.

  4. You might notice that the β€œprint” step produces no output. That’s because it is uncacheable, and thus writes out nothing.

Try the workspace UI#

You can visualize the workspace by running

tango server -w workspace

This command will start up a web server that visualizes workspace directories. It first presents you with a list of runs. Click through to your run, and you see a graph of the steps that you just ran:

Step Graph

You can click on the arrow next to each step to see more information.

Change a step#

Let’s make an update to a step! Open complex_arithmetic.py and change AdditionStep. The actual change you make in the run() method does not matter, but the important thing is to update the VERSION member of the AdditionStep class. AdditionStep does not yet have a VERSION, so we will give it one:

@Step.register("cadd")
class AdditionStep(Step):
    VERSION = "002"     # This is the important change.
    
    def run(self, a: ComplexOrTuple, b: ComplexOrTuple) -> complex:  # type: ignore
        return make_complex(a) + make_complex(b)

Now run the config again with

tango run euler_general.jsonnet -i complex_arithmetic -w workspace

This time, the output will look like this:

Starting new run right-amoeba
Server started at http://localhost:8080/run/right-amoeba
[step sum] βœ“ Found output for step "cos" in cache (needed by "sum")...
[step sum] βœ“ Found output for step "i_times_sin" in cache (needed by "sum")...
[step sum] ● Starting step "sum"...
[step sum] βœ“ Finished step "sum"
[step sub] βœ“ Found output for step "sum" in cache (needed by "sub")...
[step sub] βœ“ Found output for step "pow_e" in cache (needed by "sub")...
[step sub] ● Starting step "sub"...
[step sub] βœ“ Finished step "sub"
[step print] βœ“ Found output for step "sub" in cache (needed by "print")...
[step print] ● Starting step "print"...
[step print] 0j
[step print] βœ“ Finished step "print"
βœ“ Finished run right-amoeba

 ┏━━━━━━━━━━━━━┳━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
 ┃ Step Name   ┃ Status      ┃ Cached Result                                                     ┃
 ┑━━━━━━━━━━━━━╇━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┩
 β”‚ cos         β”‚ - not run   β”‚ workspace/cache/CosineStep-5aes9CUTRmkz5gJ5J6JSRbJZ4qkFu4kk       β”‚
 β”‚ i_times_pi  β”‚ - not run   β”‚ workspace/cache/MultiplyStep-4SRzHCCqYGs2PLeT8LeL5ukrCWGJoiae     β”‚
 β”‚ i_times_sin β”‚ - not run   β”‚ workspace/cache/MultiplyStep-2ZG7wPj9WLn5PgpYyPVHw9Qg7VM1mhwf     β”‚
 β”‚ pow_e       β”‚ - not run   β”‚ workspace/cache/ExponentiateStep-1swPpNipP6HBSP5rKdNjEqbYAWNf4CdG β”‚
 β”‚ print       β”‚ βœ“ succeeded β”‚ N/A                                                               β”‚
 β”‚ sin         β”‚ - not run   β”‚ workspace/cache/SineStep-5aes9CUTRmkz5gJ5J6JSRbJZ4qkFu4kk         β”‚
 β”‚ sub         β”‚ βœ“ succeeded β”‚ workspace/cache/SubtractionStep-42mdcQBtrNAYvxYhmzdd1vj2uCG8N5Yf  β”‚
 β”‚ sum         β”‚ βœ“ succeeded β”‚ workspace/cache/AdditionStep-002-34AiXoyiPKADMUnhcBzFYd6JeMcgx4DP β”‚
 β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                                           βœ“ 3 succeeded, 5 not run

Use your workspace to get the cached result of a step, e.g.

 >>> from tango import Workspace
 >>> workspace = Workspace.from_url(...)
 >>> workspace.step_result_for_run("right-amoeba", "sum")

As you can see, it re-used the cached results for several of the steps, and only ran three steps anew.

tango.step.Step.VERSION is just one of the ways in which you can change the behavior of a step. Head over to the documentation of the tango.step.Step class to see the others.