Unverified Commit 7fe6d0c8 authored by Minjie Wang's avatar Minjie Wang Committed by GitHub
Browse files

[Doc] Refactor API doc (#128)

* refactor API doc; add markup link in tutorials

* fix readme
parent 3e43d7b8
# Deep Graph Library # Deep Graph Library
[![Build Status](http://34.239.175.180:80/buildStatus/icon?job=DGL/master)](http://34.239.175.180:80/job/DGL/job/master/) [![Build Status](http://ci.dgl.ai:80/buildStatus/icon?job=DGL/master)](http://ci.dgl.ai:80/job/DGL/job/master/)
[![GitHub license](https://dmlc.github.io/img/apache2.svg)](./LICENSE) [![GitHub license](https://dmlc.github.io/img/apache2.svg)](./LICENSE)
For how to install and how to play with DGL, please read our For how to install and how to play with DGL, please read our
[Documentation](http://216.165.71.225:23232/index.html) [Documentation](http://docs.dgl.ai)
## Contribution rules ## Contribution rules
......
build build
# tutorials are auto-generated # tutorials are auto-generated
tutorials source/tutorials
source/generated
#!/bin/sh
make clean
rm -rf build
rm -rf source/tutorials
rm -rf source/generated
dgl.BatchedDGLGraph BatchedDGLGraph
------------------- ===============
.. autoclass:: dgl.BatchedDGLGraph
:members:
:show-inheritance:
.. autofunction:: dgl.batch .. automodule:: dgl.batched_graph
.. autoclass:: BatchedDGLGraph
.. autofunction:: dgl.unbatch .. autosummary::
:toctree: ../../generated/
batch
unbatch
.. _apifunction:
Builtin functions
=================
.. automodule:: dgl.function
Message functions
-----------------
.. autosummary::
:toctree: ../../generated/
copy_src
copy_edge
src_mul_edge
Reduce functions
----------------
.. autosummary::
:toctree: ../../generated/
sum
max
dgl.DGLGraph .. _apigraph:
------------
.. automodule:: dgl.graph
.. autoclass:: dgl.DGLGraph DGLGraph -- Graph with node/edge features
:members: =========================================
:inherited-members:
.. currentmodule:: dgl
.. autoclass:: DGLGraph
Adding nodes and edges
----------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.__init__
DGLGraph.add_nodes
DGLGraph.add_edge
DGLGraph.add_edges
DGLGraph.clear
Querying graph structure
------------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.number_of_nodes
DGLGraph.number_of_edges
DGLGraph.__len__
DGLGraph.is_multigraph
DGLGraph.has_node
DGLGraph.has_nodes
DGLGraph.__contains__
DGLGraph.has_edge_between
DGLGraph.has_edges_between
DGLGraph.predecessors
DGLGraph.successors
DGLGraph.edge_id
DGLGraph.edge_ids
DGLGraph.find_edges
DGLGraph.in_edges
DGLGraph.out_edges
DGLGraph.all_edges
DGLGraph.in_degree
DGLGraph.in_degrees
DGLGraph.out_degree
DGLGraph.out_degrees
Transforming graph
------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.subgraph
DGLGraph.subgraphs
DGLGraph.edge_subgraph
DGLGraph.line_graph
Converting from/to other format
-------------------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.to_networkx
DGLGraph.from_networkx
DGLGraph.from_scipy_sparse_matrix
DGLGraph.adjacency_matrix
DGLGraph.incidence_matrix
Using Node/edge features
------------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.nodes
DGLGraph.edges
DGLGraph.ndata
DGLGraph.edata
DGLGraph.node_attr_schemes
DGLGraph.edge_attr_schemes
DGLGraph.set_n_initializer
DGLGraph.set_e_initializer
Computing with DGLGraph
-----------------------
.. autosummary::
:toctree: ../../generated/
DGLGraph.register_message_func
DGLGraph.register_reduce_func
DGLGraph.register_apply_node_func
DGLGraph.register_apply_edge_func
DGLGraph.apply_nodes
DGLGraph.apply_edges
DGLGraph.send
DGLGraph.recv
DGLGraph.send_and_recv
DGLGraph.pull
DGLGraph.push
DGLGraph.update_all
DGLGraph.prop_nodes
DGLGraph.prop_edges
DGLGraph.filter_nodes
DGLGraph.filter_edges
Python APIs API Reference
=========== =============
.. toctree:: .. toctree::
:maxdepth: 2 :maxdepth: 2
graph graph
batch batch
function
traversal
Graph Traversal
===============
.. automodule:: dgl.traversal
.. autosummary::
:toctree: ../../generated/
bfs_nodes_generator
topological_nodes_generator
dfs_edges_generator
dfs_labeled_edges_generator
...@@ -182,14 +182,32 @@ epub_exclude_files = ['search.html'] ...@@ -182,14 +182,32 @@ epub_exclude_files = ['search.html']
# -- Extension configuration ------------------------------------------------- # -- Extension configuration -------------------------------------------------
autosummary_generate = True
intersphinx_mapping = {
'python': ('https://docs.python.org/{.major}'.format(sys.version_info), None),
'numpy': ('http://docs.scipy.org/doc/numpy/', None),
'scipy': ('http://docs.scipy.org/doc/scipy/reference', None),
'matplotlib': ('http://matplotlib.org/', None),
'networkx' : ('https://networkx.github.io/documentation/stable', None),
}
# sphinx gallery configurations # sphinx gallery configurations
from sphinx_gallery.sorting import FileNameSortKey from sphinx_gallery.sorting import FileNameSortKey
examples_dirs = ['../../tutorials'] # path to find sources examples_dirs = ['../../tutorials'] # path to find sources
gallery_dirs = ['tutorials'] # path to generate docs gallery_dirs = ['tutorials'] # path to generate docs
reference_url = {
'dgl' : None,
'numpy': 'http://docs.scipy.org/doc/numpy/',
'scipy': 'http://docs.scipy.org/doc/scipy/reference',
'matplotlib': 'http://matplotlib.org/',
'networkx' : 'https://networkx.github.io/documentation/stable',
}
sphinx_gallery_conf = { sphinx_gallery_conf = {
'backreferences_dir' : 'generated/backreferences',
'doc_module' : ('dgl', 'numpy'),
'examples_dirs' : examples_dirs, 'examples_dirs' : examples_dirs,
'gallery_dirs' : gallery_dirs, 'gallery_dirs' : gallery_dirs,
'within_subsection_order' : FileNameSortKey, 'within_subsection_order' : FileNameSortKey,
......
...@@ -13,7 +13,7 @@ from . import utils ...@@ -13,7 +13,7 @@ from . import utils
__all__ = ['BatchedDGLGraph', 'batch', 'unbatch', 'split'] __all__ = ['BatchedDGLGraph', 'batch', 'unbatch', 'split']
class BatchedDGLGraph(DGLGraph): class BatchedDGLGraph(DGLGraph):
"""The batched DGL graph. """Class for batched DGL graphs.
The batched graph is read-only. The batched graph is read-only.
......
...@@ -19,22 +19,117 @@ from .view import NodeView, EdgeView ...@@ -19,22 +19,117 @@ from .view import NodeView, EdgeView
__all__ = ['DGLGraph'] __all__ = ['DGLGraph']
class DGLGraph(object): class DGLGraph(object):
"""Base graph class specialized for neural networks on graphs. """Base graph class.
TODO(minjie): document of batching semantics The graph stores nodes, edges and also their features.
DGL graph is always directional. Undirected graph can be represented using
two bi-directional edges.
Nodes are identified by consecutive integers starting from zero.
Edges can be specified by two end points (u, v) or the integer id assigned
when the edges are added.
Node and edge features are stored as a dictionary from the feature name
to the feature data (in tensor).
Parameters Parameters
---------- ----------
graph_data : graph data graph_data : graph data, optional
Data to initialize graph. Same as networkx's semantics. Data to initialize graph. Same as networkx's semantics.
node_frame : FrameRef node_frame : FrameRef, optional
Node feature storage. Node feature storage.
edge_frame : FrameRef edge_frame : FrameRef, optional
Edge feature storage. Edge feature storage.
multigraph : bool, optional multigraph : bool, optional
Whether the graph would be a multigraph (default: False) Whether the graph would be a multigraph (default: False)
readonly : bool, optional readonly : bool, optional
Whether the graph structure is read-only (default: False). Whether the graph structure is read-only (default: False).
Examples
--------
Create an empty graph with no nodes and edges.
>>> G = dgl.DGLGraph()
G can be grown in several ways.
**Nodes:**
Add N nodes:
>>> G.add_nodes(10) # 10 isolated nodes are added
**Edges:**
Add one edge at a time,
>>> G.add_edge(0, 1)
or multiple edges,
>>> G.add_edges([1, 2, 3], [3, 4, 5]) # three edges: 1->3, 2->4, 3->5
or multiple edges starting from the same node,
>>> G.add_edges(4, [7, 8, 9]) # three edges: 4->7, 4->8, 4->9
or multiple edges pointing to the same node,
>>> G.add_edges([2, 6, 8], 5) # three edges: 2->5, 6->5, 8->5
or multiple edges using tensor type (demo in pytorch syntax).
>>> import torch as th
>>> G.add_edges(th.tensor([3, 4, 5]), 1) # three edges: 3->1, 4->1, 5->1
NOTE: Removing nodes and edges is not supported by DGLGraph.
**Features:**
Both nodes and edges can have feature data. Features are stored as
key/value pair. The key must be hashable while the value must be tensor
type. Features are batched on the first dimension.
Use G.ndata to get/set features for all nodes.
>>> G = dgl.DGLGraph()
>>> G.add_nodes(3)
>>> G.ndata['x'] = th.zeros((3, 5)) # init 3 nodes with zero vector(len=5)
>>> G.ndata
{'x' : tensor([[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.],
[0., 0., 0., 0., 0.]])}
Use G.nodes to get/set features for some nodes.
>>> G.nodes[[0, 2]].data['x'] = th.ones((2, 5))
>>> G.ndata
{'x' : tensor([[1., 1., 1., 1., 1.],
[0., 0., 0., 0., 0.],
[1., 1., 1., 1., 1.]])}
Similarly, use G.edata and G.edges to get/set features for edges.
>>> G.add_edges([0, 1], 2) # 0->2, 1->2
>>> G.edata['y'] = th.zeros((2, 4)) # init 2 edges with zero vector(len=4)
>>> G.edata
{'y' : tensor([[0., 0., 0., 0.],
[0., 0., 0., 0.]])}
>>> G.edges[1, 2].data['y'] = th.ones((1, 4))
>>> G.edata
{'y' : tensor([[0., 0., 0., 0.],
[1., 1., 1., 1.]])}
Note that each edge is assigned a unique id equal to its adding
order. So edge 1->2 has id=1. DGL supports directly use edge id
to access edge features.
>>> G.edges[0].data['y'] += 2.
>>> G.edata
{'y' : tensor([[2., 2., 2., 2.],
[1., 1., 1., 1.]])}
""" """
def __init__(self, def __init__(self,
graph_data=None, graph_data=None,
...@@ -89,6 +184,10 @@ class DGLGraph(object): ...@@ -89,6 +184,10 @@ class DGLGraph(object):
The dst node. The dst node.
reprs : dict reprs : dict
Optional edge representation. Optional edge representation.
See Also
--------
add_edges
""" """
self._graph.add_edge(u, v) self._graph.add_edge(u, v)
#TODO(minjie): change frames #TODO(minjie): change frames
...@@ -109,6 +208,10 @@ class DGLGraph(object): ...@@ -109,6 +208,10 @@ class DGLGraph(object):
The dst nodes. The dst nodes.
reprs : dict reprs : dict
Optional node representations. Optional node representations.
See Also
--------
add_edge
""" """
u = utils.toindex(u) u = utils.toindex(u)
v = utils.toindex(v) v = utils.toindex(v)
...@@ -178,6 +281,10 @@ class DGLGraph(object): ...@@ -178,6 +281,10 @@ class DGLGraph(object):
------- -------
bool bool
True if the node exists True if the node exists
See Also
--------
has_nodes
""" """
return self.has_node(vid) return self.has_node(vid)
...@@ -197,6 +304,10 @@ class DGLGraph(object): ...@@ -197,6 +304,10 @@ class DGLGraph(object):
------- -------
tensor tensor
0-1 array indicating existence 0-1 array indicating existence
See Also
--------
has_node
""" """
vids = utils.toindex(vids) vids = utils.toindex(vids)
rst = self._graph.has_nodes(vids) rst = self._graph.has_nodes(vids)
...@@ -216,6 +327,10 @@ class DGLGraph(object): ...@@ -216,6 +327,10 @@ class DGLGraph(object):
------- -------
bool bool
True if the edge exists True if the edge exists
See Also
--------
has_edges_between
""" """
return self._graph.has_edge_between(u, v) return self._graph.has_edge_between(u, v)
...@@ -233,6 +348,10 @@ class DGLGraph(object): ...@@ -233,6 +348,10 @@ class DGLGraph(object):
------- -------
tensor tensor
0-1 array indicating existence 0-1 array indicating existence
See Also
--------
has_edge_between
""" """
u = utils.toindex(u) u = utils.toindex(u)
v = utils.toindex(v) v = utils.toindex(v)
...@@ -291,6 +410,10 @@ class DGLGraph(object): ...@@ -291,6 +410,10 @@ class DGLGraph(object):
int or tensor int or tensor
The edge id if force_multi == True and the graph is a simple graph. The edge id if force_multi == True and the graph is a simple graph.
The edge id array otherwise. The edge id array otherwise.
See Also
--------
edge_ids
""" """
idx = self._graph.edge_id(u, v) idx = self._graph.edge_id(u, v)
return idx.tousertensor() if force_multi or self.is_multigraph else idx[0] return idx.tousertensor() if force_multi or self.is_multigraph else idx[0]
...@@ -313,6 +436,10 @@ class DGLGraph(object): ...@@ -313,6 +436,10 @@ class DGLGraph(object):
tensor, or (tensor, tensor, tensor) tensor, or (tensor, tensor, tensor)
If force_multi is True or the graph is multigraph, return (src nodes, dst nodes, edge ids) If force_multi is True or the graph is multigraph, return (src nodes, dst nodes, edge ids)
Otherwise, return a single tensor of edge ids. Otherwise, return a single tensor of edge ids.
See Also
--------
edge_id
""" """
u = utils.toindex(u) u = utils.toindex(u)
v = utils.toindex(v) v = utils.toindex(v)
...@@ -332,8 +459,10 @@ class DGLGraph(object): ...@@ -332,8 +459,10 @@ class DGLGraph(object):
Returns Returns
------- -------
tensor, tensor tensor
The source and destination node IDs. The source nodes.
tensor
The destination nodes.
""" """
eid = utils.toindex(eid) eid = utils.toindex(eid)
src, dst, _ = self._graph.find_edges(eid) src, dst, _ = self._graph.find_edges(eid)
...@@ -440,6 +569,10 @@ class DGLGraph(object): ...@@ -440,6 +569,10 @@ class DGLGraph(object):
------- -------
int int
The in degree. The in degree.
See Also
--------
in_degrees
""" """
return self._graph.in_degree(v) return self._graph.in_degree(v)
...@@ -455,6 +588,10 @@ class DGLGraph(object): ...@@ -455,6 +588,10 @@ class DGLGraph(object):
------- -------
tensor tensor
The in degree array. The in degree array.
See Also
--------
in_degree
""" """
v = utils.toindex(v) v = utils.toindex(v)
return self._graph.in_degrees(v).tousertensor() return self._graph.in_degrees(v).tousertensor()
...@@ -471,6 +608,10 @@ class DGLGraph(object): ...@@ -471,6 +608,10 @@ class DGLGraph(object):
------- -------
int int
The out degree. The out degree.
See Also
--------
out_degrees
""" """
return self._graph.out_degree(v) return self._graph.out_degree(v)
...@@ -486,6 +627,10 @@ class DGLGraph(object): ...@@ -486,6 +627,10 @@ class DGLGraph(object):
------- -------
tensor tensor
The out degree array. The out degree array.
See Also
--------
out_degree
""" """
v = utils.toindex(v) v = utils.toindex(v)
return self._graph.out_degrees(v).tousertensor() return self._graph.out_degrees(v).tousertensor()
...@@ -1273,6 +1418,10 @@ class DGLGraph(object): ...@@ -1273,6 +1418,10 @@ class DGLGraph(object):
------- -------
G : DGLSubGraph G : DGLSubGraph
The subgraph. The subgraph.
See Also
--------
subgraphs
""" """
induced_nodes = utils.toindex(nodes) induced_nodes = utils.toindex(nodes)
sgi = self._graph.node_subgraph(induced_nodes) sgi = self._graph.node_subgraph(induced_nodes)
...@@ -1291,6 +1440,10 @@ class DGLGraph(object): ...@@ -1291,6 +1440,10 @@ class DGLGraph(object):
------- -------
G : A list of DGLSubGraph G : A list of DGLSubGraph
The subgraphs. The subgraphs.
See Also
--------
subgraph
""" """
induced_nodes = [utils.toindex(n) for n in nodes] induced_nodes = [utils.toindex(n) for n in nodes]
sgis = self._graph.node_subgraphs(induced_nodes) sgis = self._graph.node_subgraphs(induced_nodes)
......
""" """
.. currentmodule:: dgl
DGL at a glance DGL at a glance
========================= =========================
**Author**: Minjie Wang, Quan Gan, Zheng Zhang **Author**: Minjie Wang, Quan Gan, Zheng Zhang
The goal of DGL is to build, train, and deploy *machine learning models* The goal of DGL is to build, train, and deploy *machine learning models*
on *graph-structured data*. To achieve this, DGL provides a ``DGLGraph`` on *graph-structured data*. To achieve this, DGL provides a :class:`DGLGraph`
class that defines the graph structure and the information on its nodes class that defines the graph structure and the information on its nodes
and edges. It also provides a set of feature transformation methods and edges. It also provides a set of feature transformation methods
and message passing methods to propagate information between nodes and edges. and message passing methods to propagate information between nodes and edges.
...@@ -54,7 +56,7 @@ def an_interesting_graph(): ...@@ -54,7 +56,7 @@ def an_interesting_graph():
return g return g
############################################################################### ###############################################################################
# One thing to be aware of is that DGL graphs are directional: # One thing to be aware of is that :class:`DGLGraph` is directional:
g_boring = a_boring_graph() g_boring = a_boring_graph()
g_better = an_interesting_graph() g_better = an_interesting_graph()
...@@ -96,7 +98,7 @@ def super_useful_comp(g): ...@@ -96,7 +98,7 @@ def super_useful_comp(g):
return readout(g) return readout(g)
############################################################################### ###############################################################################
# The point is, regardless of what kind of graphs and the form of repretations, # The point is, regardless of what kind of graphs and the form of representations,
# DGL handles it uniformly and efficiently. # DGL handles it uniformly and efficiently.
g_boring = a_boring_graph() g_boring = a_boring_graph()
......
""" """
.. currentmodule:: dgl
DGL Basics DGL Basics
========== ==========
...@@ -13,8 +15,8 @@ The Goal of this tutorial: ...@@ -13,8 +15,8 @@ The Goal of this tutorial:
############################################################################### ###############################################################################
# Graph Creation # Graph Creation
# -------------- # --------------
# The design of ``DGLGraph`` was influenced by other graph libraries. Indeed, # The design of :class:`DGLGraph` was influenced by other graph libraries. Indeed,
# you can create a graph from networkx, and convert it into a ``DGLGraph`` and # you can create a graph from networkx, and convert it into a :class:`DGLGraph` and
# vice versa: # vice versa:
import networkx as nx import networkx as nx
...@@ -33,13 +35,14 @@ plt.show() ...@@ -33,13 +35,14 @@ plt.show()
############################################################################### ###############################################################################
# They are the same graph, except that DGLGraph are *always* directional. # They are the same graph, except that :class:`DGLGraph` is *always* directional.
# #
# One can also create a graph by calling DGL's own interface. # One can also create a graph by calling DGL's own interface.
# #
# Now let's build a star graph. DGLGraph nodes are consecutive range of # Now let's build a star graph. :class:`DGLGraph` nodes are consecutive range of
# integers between 0 and ``g.number_of_nodes()`` and can grow by calling # integers between 0 and :func:`number_of_nodes() <DGLGraph.number_of_nodes>`
# ``g.add_nodes``. DGLGraph edges are in order of their additions. Note that # and can grow by calling :func:`add_nodes <DGLGraph.add_nodes>`.
# :class:`DGLGraph` edges are in order of their additions. Note that
# edges are accessed in much the same way as nodes, with one extra feature # edges are accessed in much the same way as nodes, with one extra feature
# of *edge broadcasting*: # of *edge broadcasting*:
...@@ -72,11 +75,11 @@ plt.show() ...@@ -72,11 +75,11 @@ plt.show()
############################################################################### ###############################################################################
# Feature Assignment # Feature Assignment
# ------------------ # ------------------
# One can also assign features to nodes and edges of a ``DGLGraph``. The # One can also assign features to nodes and edges of a :class:`DGLGraph`. The
# features are represented as dictionary of names (strings) and tensors, # features are represented as dictionary of names (strings) and tensors,
# called **fields**. # called **fields**.
# #
# The following code snippet assigns each node a 3-D vector. # The following code snippet assigns each node a vector (len=3).
# #
# .. note:: # .. note::
# #
...@@ -91,8 +94,9 @@ g.ndata['x'] = x ...@@ -91,8 +94,9 @@ g.ndata['x'] = x
############################################################################### ###############################################################################
# ``ndata`` is a syntax sugar to access states of all nodes, states are stored # :func:`ndata <DGLGraph.ndata>` is a syntax sugar to access states of all nodes,
# in a container `data` that hosts user defined dictionary. # states are stored
# in a container ``data`` that hosts user defined dictionary.
print(g.ndata['x'] == g.nodes[:].data['x']) print(g.ndata['x'] == g.nodes[:].data['x'])
...@@ -138,7 +142,7 @@ g.edata.pop('w') ...@@ -138,7 +142,7 @@ g.edata.pop('w')
############################################################################### ###############################################################################
# Multigraphs # Multigraphs
# ~~~~~~~~~~~ # ~~~~~~~~~~~
# Many graph applications need multi-edges. To enable this, construct DGLGraph # Many graph applications need multi-edges. To enable this, construct :class:`DGLGraph`
# with ``multigraph=True``. # with ``multigraph=True``.
g_multi = dgl.DGLGraph(multigraph=True) g_multi = dgl.DGLGraph(multigraph=True)
......
""" """
.. currentmodule:: dgl
PageRank with DGL Message Passing PageRank with DGL Message Passing
================================= =================================
...@@ -34,7 +36,7 @@ interface. ...@@ -34,7 +36,7 @@ interface.
# A naive implementation # A naive implementation
# ---------------------- # ----------------------
# Let us first create a graph with 100 nodes with NetworkX and convert it to a # Let us first create a graph with 100 nodes with NetworkX and convert it to a
# ``DGLGraph``: # :class:`DGLGraph`:
import networkx as nx import networkx as nx
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
...@@ -153,8 +155,8 @@ def pagerank_level2(g): ...@@ -153,8 +155,8 @@ def pagerank_level2(g):
############################################################################### ###############################################################################
# Besides ``update_all``, we also have ``pull``, ``push``, and ``send_and_recv`` # Besides ``update_all``, we also have ``pull``, ``push``, and ``send_and_recv``
# in this level-2 category. Please refer to their own API reference documents # in this level-2 category. Please refer to the :doc:`API reference <../api/python/graph>`
# for more details. (TODO: a link to the document). # for more details.
############################################################################### ###############################################################################
...@@ -164,11 +166,13 @@ def pagerank_level2(g): ...@@ -164,11 +166,13 @@ def pagerank_level2(g):
# provides **builtin functions**. For example, two builtin functions can be # provides **builtin functions**. For example, two builtin functions can be
# used in the PageRank example. # used in the PageRank example.
# #
# * ``dgl.function.copy_src(src, out)`` is an edge UDF that computes the # * :func:`dgl.function.copy_src(src, out) <function.copy_src>`
# is an edge UDF that computes the
# output using the source node feature data. User needs to specify the name of # output using the source node feature data. User needs to specify the name of
# the source feature data (``src``) and the output name (``out``). # the source feature data (``src``) and the output name (``out``).
# #
# * ``dgl.function.sum(msg, out)`` is a node UDF that sums the messages in # * :func:`dgl.function.sum(msg, out) <function.sum>` is a node UDF
# that sums the messages in
# the node's mailbox. User needs to specify the message name (``msg``) and the # the node's mailbox. User needs to specify the message name (``msg``) and the
# output name (``out``). # output name (``out``).
# #
...@@ -184,7 +188,8 @@ def pagerank_builtin(g): ...@@ -184,7 +188,8 @@ def pagerank_builtin(g):
############################################################################### ###############################################################################
# Here, we directly provide the UDFs to the `update_all` as its arguments. # Here, we directly provide the UDFs to the :func:`update_all <DGLGraph.update_all>`
# as its arguments.
# This will override the previously registered UDFs. # This will override the previously registered UDFs.
# #
# In addition to cleaner code, using builtin functions also gives DGL the # In addition to cleaner code, using builtin functions also gives DGL the
...@@ -194,7 +199,7 @@ def pagerank_builtin(g): ...@@ -194,7 +199,7 @@ def pagerank_builtin(g):
# #
# `This section <spmv_>`_ describes why spMV can speed up the scatter-gather # `This section <spmv_>`_ describes why spMV can speed up the scatter-gather
# phase in PageRank. For more details about the builtin functions in DGL, # phase in PageRank. For more details about the builtin functions in DGL,
# please read their API reference documents. (TODO: a link here). # please read the :doc:`API reference <../api/python/function>`.
# #
# You can also download and run the codes to feel the difference. # You can also download and run the codes to feel the difference.
......
...@@ -160,4 +160,4 @@ for epoch in range(30): ...@@ -160,4 +160,4 @@ for epoch in range(30):
# multiplication kernels (such as Kipf's # multiplication kernels (such as Kipf's
# `pygcn <https://github.com/tkipf/pygcn>`_ code). The above DGL implementation # `pygcn <https://github.com/tkipf/pygcn>`_ code). The above DGL implementation
# in fact has already used this trick due to the use of builtin functions. To # in fact has already used this trick due to the use of builtin functions. To
# understand what is under the hood, please read our tutorial on :doc:` PageRank <3_pagerank>`. # understand what is under the hood, please read our tutorial on :doc:`PageRank <../3_pagerank>`.
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment