1import chainerx
2from chainerx import _docs
3
4
5def set_docs():
6    ndarray = chainerx.ndarray
7
8    _docs.set_doc(
9        ndarray,
10        """ndarray(shape, dtype, device=None)
11Multi-dimensional array, the central data structure of ChainerX.
12
13This class, along with other APIs in the :mod:`chainerx` module, provides a
14subset of NumPy APIs. This class works similar to :class:`numpy.ndarray`,
15except for some differences including the following noticeable points:
16
17- :class:`chainerx.ndarray` has a :attr:`device` attribute. It indicates on
18  which device the array is allocated.
19- :class:`chainerx.ndarray` supports :ref:`Define-by-Run <define_by_run>`
20  backpropagation. Once you call :meth:`require_grad`, the array starts
21  recording the operations applied to it recursively. Gradient of the result
22  with respect to the original array can be computed then with the
23  :meth:`backward` method or the :func:`chainerx.backward` function.
24
25Args:
26    shape (tuple of ints): Shape of the new array.
27    dtype: Data type.
28    device (~chainerx.Device): Device on which the array is allocated.
29        If omitted, :ref:`the default device <chainerx_device>` is chosen.
30
31.. seealso:: :class:`numpy.ndarray`
32""")
33
34    _docs.set_doc(
35        ndarray.data_ptr,
36        """int: Address of the underlying memory allocation.
37
38The meaning of the address is device-dependent.
39""")
40
41    _docs.set_doc(
42        ndarray.data_size,
43        'int: Total size of the underlying memory allocation.')
44
45    _docs.set_doc(
46        ndarray.device, '~chainerx.Device: Device on which the data exists.')
47
48    _docs.set_doc(ndarray.dtype, 'Data type of the array.')
49
50    # TODO(beam2d): Write about backprop id.
51    _docs.set_doc(
52        ndarray.grad,
53        """~chainerx.ndarray: Gradient held by the array.
54
55It is ``None`` if the gradient is not available.
56Setter of this property overwrites the gradient.
57""")
58
59    _docs.set_doc(
60        ndarray.is_contiguous,
61        'bool: ``True`` iff the array is stored in the C-contiguous order.')
62
63    _docs.set_doc(ndarray.itemsize, 'int: Size of each element in bytes.')
64
65    _docs.set_doc(
66        ndarray.nbytes,
67        """int: Total size of all elements in bytes.
68
69It does not count skips between elements.""")
70
71    _docs.set_doc(ndarray.ndim, 'int: Number of dimensions.')
72
73    _docs.set_doc(
74        ndarray.offset,
75        'int: Offset of the first element from the memory allocation in bytes.'
76    )
77
78    _docs.set_doc(
79        ndarray.shape,
80        """tuple of int: Lengths of axes.
81
82.. note::
83    Currently, this property does not support setter.""")
84
85    _docs.set_doc(ndarray.size, 'int: Number of elements in the array.')
86
87    _docs.set_doc(ndarray.strides, 'tuple of int: Strides of axes in bytes.')
88
89    _docs.set_doc(
90        ndarray.T,
91        """~chainerx.ndarray: Shape-reversed view of the array.
92
93New array is created at every access to this property.
94``x.T`` is just a shorthand of ``x.transpose()``.
95""")
96
97    _docs.set_doc(
98        ndarray.__getitem__,
99        """___getitem__(self, key)
100Returns self[key].
101
102.. note::
103    Currently, only basic indexing is supported not advanced indexing.
104""")
105
106    def unary_op(name, s):
107        _docs.set_doc(getattr(ndarray, name), '{}()\n{}'.format(name, s))
108
109    unary_op('__bool__', 'Casts a size-one array into a :class:`bool` value.')
110    unary_op('__float__',
111             'Casts a size-one array into a :class:`float` value.')
112    unary_op('__int__', 'Casts a size-one array into :class:`int` value.')
113    unary_op('__len__', 'Returns the length of the first axis.')
114    unary_op('__neg__', 'Computes ``-x`` elementwise.')
115
116    def binary_op(name, s):
117        _docs.set_doc(getattr(ndarray, name), '{}(other)\n{}'.format(name, s))
118
119    binary_op('__eq__', 'Computes ``x == y`` elementwise.')
120    binary_op('__ne__', 'Computes ``x != y`` elementwise.')
121    binary_op('__lt__', 'Computes ``x < y`` elementwise.')
122    binary_op('__le__', 'Computes ``x <= y`` elementwise.')
123    binary_op('__ge__', 'Computes ``x >= y`` elementwise.')
124    binary_op('__gt__', 'Computes ``x > y`` elementwise.')
125
126    binary_op('__iadd__', 'Computes ``x += y`` elementwise.')
127    binary_op('__isub__', 'Computes ``x -= y`` elementwise.')
128    binary_op('__imul__', 'Computes ``x *= y`` elementwise.')
129    binary_op('__itruediv__', 'Computes ``x /= y`` elementwise.')
130    binary_op('__iand__', 'Computes ``x &= y`` elementwise.')
131    binary_op('__ior__', 'Computes ``x |= y`` elementwise.')
132    binary_op('__ixor__', 'Computes ``x ^= y`` elementwise.')
133
134    binary_op('__add__', 'Computes ``x + y`` elementwise.')
135    binary_op('__sub__', 'Computes ``x - y`` elementwise.')
136    binary_op('__mul__', 'Computes ``x * y`` elementwise.')
137    binary_op('__truediv__', 'Computes ``x / y`` elementwise.')
138
139    binary_op('__and__', 'Computes ``x & y`` elementwise.')
140    binary_op('__or__', 'Computes ``x | y`` elementwise.')
141    binary_op('__xor__', 'Computes ``x ^ y`` elementwise.')
142
143    binary_op('__radd__', 'Computes ``y + x`` elementwise.')
144    binary_op('__rsub__', 'Computes ``y - x`` elementwise.')
145    binary_op('__rmul__', 'Computes ``y * x`` elementwise.')
146    binary_op('__rand__', 'Computes ``y & x`` elementwise.')
147    binary_op('__ror__', 'Computes ``y | x`` elementwise.')
148    binary_op('__rxor__', 'Computes ``y ^ x`` elementwise.')
149
150    # TODO(beam2d): Write about as_grad_stopped(backprop_ids, copy) overload.
151    _docs.set_doc(
152        ndarray.as_grad_stopped,
153        """as_grad_stopped(copy=False)
154Creates a view or a copy of the array that stops gradient propagation.
155
156This method behaves similar to :meth:`view` and :meth:`copy`, except that
157the gradient is not propagated through this operation (internally, this
158method creates a copy or view of the array without connecting the computational
159graph for backprop).
160
161Args:
162    copy (bool): If ``True``, it copies the array. Otherwise, it returns a view
163        of the original array.
164
165Returns:
166    ~chainerx.ndarray:
167        A view or a copy of the array without propagating the  gradient on
168        backprop.
169""")
170
171    _docs.set_doc(
172        ndarray.argmax,
173        """argmax(axis=None)
174Returns the indices of the maximum elements along a given axis.
175
176See :func:`chainerx.argmax` for the full documentation.
177""")
178
179    _docs.set_doc(
180        ndarray.argmin,
181        """argmin(axis=None)
182Returns the indices of the minimum elements along a given axis.
183
184See :func:`chainerx.argmin` for the full documentation.
185""")
186
187    _docs.set_doc(
188        ndarray.astype,
189        """astype(dtype, copy=True)
190Casts each element to the specified data type.
191
192Args:
193    dtype: Data type of the new array.
194    copy (bool): If ``True``, this method always copies the data. Otherwise,
195        it creates a view of the array if possible.
196
197Returns:
198    ~chainerx.ndarray: An array with the specified dtype.
199""")
200
201    _docs.set_doc(
202        ndarray.backward,
203        """backward(backprop_id=None, enable_double_backprop=False)
204Performs backpropagation starting from this array.
205
206This method is equivalent to ``chainerx.backward([self], *args)``.
207See :func:`chainerx.backward` for the full documentation.
208""")
209
210    # TODO(beam2d): Write about backprop id.
211    _docs.set_doc(
212        ndarray.cleargrad,
213        """cleargrad()
214Clears the gradient held by this array.
215""")
216
217    _docs.set_doc(
218        ndarray.copy,
219        """copy()
220Creates an array and copies all the elements to it.
221
222The copied array is allocated on the same device as ``self``.
223
224.. seealso:: :func:`chainerx.copy`
225""")
226
227    _docs.set_doc(
228        ndarray.dot,
229        """dot(b)
230Returns the dot product with a given array.
231
232See :func:`chainerx.dot` for the full documentation.
233""")
234
235    _docs.set_doc(
236        ndarray.fill,
237        """fill(value)
238Fills the array with a scalar value in place.
239
240Args:
241    value: Scalar value with which the array will be filled.
242""")
243
244    # TODO(beam2d): Write about backprop_id argument.
245    _docs.set_doc(
246        ndarray.get_grad,
247        """get_grad()
248Returns the gradient held by the array.
249
250If the gradient is not available, it returns ``None``.
251""")
252
253    # TODO(beam2d): Write about backprop_id argument.
254    _docs.set_doc(
255        ndarray.is_backprop_required,
256        """is_backprop_required()
257Returns ``True`` if gradient propagates through this array on backprop.
258
259See the note on :meth:`require_grad` for details.
260""")
261
262    # TODO(beam2d): Write about backprop_id argument.
263    _docs.set_doc(
264        ndarray.is_grad_required,
265        """is_grad_required()
266Returns ``True`` if the gradient will be set after backprop.
267
268See the note on :meth:`require_grad` for details.
269""")
270
271    _docs.set_doc(
272        ndarray.item,
273        """item()
274Copies an element of an array to a standard Python scalar and returns it.
275
276Returns:
277    z:
278        A copy of the specified element of the array as a suitable Python
279        scalar.
280
281.. seealso:: :func:`numpy.item`
282""")
283
284    _docs.set_doc(
285        ndarray.max,
286        """max(axis=None, keepdims=False)
287Returns the maximum along a given axis.
288
289See :func:`chainerx.amax` for the full documentation.
290""")
291
292    _docs.set_doc(
293        ndarray.min,
294        """min(axis=None, keepdims=False)
295Returns the minimum along a given axis.
296
297See :func:`chainerx.amin` for the full documentation.
298""")
299
300    # TODO(beam2d): Write about backprop_id argument.
301    _docs.set_doc(
302        ndarray.require_grad,
303        """require_grad()
304Declares that a gradient for this array will be made available after backprop.
305
306Once calling this method, any operations applied to this array are recorded for
307later backprop. After backprop, the :attr:`grad` attribute holds the gradient
308array.
309
310.. note::
311    ChainerX distinguishes *gradient requirements* and *backprop requirements*
312    strictly. They are strongly related, but different concepts as follows.
313
314    - *Gradient requirement* indicates that the gradient array should be made
315      available after backprop. This attribute **is not propagated** through
316      any operations. It implicates the backprop requirement.
317    - *Backprop requirement* indicates that the gradient should be propagated
318      through the array during backprop. This attribute **is propagated**
319      through differentiable operations.
320
321    :meth:`require_grad` sets the gradient requirement flag. If you need to
322    extract the gradient after backprop, you have to call :meth:`require_grad`
323    on the array even if the array is an intermediate result of differentiable
324    computations.
325
326Returns:
327    ~chainerx.ndarray: ``self``
328""")
329
330    _docs.set_doc(
331        ndarray.reshape,
332        """reshape(newshape)
333Creates an array with a new shape and the same data.
334
335See :func:`chainerx.reshape` for the full documentation.
336""")
337
338    _docs.set_doc(
339        ndarray.set_grad,
340        """set_grad(grad)
341Sets a gradient to the array.
342
343This method overwrites the gradient with a given array.
344
345Args:
346    grad (~chainerx.ndarray): New gradient array.
347""")
348
349    _docs.set_doc(
350        ndarray.squeeze,
351        """squeeze(axis=None)
352Removes size-one axes from an array.
353
354See :func:`chainerx.squeeze` for the full documentation.
355""")
356
357    _docs.set_doc(
358        ndarray.swapaxes,
359        """swapaxes(axis1, axis2)
360Interchange two axes of an array..
361
362See :func:`chainerx.swapaxes` for the full documentation.
363""")
364
365    _docs.set_doc(
366        ndarray.repeat,
367        """repeat(repeats, axis=None)
368Constructs an array by repeating a given array.
369
370See :func:`chainerx.repeats` for the full documentation.
371""")
372
373    _docs.set_doc(
374        ndarray.sum,
375        """sum(axis=None, keepdims=False)
376Returns the sum of an array along given axes.
377
378See :func:`chainerx.sum` for the full documentation.
379""")
380
381    _docs.set_doc(
382        ndarray.take,
383        """take(indices, axis)
384Takes elements from the array along an axis.
385
386See :func:`chainerx.take` for the full documentation.
387""")
388
389    _docs.set_doc(
390        ndarray.to_device,
391        """to_device(device, index=None)
392Transfers the array to the specified device.
393
394Args:
395    device (~chainerx.Device or str): Device to which the array is transferred,
396        or a backend name. If it is a backend name, ``index`` should also be
397        specified.
398    index (int): Index of the device for the backend specified by ``device``.
399
400Returns:
401    ~chainerx.ndarray:
402        An array on the target device.
403        If the original array is already on the device, it is a view of that.
404        Otherwise, it is a copy of the array on the target device.
405""")
406
407    _docs.set_doc(
408        ndarray.transpose,
409        """transpose(axes=None)
410Creates a view of an array with permutated axes.
411
412See :func:`chainerx.transpose` for the full documentation.
413""")
414
415    _docs.set_doc(
416        ndarray.view,
417        """view()
418Returns a view of the array.
419
420The returned array shares the underlying buffer, though it has a different
421identity as a Python object.
422""")
423