Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4c455ea
TDD: SOC projections in Rust
alphaville May 4, 2026
572922f
PR template
alphaville May 4, 2026
4a5c6d7
SOC implementation
alphaville May 4, 2026
1d01559
code snippet/example in SOC
alphaville May 4, 2026
66ee773
slightly more efficient impl of SOC projection
alphaville May 4, 2026
db88881
update PR template
alphaville May 4, 2026
219afeb
improved impl of sq. distance to SOC
alphaville May 4, 2026
4143552
fix: emitted sqrt now works in no_std
alphaville May 5, 2026
f02fcb7
v0.5.1a1
alphaville May 5, 2026
0b26182
links to Google Colab demos
alphaville May 5, 2026
9b8cac7
Merge branch 'main' into feature/78-soc
alphaville May 5, 2026
1c6bdb0
efficient SOC projections
alphaville May 5, 2026
02e3958
euclidean ball projections are more efficient
alphaville May 5, 2026
2d7b416
ball centered at zero: improvements
alphaville May 5, 2026
9ea4933
infinity norm: improvements
alphaville May 5, 2026
3b84427
Addressing #81
alphaville May 5, 2026
ebc5805
update changelog
alphaville May 5, 2026
0e476e5
better use of workspace
alphaville May 5, 2026
117896c
minor fix in unit test
alphaville May 5, 2026
cfa6f6f
update unit tests
alphaville May 5, 2026
d68d095
challenging bug fixes
alphaville May 5, 2026
d6aeb1e
fix issue in render test
alphaville May 6, 2026
7c78e87
more testing
alphaville May 6, 2026
87f4938
tests use debug mode
alphaville May 6, 2026
7da7aa5
added test file
alphaville May 6, 2026
880cdf9
fixed issue with tests
alphaville May 6, 2026
fcba929
[ci skip] blog post; bumped v0.5.1
alphaville May 6, 2026
64e8002
demo on SOC and tests
alphaville May 6, 2026
4f2dab5
final polish before release of v0.5.1
alphaville May 6, 2026
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
33 changes: 33 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Main Changes

Give a summary of the key changes


## Associated Issues

- Closes #1
- Addresses #2


## Merge Dependencies

Either:
- This PR has no merge dependencies, or
- Depends on: ..., or
- Should be merged before: ...

## Target versions and releases

- Gradgen v0.X.X
- Alpha release v0.X.Xa1


## Checklist

- [ ] API documentation updated
- [ ] Appropriate testing
- [ ] Create a demo in `demos/`, if necessary
- [ ] Update `CHANGELOG`
- [ ] Update webpage documentation (incl. Google Colab demo), if necessary; update `last_update` metadata
- [ ] Bump versions in `pyproject.toml`, if necessary
- [ ] If a new version is being released, write blog post
4 changes: 3 additions & 1 deletion .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
run: python -m pip install --upgrade pip && python -m pip install -e . numpy sympy pytest

- name: Run tests
run: pytest tests -v
run: pytest tests

- name: Generate demo crates
run: make -C demos/
Expand All @@ -51,6 +51,8 @@ jobs:
cargo clippy --quiet --manifest-path demos/single_shooting/single_shooting_kernel/Cargo.toml -- -D warnings
cargo clippy --quiet --manifest-path demos/single_shooting_penalty/single_shooting_penalty_kernel/Cargo.toml -- -D warnings
cargo clippy --quiet --manifest-path demos/python_interface/foo_python/Cargo.toml -- -D warnings
cargo clippy --quiet --manifest-path demos/soc/soc_kernel/Cargo.toml -- -D warnings
cargo clippy --quiet --manifest-path demos/soc/soc_kernel_python/Cargo.toml -- -D warnings

- name: Run demo runners
run: |
Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ def zip_function(

### Docusaurus

- All docusaurus files must be `.mdx` and not `.md`. Never rename `.mdx` files to `.md`.
- All docusaurus files, with the possible exception of blog posts, must be `.mdx` and not `.md`. Never rename `.mdx` files to `.md`.

## What Agents Must Never Do

Expand Down
52 changes: 52 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,58 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).


## 0.5.1 - 06-05-2026

### Added

- Added `SquaredDistanceToSet.second_order_cone(...)` for Rust-backed
half-squared distance and projection generation for second-order cones
of the form `{x = (y, t) : ||y||_2 <= alpha t}`.
- Added a `demos/soc` demo that generates a Rust-Python interface for a
second-order cone distance kernel and prints the generated function
outputs from Python.
- Added SymPy parity integration tests covering scalar derivatives,
gradients, Jacobians, and Hessians generated by gradgen.

### Changed

- Removed the `with_prefer_direct_output_sinks` Rust backend config toggle and
made additive output accumulation the default lowering style for final
outputs. Generated kernels now write readable incremental updates directly
into the output slices whenever possible.
- Emitted `copy_from_slice` for contiguous vector outputs backed by workspace
slices, replacing element-by-element final copy assignments with idiomatic
slice copies where possible.
- Optimized the generated Rust helpers for
`SquaredDistanceToSet.second_order_cone(...)` so the projection defers
`sqrt(...)` to the nontrivial branch, and the primal helper computes the
half-squared distance directly without first materializing the projection.
- Fixed Rust-backed custom snippets used by
`SquaredDistanceToSet.second_order_cone(...)` so generated `no_std`
crates use the configured math library for `sqrt(...)` instead of calling
an unavailable inherent floating-point method.
- Optimized generated Rust gradients for projection-backed custom distances
so trivial `+ 0` and `* 1` wrappers no longer force workspace code, direct
Jacobian helper calls can be emitted again, and synthesized Jacobian
helpers now use loops instead of fully unrolled per-component assignments.
- Fixed workspace liveness tracking in Rust codegen so shared intermediates
are not overwritten before their final consumers, restoring correct
generated derivatives and other workspace-heavy kernels.

