1. About this document
Note
You can view a built version of this template on the docs portal. The source files are stored in the rTECHDOCS repo.
This document serves as a template, example and tutorial for the use of ReStructuredText (RST) markup for creating Graphcore documentation.
You might also want to look at our documentation guidelines on Confluence.
2. Headings and text
2.1. Headings
Headings have the following formatting:
Heading level 1
===============
Heading level 2
---------------
Heading level 3
...............
Heading level 4
~~~~~~~~~~~~~~~
We nest headings only up to level 4.
You must have a blank line after headings. The heading underline must be at least as long as the heading text (it can be longer).
We use sentence case in headings. This means only the first letter is capitalised.
Note
We use title case in the document title. This means that all “important” words are capitalised.
2.2. Text
A single paragraph can be split over adjacent lines. Use blank lines to separate paragraphs.
Another paragraph.
The following code block shows the formatting syntax:
This is **bold text**, this is *italic text*, this is ``code font`` and this is :strike:`struck through`.
(To support people used to Markdown, we have configured
`code` to be the same as ``code``.)
which renders as:
This is bold text, this is italic text, this is
code font
and this is struck through. To support people used to Markdown, we have configuredcode
to be the same ascode
.
3. Lists
You get bulleted, numbered and definition lists in reStructuredText.
3.1. Bulleted lists
Insert bullet lists with -
or with *
. There is no difference between these (but do try to be consistent). However, you cannot mix them in the same list.
For example:
Make sure there is a blank line before the first item.
Make sure that multi-line items maintain the same indentation.
You can have multiple paragraphs in the bullet.
Like this.
Make sure there is a blank line after the last item.
Multi-level lists can be created using indentation:
Make sure there is a blank line before the first item.
Make sure there is a blank line before the first item of the indented list
And a blank line after the last item.
Make sure there is a blank line after the last item.
Depending on how you indent your text, you can get different formatting:
* Bullet 1
Continuation text
* Bullet 2
Continuation text
* Bullet 3
Continuation text
* Bullet 4
Continuation text
renders as:
Bullet 1 Continuation text
Bullet 2
Continuation text
Bullet 3
Continuation text
- Bullet 4
Continuation text
3.2. Numbered lists
Numbered lists can use either numbers:
Item 1
Item 2
Item 3
Or the hash symbol (so you don’t have to keep track of numbers when editing the list):
Item 1
Item 2
Item 3
Note
reStructuredText is sensitive to indentation so if your numbered list doesn’t continue correctly, or you see odd formatting, check your indentation.
3.3. Definition list
You can create definition lists, just using indentation. Note that, in this case, there must be no blank line between the term and the definition.
Apple
A fruit.
Orange
An incomparable fruit.
These are not the only fruit.
Banana
The yellow one.
renders as:
- Apple
A fruit.
- Orange
An incomparable fruit.
These are not the only fruit.
- Banana
The yellow one.
4. Substitutions
A substitution in Sphinx is a way of reusing content (for example text and figures). You define a substitution as:
.. |name| replace:: replacement *text*
Refer to the Sphinx substitutions documentation for more information.
4.1. Standard Sphinx substitutions
Sphinx defines some standard shortcut “substitutions”:
|release|
is converted to the release string: latest|version|
is converted to the version number: latest|today|
is converted to the date the document was generated: Oct 26, 2023
4.2. Graphcore substitutions
We also define some extra substitutions.
There are a series of |BOW|
and |POD|
definitions for writing Pod product names, for example IPU‑POD16 or Bow Pod64.
These will be expanded to the full name (IPU-POD16 or Bow Pod64) with non-breaking space/hyphen and subscripted numbers.
Definitions exist for all plausible sizes (from 4 up to 2^13).
We also have the following substitutions:
|LEGAL:TRADEMARKS|
is converted to the legal text. This is to ensure that all documents use the latest, correct version of this text.|LEGAL:EULA|
is converted to the EULA text. This is to ensure that all documents use the latest, correct version of this text.|YEAR|
is converted to the current year. This convenient for documents which change often.
You can use |newpage|
to force a page break in PDF output.
4.3. Substitutions for symbols
Sphinx includes substitution definitions for a range of character entity sets.
You must include the relevant .txt
file at the top of the file in which the substitution is needed (it doesn’t work if it’s included in index.rst
). Include the file using the following syntax:
.. include:: <filename.txt>
For example we have included the following at the top of this file:
.. include:: <isonum.txt>
then we can use the following substitutions:
* 50\ |deg|\ C
* |copy| 2022
* |trade|
which renders as:
50°C
© 2022
™
Note
Substitutions usually require spaces around the |
symbols. If you don’t want a space, escape the space with a backslash as shown in the first example above.
5. Including content from files
You can include content (for example text, figures, tables) from other files. This can be in reStructuredText or in Markdown.
To include content in reStructuredText:
.. include:: common/filename.inc
For example, the following table has been included with:
.. include:: common/tf_supported_ops_list_rst.inc
Operator |
Type Constraint |
---|---|
|
|
|
|
|
|
To include content in Markdown:
.. include:: common/filename.md
:parser: myst_parser.sphinx_
For example, the following table has been included with:
.. include:: common/tf_supported_ops_list.md
:parser: myst_parser.sphinx_
Operator |
Type Constraint |
---|---|
|
|
|
|
|
|
6. Links
6.1. Cross-references within this document
This is how you define an anchor to a section: .. _name_of_anchor:
. This anchor must appear immediately before the section to be referenced. Make sure there is a blank line after the anchor definition.
This is how you reference the anchor: Section 6.1, Cross-references within this document.
The target of the reference must have some sort of text associated with it, for example a section heading or a caption. You can, however, cross-reference to arbitrary locations if you provide the text for the reference: a cross-reference.
6.2. Cross-references to other documents (Intersphinx)
You can use the intersphinx extension to simplify referencing content in other documents. This is particularly useful for referencing API documentation. Details and examples are available on the Confluence page Adding links to other documents with Intersphinx.
Note
If your reference is in another document, then you should use the :external:
directive. This also works for API references.
Some examples of referencing documents and sections in documents:
* Reference to a section in another document: :external+poplar-user-guide:ref:`replicated_graphs`
* Reference to a section in another document (specifying text to display) : :external+poplar-user-guide:ref:`replicated graphs in the Poplar User guide <replicated_graphs>`
* Reference to another document: :external+numpy:doc:`user/quickstart`
* Reference to another document: :external+poprun-user-guide:doc:`index`
which renders as:
Reference to a section in another document: Replicated graphs
Reference to a section in another document (specifying text to display) : replicated graphs in the Poplar User guide
Reference to another document: NumPy quickstart
Reference to another document: PopDist and PopRun: User Guide
Note
If the target does not have an explicit anchor (defined with .. _name_of_anchor:
) then you can use the text of the heading or caption, in lower case, for the reference, for example: :ref:`popart-user-guide:replicated tensor sharding`
which renders as Replicated tensor sharding (the case of the reference is taken from the case of the heading in the referenced document).
Some examples of API references:
* :cpp:func:`popnn::rnn::backwardGradientStep`
* :cpp:func:`~popnn::rnn::backwardGradientStep`
* :external+tensorflow2:py:func:`tensorflow.python.ipu.custom_ops.precompiled_user_op`
* :external+pytorch:py:class:`torch.Tensor`
* :py:class:`zipfile.ZipFile`
* :external+poplar-api:cpp:func:`poplar::Tensor::operator[]`
* :external+poplar-api:cpp:func:`~poplar::Tensor::operator[]`
* :external+popart-user-guide:py:class:`popart.SessionOptions`
* :external+popart-user-guide:py:class:`~popart.SessionOptions`
which renders as:
6.3. Hyperlinks
General hyperlinks are inserted as:
- `TensorFlow
documentation <https://docs.graphcore.ai/en/latest/software.html#tensorflow>`__
- `PyTorch
documentation <https://docs.graphcore.ai/en/latest/software.html#pytorch>`__
- `PopART
documentation <https://docs.graphcore.ai/en/latest/software.html#popart>`__
- :pep:`The Zen of Python <0020>`
This renders as:
6.4. Extlinks extension
The Sphinx extlinks
extension allows us to define shortcuts for commonly used URLs where the URL can be generated by substituting a single parameter (RFCs or bug tracking). For example, we have a shortcut to the arXiv e-print archive where you simply provide the reference for the article as:
:arxiv:`1703.10449`
This renders as: arXiv 1703.10449.
The current extlink
definitions are:
# Link to arXiv abstracts; e.g. :arxiv:`2103.16737` or :arxiv:`Mansfield & Seligman, 2021 <2103.16737>`
"arxiv": ("https://arxiv.org/abs/%s", "arXiv %s"),
# Link to ONNX operators; e.g. :onnxop:`Add`
"onnxop": ("https://github.com/onnx/onnx/blob/main/docs/Operators.md#%s", "ONNX %s"),
# Link to docs on Graphcore doc portal; e.g. :gcdoc:`graphcore-glossary`
# This is not really necessary now as we have the intersphinx mappings defined below
"gcdoc": ("https://docs.graphcore.ai/projects/%s", ""),
# Link to Graphcore tutorials on GitHub; e.g. :tutorials-repo:`tutorials/tensorflow2/tensorboard` or :tutorials-repo:`simple_applications/tensorflow/mnist/mnist.py`
"tutorials-repo": (f"https://github.com/graphcore/examples/tree/sdk-release-{SDK_RELEASE}/tutorials/", "%s"),
# Link to TensorFlow 2 on GitHub
"github-tf2": (f"https://github.com/graphcore/tensorflow/tree/{TF2_VER}/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to TensorFlow 1 on GitHub
"github-tf1": (f"https://github.com/graphcore/tensorflow/tree/{TF1_VER}/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to Keras on GitHub
"github-keras": (f"https://github.com/graphcore/keras/tree/{TF2_VER}/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to TensorFlow 2 add-ons on GitHub
"github-tf2-addons": (f"https://github.com/graphcore/ipu_tensorflow_addons/tree/{TF2_VER}/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to TensorFlow 1 add-ons on GitHub
"github-tf1-addons": (f"https://github.com/graphcore/ipu_tensorflow_addons/tree/{TF1_VER}/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to PopTorch on GitHub
"github-poptorch": (f"https://github.com/graphcore/poptorch/tree/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to PopART on GitHub
"github-popart": (f"https://github.com/graphcore/popart/tree/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to PopLibs on GitHub
"github-poplibs": (f"https://github.com/graphcore/poplibs/tree/sdk-release-{SDK_RELEASE}/", "%s"),
# Link to Poprithms on GitHub
"github-poprithms": (f"https://github.com/graphcore/poprithms/tree/sdk-release-{SDK_RELEASE}/", "%s"),
In many cases, the URL is replaced with a version number, for example the SDK release version number or the current version of TensorFlow. This is for convenience so documents don’t have to be manually updated with a change in version.
7. Figures and tables
This is a reference to a figure: Fig. 7.1.
You can use Graphviz to create graphs, for example Fig. 7.2. There is also a handy quick reference.
This is a reference to a table :numref:`tab-name
which renders as Table 7.1.
.. table:: This is a table caption. It must appear on a single line in the file.
:width: 80%
:widths: 40,20,20,20
:name: tab-name
:column-alignment: left left
+------------------------+------------+----------+----------+
| Header row, column 1 | Header 2 | Header 3 | Header 4 |
| (header rows optional) | | | |
+========================+============+==========+==========+
| body row 1, column 1 | column 2 | column 3 | column 4 |
+------------------------+------------+----------+----------+
| body row 2 | Cells may span columns. |
+------------------------+------------+---------------------+
| body row 3 | Cells may | - Table cells |
+------------------------+ span rows. | - contain |
| .. code-block:: python | | - body elements. |
| | | |
| for i in rows: | | |
| print(i) | | |
+------------------------+------------+---------------------+
which renders as the following table.
Header row, column 1 (header rows optional) |
Header 2 |
Header 3 |
Header 4 |
---|---|---|---|
body row 1, column 1 |
column 2 |
column 3 |
column 4 |
body row 2 |
Cells may span columns. |
||
body row 3 |
Cells may span rows. |
|
|
for i in rows:
print(i)
|
Simple tables can use the list-table
directive.
Good for |
simple tables |
---|---|
IPU‑POD64 |
this shows row headings with the |
We use the Sphinx extension cloud_sptheme.ext.table_styling to style tables.
There is also the heatmap
class that colours the cells of a table as a heatmap of values as shown in Table 7.2.
To use the heatmap
class:
.. table:: Specify the ``heatmap`` class.
:class: heatmap
... include other table options ...
... include table content ...
.. raw:: html
<script>heatmapify()</script>
which renders as:
A |
B |
C |
D |
---|---|---|---|
10 |
20 |
30 |
40 |
20 |
30 |
40 |
50 |
30 |
40 |
50 |
60 |
40 |
50 |
60 |
70 |
To use the heatmap
class:
8. Code listings
Add code listings with the code-block
directive. Refer to a listing as Listing 8.1. Make sure that there is a blank line between the “header” information in the code block and the code itself.
from tensorflow.python import ipu
You can also include code from a file as in Listing 8.2. In this case, you can also specify a subset of the code to be included, either as a range of line numbers or using pattern matching as in this example.
15with main:
16 a = pir.variable(3, dtype=pir.int8, name="variable_a")
17 b = pir.constant(1, dtype=pir.int8, name="constant_b")
18
19 # addition
20 o = a + b
It is good practice to provide the option to download the source file. Obviously, this only makes sense with HTML output (not PDF).
.. only:: html
:download:`code/code_example.py`
9. Other markup and extensions
9.1. Maths
There is formatting for in-line equations with :math:
and an environment .. math::
. For example:
Time is running out: :math:`T = 2 \pi \sqrt \frac{L}{g}`.
Gravity doesn't suck, it just bends everything around you:
.. math::
R_{\mu \nu} - \tfrac{1}{2}R \, g_{\mu \nu} + \Lambda g_{\mu \nu} = \frac{8 \pi G }{c^4} T_{\mu \nu}
renders as:
Time is running out: \(T = 2 \pi \sqrt \frac{L}{g}\).
Gravity doesn’t suck, it just bends everything around you:
9.2. Tabs
We can include tabs with the sphinx-tabs
extension. For more information, refer to the Sphinx Tabs documentation.
int main(const int argc, const char **argv) {
return 0;
}
int main(const int argc, const char **argv) {
return 0;
}
def main():
return
class Main {
public static void main(String[] args) {
}
}
function main()
end
PROGRAM main
END PROGRAM main
main <- function() {
return(0)
}
.. tabs::
.. code-tab:: c
int main(const int argc, const char **argv) {
return 0;
}
.. code-tab:: c++
int main(const int argc, const char **argv) {
return 0;
}
.. code-tab:: py
def main():
return
.. code-tab:: java
class Main {
public static void main(String[] args) {
}
}
.. code-tab:: julia
function main()
end
.. code-tab:: fortran
PROGRAM main
END PROGRAM main
.. code-tab:: r R
main <- function() {
return(0)
}
9.3. Collapsible sections
You can include collapsible sections in your document. We use the collapsible
extension and for more information, refer to the collapse documentation.
New to IPUs?
We suggest watching the Fundamentals of the IPU and Poplar video, which introduces the IPU architecture and programming model. You can also read the IPU Programmer’s Guide for more details on these topics.
New to Paperspace or Gradient?
Watch the videos on the Paperspace YouTube channel to learn more about Paperspace and Gradient.
.. collapse:: New to IPUs?
:name: new-to-ipus
We suggest watching the `Fundamentals of the IPU and Poplar <https://share.vidyard.com/watch/skdBqUfyHfFt4jx1WhUxeC?>`_ video, which introduces the IPU architecture and programming model. You can also read the :doc:`ipu-programmers-guide:index` for more details on these topics.
.. collapse:: New to Paperspace or Gradient?
:name: new-to-gradient
Watch the videos on the `Paperspace YouTube channel <https://youtu.be/b9pnSHP0eIs>`_ to learn more about Paperspace and Gradient.
9.4. Describing grammars
try_stmt ::= try1_stmt | try2_stmt try1_stmt ::= "try" ":"suite
("except" [expression
[","target
]] ":"suite
)+ ["else" ":"suite
] ["finally" ":"suite
] try2_stmt ::= "try" ":"suite
"finally" ":"suite
See the try_stmt
definition.
9.5. Bibliographies
If you create a file called refs.bib
then you can use the bibtex extension to create bibliography references.
10. Documenting APIs
Sphinx provides extensive support for documenting APIs. There are two parts to this:
Documenting the functions, class and so on in the API (see Section 14, Example API documentation)
Providing references to those components of the API from the documentation, as shown below
Note
An “API” is the complete set of classes, functions and other definitions that make up the interface to an application or library, not the individual functions or classes within it.
See our API documentation guidelines.
10.1. C++ APIs
C++ APIs are documented in the header files using Doxygen formatted comments. These are integrated into Sphinx by the breathe extension.
You can add extra formatting and links in the Doxygen comments using Markdown format.
Doxygen requires a configuration file called Doxyfile
. Among other things, this
specifies the location of the header files and that XML output is required. In most
cases this is built or configured by the cmake
file for the project.
You can generate links to classes and functions included in the API documentation: the
Nutshell
contains methods Nutshell::crack()
and the
Tool
enumeration.
10.2. Python APIs
Python APIs are documented by using Python docstrings. You can include ReStucturedText formatting in the docstrings.
Three formats for describing parameters and return values are supported, as shown in the examples below: Python, Google and NumPy. These all generate identical output. Our code seems to use a mixture of these.
You can generate links to components in the API documentation. For example, the
example.Example
class contains a method called example()
which is very similar to the example()
function.
Note that methods and functions are referenced differently.
10.2.1. Python
A brief example of the original Python format.
def func1(param1, param2):
"""Summary line.
Extended description of function.
:param param1: The first parameter.
:type param1: int
:param param2: The second parameter.
:type param2: str
:returns: The return value. True for success, False otherwise.
:rtype: bool
"""
return True
10.2.2. Google
A brief example of the format recommended by Google.
def func2(param1, param2):
"""Summary line.
Extended description of function.
Args:
param1 (int): Description of param1.
param2 (str): Description of param2.
Returns:
bool: Description of return value. True for success, False otherwise.
"""
return True
10.2.3. NumPy
A brief example of the NumPy format.
def func3(param1, param2):
"""Summary line.
Extended description of function.
Parameters
----------
param1 : int
Description of param1.
param2 : str
Description of param2.
Returns
-------
bool
Description of return value. True for success, False otherwise.
"""
return True
11. Debugging
Check the errors/warnings from Sphinx
Undefined label error:
check the target is defined
check there is a blank line between a
.. _label:
and the following headingcheck indentation. ReStructuredText is very fussy about indentation!
check that the target has a number (for
:numref:
) or a title/caption (for:ref:
)
If a code block doesn’t appear:
check that all the parameters (for example,
:name:
) are correctcheck that there is a blank line before the code part
Strange formatting in lists:
check that there are blank lines before and after the list, including any sub-lists (otherwise you may have created a Definition list)
check that the indentation of continuation lines is the same as the text on the first line
12. Glossaries
12.1. Inserting a glossary
To make it easier for your reader, you can insert a glossary of the terms that the user may be unfamiliar with in your document. In this case, you should also reference the A Dictionary of Graphcore Terminology.
To insert a glossary, use the reStructuredText .. glossary::
directive, for example the following inserts a sorted glossary:
.. glossary::
:sorted:
Headings
Separate your text into sections. Each section should have a meaningful, but short heading. Headings use sentence case.
Table
Simple table
There are two types of tables in reStructuredText. A table needs a caption if you wish to reference it.
Code block
Use the ``..code-block::`` directive to insert a code block.
12.1.1. Example of how a glossary should look
The following is a list of terms that are used in this document. For a full list of Graphcore terminology, refer to the A Dictionary of Graphcore Terminology.
- Code block
Use the
..code-block::
directive to insert a code block.- Headings
Separate your text into sections. Each section should have a meaningful, but short heading. Headings use sentence case.
- Table
- Simple table
There are two types of tables in reStructuredText. A table needs a caption if you wish to reference it.
12.2. Linking to terms in the glossary
You can reference the terms in a glossary irrespective of which document it appears in.
12.2.1. In the same document
To reference a term in a glossary from the same document use:
:term:`term with the case as you want it to appear in your text including spaces`
:term:`displayed text if different from term <term>`
For example:
* :term:`code block`
* :term:`Table`
* :term:`heading <headings>`
which renders as follows:
12.2.2. In another document
To reference a term in a glossary from another document use the Intersphinx short names for the documents as:
:external+intersphinx-document-short-name:term:`optional displayed text <term>`
For example:
* :external+popart-user-guide:term:`micro-batch size`
* :external+glossary:term:`Streaming Memory`
* :external+glossary:term:`micro batch size`
* :external+glossary:term:`Micro Batch Size`
which renders as follows:
13. Legal notices and copyright year
The legal notices that appear in your document depend on the exact nature of the product. All documents should include |LEGAL:TRADEMARKS|
which inserts the current list of trade marks. Some documents will need |LEGAL:EULA|
which inserts the current Graphcore EULA.
The copyright year starts from the year of first publication on the external Graphcore docs portal. For more details on copyright year, refer to the Confluence page on Copyright dates.