Skip to content

Fix the published API reference and document the missing device APIs - #582

Open
mawad-amd wants to merge 19 commits into
ROCm:mainfrom
mawad-amd:main
Open

mawad-amd wants to merge 19 commits into
ROCm:mainfrom
mawad-amd:main

Conversation

@mawad-amd

Copy link
Copy Markdown
Collaborator

Motivation

The published API reference was largely empty. iris/host/iris.py imports xio
at module load, docs CI installs only docs/sphinx/requirements.txt, so every
autodoc directive failed with ModuleNotFoundError and the reference pages
rendered with headings and no content.

With that unblocked, two surfaces turned out to be undocumented: the Triton
DeviceContext (24 public methods, including all nine in-kernel collectives)
and the tile types (Tile, TileView, TensorView, AllReduceConfig,
make_tensor_view), all exported from the top level.

Technical Details

Build fixes:

  • Mock xio, and add sphinxcontrib-jquery — Sphinx dropped bundled jQuery in
    6.0 and four rocm-docs-core theme scripts still call $().
  • Copy docs/images/ verbatim on build-finished. Sphinx only tracks images
    referenced from markdown, so the 18 referenced from raw HTML blocks 404'd.
  • Give the mocked tl.* / gl.* annotation types real classes. They were
    rendering as <MagicMock name='mock.constexpr' id='139779281861264'> in
    parameter lists, with an id that changed every build.

New pages:

  • reference/triton/device-context.md — the DeviceContext aggregate.
  • reference/triton/types.md — the tile types.
  • getting-started/slurm.md added to the nav.
  • 11 previously undocumented public host and Triton APIs.

Docstring fixes — RST needs a blank line before a bullet list, and
Example usage: / Fields: are not napoleon sections, so several blocks
collapsed into run-on paragraphs. Also documents the tile type fields, which had
annotations but no descriptions.

Renames "Fused GEMM + CCL Operations" to "Fused Communication and Compute
Operations" — GEMM is the compute side today, not the definition of the surface.

Adds workflow_dispatch to the docs workflow so the site can be rebuilt without
a commit.

Test Plan

Built on Python 3.13 and deployed to a fork, then fetched all 21 published pages
and checked the rendered HTML for: mock reprs, collapsed lists, run-on code
blocks, duplicate sections, empty sections, and API objects rendered with no
description. Each check was potency-tested against real known-bad markup from the
site before its result was trusted.

Test Result

Warnings 71 → 6. All 21 pages clean, 0 defects. Reference pages regained content:
triton/device-context 24 signatures, triton/types 29, host/class 19,
gluon/device-functions 15, triton/device-functions 13, host/tensor-creation
13, triton/ops 6, host/ccl 5, host/copy-engine 5.

Preview: https://mawad-amd.github.io/iris-docs/

Submission Checklist

mawad-amd and others added 11 commits October 11, 2026 06:04
iris/host/iris.py imports xio unconditionally at module load. The docs CI
installs only docs/sphinx/requirements.txt, so xio is never available and
every autodoc directive failed with ModuleNotFoundError, leaving the entire
API reference empty on the published site.

Build goes from 71 warnings to 6, and the reference pages regain their
content: host/class 15 signatures, triton/device-functions 13,
gluon/device-functions 15, host/tensor-creation 13, host/ccl 5,
triton/ops 4.
getting-started/slurm.md is a 290-line guide linked from index.md three times
and from installation.md twice, but it was absent from the sidebar, so Sphinx
reported it as belonging to no toctree.

Note for anyone editing the nav: sphinx/_toc.yml is GENERATED from
sphinx/_toc.yml.in during the build. Both are tracked, so editing _toc.yml
appears to work and is silently overwritten on the next build.
Nine public methods on Iris and two Triton ops had no documentation at all:

  host   put, put_tile, put_tiles, quiet, get_copy_engine_ctx
         -> new page, reference/host/copy-engine.md
  host   allocate_symmetric, device_barrier, get_device_id, ops
         -> added to reference/host/class.md
  triton atomic_sub, quiet
         -> added to reference/triton/ops.md

The first five are the entire host-side SDMA surface, which was undocumented.