### Fixed

- Fixed Rust rendering of squared expressions so non-atomic bases are
parenthesized before applying the square fast path. This restores correct
code generation for terms such as `(x - p)^2` in simplified single-shooting
costs and similar expressions.
- Optimized `SquaredDistanceToSet.euclidean_ball(...)` Rust code generation by
routing it through compact Rust helper snippets and Python callbacks,
avoiding scalarized symbolic expansions such as `x[i] - 0` chains and
enabling loop-based primal and Jacobian kernels.
- Optimized `SquaredDistanceToSet.infinity_ball(...)` Rust code generation in
the same way, including a zero-center fast path and compact loop-based
primal, projection, and Jacobian helpers.


## 0.5.0 - 01-05-2026

Expand Down
8 changes: 6 additions & 2 deletions demos/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
.PHONY: all codegen custom_function squared_distance_to_set squared_distance_to_set_rust_only multi_function vjp map_zip zip_3 reduce_map composed_function composed_chain single_shooting single_shooting_penalty python_interface help
.PHONY: all codegen custom_function squared_distance_to_set squared_distance_to_set_rust_only multi_function vjp map_zip zip_3 reduce_map composed_function composed_chain single_shooting single_shooting_penalty python_interface soc help

PYTHON ?= python
REPEATS ?= 5
HORIZON ?= 5
COUNT ?= 3

all: codegen custom_function squared_distance_to_set squared_distance_to_set_rust_only multi_function vjp map_zip zip_3 reduce_map composed_function composed_chain single_shooting single_shooting_penalty python_interface
all: codegen custom_function squared_distance_to_set squared_distance_to_set_rust_only multi_function vjp map_zip zip_3 reduce_map composed_function composed_chain single_shooting single_shooting_penalty python_interface soc

help:
@echo "Available targets:"
Expand All @@ -24,6 +24,7 @@ help:
@echo " make single_shooting HORIZON=$(HORIZON)"
@echo " make single_shooting_penalty HORIZON=$(HORIZON)"
@echo " make python_interface"
@echo " make soc"

codegen:
$(PYTHON) codegen/main.py
Expand Down Expand Up @@ -66,3 +67,6 @@ single_shooting_penalty:

python_interface:
$(PYTHON) python_interface/main.py

soc:
$(PYTHON) soc/main.py
1 change: 1 addition & 0 deletions demos/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ This directory contains runnable end-to-end examples showing how to use
- [single_shooting](./single_shooting/README.md): loop-based deterministic single-shooting OCP code generation
- [single_shooting_penalty](./single_shooting_penalty/README.md): single-shooting OCP code generation with vector residual penalties
- [python_interface](./python_interface/README.md): generate a Rust crate plus a separate PyO3 wrapper imported from Python
- [soc](./soc/README.md): second-order cone distance generation with an importable Python wrapper

## Running all demos

Expand Down
10 changes: 5 additions & 5 deletions demos/codegen/codegen_kernel/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ cargo build

## Generated Functions

- `codegen_kernel_energy_f`: workspace `2`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_energy_jf_x`: workspace `3`, inputs `(3, 1)`, outputs `(3,)`
- `codegen_kernel_energy_jf_u`: workspace `1`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_coupling_f`: workspace `2`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_energy_f`: workspace `0`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_energy_jf_x`: workspace `0`, inputs `(3, 1)`, outputs `(3,)`
- `codegen_kernel_energy_jf_u`: workspace `0`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_coupling_f`: workspace `0`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_coupling_jf_x`: workspace `0`, inputs `(3, 1)`, outputs `(3,)`
- `codegen_kernel_coupling_jf_u`: workspace `1`, inputs `(3, 1)`, outputs `(1,)`
- `codegen_kernel_coupling_jf_u`: workspace `0`, inputs `(3, 1)`, outputs `(1,)`

The generated ABI uses input slices, output slices, and a mutable workspace slice.
Each generated function also includes metadata helpers for workspace, input, and output sizes unless disabled in the backend configuration.
Expand Down
14 changes: 7 additions & 7 deletions demos/codegen/codegen_kernel/metadata.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
{
"crate_name": "codegen_kernel",
"created_at": "2026-05-01T08:32:08.672636Z",
"gradgen_version": "0.4.2a2",
"created_at": "2026-05-05T23:14:18.278994Z",
"gradgen_version": "0.5.1a1",
"functions": [
{
"function_name": "codegen_kernel_energy_f",
"workspace_size": 2,
"workspace_size": 0,
"input_names": [
"x",
"u"
Expand All @@ -23,7 +23,7 @@
},
{
"function_name": "codegen_kernel_energy_jf_x",
"workspace_size": 3,
"workspace_size": 0,
"input_names": [
"x",
"u"
Expand All @@ -41,7 +41,7 @@
},
{
"function_name": "codegen_kernel_energy_jf_u",
"workspace_size": 1,
"workspace_size": 0,
"input_names": [
"x",
"u"
Expand All @@ -59,7 +59,7 @@
},
{
"function_name": "codegen_kernel_coupling_f",
"workspace_size": 2,
"workspace_size": 0,
"input_names": [
"x",
"u"
Expand Down Expand Up @@ -95,7 +95,7 @@
},
{
"function_name": "codegen_kernel_coupling_jf_u",
"workspace_size": 1,
"workspace_size": 0,
"input_names": [
"x",
"u"
Expand Down
Loading
Loading