Skip to content

Add linear attention API - #268

Open
jhjpark wants to merge 4 commits into
NVIDIA:developfrom
jhjpark:jopark/linear_attention
Open

Add linear attention API#268
jhjpark wants to merge 4 commits into
NVIDIA:developfrom
jhjpark:jopark/linear_attention

Conversation

@jhjpark

@jhjpark jhjpark commented Jun 2, 2026

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features
    • Added the gated_delta_net linear-attention operator to the experimental ops package public namespace.
    • Supports optional initial_state and can return a final_state when requested.
    • Added CUDA-only test coverage for forward correctness, gradient behavior, default-vs-explicit scaling, empty final-state handling, and torch.compile parity.
  • Bug Fixes
    • Improved shape/dtype handling for linear-attention inputs and recurrent state outputs.

@Anerudhan Anerudhan added the cat-feature Requests for new functionality, APIs, examples, or behavior improvements. label Jun 2, 2026
@Anerudhan

Copy link
Copy Markdown
Collaborator

Can you add documentation? PR description ..

Also, seems like we are building the op out of pure Pytorch ops.. Is that the expectation?

@coderabbitai

coderabbitai Bot commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a new linear_attention package for Gated DeltaNet, with shared tensor helpers, a custom PyTorch op backed by cuTile kernels, package exports, and forward/backward test coverage.

Changes

Gated DeltaNet Linear Attention Op

Layer / File(s) Summary
Layout and chunk-decay utilities
python/cudnn/experimental/ops/linear_attention/_common.py
Adds layout conversion, chunk-decay factor, padding, dtype, and initial-state helpers.
GDN custom op and exports
python/cudnn/experimental/ops/linear_attention/gdn.py, python/cudnn/experimental/ops/linear_attention/__init__.py, python/cudnn/experimental/ops/__init__.py
Registers the custom op, fake mode, autograd rule, and public wrapper, and exports gated_delta_net from the package namespace.
Shared GDN test utilities
test/python/gdn/common.py, test/python/gdn/conftest.py, test/python/gdn/reference_gdn.py
Adds shared markers, generators, tolerances, dispatcher logic, and the fp64 reference implementation used by the tests.
Forward propagation tests
test/python/gdn/test_gdn_fprop.py
Adds forward parity, shape/state, varlen, prefill, and validation coverage.
Backward propagation tests
test/python/gdn/test_gdn_bprop.py, test/python/test_linear_attention_gdn.py
Adds backward gradient parity coverage and an additional CUDA/cuTile-gated test module for the public operator.

Estimated code review effort: 4 (Complex) | ~45 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 52.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding a new linear attention API.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@jhjpark
jhjpark force-pushed the jopark/linear_attention branch from 4d9bf15 to f595eda Compare June 29, 2026 22:37

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
python/cudnn/experimental/ops/linear_attention/gdn.py (1)

152-169: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Document the real runtime contract on gated_delta_net.

This docstring is the public API surface, but it currently omits the operational constraints that users will hit first: CUDA + cuda.tile are required, and the only covered path in this PR is the CUDA/bf16-style path reflected by the tests. Please spell that out here instead of making users discover it at runtime. As per path instructions, focus on documentation.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/experimental/ops/linear_attention/gdn.py` around lines 152 -
169, Update the `gated_delta_net` docstring to explicitly state the runtime
contract: it requires CUDA and `cuda.tile`, and the supported path in this
implementation is the CUDA/bf16-style execution covered by the existing tests.
Keep the existing argument/return docs, but add a short “runtime requirements”
note near the function description so users see the constraint before calling
`gated_delta_net`.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/cudnn/experimental/ops/__init__.py`:
- Around line 3-8: Add FE API coverage for the new public `gated_delta_net`
export by adding a matching case under the `test/python/fe_api` suite. Update
the FE API tests around the linear attention/GDN path to import and exercise
`gated_delta_net` similarly to how `test_linear_attention_gdn.py` validates the
operator, so the new symbol in `__all__` is covered end-to-end.