Also:
- get_copy_engine_ctx had no docstring; added one.
- atomic_sub's docstring had a line indented 8 spaces inside a 4-space
  paragraph, which RST parses as a block quote and warns about.
- Iris.ops is a property, so it needs autoproperty rather than automethod.

Signature counts: class 15 -> 19, triton/ops 4 -> 6, copy-engine 5 new.
Images. Several conceptual pages reference images from raw HTML blocks, which
is how the light/dark variants are selected:

    <img class="dark-theme-img only-dark" src="../images/iris-model.png">

Sphinx only tracks images referenced through markdown or image directives, so
it copied 4 of the 29 and every raw-HTML reference 404'd on the published
site: 11 on conceptual/taxonomy, 6 on conceptual/programming-model, plus the
logo on index. A build-finished hook now copies docs/images/ verbatim, which
fixes all of them without rewriting the theme-switching markup.

JavaScript. Sphinx removed its bundled jQuery in 6.0 and requirements.txt
asks only for sphinx>=5.0.0, so CI resolves 9.x. Four rocm-docs-core theme
scripts still call $() -- code_word_breaks, renameVersionLinks, rdcMisc and
theme_mode_captions -- so every page threw '$ is not defined' and all four
silently did nothing. Added sphinxcontrib-jquery.

Verified with Playwright over HTTP across all 19 content pages: every page
returns 200, renders its heading, nav, breadcrumbs and TOC, and loads all of
its images (taxonomy 12/12 and programming-model 7/7, both previously 0).
This fork exists to preview the docs, and nothing here generates the pushes
that the workflow was written to react to. It fires on push to main under a
path filter, so once the docs commits had landed there was no remaining event
that could rebuild the site -- and the deploy job additionally gated on
github.event_name == 'push', so even a manual run would have built an artifact
and stopped short of publishing.

Adds workflow_dispatch and widens the deploy gate to accept it. The branch
condition is unchanged: still main only, so a PR build still cannot publish.

Co-Authored-By: Claude <[email protected]>
iris.mem.triton.context.Context -- exported as iris.DeviceContext and the
aggregate you construct inside a @triton.jit kernel -- had no autodoc coverage
at all. Twenty-four public methods, zero directives anywhere under docs/, and
nothing in the live API index.

Nine of them existed nowhere else on the site:

  all_reduce_atomic  all_reduce_spinlock  all_reduce_one_shot
  all_reduce_ring    all_reduce_two_shot
  all_gather         gather               all_to_all        reduce_scatter

These are the tile-level collectives -- they run inside the kernel on the tile
a program already holds, which is a different surface from the host collectives
on reference/host/ccl.md that launch their own kernels. Searching the docs for
"all_gather" found only the host one, so the in-kernel form read as missing.

The remaining fifteen were reachable only as the module-level free functions on
reference/triton/device-functions.md, which take heap_bases and both ranks
explicitly. That is the layer underneath; the bound ctx.load(pointer, from_rank)
form a reader actually writes was not on the site.

The contrast made it stark: Gluon's device context has all fifteen of its
methods documented, while Triton -- the full surface, of which Gluon is a
subset -- had none.

Verified by building on Python 3.13: 24 headings, 24 rendered signatures, no
empty sections, and zero autodoc import failures across the whole build. Note
the build needs >=3.10; on 3.9 every autodoc import fails at
iris/drivers/base.py:49, which uses PEP 604 union syntax at module level.

Co-Authored-By: Claude <[email protected]>
Tile types. iris/mem/triton/types.py exports Tile, TileView, TensorView,
AllReduceConfig and make_tensor_view from the top-level package, and none of
them were documented. These are what the DeviceContext collectives operate on,
so the new device-context page referred to objects the site never defined.
Adds reference/triton/types.md -- 43 rendered signatures.

MagicMock in signatures. tl.constexpr and tl.tensor are used as parameter
annotations, so autodoc resolved them to mock attributes and printed reprs like
"<MagicMock name='mock.constexpr' id='139779281861264'>" into the rendered
parameter list. Twenty such leaks before this change, and the embedded id
changes every build, so the HTML churned too. The mocked modules now carry real
classes for those names. Gluon needed the same treatment separately: it
annotates with gl.constexpr, which resolves through triton.experimental.gluon
.language rather than triton.language.

Only the names actually used as annotations are given classes. Adding uint and
pointer_type as well tripped a pre-existing circular import between
iris/__init__.py and iris.mem.triton.ops, which surfaced as 19 autodoc failures
-- neither name appears in a rendered signature, so neither is needed.

Collapsed bullet lists. Four docstrings put a bullet list directly beneath a
line ending in a colon. RST needs a blank line there, so the dashes folded into
the paragraph and rendered as "has the format: - [cur_rank, num_ranks, ...] -
If tracing=True ...". Fixed in Iris.broadcast, Iris.put, TileView and
Context.initialize, the last as a literal block since it is a tensor layout and
smartquotes was also turning its "..." into an ellipsis.

Fifty-nine sites match the colon-then-dash pattern repo-wide, but only these
four actually render wrong; the rest sit inside Args: blocks, which napoleon
handles correctly.

Also generalises the "Fused GEMM + CCL Operations" heading to "Fused
Communication and Compute Operations" -- GEMM is the compute side today, not
the definition of the surface.

Verified on Python 3.13 across all nine API pages: 143 signatures rendered,
zero mock reprs, zero collapsed lists, zero autodoc import failures.

Co-Authored-By: Claude <[email protected]>
conf.py sets autodoc_default_options members=True, so .. autoclass already
emits every method of the class. The page additionally spelled each one out as
its own .. automethod section underneath, so TensorView.tile_ptr and friends
appeared once inside the class block and again as a standalone section -- 43
rendered signatures for 36 real objects. Dropped the explicit sections; the
autoclass directives carry them.

Two more docstring sections were rendering as run-on text. Napoleon recognises
"Example:" but not "Example usage:" or "Fields:", so those fell through as
plain paragraphs and the code samples collapsed onto one line:

    Example usage: view = make_tensor_view(ptr, M, N, ...) tile_ptr, mask = ...

"Example usage:" -> "Example:" in TileView, Tile, TensorView and Iris.CCL, and
"Fields:" -> "Attributes:" in AllReduceConfig, which additionally promotes
variant_code and locks_ptr to documented attributes carrying their types rather
than one undifferentiated blob.

The earlier sweep missed these because it only looked for bullet lists under a
colon, and these are indented code under a colon.

Verified on 3.13 across all nine API pages: no method rendered twice, no
collapsed blocks, no mock reprs, zero autodoc import failures.

Co-Authored-By: Claude <[email protected]>
Two faults on the tile types page, both in iris/mem/triton/types.py.

Examples rendered on one line. The Example: sections in TensorView, TileView
and Tile hold plain indented code, and RST joins consecutive lines into a
single paragraph, so the reader got

    view = make_tensor_view(ptr, M, N, stride_m, stride_n) tile_ptr, mask = ...

Every other example in the codebase uses >>> doctest style, which preserves
the breaks. These three now match.

Fields had no descriptions. ptr, M, N, stride_m, stride_n on TensorView, and
the pid/block fields on TileView and Tile, are annotated but were never
described, so undoc-members rendered them as a bare "ptr: tensor" list under
__init__. Added Attributes: sections. The wording for TensorView is taken from
make_tensor_view's existing Args, which documents the same five values, so the
two agree rather than drifting.

iris/mem/triton/ops.py put() looked like a fourth instance but is not: its
example is already >>> style with a caption line above it, which renders
correctly.

Verified on 3.13: 150 signatures across nine API pages, no run-on examples, no
collapsed lists, no duplicate sections, no mock reprs, zero import failures.
The run-on check was potency-tested against both known-bad strings before its
zero was believed.

Co-Authored-By: Claude <[email protected]>
autodoc_default_options sets undoc-members and special-members globally, so
every annotated field was rendered a third time as a bare "ptr: tensor" entry
with an empty body, underneath an equally empty __init__. The same five values
already appear twice above: once in Parameters, once as documented attributes.

The "no-" prefix turns a default option off per directive, so the five
directives on this page now carry :no-undoc-members: and :no-special-members:.
Scoped to this page -- the setting is left alone elsewhere.

Co-Authored-By: Claude <[email protected]>
The previous commit added :no-undoc-members: and :no-special-members: to all
five directives on the page, but make_tensor_view is an autofunction and those
options belong to autoclass. Sphinx accepted them without complaint, built
cleanly, and emitted the section heading with nothing underneath -- so the
function silently vanished from the page while the build still reported
success.

