| .. automodule:: torch.masked | 
 | .. automodule:: torch.masked.maskedtensor | 
 |  | 
 | .. currentmodule:: torch | 
 |  | 
 | .. _masked-docs: | 
 |  | 
 | torch.masked | 
 | ============ | 
 |  | 
 | Introduction | 
 | ++++++++++++ | 
 |  | 
 | Motivation | 
 | ---------- | 
 |  | 
 | .. warning:: | 
 |  | 
 |   The PyTorch API of masked tensors is in the prototype stage and may or may not change in the future. | 
 |  | 
 | MaskedTensor serves as an extension to :class:`torch.Tensor` that provides the user with the ability to: | 
 |  | 
 | * use any masked semantics (e.g. variable length tensors, nan* operators, etc.) | 
 | * differentiate between 0 and NaN gradients | 
 | * various sparse applications (see tutorial below) | 
 |  | 
 | "Specified" and "unspecified" have a long history in PyTorch without formal semantics and certainly without | 
 | consistency; indeed, MaskedTensor was born out of a build up of issues that the vanilla :class:`torch.Tensor` | 
 | class could not properly address. Thus, a primary goal of MaskedTensor is to become the source of truth for | 
 | said "specified" and "unspecified" values in PyTorch where they are a first class citizen instead of an afterthought. | 
 | In turn, this should further unlock `sparsity's <https://pytorch.org/docs/stable/sparse.html>`_ potential, | 
 | enable safer and more consistent operators, and provide a smoother and more intuitive experience | 
 | for users and developers alike. | 
 |  | 
 | What is a MaskedTensor? | 
 | ----------------------- | 
 |  | 
 | A MaskedTensor is a tensor subclass that consists of 1) an input (data), and 2) a mask. The mask tells us | 
 | which entries from the input should be included or ignored. | 
 |  | 
 | By way of example, suppose that we wanted to mask out all values that are equal to 0 (represented by the gray) | 
 | and take the max: | 
 |  | 
 | .. image:: _static/img/masked/tensor_comparison.jpg | 
 |       :scale: 50% | 
 |  | 
 | On top is the vanilla tensor example while the bottom is MaskedTensor where all the 0's are masked out. | 
 | This clearly yields a different result depending on whether we have the mask, but this flexible structure | 
 | allows the user to systematically ignore any elements they'd like during computation. | 
 |  | 
 | There are already a number of existing tutorials that we've written to help users onboard, such as: | 
 |  | 
 | -  `Overview - the place to start for new users, discusses how to use MaskedTensors and why they're useful`_ | 
 | -  `Sparsity - MaskedTensor supports sparse COO and CSR data and mask Tensors`_ | 
 | -  `Adagrad sparse semantics - a practical example of how MaskedTensor can simplify sparse semantics and implementations`_ | 
 | -  `Advanced semantics - discussion on why certain decisions were made (e.g. requiring masks to match for binary/reduction operations), | 
 |    differences with NumPy's MaskedArray, and reduction semantics`_ | 
 |  | 
 | .. _Overview - the place to start for new users, discusses how to use MaskedTensors and why they're useful: https://pytorch.org/tutorials/prototype/maskedtensor_overview | 
 | .. _Sparsity - MaskedTensor supports sparse COO and CSR data and mask Tensors: https://pytorch.org/tutorials/prototype/maskedtensor_sparsity | 
 | .. _Adagrad sparse semantics - a practical example of how MaskedTensor can simplify sparse semantics and implementations: https://pytorch.org/tutorials/prototype/maskedtensor_adagrad | 
 | .. _Advanced semantics - discussion on why certain decisions were made (e.g. requiring masks to match for binary/reduction operations), differences with NumPy's MaskedArray, and reduction semantics: https://pytorch.org/tutorials/prototype/maskedtensor_advanced_semantics | 
 |  | 
 | Supported Operators | 
 | +++++++++++++++++++ | 
 |  | 
 | Unary Operators | 
 | --------------- | 
 |  | 
 | Unary operators are operators that only contain only a single input. | 
 | Applying them to MaskedTensors is relatively straightforward: if the data is masked out at a given index, | 
 | we apply the operator, otherwise we'll continue to mask out the data. | 
 |  | 
 | The available unary operators are: | 
 |  | 
 | .. autosummary:: | 
 |     :toctree: generated | 
 |     :nosignatures: | 
 |  | 
 |     abs | 
 |     absolute | 
 |     acos | 
 |     arccos | 
 |     acosh | 
 |     arccosh | 
 |     angle | 
 |     asin | 
 |     arcsin | 
 |     asinh | 
 |     arcsinh | 
 |     atan | 
 |     arctan | 
 |     atanh | 
 |     arctanh | 
 |     bitwise_not | 
 |     ceil | 
 |     clamp | 
 |     clip | 
 |     conj_physical | 
 |     cos | 
 |     cosh | 
 |     deg2rad | 
 |     digamma | 
 |     erf | 
 |     erfc | 
 |     erfinv | 
 |     exp | 
 |     exp2 | 
 |     expm1 | 
 |     fix | 
 |     floor | 
 |     frac | 
 |     lgamma | 
 |     log | 
 |     log10 | 
 |     log1p | 
 |     log2 | 
 |     logit | 
 |     i0 | 
 |     isnan | 
 |     nan_to_num | 
 |     neg | 
 |     negative | 
 |     positive | 
 |     pow | 
 |     rad2deg | 
 |     reciprocal | 
 |     round | 
 |     rsqrt | 
 |     sigmoid | 
 |     sign | 
 |     sgn | 
 |     signbit | 
 |     sin | 
 |     sinc | 
 |     sinh | 
 |     sqrt | 
 |     square | 
 |     tan | 
 |     tanh | 
 |     trunc | 
 |  | 
 | The available inplace unary operators are all of the above **except**: | 
 |  | 
 | .. autosummary:: | 
 |     :toctree: generated | 
 |     :nosignatures: | 
 |  | 
 |     angle | 
 |     positive | 
 |     signbit | 
 |     isnan | 
 |  | 
 | Binary Operators | 
 | ---------------- | 
 |  | 
 | As you may have seen in the tutorial, :class:`MaskedTensor` also has binary operations implemented with the caveat | 
 | that the masks in the two MaskedTensors must match or else an error will be raised. As noted in the error, if you | 
 | need support for a particular operator or have proposed semantics for how they should behave instead, please open | 
 | an issue on GitHub. For now, we have decided to go with the most conservative implementation to ensure that users | 
 | know exactly what is going on and are being intentional about their decisions with masked semantics. | 
 |  | 
 | The available binary operators are: | 
 |  | 
 | .. autosummary:: | 
 |     :toctree: generated | 
 |     :nosignatures: | 
 |  | 
 |     add | 
 |     atan2 | 
 |     arctan2 | 
 |     bitwise_and | 
 |     bitwise_or | 
 |     bitwise_xor | 
 |     bitwise_left_shift | 
 |     bitwise_right_shift | 
 |     div | 
 |     divide | 
 |     floor_divide | 
 |     fmod | 
 |     logaddexp | 
 |     logaddexp2 | 
 |     mul | 
 |     multiply | 
 |     nextafter | 
 |     remainder | 
 |     sub | 
 |     subtract | 
 |     true_divide | 
 |     eq | 
 |     ne | 
 |     le | 
 |     ge | 
 |     greater | 
 |     greater_equal | 
 |     gt | 
 |     less_equal | 
 |     lt | 
 |     less | 
 |     maximum | 
 |     minimum | 
 |     fmax | 
 |     fmin | 
 |     not_equal | 
 |  | 
 | The available inplace binary operators are all of the above **except**: | 
 |  | 
 | .. autosummary:: | 
 |     :toctree: generated | 
 |     :nosignatures: | 
 |  | 
 |     logaddexp | 
 |     logaddexp2 | 
 |     equal | 
 |     fmin | 
 |     minimum | 
 |     fmax | 
 |  | 
 | Reductions | 
 | ---------- | 
 |  | 
 | The following reductions are available (with autograd support). For more information, the | 
 | `Overview <https://pytorch.org/tutorials/prototype/maskedtensor_overview.html>`_ tutorial | 
 | details some examples of reductions, while the | 
 | `Advanced semantics <https://pytorch.org/tutorials/prototype/maskedtensor_advanced_semantics.html>`_ tutorial | 
 | has some further in-depth discussions about how we decided on certain reduction semantics. | 
 |  | 
 | .. autosummary:: | 
 |     :toctree: generated | 
 |     :nosignatures: | 
 |  | 
 |     sum | 
 |     mean | 
 |     amin | 
 |     amax | 
 |     argmin | 
 |     argmax | 
 |     prod | 
 |     all | 
 |     norm | 
 |     var | 
 |     std | 
 |  | 
 | View and select functions | 
 | ------------------------- | 
 |  | 
 | We've included a number of view and select functions as well; intuitively, these operators will apply to | 
 | both the data and the mask and then wrap the result in a :class:`MaskedTensor`. For a quick example, | 
 | consider :func:`select`: | 
 |  | 
 |     >>> data = torch.arange(12, dtype=torch.float).reshape(3, 4) | 
 |     >>> data | 
 |     tensor([[ 0.,  1.,  2.,  3.], | 
 |             [ 4.,  5.,  6.,  7.], | 
 |             [ 8.,  9., 10., 11.]]) | 
 |     >>> mask = torch.tensor([[True, False, False, True], [False, True, False, False], [True, True, True, True]]) | 
 |     >>> mt = masked_tensor(data, mask) | 
 |     >>> data.select(0, 1) | 
 |     tensor([4., 5., 6., 7.]) | 
 |     >>> mask.select(0, 1) | 
 |     tensor([False,  True, False, False]) | 
 |     >>> mt.select(0, 1) | 
 |     MaskedTensor( | 
 |       [      --,   5.0000,       --,       --] | 
 |     ) | 
 |  | 
 | The following ops are currently supported: | 
 |  | 
 | .. autosummary:: | 
 |     :toctree: generated | 
 |     :nosignatures: | 
 |  | 
 |     atleast_1d | 
 |     broadcast_tensors | 
 |     broadcast_to | 
 |     cat | 
 |     chunk | 
 |     column_stack | 
 |     dsplit | 
 |     flatten | 
 |     hsplit | 
 |     hstack | 
 |     kron | 
 |     meshgrid | 
 |     narrow | 
 |     ravel | 
 |     select | 
 |     split | 
 |     t | 
 |     transpose | 
 |     vsplit | 
 |     vstack | 
 |     Tensor.expand | 
 |     Tensor.expand_as | 
 |     Tensor.reshape | 
 |     Tensor.reshape_as | 
 |     Tensor.view |