In `@python/cudnn/experimental/ops/linear_attention/_common.py`:
- Around line 109-117: The pad_to_multiple helper currently uses pad_spec math
that assumes a non-negative dim, so negative axes like dim=-1 build the wrong
padding tuple. Normalize dim to a canonical non-negative index at the start of
pad_to_multiple (or explicitly reject negative dims) before computing n and
pad_spec, and keep the existing torch.nn.functional.pad behavior unchanged.

In `@python/cudnn/experimental/ops/linear_attention/gdn.py`:
- Around line 51-55: The `chunk_size` argument in `gated_delta_net` is being
ignored, so both `_gdn_fwd` and `_gdn_fwd_fake` still behave as if the chunk
size were fixed at 64. Update the `gdn.py` implementation so `chunk_size` is
threaded through the real forward path and used when constructing the fake/meta
tensors in `_gdn_fwd_fake`, instead of hard-coding `_BT = 64`. Make sure the
helper functions and any related shape logic use the passed `chunk_size`
consistently so `gated_delta_net(..., chunk_size=32)` actually respects the
caller’s value.

In `@test/python/test_linear_attention_gdn.py`:
- Around line 120-121: The chained requires_grad_ calls in the linear attention
test are triggering Ruff E702, so split them into separate standalone
statements. Update the tensor setup in test_linear_attention_gdn so q, k, v, g,
and beta each call requires_grad_ on their own line, preserving the same
behavior while satisfying lint.

---

Nitpick comments:
In `@python/cudnn/experimental/ops/linear_attention/gdn.py`:
- Around line 152-169: Update the `gated_delta_net` docstring to explicitly
state the runtime contract: it requires CUDA and `cuda.tile`, and the supported
path in this implementation is the CUDA/bf16-style execution covered by the
existing tests. Keep the existing argument/return docs, but add a short “runtime
requirements” note near the function description so users see the constraint
before calling `gated_delta_net`.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 60603b18-6e9f-4e03-9ea4-900fe458c3cd

📥 Commits

Reviewing files that changed from the base of the PR and between 8612893 and f595eda.

📒 Files selected for processing (6)
  • python/cudnn/experimental/ops/__init__.py
  • python/cudnn/experimental/ops/linear_attention/__init__.py
  • python/cudnn/experimental/ops/linear_attention/_common.py
  • python/cudnn/experimental/ops/linear_attention/_gdn_chunk_cutile.py
  • python/cudnn/experimental/ops/linear_attention/gdn.py
  • test/python/test_linear_attention_gdn.py

Comment on lines +3 to +8
from .linear_attention import gated_delta_net

