Skip to content

DOC: Docstrings for Elemwise Ops are not very helpful #292

Closed
@jessegrabowski

Description

@jessegrabowski

Issue with current documentation:

When a user checks a docstring for most basic Elemwise Ops, he is met with a wall of generic boilerplate:

import pytensor.tensor as pt

help(pt.exp)

Returns:

Help on Elemwise in module pytensor.tensor.math:

<pytensor.tensor.elemwise.Elemwise object>
    e^`a`
    
    Generalizes a scalar `Op` to tensors.
    
    All the inputs must have the same number of dimensions. When the
    `Op` is performed, for each dimension, each input's size for that
    dimension must be the same. As a special case, it can also be one
    but only if the input's `broadcastable` flag is ``True`` for that
    dimension. In that case, the tensor is (virtually) replicated
    along that dimension to match the size of the others.
    
    The dtypes of the outputs mirror those of the scalar `Op` that is
    being generalized to tensors. In particular, if the calculations
    for an output are done in-place on an input, the output type must
    be the same as the corresponding input type (see the doc of
    `ScalarOp` to get help about controlling the output type)
    
    Notes
    -----
    -``Elemwise(add)``: represents ``+`` on tensors ``x + y``
    -``Elemwise(add, {0 : 0})``: represents the ``+=`` operation ``x += y``
    -``Elemwise(add, {0 : 1})``: represents ``+=`` on the second argument ``y += x``
    -``Elemwise(mul)(np.random.random((10, 5)), np.random.random((1, 5)))``:
    the second input is completed along the first dimension to match the first input
    -``Elemwise(true_div)(np.random.random(10, 5), np.random.random(10, 1))``: same but along the
    second dimension
    -``Elemwise(int_div)(np.random.random((1, 5)), np.random.random((10, 1)))``:
    the output has size ``(10, 5)``.
    -``Elemwise(log)(np.random.random((3, 4, 5)))``

I'm not sure how much needs to be said on the exponential function as such, but there are some important Elemwise Ops that are not so obvious. For example, the fact that pt.eq needs to be used instead of == isn't immediately obvious, and could be explained with examples (and counter-examples) in its docstring. A small examples section would also a opportunity to present new users with some basics about building computational graphs, compiling functions, using .eval(), etc.

At the very least, the boilerplate is clutter that could be eliminated. The clutter is worse when you open the docstring in juypter, because it displays the Class docstring (shown above) and the Call docstring, which explains what an Apply node is.

I remember being very confused by all this when I was getting started, so it might be something nice to refine.

Idea or request for content:

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions