Skip to main content

Python client and utilities for tierkreis.

Project description

Tierkreis

Tierkreis is a higher-order dataflow graph program representation and runtime designed for compositional, quantum-classical hybrid algorithms.

For a detailed introduction read the paper: Tierkreis: a Dataflow Framework for Hybrid Quantum-Classical Computing.

This repository contains the source for the tierkreis python package. The python package provides a complete development and testing environment for writing and running Tierkreis program, and allows you to write extensions ("workers") in python.

Getting Started

To install the python package run:

pip install tierkreis

This package is pure python and is compatible with Python 3.10 and above. In it's simplest form, tierkreis takes a computation graph (a workflow) and executes it. To simply run a workflow we can use the run_workflow function:

run_workflow(
    graph = times_5(),
    inputs = {Labels.VALUE: json.dumps(3).encode()},
    run_id = 123,
    name="times_5",
    print_output=True,
)

Build graphs

A workflow graph can be constructed by adding nodes to a graph object. For each node one has to define the input and output ports of the node. The following example shows how to multiple a user input with a constant value.

def times_5() -> GraphData:
    """A graph that calculates input*5 """
    g = GraphData()
    # declare the constant value 5 with the output port "value"
    const = g.add(Const(5))("value")
    # declare the Input node that reads from a port "value" and maps to a port "value" 
    user_input = g.add(Input("value"))("value")
    # use a built in functionality that takes two inputs "a" and "b" and maps to a port "value"
    output = g.add(
        Func("builtins.itimes", {"a": const, "b": user_input})
    )("value")
    # the final output of the graph is put out at a port "value"
    g.add(Output({"value": output}))
    return g

Visualize

To visualize a workflow we provide a separate package tierkreis-visualize found here. It can be invoked from the command line with tkr-vis. Opening localhost:8000 will open a browser window with the visualization.

times 5

CLI

Tierkreis comes with a command line interface for running workflows. To see all available options use tkr --help. To run the hello world example from the cli

uv run tkr -g examples/hello_world/hello_world_graph.py:hello_graph -i data.json --uv --registry-path examples/hello_world/ -o

Explanation:

  • -g specifies the graph to run by specifying the location and function to run.
  • -i specifies the input for the graph function. In this case it loads a json file from the project root with the contents {"value": "world!"}
  • --uv enables the use of the UV executor.
  • --registry-path specifies the location of the registry to use for the UV executor.
  • -o enables output printing.

Examples

For more involved examples see examples directory.

Under the Hood

Under the hood, Tierkreis consists of three main components.

  • Controller: The controller orchestrates the workflow and progresses the computation.
  • Executor: Executors are responsible to execute external function calls implemented by workers.
  • Worker: A worker is a standalone program which conforms to the tierkreis worker interface.

The run_workflow() function provides sensible defaults which can be replaced as needed. Roughly, a workflow runs by

graph = times_5()
# Define a file based controller
storage = ControllerFileStorage(UUID(int=id), name=name, do_cleanup=True)
# Define an executor running binaries from the shell
executor = ShellExecutor(
    Path("./examples/launchers"), logs_path=storage.logs_path
)
inputs = {Labels.VALUE: json.dumps(3).encode()},
run_graph(storage, executor, g, inputs)

output_ports = g.nodes[g.output_idx()].inputs.keys()
actual_output = {}
for port in output_ports:
    print(json.loads(storage.read_output(Loc(), port)))

Controller

The controller internally stores the progress of the workflow including:

  • The definition of nodes
  • The status of nodes (not started, started, error, done)
  • A map between node in- and output ports

By default this is stored in the filesystem under ~/.tierkreis/workflows/<workflow_id>/.

Executor

An executor defines a way to run workers in a workflow. For example the UVExecutor provided out of the box, will run a python program by executing

uv run main.py <node_definition_path>

The command will be executed in the registry directory of multiple workers which can be configured manually:

executor = UVExecutor(registry_path=Path("/example/example_workers"))
# the path to the directory where workers are stored

Worker

Workers are standalone programs which implement a set of functions which can connect to a Tierkreis controller to add extra primitives. To define python based workers that run in an isolated environment, you can use the build in Worker utilities and the UVExecutor.

For example, we could define a custom hello world worker:

# The following defines the python program for uv 
# /// script 
# requires-python = ">=3.12"
# dependencies = ["pydantic", "tierkreis"]
#
# ///
import logging
from sys import argv
from pathlib import Path
from tierkreis import Worker, Value

logger = logging.getLogger(__name__)
worker = Worker("hello_world_worker")

# Workers can expose multiple functions returning a Value object
@worker.function()
def greet(greeting: str, subject: str) -> Value[str]:
    logger.info("%s %s", greeting, subject)
    return Value(value=greeting + subject)

# The worker will be invoked from the executor with the node definition path as the only argument
def main() -> None:
    node_definition_path = argv[1]
    logger.info(node_definition_path)
    worker.run(Path(node_definition_path))

if __name__ == "__main__":
    logger.info("starting worker")
    main()

In a graph such a worker would be invoked by calling

    g = GraphData()
    hello = g.add(Const("hello "))("value")
    subject = g.add(Const("world!"))("value")
    output = g.add(
        Func("hello_world_worker.greet", {"greeting": hello, "subject": subject})
    )("value")
    g.add(Output({"value": output}))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tierkreis-2.0.1.tar.gz (78.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

tierkreis-2.0.1-py3-none-any.whl (47.8 kB view details)

Uploaded Python 3

File details

Details for the file tierkreis-2.0.1.tar.gz.

File metadata

  • Download URL: tierkreis-2.0.1.tar.gz
  • Upload date:
  • Size: 78.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for tierkreis-2.0.1.tar.gz
Algorithm Hash digest
SHA256 d92d65ed96a68a9590b130592026a078c97a2af61388f91403d3f7707e792d4f
MD5 e01bde0b02da4ee93563082be2514b46
BLAKE2b-256 d4ffeb3ceef9534098eb1775bb6bd3969e7db9440d44147f01aa1bf2640612c2

See more details on using hashes here.

Provenance

The following attestation bundles were made for tierkreis-2.0.1.tar.gz:

Publisher: release.yml on CQCL/tierkreis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tierkreis-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: tierkreis-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 47.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for tierkreis-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 76c9d0366bd6b0e1df649d4aa610bdd928b48745a7f19ebb080c77e0888a945b
MD5 f394e082d55e354c4580c81ed98d5977
BLAKE2b-256 11c5ba5b112d6ff20948fae879b95ee532685647b97fea75218cae86f6486725

See more details on using hashes here.

Provenance

The following attestation bundles were made for tierkreis-2.0.1-py3-none-any.whl:

Publisher: release.yml on CQCL/tierkreis

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page