__all__ = [
"scaled_dot_product_attention",
"moe_grouped_matmul",
"gated_delta_net",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Looking for FE API coverage for gated_delta_net..."
if [ -d test/python/fe_api ]; then
  rg -n 'gated_delta_net|linear_attention' test/python/fe_api || true
else
  echo "test/python/fe_api is not present in this checkout"
fi

echo
echo "All matching tests under test/python:"
rg -n 'gated_delta_net|linear_attention' test/python || true

Repository: NVIDIA/cudnn-frontend

Length of output: 1643


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Top-level test tree:"
find test/python -maxdepth 2 -type d | sort

echo
echo "Files mentioning cudnn.experimental.ops.gated_delta_net:"
rg -n 'cudnn\.experimental\.ops\.gated_delta_net|from cudnn\.experimental\.ops import gated_delta_net|gated_delta_net\(' test/python || true

echo
echo "Check whether test/python/fe_api exists and what is inside:"
if [ -d test/python/fe_api ]; then
  find test/python/fe_api -maxdepth 2 -type f | sort
else
  echo "MISSING: test/python/fe_api"
fi

Repository: NVIDIA/cudnn-frontend

Length of output: 3765


Add FE API coverage for gated_delta_net test/python/test_linear_attention_gdn.py covers the operator, but there’s no matching case under test/python/fe_api for this new public export.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/experimental/ops/__init__.py` around lines 3 - 8, Add FE API
coverage for the new public `gated_delta_net` export by adding a matching case
under the `test/python/fe_api` suite. Update the FE API tests around the linear
attention/GDN path to import and exercise `gated_delta_net` similarly to how
`test_linear_attention_gdn.py` validates the operator, so the new symbol in
`__all__` is covered end-to-end.

Source: Path instructions

Comment on lines +109 to +117
def pad_to_multiple(t: torch.Tensor, multiple: int, dim: int, value: float = 0.0) -> Tuple[torch.Tensor, int]:
"""Pad ``t`` along ``dim`` to the next multiple of ``multiple``."""
n = t.shape[dim]
pad = (-n) % multiple
if pad == 0:
return t, 0
# torch.nn.functional.pad operates on the last dims; convert to that form.
pad_spec = [0, 0] * (t.ndim - 1 - dim) + [0, pad]
return torch.nn.functional.pad(t, pad_spec, value=value), pad

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalize negative dim values before building pad_spec.

t.shape[dim] already accepts negative axes, but the pad_spec math does not. For example, dim=-1 produces the wrong pad tuple length/placement. Normalize first (dim %= t.ndim) or reject negative dims explicitly.

Suggested fix
 def pad_to_multiple(t: torch.Tensor, multiple: int, dim: int, value: float = 0.0) -> Tuple[torch.Tensor, int]:
     """Pad ``t`` along ``dim`` to the next multiple of ``multiple``."""
+    dim %= t.ndim
     n = t.shape[dim]
     pad = (-n) % multiple
     if pad == 0:
         return t, 0
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def pad_to_multiple(t: torch.Tensor, multiple: int, dim: int, value: float = 0.0) -> Tuple[torch.Tensor, int]:
"""Pad ``t`` along ``dim`` to the next multiple of ``multiple``."""
n = t.shape[dim]
pad = (-n) % multiple
if pad == 0:
return t, 0
# torch.nn.functional.pad operates on the last dims; convert to that form.
pad_spec = [0, 0] * (t.ndim - 1 - dim) + [0, pad]
return torch.nn.functional.pad(t, pad_spec, value=value), pad
def pad_to_multiple(t: torch.Tensor, multiple: int, dim: int, value: float = 0.0) -> Tuple[torch.Tensor, int]:
"""Pad ``t`` along ``dim`` to the next multiple of ``multiple``."""
dim %= t.ndim
n = t.shape[dim]
pad = (-n) % multiple
if pad == 0:
return t, 0
# torch.nn.functional.pad operates on the last dims; convert to that form.
pad_spec = [0, 0] * (t.ndim - 1 - dim) + [0, pad]
return torch.nn.functional.pad(t, pad_spec, value=value), pad
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/experimental/ops/linear_attention/_common.py` around lines 109 -
117, The pad_to_multiple helper currently uses pad_spec math that assumes a
non-negative dim, so negative axes like dim=-1 build the wrong padding tuple.
Normalize dim to a canonical non-negative index at the start of pad_to_multiple
(or explicitly reject negative dims) before computing n and pad_spec, and keep
the existing torch.nn.functional.pad behavior unchanged.

Comment on lines +51 to +55
scale: float,
chunk_size: int,
initial_state: Optional[torch.Tensor] = None,
output_final_state: bool = False,
) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Don't silently ignore chunk_size.

The API accepts chunk_size, but both execution paths are still hard-coded to _BT = 64: _gdn_fwd() never passes chunk_size downstream, and _gdn_fwd_fake() bakes 64 into A's shape. gated_delta_net(..., chunk_size=32) will therefore behave like 64 while the docstring suggests configurability.