Removed them from that one directive. The four autoclass directives keep them.

Co-Authored-By: Claude <[email protected]>
Comment thread .github/workflows/docs.yml Outdated
mawad-amd and others added 7 commits October 12, 2026 15:57
ruff E402. The image-copy hook added its own `import shutil as _shutil` next to
the function that uses it, which reads fine but is the one lint error in the
repo -- and CI runs `ruff check . --fix`, which cannot auto-fix E402, so the
job goes red rather than quietly correcting it.

Rebuilt after the move: still 29 of 29 images copied into _build/html/images,
so the hook is intact and not merely syntactically valid.

Co-Authored-By: Claude <[email protected]>
The workflow_dispatch addition was for previewing on a fork, which gets no
pushes of its own. Upstream main does, so the trigger it already has is
sufficient there and this does not belong in the change.

Co-Authored-By: Claude <[email protected]>
Only conflict was get_copy_engine_ctx's docstring: ROCm#568 added the
-> torch.Tensor | None annotation and shortened the prose to one line, while
this branch had expanded it as part of documenting the 11 undocumented public
APIs. Kept the annotation and the fuller docstring, reworded to name
engines=("sdma",) since ROCm#568 replaced copy_engine=.
Swept in by a git add -A during the merge. It is a separate proposal and this
PR was deliberately scoped back to docs content after the workflow change was
reverted. Kept at /tmp/check_docs_build.py pending a decision on whether it
lands here or on its own.
Quote the return annotation on get_copy_engine_ctx. ROCm#568 added
`-> torch.Tensor | None`, but torch is in autodoc_mock_imports, so the
annotation evaluates mock | None at class-definition time and raises
TypeError: unsupported operand type(s) for |: 'Tensor' and 'NoneType'.
That killed the import of iris.host.iris and took 45 autodoc directives with
it -- the API reference went empty again, by a different route than the xio
import did. Quoting defers evaluation; it is the only PEP 604 annotation on a
mocked type in iris/, and nothing introspects annotations at runtime.

Defer the get_copy_engine_ctx index entry to class.md. ROCm#568 documents the
method in its new "Optional SDMA Copy Engine" section and this branch already
documented it on the dedicated copy-engine page, so Sphinx warned about a
duplicate object description. Added :no-index: to this branch's copy rather
than touching the section ROCm#568 just added.

Verified on 3.13: 39 pages, 0 autodoc import failures, 4 warnings (all
external intersphinx), and every page rendered in headless Chrome over HTTP --
no dead links, no broken images, no page errors beyond two the rocm-docs-core
theme also throws on rocm.github.io/iris. jQuery errors per page: 4 upstream,
0 here.
The workflow only fires on push to main under a paths filter. A fork gets no
pushes of its own, so once the docs commits have landed there is no remaining
event that can rebuild the site -- which is why this fork has never produced a
run. The deploy job additionally gated on event_name == 'push', so even a
manual run would have built an artifact and stopped short of publishing.

Adds workflow_dispatch and widens that gate to accept it. The branch condition
is unchanged -- still main only, so a PR build still cannot publish. Useful
upstream too when the rendered output changes without the sources changing,
such as a rocm-docs-core or Sphinx release.
Keeping this PR to docs content only.

```{eval-rst}
.. autofunction:: iris.mem.triton.ops.quiet
```

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

do these ops belong here or in docs/reference/triton/device-functions.md?

```

```{note}
Every operation here also exists as a free function -- see

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

what do you mean by free fucntion?


```{eval-rst}
.. autoclass:: iris.mem.triton.types.TensorView
:noindex:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

my agent flagged this and I do not understand it :)

Remove :noindex: from the newly documented APIs. In types.md:16 (/tmp/iris-pr582-review/docs/reference/triton/types.md:16) and device-context.md:42 (/tmp/iris-pr582-review/docs/reference/triton/device-context.md:42), it suppresses API anchors and inventory entries. Confirmed in the build: these APIs are absent from objects.inv, and their generated source-page [docs] links target nonexistent anchors. These are their primary documentation locations, so indexing should remain enabled

@drprajap drprajap left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM after addressing those minor comments

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants