Skip to content

doc: Fine-tune onboarding experience #243

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ addition to the project itself, then run `make html`:
```console
$ . venv/bin/activate
$ pip install -e .[dev]
$ pip install -r docs/requirements.txt
$ cd docs
$ make html
```
Expand Down Expand Up @@ -73,7 +72,7 @@ clone the repository, install the dependencies, and setup pre-commit hooks:

```console
$ git clone git@github.com:pasteurlabs/tesseract-core.git
$ cd tesseract
$ cd tesseract-core
$ python -m venv venv
$ . venv/bin/activate
$ pip install -e .[dev]
Expand Down
4 changes: 4 additions & 0 deletions docs/content/creating-tesseracts/create.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ The last section in `tesseract_api.py` contains templates for optional endpoints
You can leave it untouched for this example, as the operation we are
implementing is not differentiable.

```{tip}
For a Tesseract that has all optional endpoints implemented, check out the [Univariate example](../examples/building-blocks/univariate.md).
```

Finally, we can set the name of this Tesseract and its version in
`tesseract_config.yaml`.

Expand Down
74 changes: 74 additions & 0 deletions docs/content/examples/building-blocks/univariate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Univariate Rosenbrock function

## Context
Example that wraps the univariate [Rosenbrock function](https://en.wikipedia.org/wiki/Rosenbrock_function), which is a common test problem for optimization algorithms. Defines a Tesseract that has all optional endpoints implemented, including `apply`, `abstract_eval`, `jacobian`, `jacobian_vector_product`, and `vector_jacobian_product`.

```{seealso}
This example (and using it to perform optimization) is also part of an [Expert Showcase](https://si-tesseract.discourse.group/t/jax-based-rosenbrock-function-minimization/48) in the Tesseract Community Forum.
```

## Example Tesseract (examples/univariate)

### Core functionality --- schemas and `apply` function

This example uses a pure-Python implementation of the Rosenbrock function as the basis for all endpoints:

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: rosenbrock
:language: python
```

As such, the Tesseract has 2 differentiable scalar inputs (`x` and `y`) and a single output (the value of the Rosenbrock function at those inputs). The parameters `a` and `b` are treated as non-differentiable constants.

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: InputSchema
:language: python
```

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: OutputSchema
:language: python
```

This makes it straightforward to write the `apply` function, which simply unpacks the inputs and calls the `rosenbrock` function with them:

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: apply
:language: python
```

### Jacobian endpoint

For the Jacobian, we exploit the fact that the `rosenbrock` function is traceable by [JAX](https://github.com/jax-ml/jax). We can therefore use [`jax.jacrev`](https://docs.jax.dev/en/latest/_autosummary/jax.jacrev.html) to compute the Jacobian of the function with respect to its inputs:

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: jacobian
:language: python
```

### Other AD endpoints

We define the JVP (Jacobian-vector product) and VJP (vector-Jacobian product) endpoints by summing over rows / columns of the Jacobian matrix. That is, we call `jacobian` under the hood, then multiply the resulting Jacobian matrix by the (tangent / cotangent) vector input.

```{warning}
Defining JVP and VJP operations through sums over the full Jacobian matrix is inefficient and negates the benefits of using JVP / VJP. These endpoints are provided for completeness, but in practice, you would typically use JAX's built-in JVP and VJP functions directly.
```

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: jacobian_vector_product
:language: python
```

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: vector_jacobian_product
:language: python
```

### Abstract evaluation

Some Tesseract clients (like [Tesseract-JAX](https://github.com/pasteurlabs/tesseract-jax)) require an abstract evaluation endpoint in order to pre-allocate memory for the inputs and outputs. This is a simple function that returns the shapes of the outputs based on the shapes of the inputs. In this case, the output is always a scalar, so we return an empty shape tuple:

```{literalinclude} ../../../../examples/univariate/tesseract_api.py
:pyobject: abstract_eval
:language: python
```
7 changes: 0 additions & 7 deletions docs/content/examples/building-blocks/vectoradd.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,6 @@ We also have an example of a basic apply function and how it utilizes the inputs
As previously mentioned, the inputs are marked as Differentiable in order for us to write
a Jacobian function.

In order for us to do that, we must also write the abstract eval function.

```{literalinclude} ../../../../examples/vectoradd/tesseract_api.py
:pyobject: abstract_eval
:language: python
```

```{literalinclude} ../../../../examples/vectoradd/tesseract_api.py
:pyobject: jacobian
:language: python
Expand Down
6 changes: 6 additions & 0 deletions docs/content/examples/example_gallery.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
:glob:
building-blocks/helloworld.md
building-blocks/vectoradd.md
building-blocks/univariate.md
building-blocks/packagedata.md
building-blocks/arm64.md
building-blocks/localdependency.md
Expand Down Expand Up @@ -36,6 +37,11 @@ You can also find these Tesseracts in the `examples` directory of the [code repo

Tesseract performing vector addition. Highlighting simple array operations and how to use the Tesseract Python API.
:::
:::{grid-item-card} Univariate
:link: building-blocks/univariate.html

A Tesseract that wraps the univariate Rosenbrock function, which is a common test problem for optimization algorithms.
:::
:::{grid-item-card} Package Data
:link: building-blocks/packagedata.html

Expand Down
6 changes: 5 additions & 1 deletion docs/content/introduction/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ These files are all that's needed to define a Tesseract.
### `tesseract_api.py`

The `tesseract_api.py` file defines the Tesseract's input and output schemas, and the functions that are being called when we invoke `tesseract run <funcname>`. These are,
`apply`, `jacobian`, `jacobian_vector_product`, and `vector_jacobian_product`. Out of all of the endpoints you
`apply`, `abstract_eval`, `jacobian`, `jacobian_vector_product`, and `vector_jacobian_product` (see [endpoints](../api/endpoints.md)). Out of all of the endpoints you
can implement, only `apply` is required for a Tesseract to work.

```{literalinclude} ../../../examples/helloworld/tesseract_api.py
Expand All @@ -130,6 +130,10 @@ These files are all that's needed to define a Tesseract.
:pyobject: apply
```

```{tip}
For a Tesseract that has all optional endpoints implemented, check out the [Univariate example](../examples/building-blocks/univariate.md).
```

(quickstart-tr-config)=
### `tesseract_config.yaml`

Expand Down