Suggested fix
 def _gdn_fwd(
@@
 ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
+    if chunk_size != _BT:
+        raise ValueError(f"Unsupported chunk_size={chunk_size}; expected {_BT}")
     """GDN forward.
@@
 `@_gdn_fwd.register_fake`
 def _gdn_fwd_fake(q, k, v, g, beta, scale, chunk_size, initial_state=None, output_final_state=False):
+    if chunk_size != _BT:
+        raise ValueError(f"Unsupported chunk_size={chunk_size}; expected {_BT}")
     B, T, H, K = q.shape
@@
-        chunk_size: chunk length (cuTile kernel uses 64).
+        chunk_size: chunk length. The current cuTile kernel requires ``64``.

Also applies to: 79-88, 150-180

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/experimental/ops/linear_attention/gdn.py` around lines 51 - 55,
The `chunk_size` argument in `gated_delta_net` is being ignored, so both
`_gdn_fwd` and `_gdn_fwd_fake` still behave as if the chunk size were fixed at
64. Update the `gdn.py` implementation so `chunk_size` is threaded through the
real forward path and used when constructing the fake/meta tensors in
`_gdn_fwd_fake`, instead of hard-coding `_BT = 64`. Make sure the helper
functions and any related shape logic use the passed `chunk_size` consistently
so `gated_delta_net(..., chunk_size=32)` actually respects the caller’s value.

Source: Linters/SAST tools

Comment thread test/python/test_linear_attention_gdn.py Outdated
@jhjpark
jhjpark force-pushed the jopark/linear_attention branch from f595eda to 598da12 Compare July 2, 2026 20:16

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
test/python/gdn/test_gdn_bprop.py (1)

134-178: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a zero-length-sequence backward test.

test_gdn_fprop.py has test_fprop_zero_length_sequence verifying empty segments in a varlen batch don't perturb others and their final state stays zero, but there's no analogous backward-pass test here. Gradients flowing through a zero-length segment (e.g., ensuring no NaN/garbage gradient leaks into adjacent segments) are untested.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/python/gdn/test_gdn_bprop.py` around lines 134 - 178, Add a
backward-path regression test for zero-length varlen segments in
test_gdn_bprop.py, mirroring the existing zero-length forward coverage in
test_fprop_zero_length_sequence. Use the same _run_bprop_case and
cu_seqlens-style setup as test_bprop_varlen_ragged, but include an empty segment
in the sequence boundaries and assert the backward pass produces valid gradients
without leaking NaN/garbage into neighboring segments. Reference the
varlen/backward helpers and the zero-length-sequence case so the new test stays
aligned with the existing bprop coverage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@python/cudnn/experimental/ops/linear_attention/gdn.py`:
- Around line 156-165: Update the docstring in gdn.py so the tensor shapes for
g, beta, initial_state, and final_state match the implementation and tests:
document g and beta as value-head dimensioned [B, T, HV] rather than [B, T, H],
and initial_state/final_state as [B, HV, K, V] rather than [B, H, K, V]. Also
note in the gdn op docs that the current implementation requires H == HV so the
public API contract is clear.

---

Nitpick comments:
In `@test/python/gdn/test_gdn_bprop.py`:
- Around line 134-178: Add a backward-path regression test for zero-length
varlen segments in test_gdn_bprop.py, mirroring the existing zero-length forward
coverage in test_fprop_zero_length_sequence. Use the same _run_bprop_case and
cu_seqlens-style setup as test_bprop_varlen_ragged, but include an empty segment
in the sequence boundaries and assert the backward pass produces valid gradients
without leaking NaN/garbage into neighboring segments. Reference the
varlen/backward helpers and the zero-length-sequence case so the new test stays
aligned with the existing bprop coverage.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 9c1a7ce0-d127-40bb-ab30-475f2e6cbc83

📥 Commits

Reviewing files that changed from the base of the PR and between f595eda and 598da12.

📒 Files selected for processing (12)
  • python/cudnn/experimental/ops/__init__.py
  • python/cudnn/experimental/ops/linear_attention/__init__.py
  • python/cudnn/experimental/ops/linear_attention/_common.py
  • python/cudnn/experimental/ops/linear_attention/_gdn_chunk_cutile.py
  • python/cudnn/experimental/ops/linear_attention/gdn.py
  • test/python/gdn/__init__.py
  • test/python/gdn/common.py
  • test/python/gdn/conftest.py
  • test/python/gdn/reference_gdn.py
  • test/python/gdn/test_gdn_bprop.py
  • test/python/gdn/test_gdn_fprop.py
  • test/python/test_linear_attention_gdn.py
✅ Files skipped from review due to trivial changes (1)
  • python/cudnn/experimental/ops/linear_attention/init.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • python/cudnn/experimental/ops/init.py
  • test/python/test_linear_attention_gdn.py
  • python/cudnn/experimental/ops/linear_attention/_common.py

Comment on lines +156 to +165
g: log-space scalar decay per token, ``[B, T, H]``
(``alpha = exp(g) in (0, 1]``).
beta: per-token write strength, ``[B, T, H]``.
scale: attention scale applied to ``q``. Defaults to ``1 / sqrt(K)``.
initial_state: optional recurrent state ``[B, H, K, V]`` (otherwise zero).
output_final_state: if ``True``, also return the state after the last token.

Returns:
``(o, final_state)`` where ``o`` is ``[B, T, H, V]``. ``final_state`` is
``[B, H, K, V]`` when ``output_final_state=True``, otherwise empty.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Docstring head dimensions for g/beta/state don't match the code and tests.

The code derives HV = beta.shape[2] and the tests build g/beta with HV and initial_state as [N, HV, K, V], but the docstring documents g/beta as [B, T, H] and initial_state/final_state as [B, H, K, V]. Since these gates and the recurrent state are value-head dimensioned, please document them as HV (and note the H == HV requirement of the current op) so the public API contract is unambiguous.

As per path instructions for python/cudnn/**: "Focus on documentation."

Suggested doc update
-        g: log-space scalar decay per token, ``[B, T, H]``
+        g: log-space scalar decay per token, ``[B, T, HV]``
            (``alpha = exp(g) in (0, 1]``).
-        beta: per-token write strength, ``[B, T, H]``.
+        beta: per-token write strength, ``[B, T, HV]``.
         scale: attention scale applied to ``q``. Defaults to ``1 / sqrt(K)``.
-        initial_state: optional recurrent state ``[B, H, K, V]`` (otherwise zero).
+        initial_state: optional recurrent state ``[B, HV, K, V]`` (otherwise zero).
         output_final_state: if ``True``, also return the state after the last token.

     Returns:
         ``(o, final_state)`` where ``o`` is ``[B, T, H, V]``. ``final_state`` is
-        ``[B, H, K, V]`` when ``output_final_state=True``, otherwise empty.
+        ``[B, HV, K, V]`` when ``output_final_state=True``, otherwise empty.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
g: log-space scalar decay per token, ``[B, T, H]``
(``alpha = exp(g) in (0, 1]``).
beta: per-token write strength, ``[B, T, H]``.
scale: attention scale applied to ``q``. Defaults to ``1 / sqrt(K)``.
initial_state: optional recurrent state ``[B, H, K, V]`` (otherwise zero).
output_final_state: if ``True``, also return the state after the last token.
Returns:
``(o, final_state)`` where ``o`` is ``[B, T, H, V]``. ``final_state`` is
``[B, H, K, V]`` when ``output_final_state=True``, otherwise empty.
g: log-space scalar decay per token, ``[B, T, HV]``
(``alpha = exp(g) in (0, 1]``).
beta: per-token write strength, ``[B, T, HV]``.
scale: attention scale applied to ``q``. Defaults to ``1 / sqrt(K)``.
initial_state: optional recurrent state ``[B, HV, K, V]`` (otherwise zero).
output_final_state: if ``True``, also return the state after the last token.
Returns:
``(o, final_state)`` where ``o`` is ``[B, T, H, V]``. ``final_state`` is
``[B, HV, K, V]`` when ``output_final_state=True``, otherwise empty.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@python/cudnn/experimental/ops/linear_attention/gdn.py` around lines 156 -
165, Update the docstring in gdn.py so the tensor shapes for g, beta,
initial_state, and final_state match the implementation and tests: document g
and beta as value-head dimensioned [B, T, HV] rather than [B, T, H], and
initial_state/final_state as [B, HV, K, V] rather than [B, H, K, V]. Also note
in the gdn op docs that the current implementation requires H == HV so the
public API contract is clear.

Source: Path instructions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cat-feature Requests for new functionality, APIs, examples, or behavior improvements.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants