Shortcuts

Documentation

Both FBGEMM and FBGEMM_GPU provide extensive comments in its source files, which serve as the most authoritative and up-to-date documentation available for the two libraries.

Building the API Documentation

Note: The most up-to-date documentation build instructions are embedded in a set of scripts bundled in the FBGEMM repo under setup_env.bash.

The general steps for building the FBGEMM and FBGEMM_GPU documentation are as follows:

  1. Set up an isolated build environment.

  2. Build FBGEMM_GPU (CPU variant).

  3. Set up the documentation toolchain.

  4. Run documentation build scripts.

Set Up Build Environment

Follow the instructions for setting up the Conda environment at Set Up an Isolated Build Environment.

Build FBGEMM_GPU

A build pass of FBGEMM_GPU is required for the documentation to be built correctly. Follow the instructions in Install the Build Tools, followed by CPU-Only Build, to build FBGEMM_GPU (CPU variant).

Set Up the Documentation Toolchain

# !! Run inside the Conda environment !!

# From the /fbgemm_gpu/ directory
cd docs

# Install Sphinx and other docs tools
pip install -r requirements.txt

# Install Doxygen and Make
conda install -c conda-forge -y doxygen graphviz make

Build the Documentation

# Generate the C++ documentation, the Python documentation, and assemble
# together
make clean doxygen html

After the build completes, view the generated documentation:

sphinx-serve -b build

Deployment Preview

As a PyTorch project, a preview of the FBGEMM and FBGEMM_GPU documentation will be automatically built and deployed by Netlify when pull requests are made. When the build completes, the deployment preview can be found at:

https://deploy-preview-<PR NUMBER>>--pytorch-fbgemm-docs.netlify.app/

General Documentation Guidelines

When new public API methods are added, they should be accompanied by sufficient documentation. Here are some guidelines for documenting FBGEMM and FBGEMM_GPU code:

  • Code by itself is not documentation! Put yourself in the shoes of new developers who has to understand what your code does, and make their lives easier.

  • Documentation should be added for any and all public API methods.

  • Don’t leave docstring-writing as a separate task.

  • Write docstrings together with the code.

  • At a very minimum, add:

    • A description of the method.

    • A description for each argument that can be passed into the method.

    • A description of the method’s return value.

  • Add usage examples, links to other methods, and method invocation limitations.

Adding Documentation to Python Code

Documentation for Python is provided through docstrings and generated using Sphinx. Please reference the Google-style Python docstrings guide for docstring formatting examples.

Follow these instructions to document, generate, and publish a new Python docstring:

  1. Add the docstring directly under the name of the target method. At a very minimum, please add descriptions of:

    • The method’s functional behavior

    • The arguments, as denoted by the Args section

    • The return value, as denoted by the Returns section

    • The exceptions that can be thrown (if applicable), as denoted by the Raises section

    Other sections such as Todo, Note, and Example should be added as needed.

    Here is an example Python docstring:

    def example_method(alignment: c_size_t, param: float) -> int:
        """
        This class is an example of how you can write docstrings.
        You can add multiple lines of those descriptions. Make sure to include
        useful information about your method.
    
        **Code Example:**
    
        .. code-block:: cpp
    
            // Here is a C++ code block
            std::vector<int32_t> foo(const std::vector<int32_t> &lst) {
                std::vector<int32_t> ret;
                for (const auto x : lst) {
                    ret.emplace_back(x * 2);
                }
                return ret;
            }
    
        And here is a verbatim-text diagram example:
    
        .. code-block:: text
    
            .------+---------------------------------.-----------------------------
            |            Block A (first)             |       Block B (second)
            +------+------+--------------------------+------+------+---------------
            | Next | Prev |   usable space           | Next | Prev | usable space..
            +------+------+--------------------------+------+--+---+---------------
            ^  |                                     ^         |
            |  '-------------------------------------'         |
            |                                                  |
            '----------- Block B's prev points to Block A -----'
    
        Todo:
            * This is a TODO item.
            * And a second TODO item.
    
        Args:
            alignment (c_size_t): Description of the `alignment` value.
            param (float): Description of `param1`.
    
        Returns:
            Description of the method's return value.
    
        Raises:
            AttributeError: If there is an error with the attributes.
            ValueError: If `param` is equal to 3.14.
    
        Example:
            This is how you can use this function
    
            >>> print("Code blocks are supported")
    
        Note:
            For more info on reStructuredText docstrings, see
            `here <https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`__
            and
            `here <https://peps.python.org/pep-0287/>`__.
        """
        return 42
    
    
    
  2. On the Sphinx documentation side, add an autofunction directive to the corresponding .rst file. If an .rst file for the corresponding Python source file does not exist, create a new one by the same name as the Python source file. Using the above example:

    .. autofunction:: fbgemm_gpu.docs.examples.example_method
    
  3. Make sure the .rst file is included in to the toctree in index.rst (e.g. FBGEMM_GPU Python API).

  4. Verify the changes by building the docs locally with Building the API Documentation or submitting a PR for a Netlify preview.


The Python docstring example above generates the following HTML output:

fbgemm_gpu.docs.examples.example_method(alignment: c_ulong, param: float) int[source]

This class is an example of how you can write docstrings. You can add multiple lines of those descriptions. Make sure to include useful information about your method.

Code Example:

// Here is a C++ code block
std::vector<int32_t> foo(const std::vector<int32_t> &lst) {
    std::vector<int32_t> ret;
    for (const auto x : lst) {
        ret.emplace_back(x * 2);
    }
    return ret;
}

And here is a verbatim-text diagram example:

.------+---------------------------------.-----------------------------
|            Block A (first)             |       Block B (second)
+------+------+--------------------------+------+------+---------------
| Next | Prev |   usable space           | Next | Prev | usable space..
+------+------+--------------------------+------+--+---+---------------
^  |                                     ^         |
|  '-------------------------------------'         |
|                                                  |
'----------- Block B's prev points to Block A -----'

Todo

  • This is a TODO item.

  • And a second TODO item.

Parameters:
  • alignment (c_size_t) – Description of the alignment value.

  • param (float) – Description of param1.

Returns:

Description of the method’s return value.

Raises:

Example

This is how you can use this function

>>> print("Code blocks are supported")

Note

For more info on reStructuredText docstrings, see here and here.


Adding Documentation to C++ Code

Documentation for C++ is provided through Javadoc-style comments and generated using Sphinx, Doxygen, and Breathe.

Documentation is kept in header files with the .h extension as well as in .cpp, cu, and cuh files. In these files, everything between #ifndef DOXYGEN_THIS_WILL_BE_SKIPPED and #endif will be hidden from the HTML output. When you add descriptionss to a function, make sure that the #ifndef and #endif are configured correctly.

Follow these instructions to document, generate, and publish a new C++ docstring:

  1. API methods are grouped together by group tags for better organization in Sphinx. If a desired method group for the target method is not defined yet, define it near the top of the relevant header file with the @defgroup command:

    /// @defgroup example-method-group Example Method Group
    /// This is a description of the example method group.
    
  2. Add the docstring directly above the target method’s declaration. At a very minimum, please add descriptions of:

    • The method’s functional behavior

    • The type parameters, as denoted by the @tparam tag

    • The arguments, as denoted by the @param tag

    • The return value, as denoted by the @return tag

    • The exceptions that can be thrown (if applicable), as denoted by the @throw tag

    Other commands such as @note, @warning, and @see should be added as needed.

    Here is an example C++ docstring:

    /// @ingroup example-method-group
    ///
    /// @brief A very short description of `example_method`.
    ///
    /// Here is a much longer description of `example_method` with code examples:
    ///
    /// **Example:**
    /// ```python
    /// # Here is a Python code block
    /// def foo(lst: list[int]) -> list[int]:
    ///   return [ x ** 2 for x in lst ]
    /// ```
    ///
    /// And here is a verbatim-text diagram example:
    ///
    /// @code{.unparsed}
    ///   .------+---------------------------------.-----------------------------
    ///   |            Block A (first)             |       Block B (second)
    ///
    ///   +------+------+--------------------------+------+------+---------------
    ///   | Next | Prev |   usable space           | Next | Prev | usable space..
    ///   +------+------+--------------------------+------+--+---+---------------
    ///   ^  |                                     ^         |
    ///   |  '-------------------------------------'         |
    ///   |                                                  |
    ///   '----------- Block B's prev points to Block A -----'
    /// @endcode
    ///
    /// @tparam T Description of `T`
    /// @tparam Alignment Description of the `Alignment` value
    /// @param param1 Description of `param1`
    /// @param param2 Description of `param2`
    ///
    /// @return Description of the method's return value.
    ///
    /// @throw std::bad_alloc if allocation failed
    /// @throw std::logic_error if a logic error occurs
    ///
    /// @note This is an example note.
    ///
    /// @warning This is an example warning.
    ///
    /// @see For more info on Doxygen docstrings, see
    /// <a href="https://www.doxygen.nl/manual/commands.html#cmdlink">here</a>.
    template <typename T, std::size_t Alignment>
    int32_t example_method(T param1, float param2);
    
  3. On the Sphinx documentation side, add a doxygengroup directive to the corresponding .rst file. If an .rst file for the corresponding header file does not exist, create a new one by the same name as the header file. Using the above example:

    .. doxygengroup:: example-method-group
      :content-only:
    
  4. Make sure the .rst file is included in to the toctree in index.rst (e.g. FBGEMM_GPU C++ API).

  5. The C++ source header file needs to be in one of the directories listed in the INPUT parameter in Doxygen.ini. In general, this has already been taken care of, but if it’s in a directory not listed, be sure to append the directory path to the parameter.

  6. Verify the changes by building the docs locally with Building the API Documentation or submitting a PR for a Netlify preview.


The Doxygen example above generates the following HTML output:

template<typename T, std::size_t Alignment>
int32_t example_method(T param1, float param2)

A very short description of example_method.


Here is a much longer description of example_method with code examples:

Example:

# Here is a Python code block
def foo(lst: list[int]) -> list[int]:
  return [ x ** 2 for x in lst ]

And here is a verbatim-text diagram example:

.------+---------------------------------.-----------------------------
|            Block A (first)             |       Block B (second)

+------+------+--------------------------+------+------+---------------
| Next | Prev |   usable space           | Next | Prev | usable space..
+------+------+--------------------------+------+--+---+---------------
^  |                                     ^         |
|  '-------------------------------------'         |
|                                                  |
'----------- Block B's prev points to Block A -----'

See also

For more info on Doxygen docstrings, see here.

Note

This is an example note.

Warning

This is an example warning.

Template Parameters:
  • T – Description of T

  • Alignment – Description of the Alignment value

Parameters:
  • param1 – Description of param1

  • param2 – Description of param2

Throws:
  • std::bad_alloc – if allocation failed

  • std::logic_error – if a logic error occurs

Returns:

Description of the method’s return value.


Sphinx Documentation Pointers

References Other Sections of the Documentation

To reference other sections in the documentation, an anchor must first be created above the target section:

.. _fbgemm-gpu.example.reference:

Example Section Header
----------------------

NOTES:

#.  The reference anchor must start with an underscore, i.e. ``_``.

#.  !! There must be an empty line between the anchor and its target !!

The anchor can then be referenced elsewhere in the docs:

Referencing the section :ref:`fbgemm-gpu.example.reference` from
another page in the docs.

Referencing the section with
:ref:`custom text <fbgemm-gpu.example.reference>` from another page
in the docs.

Note that the prefix underscore is not needed when referencing the anchor.

Referencing the Source Code

The literalinclude directive can be used to display the source code inside a Sphinx document. To display the full file content:

.. literalinclude::  relative/path/from/this/rst/file/to/the/source.txt

To display only a section of the file, a pair of unique tags must first be added to the target source file, as comments with the tag string enclosed in brackets.

For Python source files:

# [example.tag.start]

# ... code section that will be referenced ...

# [example.tag.end]

For C++ source files:

/// @skipline [example.tag.start]

/// ... code section that will be referenced ...

/// @skipline [example.tag.end]

The tags then need to be supplied to the literalinclude directive:

.. literalinclude::  relative/path/from/this/rst/file/to/the/source.cpp
  :language: cpp
  :start-after: example.tag.start
  :end-before: example.tag.end

See the Sphinx documentation here for more information.

Adding LaTeX

Math expressions with LaTeX can be added inline to Sphinx docs using the math directive:

Example text: :math:`k_{n+1} = n^2 + k_n^2 - k_{n-1}`

The above example will be rendered as: \(k_{n+1} = n^2 + k_n^2 - k_{n-1}\).

Math expressinos can also be inserted as a code block:

.. math::

  \int_a^bu \frac{d^2v}{dx^2} \,dx
    = \left.u \frac{dv}{dx} \right|_a^b
    - \int_a^b \frac{du}{dx} \frac{dv}{dx} \,dx
\[\int_a^bu \frac{d^2v}{dx^2} \,dx = \left.u \frac{dv}{dx} \right|_a^b - \int_a^b \frac{du}{dx} \frac{dv}{dx} \,dx\]

See the Sphinx documentation here and here for more information.

Adding Graphs

Graphs can be generated in Sphinx using graphviz directive. Graph descriptions can be added inside a block:

.. graphviz::

  digraph example {
    "From" -> "To";
  }

digraph example { "From" -> "To"; }

Alternatively, they can be imported from an external .dot file:

.. graphviz:: ExampleGraph.dot

digraph "sphinx-ext-graphviz" { size="6,8"; rankdir="LR"; graph [fontname="Verdana", fontsize="12"]; node [fontname="Verdana", fontsize="12"]; edge [fontname="Sans", fontsize="9"]; sphinx [label="Sphinx", shape="component", href="https://www.sphinx-doc.org/", target="_blank"]; dot [label="GraphViz", shape="component", href="https://www.graphviz.org/", target="_blank"]; docs [label="Docs (.rst)", shape="folder", fillcolor=green, style=filled]; svg_file [label="SVG Image", shape="note", fontcolor=white, fillcolor="#3333ff", style=filled]; html_files [label="HTML Files", shape="folder", fillcolor=yellow, style=filled]; docs -> sphinx [label=" parse "]; sphinx -> dot [label=" call ", style=dashed, arrowhead=none]; dot -> svg_file [label=" draw "]; sphinx -> html_files [label=" render "]; svg_file -> html_files [style=dashed]; }

See the Sphinx and Graphviz documentation more information.

Docs

Access comprehensive developer documentation for PyTorch

View Docs

Tutorials

Get in-depth tutorials for beginners and advanced developers

View Tutorials

Resources

Find development resources and get your questions answered

View Resources