mirror of
https://github.com/pytorch/pytorch.git
synced 2025-10-21 05:34:18 +08:00
Summary: I was looking into why the non-standard bool value will fail for msort - it makes sense for argsort and sort to fail, because we're randomly generating uint8 so the order will be different (and thus the indices will be different). But msort should work. After some digging, it's interesting that even though scalar_t is bool, when the actual value is a uint8_t, the comparison will treat them as signed. I tried lhs=255 and rhs=0: lhs < rhs is equivalent to -1 < 0 which is true (but it's supposed to be False) Therefore we add an explicit type cast. Test Plan: Remove the test skip Differential Revision: D65472170 Pull Request resolved: https://github.com/pytorch/pytorch/pull/139870 Approved by: https://github.com/Skylion007, https://github.com/davidberard98
24717 lines
1.1 MiB
24717 lines
1.1 MiB
# mypy: ignore-errors
|
|
|
|
from functools import wraps, partial
|
|
from itertools import product, chain, islice
|
|
import itertools
|
|
import functools
|
|
import copy
|
|
import operator
|
|
import random
|
|
import unittest
|
|
import math
|
|
import enum
|
|
|
|
import torch
|
|
import numpy as np
|
|
import numpy.typing as npt
|
|
from torch import inf, nan
|
|
|
|
from typing import Any, Dict, List, Tuple, Union, Sequence
|
|
from torch.testing import make_tensor
|
|
from torch.testing._internal.common_dtype import (
|
|
_dispatch_dtypes, floating_types, floating_types_and, complex_types, floating_and_complex_types,
|
|
floating_and_complex_types_and, all_types_and_complex_and, all_types_and, all_types_and_complex, integral_types_and,
|
|
empty_types, complex_types_and, integral_types, custom_types,
|
|
)
|
|
from torch.testing._internal.common_device_type import \
|
|
(onlyCPU, onlyCUDA, onlyNativeDeviceTypes, disablecuDNN, skipCUDAIfNoMagma, skipCUDAIfNoMagmaAndNoCusolver,
|
|
skipCUDAIfNoCusolver, skipCPUIfNoLapack, skipCPUIfNoFFT, skipCUDAIf, precisionOverride,
|
|
skipCPUIfNoMklSparse,
|
|
toleranceOverride, tol)
|
|
from torch.testing._internal.common_cuda import (
|
|
PLATFORM_SUPPORTS_FLASH_ATTENTION, PLATFORM_SUPPORTS_MEM_EFF_ATTENTION,
|
|
SM53OrLater, SM80OrLater, SM90OrLater, with_tf32_off, TEST_CUDNN, _get_torch_cuda_version,
|
|
_get_torch_rocm_version,
|
|
)
|
|
from torch.testing._internal.common_utils import (
|
|
make_fullrank_matrices_with_distinct_singular_values,
|
|
TEST_WITH_ROCM, IS_FBCODE, IS_WINDOWS, IS_MACOS, TEST_SCIPY,
|
|
torch_to_numpy_dtype_dict, numpy_to_torch_dtype, TEST_WITH_ASAN,
|
|
GRADCHECK_NONDET_TOL, slowTest, TEST_WITH_SLOW,
|
|
TEST_WITH_TORCHINDUCTOR
|
|
)
|
|
from torch.testing._utils import wrapper_set_seed
|
|
|
|
import torch._refs as refs # noqa: F401
|
|
import torch._refs.nn.functional
|
|
import torch._refs.special
|
|
import torch._refs.linalg
|
|
import torch._prims as prims # noqa: F401
|
|
from torch.utils import _pytree as pytree
|
|
|
|
|
|
from packaging import version
|
|
|
|
from torch.testing._internal.opinfo.core import ( # noqa: F401
|
|
L,
|
|
M,
|
|
S,
|
|
XS,
|
|
_NOTHING,
|
|
_getattr_qual,
|
|
DecorateInfo,
|
|
SampleInput,
|
|
ErrorInput,
|
|
AliasInfo,
|
|
NumericsFilter,
|
|
OpInfo,
|
|
_generate_reduction_inputs,
|
|
_generate_reduction_kwargs,
|
|
sample_inputs_reduction,
|
|
ReductionOpInfo,
|
|
reference_inputs_elementwise_binary,
|
|
make_error_inputs_elementwise_binary,
|
|
generate_elementwise_binary_tensors,
|
|
generate_elementwise_binary_arbitrarily_strided_tensors,
|
|
generate_elementwise_binary_small_value_tensors,
|
|
generate_elementwise_binary_large_value_tensors,
|
|
generate_elementwise_binary_extremal_value_tensors,
|
|
generate_elementwise_binary_broadcasting_tensors,
|
|
generate_elementwise_binary_with_scalar_samples,
|
|
generate_elementwise_binary_with_scalar_and_type_promotion_samples,
|
|
generate_elementwise_binary_noncontiguous_tensors,
|
|
sample_inputs_elementwise_binary,
|
|
BinaryUfuncInfo,
|
|
sample_inputs_elementwise_unary,
|
|
generate_elementwise_unary_tensors,
|
|
generate_elementwise_unary_small_value_tensors,
|
|
generate_elementwise_unary_large_value_tensors,
|
|
generate_elementwise_unary_extremal_value_tensors,
|
|
reference_inputs_elementwise_unary,
|
|
UnaryUfuncInfo,
|
|
sample_inputs_spectral_ops,
|
|
SpectralFuncType,
|
|
SpectralFuncInfo,
|
|
ShapeFuncInfo,
|
|
sample_inputs_foreach,
|
|
ForeachFuncInfo,
|
|
gradcheck_wrapper_hermitian_input,
|
|
gradcheck_wrapper_triangular_input,
|
|
gradcheck_wrapper_triangular_input_real_positive_diagonal,
|
|
gradcheck_wrapper_masked_operation,
|
|
gradcheck_wrapper_masked_pointwise_operation,
|
|
clone_sample,
|
|
)
|
|
from torch.testing._internal.opinfo.refs import ( # NOQA: F401
|
|
_find_referenced_opinfo,
|
|
_inherit_constructor_args,
|
|
PythonRefInfo,
|
|
ReductionPythonRefInfo,
|
|
ElementwiseUnaryPythonRefInfo,
|
|
ElementwiseBinaryPythonRefInfo,
|
|
)
|
|
from torch.testing._internal.opinfo.utils import (
|
|
np_unary_ufunc_integer_promotion_wrapper,
|
|
reference_reduction_numpy,
|
|
prod_numpy
|
|
)
|
|
from torch.testing._internal import opinfo
|
|
from torch.testing._internal.opinfo.definitions.linalg import (
|
|
sample_inputs_linalg_cholesky,
|
|
sample_inputs_linalg_cholesky_inverse,
|
|
sample_inputs_cross,
|
|
sample_inputs_linalg_qr_geqrf,
|
|
sample_inputs_linalg_invertible,
|
|
sample_inputs_lu_solve,
|
|
sample_inputs_legacy_solve,
|
|
sample_inputs_svd,
|
|
sample_inputs_linalg_det_logdet_slogdet,
|
|
sample_inputs_linalg_lu,
|
|
sample_inputs_diagonal_diag_embed,
|
|
error_inputs_diagonal_diag_embed,
|
|
)
|
|
from torch.testing._internal.opinfo.definitions.special import (
|
|
sample_inputs_i0_i1,
|
|
sample_inputs_polygamma,
|
|
reference_polygamma,
|
|
)
|
|
from torch.testing._internal.opinfo.definitions._masked import (
|
|
sample_inputs_softmax_variant,
|
|
)
|
|
from torch.testing._internal.opinfo.definitions.sparse import (
|
|
error_inputs_sparse_like_fns,
|
|
sample_inputs_sparse_like_fns,
|
|
error_inputs_sparse_mul,
|
|
sample_inputs_sparse_mul,
|
|
error_inputs_sparse_reduction_sum,
|
|
sample_inputs_sparse_reduction_sum
|
|
)
|
|
|
|
if TEST_SCIPY:
|
|
from scipy import stats
|
|
import scipy.spatial
|
|
import scipy.special
|
|
|
|
|
|
# test if a tensor is close to an integer
|
|
def close_to_int(x, eps=0.1):
|
|
if x.is_complex():
|
|
y = torch.abs(torch.view_as_complex(torch.frac(torch.view_as_real(x))))
|
|
else:
|
|
y = torch.abs(torch.frac(x))
|
|
return (y < eps) | (y > (1 - eps))
|
|
|
|
|
|
def sample_inputs_slice(op_info, device, dtype, requires_grad, **kwargs):
|
|
|
|
make_input = partial(make_tensor, device=device, dtype=dtype,
|
|
low=None, high=None, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_input(3), 0)
|
|
|
|
yield SampleInput(make_input(20, 30, 40), dim=1, start=1, end=-2)
|
|
|
|
yield SampleInput(make_input(20, 30, 40), dim=1, start=1, end=-2, step=3)
|
|
|
|
yield SampleInput(make_input(20, 30, 40), dim=0, start=-10, end=-2, step=2)
|
|
|
|
|
|
def sample_inputs_tensor_split(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=dtype,
|
|
low=None, high=None, requires_grad=requires_grad)
|
|
|
|
args_cases = (
|
|
# Cases with tensor indices.
|
|
(torch.tensor([1, 2, 3]),),
|
|
(torch.tensor(1),),
|
|
(torch.tensor([1, 2, 3]), 1),
|
|
(torch.tensor([1, 4, 2, 5, 3, 6])[::2], 1),
|
|
# Cases with list of indices.
|
|
((2, 4),),
|
|
((2, 4), 1),
|
|
((2, 4), -1),
|
|
# Cases with integer section.
|
|
(3,),
|
|
(3, 1),
|
|
(3, -1),
|
|
)
|
|
|
|
for args in args_cases:
|
|
yield SampleInput(make_input((S, S, S)), args=args)
|
|
|
|
|
|
def sample_inputs_hsplit(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device,
|
|
low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(6), 2)
|
|
yield SampleInput(make_arg(S, S, S), [1, 2, 3])
|
|
|
|
def sample_inputs_vsplit(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device,
|
|
low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(6, S), 2)
|
|
yield SampleInput(make_arg(S, S, S), [1, 2, 3])
|
|
|
|
def sample_inputs_dsplit(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device,
|
|
low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(S, S, S), [1, 2, 3])
|
|
yield SampleInput(make_arg(S, S, 6), 2)
|
|
|
|
def error_inputs_hsplit(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=torch.float32, device=device)
|
|
err_msg1 = ("torch.hsplit requires a tensor with at least 1 dimension, "
|
|
"but got a tensor with 0 dimensions!")
|
|
yield ErrorInput(SampleInput(make_arg(()), 0), error_regex=err_msg1)
|
|
|
|
err_msg2 = (f"torch.hsplit attempted to split along dimension 1, "
|
|
f"but the size of the dimension {S} "
|
|
f"is not divisible by the split_size 0!")
|
|
yield ErrorInput(SampleInput(make_arg((S, S, S)), 0), error_regex=err_msg2)
|
|
|
|
# Incorrect type for indices_or_section argument
|
|
err_msg3 = ("received an invalid combination of arguments.")
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((S, S, S)), "abc"),
|
|
error_type=TypeError, error_regex=err_msg3)
|
|
|
|
def error_inputs_vsplit(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=torch.float32, device=device)
|
|
err_msg1 = ("torch.vsplit requires a tensor with at least 2 dimension, "
|
|
"but got a tensor with 1 dimensions!")
|
|
yield ErrorInput(SampleInput(make_arg(S), 0), error_regex=err_msg1)
|
|
|
|
err_msg2 = (f"torch.vsplit attempted to split along dimension 0, "
|
|
f"but the size of the dimension {S} "
|
|
f"is not divisible by the split_size 0!")
|
|
yield ErrorInput(SampleInput(make_arg(S, S, S), 0),
|
|
error_regex=err_msg2)
|
|
|
|
# Incorrect type for indices_or_section argument
|
|
err_msg3 = ("received an invalid combination of arguments.")
|
|
yield ErrorInput(SampleInput(make_arg(S, S, S), "abc"),
|
|
error_type=TypeError, error_regex=err_msg3)
|
|
|
|
def error_inputs_dsplit(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=torch.float32, device=device)
|
|
err_msg1 = ("torch.dsplit requires a tensor with at least 3 dimension, "
|
|
"but got a tensor with 1 dimensions!")
|
|
yield ErrorInput(SampleInput(make_arg(S), 0), error_regex=err_msg1)
|
|
|
|
err_msg2 = (f"torch.dsplit attempted to split along dimension 2, "
|
|
f"but the size of the dimension {S} "
|
|
f"is not divisible by the split_size 0!")
|
|
yield ErrorInput(SampleInput(make_arg(S, S, S), 0), error_regex=err_msg2)
|
|
|
|
|
|
def sample_inputs_as_strided(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# input shape, output shape, output stride, output storage offset
|
|
test_cases = (
|
|
((1,), (1,), (1,), 0),
|
|
((3, 3), (2, 2), (1, 2), 0),
|
|
((3, 3), (2, 2), (1, 2), 1),
|
|
((16,), (2, 2, 2, 2), (1, 1, 1, 1), 0),
|
|
((16,), (2, 1, 1, 2), (1, 7, 7, 1), 0),
|
|
)
|
|
|
|
for input_shape, output_shape, stride, storage_offset in test_cases:
|
|
input_t = make_arg(input_shape)
|
|
kwargs = dict(storage_offset=storage_offset)
|
|
yield SampleInput(input_t, args=(output_shape, stride), kwargs=kwargs)
|
|
|
|
def sample_inputs_as_strided_partial_views(op_info, device, dtype, requires_grad, **kwargs):
|
|
def make_arg():
|
|
base = make_tensor((20,), device=device, dtype=dtype)
|
|
return base[5:15].requires_grad_(requires_grad)
|
|
|
|
# as_strided on offset, partial views
|
|
yield SampleInput(make_arg(), (2, 2), (1, 2))
|
|
yield SampleInput(make_arg(), (2, 2), (1, 2), storage_offset=0)
|
|
yield SampleInput(make_arg(), (2, 2), (1, 2), storage_offset=10)
|
|
|
|
def sample_inputs_as_strided_scatter(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# input shape, output shape, output stride, output storage offset
|
|
test_cases = [
|
|
((1,), (), (), 0),
|
|
((1,), (1,), (1,), 0),
|
|
((3, 3), (2, 2), (1, 2), 0),
|
|
((3, 3), (2, 2), (1, 2), 1),
|
|
((3, 3), (2, 2), (2, 1), 0),
|
|
# Scatter to larger dimensions
|
|
((16,), (2, 2, 2, 2), (8, 4, 2, 1), 0),
|
|
# Scatter to larger dimensions with strides inverted
|
|
((16,), (2, 1, 1, 2), (1, 2, 4, 8), 0),
|
|
]
|
|
|
|
for input_shape, output_shape, stride, storage_offset in test_cases:
|
|
input_t = make_arg(input_shape)
|
|
input_src = make_arg(output_shape)
|
|
yield SampleInput(input_t, input_src, output_shape, stride, storage_offset=storage_offset)
|
|
|
|
|
|
def error_inputs_as_strided_scatter(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32, requires_grad=False)
|
|
|
|
# Create a small tensor and try to scatter it out of bounds
|
|
input_t = make_arg([4, 4])
|
|
input_src = make_arg([2, 2])
|
|
yield ErrorInput(
|
|
SampleInput(input_t, input_src, [2, 2], [200, 200], storage_offset=0),
|
|
error_regex="itemsize 4 requiring a storage size of 1604 are out of bounds for storage of size 64"
|
|
)
|
|
|
|
|
|
def sample_inputs_combinations(op_info, device, dtype, requires_grad, **kwargs):
|
|
inputs = (
|
|
(0,),
|
|
(0, 1),
|
|
(0, 1, 2, 3),
|
|
)
|
|
|
|
rvals = [1, 2, 4]
|
|
|
|
products = product(inputs, rvals, [False, True])
|
|
|
|
for input_data, r, with_replacement in products:
|
|
input_t = torch.tensor(input_data, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(input_t, r=r, with_replacement=with_replacement)
|
|
|
|
def sample_inputs_cartesian_prod(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(torch.tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# constructs 1-D tensors with varying number of elements
|
|
a = make_arg((0,))
|
|
b = make_arg((0, 1))
|
|
c = make_arg((0, 1, 2, 3))
|
|
|
|
# sample with only 1 tensor
|
|
yield SampleInput(a)
|
|
|
|
# sample with 2 tensors
|
|
yield SampleInput(a, b)
|
|
|
|
# sample with 3 tensors
|
|
yield SampleInput(a, b, c)
|
|
|
|
def sample_inputs_cosine_similarity(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as input_shape, dict of dim and eps
|
|
cases: Tuple[tuple, dict] = ( # type: ignore[assignment]
|
|
((S, S), {'dim': 1}),
|
|
((S, 2), {'dim': -1}),
|
|
((S,), {'dim': 0, 'eps': 0.5}),
|
|
((), {'dim': 0}),
|
|
((S, S, M), {'dim': 2}),
|
|
((S, S), {})
|
|
)
|
|
|
|
for input_shape, kwargs in cases:
|
|
yield SampleInput(make_arg(input_shape), args=(make_arg(input_shape),), kwargs=kwargs)
|
|
# Test for Broadcasting
|
|
yield SampleInput(make_arg((1, 2, 3)), args=(make_arg((2, 1, 3)),), kwargs={'dim': -1})
|
|
yield SampleInput(make_arg((1, 2, 3)), args=(make_arg((2, 1, 3)),), kwargs={'dim': -2})
|
|
yield SampleInput(make_arg((2, 3)), args=(make_arg((2, 1, 3)),), kwargs={'dim': -1})
|
|
|
|
|
|
def sample_inputs_item(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
|
|
cases = (
|
|
(),
|
|
(()),
|
|
(1),
|
|
((1,)),
|
|
)
|
|
|
|
for shape in cases:
|
|
yield SampleInput(make_arg(shape))
|
|
|
|
def error_inputs_item(op, device, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=torch.float32, device=device, requires_grad=False)
|
|
|
|
cases = (
|
|
(M),
|
|
((S,)),
|
|
(S, S),
|
|
(S, M, L),
|
|
)
|
|
|
|
for shape in cases:
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(shape)), error_type=RuntimeError,
|
|
error_regex="elements cannot be converted to Scalar")
|
|
|
|
|
|
def sample_inputs_batch_norm(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_arg_without_requires_grad = partial(make_tensor, device=device, dtype=dtype, requires_grad=False)
|
|
|
|
# Ordered as: input shape, kwargs for training, momentum, eps
|
|
cases: Tuple[Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((S, S, S), {'training': True, 'momentum': 0.5, 'eps': 0.6}),
|
|
((3, 2, 4), {'training': False, 'momentum': -1.2}),
|
|
((3, 1), {'training': True, 'momentum': 0.0}),
|
|
((0,), {'training': True}),
|
|
((0,), {'training': False}),
|
|
((3, 2, 3, 4), {'training': True, 'momentum': -1.0, 'eps': 0.5}),
|
|
((3, 2, 3, 4), {'training': False, 'momentum': -1.0, 'eps': 0.5}),
|
|
((2, 1), {}),
|
|
)
|
|
|
|
for input_shape, kwargs in cases:
|
|
# args: running mean, running var, weight and bias should necessarily be of shape: (channels,)
|
|
channels = input_shape[1] if len(input_shape) > 1 else 0
|
|
weight = make_arg(channels) if channels > 0 else None
|
|
bias = make_arg(channels) if channels > 0 else None
|
|
running_mean = make_arg_without_requires_grad(channels, low=0)
|
|
running_var = make_arg_without_requires_grad(channels, low=0)
|
|
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(
|
|
running_mean,
|
|
running_var,
|
|
weight,
|
|
bias
|
|
),
|
|
kwargs=kwargs
|
|
)
|
|
|
|
# Checking for permutations of weights and biases as `None`
|
|
weights = [channels, None, None]
|
|
biases = [None, channels, None]
|
|
is_training = [True, False, False]
|
|
|
|
for weight, bias, training in zip(weights, biases, is_training):
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(
|
|
running_mean,
|
|
running_var,
|
|
make_arg(channels),
|
|
make_arg(channels)
|
|
),
|
|
kwargs={'training': training}
|
|
)
|
|
|
|
# Test case for no optional kwargs
|
|
# running_mean and running_var are required in evaluation mode (training: False) but not in training mode
|
|
yield SampleInput(make_arg((1, 2, 3)), args=(None, None, None, None), kwargs={'training': True})
|
|
|
|
def sample_inputs_softmax_backward_data(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(
|
|
make_tensor, device=device, dtype=dtype, requires_grad=requires_grad
|
|
)
|
|
cases = [
|
|
((S,), 0),
|
|
((S, S), 0),
|
|
((S, M, S), -1),
|
|
]
|
|
input_dtypes = [dtype]
|
|
if dtype == torch.float and device == 'cuda':
|
|
input_dtypes += [torch.float16]
|
|
|
|
for (shape, dim), input_dtype in product(cases, input_dtypes):
|
|
input = make_arg(shape)
|
|
output = torch.nn.functional.softmax(input, dim=dim, dtype=input_dtype)
|
|
yield SampleInput(make_arg(shape), output, dim, input_dtype)
|
|
|
|
def sample_inputs_native_batch_norm(op_info, device, dtype, requires_grad, **kwargs):
|
|
samples = sample_inputs_batch_norm(op_info, device, dtype, requires_grad, **kwargs)
|
|
for sample in samples:
|
|
# torch.native_batch_norm does not support 0 numel tensors
|
|
# IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
|
|
if sample.input.numel() == 0:
|
|
continue
|
|
args = sample.args
|
|
training = sample.kwargs.get('training', True)
|
|
momentum = sample.kwargs.get('momentum', 0.5)
|
|
eps = sample.kwargs.get('eps', 1e-5)
|
|
yield SampleInput(sample.input, args=(args[2], args[3], args[0], args[1], training, momentum, eps))
|
|
|
|
|
|
def sample_inputs__native_batch_norm_legit(op_info, device, dtype, requires_grad, **kwargs):
|
|
samples = sample_inputs_batch_norm(op_info, device, dtype, requires_grad, **kwargs)
|
|
for sample in samples:
|
|
# torch.native_batch_norm does not support 0 numel tensors
|
|
# IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
|
|
if sample.input.numel() == 0:
|
|
continue
|
|
args = sample.args
|
|
training = sample.kwargs.get('training', True)
|
|
momentum = sample.kwargs.get('momentum', 0.5)
|
|
eps = sample.kwargs.get('eps', 1e-5)
|
|
if args[0] is not None and args[1] is not None:
|
|
yield SampleInput(sample.input, args=(args[2], args[3], args[0], args[1], training, momentum, eps))
|
|
else:
|
|
yield SampleInput(sample.input, args=(args[2], args[3], training, momentum, eps))
|
|
|
|
def sample_inputs__batch_norm_with_update(op_info, device, dtype, requires_grad, **kwargs):
|
|
samples = sample_inputs_batch_norm(op_info, device, dtype, requires_grad, **kwargs)
|
|
for sample in samples:
|
|
# torch.native_batch_norm does not support 0 numel tensors
|
|
# IndexError: Dimension out of range (expected to be in range of [-1, 0], but got 1)
|
|
if sample.input.numel() == 0:
|
|
continue
|
|
args = sample.args
|
|
momentum = sample.kwargs.get('momentum', 0.5)
|
|
eps = sample.kwargs.get('eps', 1e-5)
|
|
if any(args[i] is None for i in range(4)):
|
|
continue
|
|
yield SampleInput(sample.input, args=(args[2], args[3], args[0], args[1], momentum, eps))
|
|
|
|
def sample_inputs_nn_activation_relu(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
(()),
|
|
((S, )),
|
|
((S, S)),
|
|
((S, M, S))
|
|
)
|
|
|
|
for shape in cases:
|
|
yield SampleInput(make_arg(shape))
|
|
|
|
def sample_inputs_prelu(op_info, device, dtype, requires_grad, **kwargs):
|
|
op_kwargs = op_info.sample_kwargs(device, dtype, None)[0]
|
|
yield from sample_inputs_elementwise_unary(op_info, device, dtype, requires_grad,
|
|
op_kwargs=op_kwargs)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
(()),
|
|
((S, )),
|
|
((S, S)),
|
|
((S, M, S))
|
|
)
|
|
|
|
for shape in cases:
|
|
for weight in [-1., 0., 0.8, 1.]:
|
|
weight_tensor = torch.tensor(weight, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(shape), args=(weight_tensor,))
|
|
|
|
channel_size = shape[1] if len(shape) >= 2 else 1
|
|
yield SampleInput(make_arg(shape), args=(make_arg((channel_size,)),))
|
|
|
|
weight_tensor = torch.tensor(1., device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, S)), kwargs=dict(weight=weight_tensor,))
|
|
yield SampleInput(make_arg((S, S)), kwargs=dict(weight=make_arg((S,)),))
|
|
|
|
def reference_inputs_prelu(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_prelu(op, device, dtype, requires_grad, **kwargs)
|
|
yield from reference_inputs_elementwise_unary(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
def sample_kwargs_prelu_scalar_weight(device, dtype, input):
|
|
weight = torch.rand((), device=device, dtype=dtype)
|
|
# NumPy does not support bfloat16, so we default to float32 (only for NumPy) in that case
|
|
if dtype == torch.bfloat16:
|
|
weight_cpu = weight.to(dtype=torch.float32, device="cpu")
|
|
else:
|
|
weight_cpu = weight.cpu()
|
|
np_weight = weight_cpu.numpy()
|
|
return ({'weight': weight}, {'weight': np_weight})
|
|
|
|
def error_inputs_prelu(op, device):
|
|
# Weight has numel != 1, but self.ndim is zero-dim tensor
|
|
inp = make_tensor((), device=device, dtype=torch.float32)
|
|
weight = make_tensor((2,), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(inp, kwargs={'weight': weight}),
|
|
error_regex="Not allow zero-dim input tensor.")
|
|
|
|
# Weight has numel != 1, but numel does not match channel size
|
|
inp = make_tensor((2, 8, 3), device=device, dtype=torch.float32)
|
|
weight = make_tensor((9,), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(inp, kwargs={'weight': weight}),
|
|
error_regex="Mismatch of parameter numbers and input channel size.")
|
|
|
|
# Weight is neither a scalar nor 1-D tensor
|
|
inp = make_tensor((2, 8, 3), device=device, dtype=torch.float32)
|
|
weight = make_tensor((2, 4), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(inp, kwargs={'weight': weight}),
|
|
error_regex="prelu: Expected `weight` to be a scalar or 1D tensor, but got: ndim = 2")
|
|
|
|
# src and index tensors must have the same # of dimensions
|
|
def sample_inputs_norm(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# ord = inf is tested in inputs_norm_inf as it fails on some tests
|
|
cases = [
|
|
((S, S), (2,), '2'),
|
|
((S, S), (0,), '0'),
|
|
((S, S), (0.5,), '0_5'),
|
|
((S, S), (1,), '1'),
|
|
((S, S), (3,), '3'),
|
|
((S, S), (-1,), 'neg_1'),
|
|
((S, S), (-2,), 'neg_2'),
|
|
((S, S), (-0.5,), 'neg_0_5'),
|
|
((S, S), (-1.5,), 'neg_1_5'),
|
|
]
|
|
|
|
cases_nonzero_input = (
|
|
((S, S, S), (1.5,), '1_5_default'),
|
|
((S, S, S), (1.5, 1), '1_5_dim'),
|
|
((S, S, S), (1.5, -1), '1_5_neg_dim'),
|
|
((S, S, S), (1.5, 1, True), 'keepdim_1_5_dim'),
|
|
((S, S, S), (1.5, -1, True), 'keepdim_1_5_neg_dim'),
|
|
)
|
|
|
|
cases_posdim = (
|
|
((S, S), (-2, 1,), 'neg_2_dim'),
|
|
((S, S), (-1, 1,), 'neg_1_dim'),
|
|
((S, S), (0, 1,), '0_dim'),
|
|
((S, S), (1, 1,), '1_dim'),
|
|
((S, S), (2, 1,), '2_dim'),
|
|
((S, S), (3, 1,), '3_dim'),
|
|
((S, S, S), (2, 1), '2_dim'),
|
|
((S, S, S), (3, 1), '3_dim'),
|
|
((S, S, S), (2, 1, True), 'keepdim_2_dim'),
|
|
((S, S, S), (3, 1, True), 'keepdim_3_dim'),
|
|
((), (2, 0), '2_dim_scalar'),
|
|
((), (3, 0), '3_dim_scalar'),
|
|
((), (2, 0, True), 'keepdim_2_dim_scalar'),
|
|
((), (3, 0, True), 'keepdim_3_dim_scalar'),
|
|
)
|
|
|
|
cases_negdim = ((shape, args[:1] + (-args[1],) + args[2:], name.replace("_dim", "_neg_dim"))
|
|
for shape, args, name in cases_posdim)
|
|
|
|
for shape, args, name in itertools.chain(cases, cases_posdim, cases_negdim):
|
|
yield SampleInput(make_arg(shape), args=args, name=name)
|
|
|
|
for shape, args, name in cases_nonzero_input:
|
|
yield SampleInput(make_arg(shape, exclude_zero=True), args=args, name=name)
|
|
|
|
|
|
def sample_inputs_norm_fro(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
((S, S), (), 'default'),
|
|
((S, S), ('fro',), 'fro_default'),
|
|
((S, S), ('fro', [0, 1],), 'fro'),
|
|
)
|
|
|
|
for shape, args, name in cases:
|
|
yield SampleInput(make_arg(shape), args=args, name=name)
|
|
|
|
|
|
def sample_inputs_norm_nuc(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
((S, S), ('nuc',), 'nuc'),
|
|
((S, S, S), ('nuc', [1, 2]), 'nuc_batched'),
|
|
)
|
|
|
|
for shape, args, name in cases:
|
|
yield SampleInput(make_arg(shape), args=args, name=name)
|
|
|
|
|
|
def sample_inputs_norm_inf(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
((S, S), (-inf,), '-inf'),
|
|
((S, S), (inf,), 'inf'),
|
|
((S, S), (inf, 1,), 'inf_2_dim'),
|
|
((S, S), (inf, -1,), 'inf_2_neg_dim'),
|
|
)
|
|
|
|
for shape, args, name in cases:
|
|
yield SampleInput(make_arg(shape), args=args, name=name)
|
|
|
|
|
|
def sample_inputs_equal(op, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(
|
|
make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shapes = (
|
|
((), ()),
|
|
((S,), ()),
|
|
((), (S,)),
|
|
((S, 1), (S,)),
|
|
((M, S), ()),
|
|
((S, S), (S, S))
|
|
)
|
|
|
|
for shape_lhs, shape_rhs in shapes:
|
|
lhs = make_arg(shape_lhs)
|
|
rhs = make_arg(shape_rhs)
|
|
broadcasts_input = shape_lhs != torch.broadcast_shapes(shape_lhs, shape_rhs)
|
|
|
|
yield SampleInput(lhs, args=(rhs,), broadcasts_input=broadcasts_input)
|
|
if shape_lhs == shape_rhs:
|
|
yield SampleInput(lhs, args=(lhs.clone().detach_(),))
|
|
|
|
|
|
def sample_inputs_jiterator(op, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shapes = (
|
|
((), ()),
|
|
((S,), ()),
|
|
((S, 1), (S,)),
|
|
((M, S), ()),
|
|
((S, M, S), (M, S)),
|
|
((S, M, S), (S, M, S)),
|
|
((M, 1, S), (M, S)),
|
|
((M, 1, S), (1, M, S)),
|
|
((0, 1, 3), (0, 10, 3))
|
|
)
|
|
|
|
num_inputs = kwargs.get('num_inputs')
|
|
sample_kwargs = kwargs.get('sample_kwargs', {})
|
|
|
|
for shape_lhs, shape_rhs in shapes:
|
|
lhs = make_arg(shape_lhs)
|
|
args = [make_arg(shape_rhs) for _ in range(num_inputs - 1)]
|
|
broadcasts_input = (shape_lhs != torch.broadcast_shapes(shape_lhs, shape_rhs))
|
|
|
|
yield SampleInput(lhs, args=tuple(args), kwargs=sample_kwargs, broadcasts_input=broadcasts_input)
|
|
|
|
def sample_inputs_broadcast_shapes(op, device, dtype, requires_grad, **kwargs):
|
|
shapes = (
|
|
((), ()),
|
|
((S,), ()),
|
|
((S, 1), (S,)),
|
|
((S, 1), S),
|
|
((M, S), ()),
|
|
((S, M, S), (M, S)),
|
|
((S, M, S), (S, M, S)),
|
|
((M, 1, S), (M, S)),
|
|
((M, 1, S), (1, M, S)),
|
|
((0, 1, 3), (0, 10, 3))
|
|
)
|
|
|
|
for shape in shapes:
|
|
inp, *arg0 = shape
|
|
yield SampleInput(inp, args=tuple(arg0))
|
|
|
|
def sample_inputs_add_sub(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_elementwise_binary(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
# Adds alpha kwarg cases
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
lhs = make_arg((S, S), **op.lhs_make_tensor_kwargs)
|
|
rhs = make_arg((S, S), **op.rhs_make_tensor_kwargs)
|
|
if dtype is not torch.bool:
|
|
yield SampleInput(lhs, args=(rhs,), kwargs={'alpha': 2})
|
|
else:
|
|
yield SampleInput(lhs, args=(rhs,), kwargs={'alpha': True})
|
|
neg_alpha = -3.125 if (dtype.is_floating_point or dtype.is_complex) else -3
|
|
lhs = make_arg((S, S), **op.lhs_make_tensor_kwargs)
|
|
rhs = make_arg((S, S), **op.rhs_make_tensor_kwargs)
|
|
if dtype is not torch.bool:
|
|
yield SampleInput(lhs, args=(rhs,), kwargs={'alpha': neg_alpha})
|
|
else:
|
|
yield SampleInput(lhs, args=(rhs,), kwargs={'alpha': False})
|
|
|
|
def error_inputs_arange(op, device, **kwargs):
|
|
yield ErrorInput(SampleInput(0, args=(3, 0)), error_type=RuntimeError, error_regex='step must be nonzer')
|
|
yield ErrorInput(SampleInput(0, args=(-3, 2)), error_type=RuntimeError, error_regex='bound inconsistent with step sign')
|
|
yield ErrorInput(SampleInput(0, args=(3, -2)), error_type=RuntimeError, error_regex='bound inconsistent with step sign')
|
|
yield ErrorInput(SampleInput(0, args=(float('inf'), 2)), error_type=RuntimeError, error_regex='unsupported range')
|
|
yield ErrorInput(SampleInput(float('-inf'), args=(1, 2)), error_type=RuntimeError, error_regex='unsupported range')
|
|
|
|
def sample_inputs_arange(op, device, dtype, requires_grad, **kwargs):
|
|
int_samples = (
|
|
# positive direction
|
|
(-1, 2, 2),
|
|
# negative direction
|
|
(2, -3, -1),
|
|
# start == end
|
|
(1, 1, 1),
|
|
(1, 1, -1),
|
|
# divides evenly
|
|
(0, -8, -4),
|
|
(1, 5, 2),
|
|
# bool
|
|
(False, True, True),
|
|
# default step
|
|
(0, 1, None),
|
|
# default start
|
|
(None, 3, None),
|
|
)
|
|
|
|
def to_float(start, end, step):
|
|
start = start + 0.1 if start is not None else None
|
|
end = end + 0.1
|
|
step = float(step) if step is not None else None
|
|
return start, end, step
|
|
|
|
float_samples = (
|
|
# includes endpoint
|
|
(0., -8. - 1e-6, -4.),
|
|
(1., 5. + 1e-6, 2.),
|
|
(0., -8., -4.),
|
|
(1., 5., 2.),
|
|
*(to_float(start, end, step) for (start, end, step) in int_samples),
|
|
)
|
|
|
|
large_samples = (
|
|
(0, 10000, None),
|
|
)
|
|
|
|
samples = int_samples + float_samples
|
|
if dtype not in (torch.int8, torch.uint8):
|
|
samples += large_samples
|
|
|
|
for start, end, step in samples:
|
|
if start is None:
|
|
assert step is None
|
|
# Pass end as positional arg
|
|
yield SampleInput(end, kwargs={"dtype": dtype, "device": device})
|
|
# (Similar to) calling torch.arange(end=3)
|
|
yield SampleInput(0, kwargs={"end": end, "dtype": dtype, "device": device})
|
|
elif step is None:
|
|
yield SampleInput(start, args=(end,), kwargs={"dtype": dtype, "device": device})
|
|
else:
|
|
yield SampleInput(start, args=(end, step), kwargs={"dtype": dtype, "device": device})
|
|
|
|
yield SampleInput(2)
|
|
yield SampleInput(1, args=(3, 1))
|
|
|
|
def sample_inputs_randn(op, device, dtype, requires_grad, **kwargs):
|
|
shapes = (
|
|
(M,),
|
|
(S, S)
|
|
)
|
|
|
|
for shape in shapes:
|
|
yield SampleInput(input=shape, kwargs=dict(dtype=dtype, device=device, requires_grad=requires_grad))
|
|
|
|
def sample_inputs_normal(op, device, dtype, requires_grad, **kwargs):
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
samples = (
|
|
((S, S), 0, 5),
|
|
((S, S, S), -2, 0.5),
|
|
)
|
|
for shape, mean, std in samples:
|
|
yield SampleInput(make_arg(shape), args=(mean, std))
|
|
|
|
def error_inputs_normal(op, device, **kwargs):
|
|
t = torch.zeros([10], device=device)
|
|
invalid_std = -1
|
|
yield ErrorInput(
|
|
SampleInput(t, args=(0, invalid_std)),
|
|
error_type=RuntimeError,
|
|
error_regex=fr"normal expects std >= 0.0, but found std {invalid_std}",
|
|
)
|
|
|
|
def sample_inputs_cauchy(op, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
samples = (
|
|
((M,), 0, 0.5),
|
|
((S, S), 0, 1),
|
|
((S, S, S), -2, 1),
|
|
)
|
|
for shape, median, gamma in samples:
|
|
yield SampleInput(make_arg(shape), args=(median, gamma))
|
|
|
|
|
|
def error_inputs_cauchy(op, device, **kwargs):
|
|
t = torch.zeros([10], device=device)
|
|
invalid_scale = 0
|
|
yield ErrorInput(
|
|
SampleInput(t, args=(0, invalid_scale,)),
|
|
error_type=RuntimeError,
|
|
error_regex=fr"cauchy_ expects sigma > 0.0, but found sigma={invalid_scale}",
|
|
)
|
|
|
|
|
|
def sample_inputs_exponential(op, device, dtype, requires_grad, **kwargs):
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
samples = (
|
|
((M,), 0.5),
|
|
((S, S), 1),
|
|
((S, S, S), 1.5),
|
|
)
|
|
for shape, rate in samples:
|
|
yield SampleInput(make_arg(shape), args=(rate,))
|
|
|
|
|
|
def error_inputs_exponential(op, device, **kwargs):
|
|
t = torch.zeros([10], device=device)
|
|
invalid_rate = 0
|
|
yield ErrorInput(
|
|
SampleInput(t, args=(invalid_rate,)),
|
|
error_type=RuntimeError,
|
|
error_regex=fr"exponential_ expects lambda > 0.0, but found lambda={invalid_rate}",
|
|
)
|
|
|
|
|
|
def sample_inputs_geometric(op, device, dtype, requires_grad, **kwargs):
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
samples = (
|
|
((M,), 0.2),
|
|
((S, S), 0.5),
|
|
((S, S, S), 0.8),
|
|
)
|
|
for shape, rate in samples:
|
|
yield SampleInput(make_arg(shape), args=(rate,))
|
|
|
|
|
|
def error_inputs_geometric(op, device, **kwargs):
|
|
t = torch.zeros([10], device=device)
|
|
neg_prob = -1
|
|
yield ErrorInput(
|
|
SampleInput(t, args=(neg_prob,)),
|
|
error_type=RuntimeError,
|
|
error_regex=fr"geometric_ expects p to be in \(0, 1\), but got p={neg_prob}",
|
|
)
|
|
|
|
|
|
def sample_inputs_log_normal(op, device, dtype, requires_grad, **kwargs):
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
samples = (
|
|
((M,), 0, 0.25),
|
|
((S, S), 0.5, 1),
|
|
((S, S, S), 0, 0.5),
|
|
)
|
|
for shape, mean, std in samples:
|
|
yield SampleInput(make_arg(shape), args=(mean, std))
|
|
|
|
|
|
def error_inputs_log_normal(op, device, **kwargs):
|
|
t = torch.zeros([10], device=device)
|
|
invalid_std = 0
|
|
yield ErrorInput(
|
|
SampleInput(t, args=(0, invalid_std)),
|
|
error_type=RuntimeError,
|
|
error_regex=fr"log_normal_ expects std > 0.0, but found std={invalid_std}",
|
|
)
|
|
|
|
|
|
def sample_inputs_uniform(op, device, dtype, requires_grad, **kwargs):
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=False)
|
|
samples = (
|
|
((M,), -100, 100),
|
|
((S, S), 0, 1),
|
|
((S, S, S), 1, 2),
|
|
)
|
|
for shape, hi, lo in samples:
|
|
yield SampleInput(make_arg(shape), args=(hi, lo))
|
|
|
|
def sample_inputs_ones_zeros(op, device, dtype, requires_grad, **kwargs):
|
|
# this is a bit messy, as we want the args to be tuples
|
|
# so if we pass size as a tuple, we have a tuple containing a tuple
|
|
sizes = (
|
|
(M,),
|
|
(S, S),
|
|
)
|
|
for size in sizes:
|
|
yield SampleInput(size, kwargs={'dtype': dtype, 'device': device})
|
|
|
|
def sample_inputs_full(op, device, dtype, requires_grad, **kwargs):
|
|
def get_val(dtype):
|
|
return make_tensor([], dtype=dtype, device="cpu").item()
|
|
|
|
sizes = (
|
|
(M,),
|
|
(S, S),
|
|
)
|
|
fill_values = [get_val(dtype), get_val(torch.int)]
|
|
|
|
for size, fill_value in product(sizes, fill_values):
|
|
yield SampleInput(size, fill_value, dtype=dtype, device=device)
|
|
|
|
|
|
def error_inputs_uniform(op, device, **kwargs):
|
|
t = torch.zeros([10], device=device)
|
|
yield ErrorInput(
|
|
SampleInput(t, args=(3, -1)),
|
|
error_type=RuntimeError,
|
|
error_regex=r"uniform_ expects to return a \[from, to\) range, but found from=3 > to=-1",
|
|
)
|
|
|
|
|
|
def error_inputs_linspace(op, device, **kwargs):
|
|
yield ErrorInput(SampleInput(0, args=(3, -1)), error_type=RuntimeError, error_regex='number of steps must be non-negative')
|
|
yield ErrorInput(
|
|
SampleInput(0, args=(3, 1.)),
|
|
error_type=TypeError,
|
|
error_regex="received an invalid combination of arguments - got \\(int, int, float",
|
|
)
|
|
yield ErrorInput(
|
|
SampleInput(torch.tensor([1, 1], device=device), args=(torch.tensor([3, 3], device=device), 1)),
|
|
error_type=RuntimeError,
|
|
error_regex="only supports 0-dimensional start and end tensors"
|
|
)
|
|
|
|
|
|
def sample_inputs_linspace(op, device, dtype, requires_grad, **kwargs):
|
|
ends = (-3, 0, 1, 4, 50)
|
|
starts = (-2., 0, 4.3, 50)
|
|
nsteps = (0, 1, 50)
|
|
# Extra case to replicate off-by-one issue on CUDA
|
|
cases = list(product(starts, ends, nsteps)) + [(0, 7, 50)]
|
|
for start, end, nstep in cases:
|
|
if dtype == torch.uint8 and (end < 0 or start < 0):
|
|
continue
|
|
yield SampleInput(start, args=(end, nstep), kwargs={"dtype": dtype, "device": device})
|
|
|
|
yield SampleInput(1, args=(3, 1))
|
|
|
|
|
|
def sample_inputs_linspace_tensor_overload(op, device, dtype, requires_grad, **kwargs):
|
|
ends = (-3, 0, 1, 4, 50)
|
|
starts = (-2., 0, 4.3, 50)
|
|
nsteps = (0, 1, 50)
|
|
is_start_end_tensors = ((True, True), (True, False), (False, True))
|
|
make_arg = partial(torch.tensor, device=device, requires_grad=False)
|
|
|
|
# Extra case to replicate off-by-one issue on CUDA
|
|
cases = list(product(starts, ends, nsteps, is_start_end_tensors)) + [(0, 7, 50, (True, True))]
|
|
for start, end, nstep, (is_start_tensor, is_end_tensor) in cases:
|
|
if dtype == torch.uint8 and (end < 0 or start < 0):
|
|
continue
|
|
|
|
tensor_options = {"dtype": dtype, "device": device}
|
|
if is_start_tensor:
|
|
start = make_arg(start, dtype=torch.float32 if isinstance(start, float) else torch.int64)
|
|
if is_end_tensor:
|
|
end = make_arg(end, dtype=torch.float32 if isinstance(end, float) else torch.int64)
|
|
|
|
yield SampleInput(start, args=(end, nstep), kwargs=tensor_options)
|
|
|
|
yield SampleInput(1, args=(3, 1))
|
|
|
|
|
|
def sample_inputs_logspace(op, device, dtype, requires_grad, **kwargs):
|
|
ends = (-3, 0, 1.2, 2, 4)
|
|
starts = (-2., 0, 1, 2, 4.3)
|
|
nsteps = (0, 1, 2, 4)
|
|
bases = (2., 1.1) if dtype in (torch.int8, torch.uint8) else (None, 2., 3., 1.1, 5.)
|
|
for start, end, nstep, base in product(starts, ends, nsteps, bases):
|
|
if dtype == torch.uint8 and end < 0 or start < 0:
|
|
continue
|
|
if nstep == 1 and isinstance(start, float) and not (dtype.is_complex or dtype.is_floating_point):
|
|
# https://github.com/pytorch/pytorch/issues/82242
|
|
continue
|
|
if base is None:
|
|
yield SampleInput(start, args=(end, nstep), kwargs={"dtype": dtype, "device": device})
|
|
else:
|
|
yield SampleInput(start, args=(end, nstep, base), kwargs={"dtype": dtype, "device": device})
|
|
|
|
yield SampleInput(1, args=(3, 1, 2.))
|
|
|
|
|
|
def sample_inputs_logspace_tensor_overload(op, device, dtype, requires_grad, **kwargs):
|
|
ends = (-3, 0, 1.2, 2, 4)
|
|
starts = (-2., 0, 1, 2, 4.3)
|
|
nsteps = (0, 1, 2, 4)
|
|
bases = (2., 1.1) if dtype in (torch.int8, torch.uint8) else (None, 2., 3., 1.1, 5.)
|
|
is_start_end_tensors = ((True, True), (True, False), (False, True))
|
|
make_arg = partial(torch.tensor, device=device)
|
|
for start, end, nstep, base, (is_start_tensor, is_end_tensor) in product(starts, ends, nsteps, bases, is_start_end_tensors):
|
|
if dtype == torch.uint8 and end < 0 or start < 0:
|
|
continue
|
|
if nstep == 1 and isinstance(start, float) and not (dtype.is_complex or dtype.is_floating_point):
|
|
# https://github.com/pytorch/pytorch/issues/82242
|
|
continue
|
|
|
|
tensor_options = {"dtype": dtype, "device": device}
|
|
|
|
if (is_start_tensor):
|
|
start = make_arg(start, dtype=torch.float32 if isinstance(start, float) else torch.int64)
|
|
if (is_end_tensor):
|
|
end = make_arg(end, dtype=torch.float32 if isinstance(end, float) else torch.int64)
|
|
|
|
if base is None:
|
|
yield SampleInput(start, args=(end, nstep), kwargs=tensor_options)
|
|
else:
|
|
yield SampleInput(start, args=(end, nstep, base), kwargs=tensor_options)
|
|
|
|
yield SampleInput(1, args=(3, 1, 2.))
|
|
|
|
|
|
def sample_inputs_isclose(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_elementwise_binary(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
# Creates additional inputs to test the rtol, atol, and equal_nan params
|
|
rtols = [0., 1e-7]
|
|
atols = [0., 1e-7]
|
|
equal_nans = [False, True]
|
|
|
|
products = product(rtols, atols, equal_nans)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
for rtol, atol, equal_nan in products:
|
|
lhs = make_arg((S, S), **op.lhs_make_tensor_kwargs)
|
|
rhs = make_arg((S, S), **op.rhs_make_tensor_kwargs)
|
|
|
|
yield SampleInput(lhs, args=(rhs,),
|
|
kwargs=dict(rtol=rtol, atol=atol, equal_nan=equal_nan))
|
|
|
|
|
|
def error_inputs_isclose(op, device, **kwargs):
|
|
make_float_arg = partial(make_tensor, device=device, dtype=torch.float, requires_grad=False)
|
|
|
|
yield ErrorInput(SampleInput(make_float_arg(()), args=(make_float_arg(()),), kwargs={'rtol': -0.4}),
|
|
error_type=RuntimeError,
|
|
error_regex='rtol must be greater than or equal to zero')
|
|
|
|
yield ErrorInput(SampleInput(make_float_arg(()), args=(make_float_arg(()),), kwargs={'atol': -0.4}),
|
|
error_type=RuntimeError,
|
|
error_regex='atol must be greater than or equal to zero')
|
|
|
|
|
|
def sample_inputs_t(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg((1, 2)))
|
|
yield SampleInput(make_arg((2,)))
|
|
yield SampleInput(make_arg(()))
|
|
|
|
|
|
def sample_inputs_mm(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_arg_conj(size):
|
|
return make_arg(size).conj().requires_grad_(requires_grad)
|
|
|
|
first_shape, second_shape = (S, M), (M, S)
|
|
|
|
yield SampleInput(make_arg(first_shape), args=(make_arg(second_shape),))
|
|
|
|
if dtype.is_complex:
|
|
yield SampleInput(make_arg(first_shape), args=(make_arg_conj(second_shape),))
|
|
|
|
# Matmul of empty matrices
|
|
yield SampleInput(make_arg((0, S)), args=(make_arg(S, M),))
|
|
yield SampleInput(make_arg((S, 0)), args=(make_arg(0, M),))
|
|
|
|
|
|
def sample_inputs_addmm(op_info, device, dtype, requires_grad, **kwargs):
|
|
alpha_val = kwargs.get('alpha', 2 + 3j if dtype.is_complex else 0.6)
|
|
beta_val = kwargs.get('beta', 1 + 2j if dtype.is_complex else 0.2)
|
|
tests_list = [
|
|
((2, 3), (2, 2), (2, 3), False),
|
|
((3, 3), (3, 3), (3, 3), False),
|
|
]
|
|
tests_with_lhs_broadcasting = [
|
|
((1,), (2, 2), (2, 3), True),
|
|
((), (2, 2), (2, 3), True),
|
|
]
|
|
test_cases = tests_list + tests_with_lhs_broadcasting # type: ignore[operator]
|
|
|
|
kwargs = dict(alpha=alpha_val, beta=beta_val)
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape_a, shape_b, shape_c, broadcasts_input in test_cases:
|
|
yield SampleInput(
|
|
make_arg(shape_a),
|
|
make_arg(shape_b),
|
|
make_arg(shape_c),
|
|
**kwargs,
|
|
).with_metadata(broadcasts_input=broadcasts_input)
|
|
|
|
if dtype.is_complex:
|
|
shape = (3, 3)
|
|
yield SampleInput(
|
|
make_arg(shape),
|
|
make_arg(shape, requires_grad=False).mH.requires_grad_(requires_grad),
|
|
make_arg(shape),
|
|
**kwargs,
|
|
)
|
|
yield SampleInput(
|
|
make_arg(shape),
|
|
make_arg(shape),
|
|
make_arg(shape, requires_grad=False).mH.requires_grad_(requires_grad),
|
|
**kwargs,
|
|
)
|
|
# addmm of empty matrices
|
|
if dtype.is_floating_point:
|
|
yield SampleInput(make_arg(S, M), make_arg(S, 0), make_arg(0, M), **kwargs)
|
|
# empty matmul with broadcastable input
|
|
yield SampleInput(make_arg(M), make_arg(S, 0), make_arg(0, M), **kwargs).with_metadata(broadcasts_input=True)
|
|
|
|
def sample_inputs_sparse_sampled_addmm(op_info, device, dtype, requires_grad, **kwargs):
|
|
alpha = 2 + 3j if dtype.is_complex else 0.6
|
|
beta = 1 + 2j if dtype.is_complex else 0.2
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# sparse.sampled_addmm performs: alpha * (A @ B) * sparse_ones_like(C) + beta * C
|
|
for m, n, k in itertools.product([0, 5], repeat=3):
|
|
yield SampleInput(
|
|
torch.eye(m, n, device=device, dtype=dtype)
|
|
.to_sparse_csr()
|
|
.requires_grad_(requires_grad),
|
|
make_arg((m, k)),
|
|
make_arg((k, n)),
|
|
alpha=alpha,
|
|
beta=beta,
|
|
)
|
|
|
|
def sample_inputs_sparse_mm_reduce(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
reductions = ["sum", "mean", "amax", "amin"]
|
|
for m, k, reduce in product([5, 7], [3, 11], reductions):
|
|
yield SampleInput(
|
|
torch.eye(m, m)
|
|
.to(device=device, dtype=dtype)
|
|
.to_sparse_csr()
|
|
.requires_grad_(requires_grad),
|
|
make_arg((m, k)),
|
|
reduce,
|
|
)
|
|
|
|
|
|
def sample_inputs_mv(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(S, M), make_arg(M))
|
|
|
|
def sample_inputs_bmm(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(M, S, M), make_arg(M, M, S))
|
|
|
|
def sample_inputs_dot_vdot(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_arg_conj(size):
|
|
return make_arg(size).conj().requires_grad_(requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, )), make_arg((S, )))
|
|
if dtype.is_complex:
|
|
# dot/vdot for (conj(input), conj(arg_tensor)) and (conj(input), arg_tensor)
|
|
# is tested in test_conj_view (which tests operations with only conjugated input tensor
|
|
# -- not conjugated arg tensors)
|
|
yield SampleInput(make_arg((S, )), make_arg_conj((S, )))
|
|
|
|
|
|
def error_inputs_dot_vdot(op_info, device, is_ref=False, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
yield ErrorInput(SampleInput(make_input(1), args=(make_input(3, dtype=torch.float16),)),
|
|
error_regex='dot : expected both vectors to have same dtype')
|
|
yield ErrorInput(SampleInput(make_input(1, 1), args=(make_input(3),)),
|
|
error_regex='1D tensors expected')
|
|
yield ErrorInput(SampleInput(make_input(9), args=(make_input(3),)),
|
|
error_regex='inconsistent tensor size')
|
|
if device != "cpu" and not is_ref:
|
|
yield ErrorInput(SampleInput(make_input(3), args=(make_input(3, device="cpu"),)),
|
|
error_regex='Expected all tensors to be on the same device')
|
|
|
|
|
|
def sample_inputs_addmv(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
test_cases = (((S,), (S, M), (M,), 1, 1, False),
|
|
((S,), (S, M), (M,), 0.2, 0.6, False),
|
|
)
|
|
|
|
test_cases_with_broadcast = (((1,), (S, M), (M,), 1, 1, True),
|
|
((1,), (S, M), (M,), 0.2, 0.6, True),
|
|
((), (S, M), (M,), 1, 1, True),
|
|
((), (S, M), (M,), 0.2, 0.6, True),
|
|
)
|
|
|
|
cases = test_cases + test_cases_with_broadcast
|
|
|
|
# addmv performs: beta * M + alpha * (mat @ vec)
|
|
for size, mat, vec, beta, alpha, broadcasts_input in cases:
|
|
yield SampleInput(make_arg(size), args=(make_arg(mat), make_arg(vec)),
|
|
kwargs=dict(beta=beta, alpha=alpha), broadcasts_input=broadcasts_input)
|
|
|
|
def sample_inputs_addbmm(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# input_shape, batch1_shape, batch2_shape, beta_val, alpha_val, is_broadcasting
|
|
test_cases = [((S, M), (S, S, S), (S, S, M), 1, 1, False),
|
|
((1,), (S, S, S), (S, S, M), 1, 1, True),
|
|
((S, M), (S, S, S), (S, S, M), 0.6, 0.2, False),
|
|
((1,), (S, S, S), (S, S, M), 0.6, 0.2, True),
|
|
((), (S, S, S), (S, S, M), 1, 1, True),
|
|
((), (S, S, S), (S, S, M), 0.6, 0.2, True),
|
|
]
|
|
|
|
for input_shape, batch1_shape, batch2_shape, beta, alpha, is_broadcasting in test_cases:
|
|
if dtype.is_complex:
|
|
beta_complex, alpha_complex = beta * (1 + 2j), alpha * (2 + 3j)
|
|
yield SampleInput(make_arg(input_shape), args=(make_arg(batch1_shape), make_arg(batch2_shape)),
|
|
kwargs=dict(beta=beta_complex, alpha=alpha_complex), broadcasts_input=is_broadcasting)
|
|
yield SampleInput(make_arg(input_shape), args=(make_arg(batch1_shape), make_arg(batch2_shape)),
|
|
kwargs=dict(beta=beta, alpha=alpha), broadcasts_input=is_broadcasting)
|
|
|
|
def sample_inputs_addcmul_addcdiv(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
test_cases = [(((S, S), (S, S), (S, S)), False),
|
|
(((S, S), (S, 1), (1, S)), False),
|
|
(((1,), (S, S, 1), (1, S)), True),
|
|
(((), (), ()), False),
|
|
(((S, S), (), ()), True),
|
|
(((), (S, S, 1), (1, S)), True)
|
|
]
|
|
|
|
for input_args, broadcasts_input in test_cases:
|
|
# addcdiv should accept inputs with zero value
|
|
# Currently, it throws ZeroDivisionError when the denominator is zero
|
|
# TODO: exclude_zeros can be removed after https://github.com/pytorch/pytorch/issues/73638 is fixed
|
|
args = tuple(make_arg(arg, exclude_zero=True) if isinstance(arg, tuple) else arg
|
|
for arg in input_args)
|
|
yield SampleInput(*args).with_metadata(broadcasts_input=broadcasts_input)
|
|
|
|
# addcdiv should accept inputs with zero value
|
|
# Currently, it throws ZeroDivisionError when the denominator is zero
|
|
# TODO: exclude_zeros can be removed after https://github.com/pytorch/pytorch/issues/73638 is fixed
|
|
args = tuple(make_arg(arg, exclude_zero=True) if isinstance(arg, tuple) else arg
|
|
for arg in input_args)
|
|
yield SampleInput(
|
|
*args, value=3.14 if dtype.is_floating_point or dtype.is_complex else 3
|
|
).with_metadata(broadcasts_input=broadcasts_input)
|
|
|
|
def reference_inputs_addcmul_addcdiv(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_addcmul_addcdiv(
|
|
op_info, device, dtype, requires_grad, **kwargs)
|
|
|
|
# type promotion cases
|
|
supported_dtypes = op_info.supported_dtypes(device)
|
|
make_arg = partial(make_tensor, device=device, requires_grad=requires_grad)
|
|
|
|
types = (
|
|
(torch.float64, torch.complex128),
|
|
(torch.bfloat16, torch.float32),
|
|
)
|
|
|
|
values = (
|
|
None,
|
|
True, False,
|
|
3.14, 3,
|
|
1.0, 1,
|
|
0.0, 0,
|
|
-3.14, -3,
|
|
3.14 + 2.71j,
|
|
)
|
|
|
|
for (type2, type3), value in product(types, values):
|
|
if (type2 not in supported_dtypes or
|
|
type3 not in supported_dtypes):
|
|
continue
|
|
|
|
# RuntimeError: value cannot be converted without overflow
|
|
if (type(value) is complex and
|
|
type2 is not torch.complex128):
|
|
continue
|
|
|
|
arg1 = make_arg([5, 5], dtype=dtype)
|
|
arg2 = make_arg([5, 5], dtype=type2)
|
|
arg3 = make_arg([1, 5], dtype=type3)
|
|
|
|
# TypeError: addcdiv(): argument 'value' must be Number, not NoneType
|
|
if value is not None:
|
|
yield SampleInput(arg1, args=(arg2, arg3), kwargs=dict(value=value))
|
|
else:
|
|
yield SampleInput(arg1, args=(arg2, arg3))
|
|
|
|
def sample_inputs_baddbmm(op_info, device, dtype, requires_grad, **kwargs):
|
|
test_cases = [((S, S, M), (S, S, S), (S, S, M), 1, 1, False),
|
|
((1,), (S, S, S), (S, S, M), 1, 1, True),
|
|
((S, S, M), (S, S, S), (S, S, M), 0.6, 0.2, False),
|
|
((1,), (S, S, S), (S, S, M), 0.6, 0.2, True),
|
|
((), (S, S, S), (S, S, M), 1, 1, True),
|
|
((), (S, S, S), (S, S, M), 0.6, 0.2, True),
|
|
]
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
for (input_shape, batch1_shape, batch2_shape, alpha, beta, broadcasts_input) in test_cases:
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
make_arg(batch1_shape),
|
|
make_arg(batch2_shape),
|
|
beta=beta,
|
|
alpha=alpha
|
|
).with_metadata(broadcasts_input=broadcasts_input)
|
|
|
|
if dtype.is_complex:
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
make_arg(batch1_shape),
|
|
make_arg(batch2_shape),
|
|
beta=beta * (1 + 2j),
|
|
alpha=alpha * (2 + 3j),
|
|
).with_metadata(broadcasts_input=broadcasts_input)
|
|
|
|
if dtype.is_complex:
|
|
shapes = [(S, S, S), (S, M, S), (S, S, M)]
|
|
args = tuple(make_arg(s) for s in shapes)
|
|
yield SampleInput(
|
|
args[0].transpose_(-1, 1),
|
|
args[1].transpose(-1, 1).conj().requires_grad_(requires_grad),
|
|
args[2].transpose(-1, 1).conj().requires_grad_(requires_grad),
|
|
beta=beta * (1 + 2j),
|
|
alpha=alpha * (2 + 3j),
|
|
)
|
|
|
|
# TODO: add reduction kwargs
|
|
def sample_inputs_multilabel_soft_margin_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shapes = (
|
|
(S,),
|
|
(S, S),
|
|
)
|
|
|
|
for shape in shapes:
|
|
# Produce one with weight and one without.
|
|
yield SampleInput(_make_tensor(shape), args=(_make_tensor(shape, requires_grad=False),), kwargs={})
|
|
yield SampleInput(_make_tensor(shape), args=(_make_tensor(shape, requires_grad=False),),
|
|
kwargs={'weight': _make_tensor(shape, requires_grad=False)})
|
|
|
|
def sample_inputs_addr(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(
|
|
make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None
|
|
)
|
|
yield SampleInput(make_arg(S, M), make_arg(S), make_arg(M))
|
|
|
|
yield SampleInput(make_arg(), make_arg(S), make_arg(M)).with_metadata(broadcasts_input=True)
|
|
|
|
if dtype.is_complex:
|
|
alpha, beta = 0.1 + 0.3j, 0.4 + 0.6j
|
|
elif dtype.is_floating_point:
|
|
alpha, beta = 0.2, 0.6
|
|
else:
|
|
alpha, beta = 2, 3
|
|
|
|
yield SampleInput(make_arg(S, M), make_arg(S), make_arg(M), beta=beta, alpha=alpha)
|
|
|
|
yield SampleInput(
|
|
make_arg(),
|
|
make_arg(S),
|
|
make_arg(M),
|
|
beta=beta,
|
|
alpha=alpha,
|
|
).with_metadata(broadcasts_input=True)
|
|
|
|
# These samples fail gradcheck
|
|
if dtype.is_floating_point and not requires_grad:
|
|
tensor_options = dict(device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(
|
|
torch.tensor([[math.nan]], **tensor_options),
|
|
torch.tensor([0.0], **tensor_options),
|
|
torch.tensor([0.0], **tensor_options),
|
|
beta=0.0,
|
|
alpha=0.0,
|
|
).with_metadata(broadcasts_input=True)
|
|
|
|
yield SampleInput(
|
|
torch.tensor([[0.0]], **tensor_options),
|
|
torch.tensor([math.nan], **tensor_options),
|
|
torch.tensor([math.nan], **tensor_options),
|
|
beta=0.0,
|
|
alpha=0.0,
|
|
).with_metadata(broadcasts_input=True)
|
|
|
|
def sample_inputs_zero_(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = ((), (S, S, S), (S,))
|
|
|
|
for shape in cases:
|
|
yield SampleInput(make_arg(shape))
|
|
|
|
def sample_inputs_multi_margin_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_target = partial(_make_tensor, dtype=torch.long, requires_grad=False)
|
|
make_weight = partial(_make_tensor, requires_grad=False)
|
|
|
|
inputs = (
|
|
((), make_target([], low=0, high=1), {}),
|
|
((S,), make_target([], low=0, high=S), {"p": 1}),
|
|
((S,), make_target([1], low=0, high=S), {"p": 2}),
|
|
((S, M), make_target([S], low=0, high=M), {"margin": 1.0}),
|
|
((S, M), make_target([S], low=0, high=M), {"margin": -3.14}),
|
|
((M, S), make_target([M], low=0, high=S), {"weight": None}),
|
|
((M, S), make_target([M], low=0, high=S), {"weight": make_weight([S], low=-10., high=10.)}),
|
|
((M, S), make_target([M], low=0, high=S), {"reduction": "none"}),
|
|
((M, S), make_target([M], low=0, high=S), {"reduction": "mean"}),
|
|
((M, S), make_target([M], low=0, high=S), {"reduction": "sum"}),
|
|
)
|
|
|
|
for input_shape, target, kwargs in inputs:
|
|
yield SampleInput(_make_tensor(input_shape), args=(target,), kwargs=kwargs)
|
|
|
|
|
|
def reference_inputs_multi_margin_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_multi_margin_loss(op_info, device, dtype, requires_grad, **kwargs)
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_target = partial(_make_tensor, dtype=torch.long, requires_grad=False)
|
|
make_weight = partial(_make_tensor, requires_grad=False)
|
|
|
|
inputs = (
|
|
((), make_target([], low=0, high=1)),
|
|
((S,), make_target([], low=0, high=S)),
|
|
((S,), make_target([1], low=0, high=S)),
|
|
((M, S), make_target([M], low=0, high=S)),
|
|
)
|
|
ps = (1, 2)
|
|
margins = (0, 7, -3.14)
|
|
weights = (False, True)
|
|
reductions = (None, "none", "mean", "sum")
|
|
|
|
for (input_shape, target), p, margin, weight, reduction in product(inputs, ps, margins, weights, reductions):
|
|
input = _make_tensor(input_shape)
|
|
weight_shape = [input.size(-1)] if input.ndim > 0 else [1]
|
|
weight = make_weight(weight_shape, low=-10., high=10.) if weight else None
|
|
kwargs = {"p": p, "margin": margin, "weight": weight}
|
|
if reduction is not None:
|
|
kwargs["reduction"] = reduction
|
|
yield SampleInput(input, args=(target,), kwargs=kwargs)
|
|
|
|
|
|
def error_inputs_multi_margin_loss(op, device, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
# invalid reduction
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5,),), kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError, error_regex='abc is not a valid value for reduction')
|
|
# invalid input
|
|
yield ErrorInput(SampleInput(make_input(5, 0), args=(make_input(5,),), kwargs={}),
|
|
error_type=RuntimeError,
|
|
error_regex=r'Expected non-empty vector or matrix with optional 0-dim batch size, but got: \[5, 0\]')
|
|
yield ErrorInput(SampleInput(make_input(0,), args=(make_input(5,),), kwargs={}),
|
|
error_type=RuntimeError,
|
|
error_regex=r'Expected non-empty vector or matrix with optional 0-dim batch size, but got: \[0\]')
|
|
# invalid target
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4),), kwargs={}),
|
|
error_type=RuntimeError, error_regex=r'inconsistent target size, expected 5 but got \[5, 4\]')
|
|
# invalid target dtype
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5,),), kwargs={}),
|
|
error_type=RuntimeError, error_regex='expected scalar type Long but found Float')
|
|
# invalid weight
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5,),), kwargs={'weight': make_input(())}),
|
|
error_type=ValueError, error_regex='weight must be one-dimensional')
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5,),), kwargs={'weight': make_input(5, 4)}),
|
|
error_type=ValueError, error_regex='weight must be one-dimensional')
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5,),), kwargs={'weight': make_input(5,)}),
|
|
error_type=RuntimeError, error_regex=r'inconsistent weight size, expected 4 but got \[5\]')
|
|
# invalid p
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5,),), kwargs={'p': 3}),
|
|
error_type=ValueError, error_regex='only p == 1 and p == 2 supported')
|
|
|
|
|
|
def sample_inputs_logsumexp(self, device, dtype, requires_grad, **kwargs):
|
|
inputs = (
|
|
((), (0,), True),
|
|
((S, S), (1,), True),
|
|
((S, S), (1,), False),
|
|
((S, S), (-2,), False),
|
|
((S, S), (0, 1), False),
|
|
)
|
|
# Test large inputs to check numerical stability
|
|
lows = (None, 1e3, 1e6) if dtype in (torch.float32, torch.float64, torch.complex64, torch.complex128) else (None,)
|
|
for low in lows:
|
|
high = low * 2 if low is not None else None
|
|
for shape, dim, keepdim in inputs:
|
|
t = make_tensor(shape, dtype=dtype, device=device,
|
|
low=low, high=high,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(t, dim, keepdim)
|
|
|
|
def reference_inputs_logsumexp(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_logsumexp(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
# https://github.com/pytorch/pytorch/issues/91843
|
|
t = torch.tensor([20, 30, 100], dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(t, 0, False)
|
|
|
|
t = torch.tensor((), dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(t, 0, False)
|
|
|
|
# tests masking
|
|
# https://github.com/pytorch/pytorch/pull/91860#pullrequestreview-1241344073
|
|
t = torch.tensor(float("inf"))
|
|
yield SampleInput(t, 0, True)
|
|
|
|
def sample_inputs_like_fns(self, device, dtype, requires_grad, **kwargs):
|
|
inputs = [
|
|
((), {}),
|
|
((S, S), {}),
|
|
((0, S, 0), {}),
|
|
((S,), {'dtype': dtype, 'device': device}),
|
|
# Hard-code some dtypes/devices. We want to test cases where the
|
|
# (dtype, device) is different from the input's (dtype, device)
|
|
((S,), {'dtype': torch.double}),
|
|
((S,), {'device': 'cpu'}),
|
|
((S,), {'dtype': torch.double, 'device': 'cpu'}),
|
|
]
|
|
if torch.cuda.is_available():
|
|
inputs.append(((S,), {'device': 'cuda'}))
|
|
|
|
for shape, kwargs in inputs:
|
|
t = make_tensor(shape, dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(t, **kwargs)
|
|
|
|
def reference_inputs_like_fns(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_like_fns(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
# shape
|
|
cases = (
|
|
(), (0,), (1, 0), (1, 1, 4, 5), (5, 3, 0, 1), (1, 4, 3, 1, 1)
|
|
)
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape in cases:
|
|
yield SampleInput(make_arg(shape))
|
|
yield SampleInput(make_arg(shape).transpose(0, -1))
|
|
yield SampleInput(make_arg(shape, noncontiguous=True))
|
|
yield SampleInput(make_arg(shape, noncontiguous=True).transpose(0, -1))
|
|
|
|
def sample_inputs_multilabel_margin_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_target = partial(_make_tensor, dtype=torch.long, requires_grad=False)
|
|
|
|
inputs = (
|
|
([], make_target([], low=0, high=1), {}),
|
|
([S], make_target([S], low=0, high=S), {}),
|
|
([M, S], make_target([M, S], low=0, high=S), {}),
|
|
([M, S], make_target([M, S], low=0, high=S), {"reduction": "none"}),
|
|
([M, S], make_target([M, S], low=0, high=S), {"reduction": "mean"}),
|
|
([M, S], make_target([M, S], low=0, high=S), {"reduction": "sum"}),
|
|
)
|
|
|
|
for shape, target, kwargs in inputs:
|
|
yield SampleInput(_make_tensor(shape), args=(target,), kwargs=kwargs)
|
|
|
|
|
|
def reference_inputs_multilabel_margin_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_multilabel_margin_loss(op_info, device, dtype, requires_grad, **kwargs)
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_target = partial(_make_tensor, dtype=torch.long, requires_grad=False)
|
|
make_target_tensor = partial(torch.tensor, device=device, dtype=torch.long, requires_grad=False)
|
|
|
|
inputs = (
|
|
# random tests including -1 target labels
|
|
([], make_target([], low=-1, high=1)),
|
|
([S], make_target([S], low=-1, high=S)),
|
|
([M, S], make_target([M, S], low=-1, high=S)),
|
|
# repeated target labels and -1 (labels after the first -1 are ignored)
|
|
([], make_target_tensor(-1)),
|
|
([7], make_target_tensor([2, 0, 6, -1, 4, -1, 6])),
|
|
([4, 5], make_target_tensor([[4, -1, 0, -1, 2], [0, 0, 4, 1, 4], [-1, 3, -1, 1, 0], [4, 3, 2, 1, 0]])),
|
|
)
|
|
reductions = (None, "none", "mean", "sum")
|
|
|
|
for (shape, target), reduction in product(inputs, reductions):
|
|
kwargs = {}
|
|
if reduction is not None:
|
|
kwargs["reduction"] = reduction
|
|
yield SampleInput(_make_tensor(shape), args=(target,), kwargs=kwargs)
|
|
|
|
|
|
def error_inputs_multilabel_margin_loss(op, device, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
# invalid reduction
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4),), kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError, error_regex='abc is not a valid value for reduction')
|
|
# invalid input
|
|
yield ErrorInput(SampleInput(make_input(5, 0), args=(make_input(5, 4),), kwargs={}),
|
|
error_type=RuntimeError,
|
|
error_regex=r'Expected non-empty vector or matrix with optional 0-dim batch size, but got: \[5, 0\]')
|
|
yield ErrorInput(SampleInput(make_input(0,), args=(make_input(0,),), kwargs={}),
|
|
error_type=RuntimeError,
|
|
error_regex=r'Expected non-empty vector or matrix with optional 0-dim batch size, but got: \[0\]')
|
|
# invalid target
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(4,),), kwargs={}),
|
|
error_type=RuntimeError,
|
|
error_regex=r'inconsistent target size: \[4\] for input of size: \[5, 4\]')
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input((),),), kwargs={}),
|
|
error_type=RuntimeError,
|
|
error_regex=r'inconsistent target size: \[\] for input of size: \[5, 4\]')
|
|
|
|
|
|
def get_independent_tensor(tensor):
|
|
return tensor.clone().requires_grad_(tensor.requires_grad)
|
|
|
|
def sample_inputs_randint(self, device, dtype, requires_grad, **kwargs):
|
|
low = 2
|
|
high = 10
|
|
|
|
for sample in sample_inputs_like_fns(self, device, dtype, requires_grad, **kwargs):
|
|
sample.kwargs.setdefault('device', device)
|
|
# With high
|
|
yield SampleInput(high, sample.input.shape, *sample.args, **sample.kwargs)
|
|
# With low and high
|
|
yield SampleInput(low, high, sample.input.shape, *sample.args, **sample.kwargs)
|
|
|
|
def sample_inputs_randint_like(self, device, dtype, requires_grad, **kwargs):
|
|
low = 2
|
|
high = 10
|
|
|
|
for sample in sample_inputs_like_fns(self, device, dtype, requires_grad, **kwargs):
|
|
# With high
|
|
yield SampleInput(
|
|
sample.input,
|
|
high,
|
|
*sample.args,
|
|
**sample.kwargs)
|
|
# With low and high
|
|
yield SampleInput(
|
|
get_independent_tensor(sample.input),
|
|
low,
|
|
high,
|
|
*sample.args,
|
|
**sample.kwargs)
|
|
|
|
def sample_inputs_margin_ranking_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shapes = (
|
|
(),
|
|
(S,),
|
|
(S, S),
|
|
(S, S, S),
|
|
)
|
|
|
|
margins = (0., 1.)
|
|
reductions = ('sum', 'mean', 'none')
|
|
|
|
for shape in shapes:
|
|
for margin, reduction in product(margins, reductions):
|
|
kwargs = {'margin': margin, 'reduction': reduction}
|
|
yield SampleInput(_make_tensor(shape),
|
|
args=(_make_tensor(shape, requires_grad=False),
|
|
_make_tensor(shape, requires_grad=False)),
|
|
kwargs=kwargs)
|
|
|
|
def reference_inputs_margin_ranking_loss(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_margin_ranking_loss(op, device, dtype, requires_grad, **kwargs)
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
for reduction in ('sum', 'mean', 'none'):
|
|
if dtype.is_floating_point: # only supports ints and floats
|
|
# NaN propagation
|
|
inp1 = make_input((10, ))
|
|
inp1[2] = float('nan')
|
|
inp2 = make_input((10, ))
|
|
inp2[4] = float('nan')
|
|
target = make_input((10, ))
|
|
inp2[9] = float('nan')
|
|
yield SampleInput(inp1, args=(inp2, target), kwargs={'reduction': reduction})
|
|
|
|
# Inf handling
|
|
inp1 = make_input((10, ))
|
|
inp2[1] = float('inf')
|
|
inp2 = make_input((10, ))
|
|
inp2[4] = float('inf')
|
|
target = make_input((10, ))
|
|
inp2[7] = float('inf')
|
|
yield SampleInput(inp1, args=(inp2, target), kwargs={'reduction': reduction})
|
|
|
|
# Broadcasting
|
|
inp1 = make_input((5, 2))
|
|
inp2 = make_input((5, 1))
|
|
target = make_input((1, 2))
|
|
yield SampleInput(inp1, args=(inp2, target), kwargs={'reduction': reduction})
|
|
|
|
def error_inputs_margin_ranking_loss(op, device, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
# invalid reduction value.
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4), make_input(5, 4),), kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError, error_regex='is not a valid value')
|
|
# invalid input shapes
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4), make_input(5,),)),
|
|
error_regex='margin_ranking_loss : All input tensors should')
|
|
|
|
def sample_inputs_new_fns(self, device, dtype, requires_grad, *, is_strided=False, **kwargs):
|
|
other_dtype = torch.half if torch.backends.mps.is_available() else torch.double
|
|
# input_shape, output_shape, strides, kwargs
|
|
# lengths of output_shape and strides must be equal
|
|
inputs = [
|
|
((), (), (), {}),
|
|
((S, S), (2, 0), (3, 4), {}),
|
|
((0, S, 0), (3, 2, 2), (1, 2, 3), {}),
|
|
((S,), (2, 3), (7, 8), {'dtype': dtype, 'device': device}),
|
|
# Hard-code some dtypes/devices. We want to test cases where the
|
|
# (dtype, device) is different from the input's (dtype, device)
|
|
((S,), (10,), (S,), {'dtype': other_dtype}),
|
|
((S,), (1, 1, 12), (S, L, M), {'device': 'cpu'}),
|
|
((S,), (2, 2, 2), (L, M, S), {'dtype': other_dtype, 'device': 'cpu'}),
|
|
]
|
|
if torch.cuda.is_available():
|
|
inputs.append(((S,), (7, 2), (3, 4), {'device': 'cuda'}))
|
|
|
|
for input_shape, output_shape, strides, kwargs in inputs:
|
|
t = make_tensor(input_shape, dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
if is_strided:
|
|
yield SampleInput(t, output_shape, strides, **kwargs)
|
|
else:
|
|
yield SampleInput(t, output_shape, **kwargs)
|
|
|
|
def sample_inputs_empty_strided(op, device, dtype, requires_grad=False, **kwargs):
|
|
|
|
inputs = [
|
|
((), (), {'dtype': dtype, 'device': device}),
|
|
((S,), (4,), {'dtype': dtype, 'device': device}),
|
|
((S, S), (2, 1), {'dtype': dtype, 'device': device}),
|
|
((S, S, S), (2, 0, 1), {'dtype': dtype, 'device': device}),
|
|
]
|
|
|
|
for shape, strides, kwargs in inputs:
|
|
yield SampleInput(shape, strides, requires_grad=requires_grad, **kwargs)
|
|
|
|
def sample_inputs_empty(op, device, dtype, requires_grad, **kwargs):
|
|
# shape
|
|
cases = (
|
|
(), (0,), (1,), (1, 3, 5), (5, 3, 1), (1, 0, 5, 1),
|
|
)
|
|
|
|
for case in cases:
|
|
yield SampleInput(case, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def sample_inputs_empty_permuted(op, device, dtype, requires_grad, **kwargs):
|
|
# shape
|
|
cases = (
|
|
(), (0,), (1,), (1, 3, 5), (5, 3, 1), (1, 0, 5, 1),
|
|
)
|
|
|
|
for case in cases:
|
|
for layout in itertools.permutations(range(len(case))):
|
|
yield SampleInput(case, layout, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def error_inputs_empty_permuted(op_info, device, **kwargs):
|
|
yield ErrorInput(
|
|
SampleInput((2,), args=((0, 1),)),
|
|
error_type=RuntimeError,
|
|
error_regex="Number of dimensions in size does not match the length of the physical_layout"
|
|
)
|
|
yield ErrorInput(
|
|
SampleInput((2,), args=((3,),)),
|
|
error_type=RuntimeError,
|
|
error_regex="Dimension out of range"
|
|
)
|
|
yield ErrorInput(
|
|
SampleInput((2, 3), args=((0, 0),)),
|
|
error_type=RuntimeError,
|
|
error_regex="Duplicate dim not allowed"
|
|
)
|
|
|
|
def sample_inputs_scalar_tensor(op, device, dtype, requires_grad, **kwargs):
|
|
# Not including a scalar tensor in vals because meta tests start failing due to
|
|
# lack of meta support for _local_scalar_dense
|
|
# torch.tensor(2, device=device)
|
|
vals = (-5, 0, 1)
|
|
|
|
for item in vals:
|
|
yield SampleInput(item, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def sample_inputs_eye(op, device, dtype, requires_grad, **kwargs):
|
|
# only ints >= 0 are allowed for both arguments, unless m is omitted
|
|
sizes = (None, 0, 1, 2, 3, 4, 7, L, M, S)
|
|
|
|
for n, m in product(sizes, sizes):
|
|
if n is None:
|
|
continue
|
|
|
|
# TODO: no layout
|
|
_kwargs = {'device': device, 'dtype': dtype, 'requires_grad': requires_grad}
|
|
if m is None:
|
|
yield SampleInput(n, args=(), kwargs=_kwargs)
|
|
else:
|
|
yield SampleInput(n, args=(m,), kwargs=_kwargs)
|
|
|
|
def error_inputs_eye(op_info, device, **kwargs):
|
|
# TODO: no layout
|
|
_kwargs = {'device': device, 'dtype': torch.float32}
|
|
|
|
yield ErrorInput(
|
|
SampleInput(-1, args=(), kwargs=_kwargs),
|
|
error_regex="n must be greater or equal to 0, got -1"
|
|
)
|
|
|
|
yield ErrorInput(
|
|
SampleInput(-7, args=(42,), kwargs=_kwargs),
|
|
error_regex="n must be greater or equal to 0, got -7"
|
|
)
|
|
|
|
yield ErrorInput(
|
|
SampleInput(0, args=(-3,), kwargs=_kwargs),
|
|
error_regex="m must be greater or equal to 0, got -3"
|
|
)
|
|
|
|
|
|
def sample_inputs_new_full(self, device, dtype, requires_grad, **kwargs):
|
|
def get_val(dtype):
|
|
return make_tensor([], dtype=dtype, device="cpu").item()
|
|
|
|
for sample in sample_inputs_new_fns(self, device, dtype, requires_grad, **kwargs):
|
|
# The scalar we are passing to new_full must be the same dtype
|
|
# as the one of the resulting tensor
|
|
use_dtype = sample.kwargs['dtype'] if 'dtype' in sample.kwargs else dtype
|
|
yield SampleInput(
|
|
sample.input, *sample.args, get_val(use_dtype), **sample.kwargs)
|
|
|
|
def sample_inputs_full_like(self, device, dtype, requires_grad, **kwargs):
|
|
def get_val(dtype):
|
|
return make_tensor([], dtype=dtype, device="cpu").item()
|
|
|
|
inputs = [
|
|
((), get_val(dtype), {}),
|
|
((S, S), get_val(dtype), {}),
|
|
((0, S, 0), get_val(dtype), {}),
|
|
((S,), get_val(dtype), {'dtype': dtype, 'device': device}),
|
|
# Hard-code some dtypes/devices. We want to test cases where the
|
|
# (dtype, device) is different from the input's (dtype, device)
|
|
((S,), get_val(torch.double), {'dtype': torch.double}),
|
|
((S,), get_val(dtype), {'device': 'cpu'}),
|
|
((S,), get_val(torch.double), {'dtype': torch.double, 'device': 'cpu'}),
|
|
]
|
|
if torch.cuda.is_available():
|
|
inputs.append(((S,), get_val(dtype), {'device': 'cuda'}))
|
|
|
|
for shape, fill_value, kwargs in inputs:
|
|
t = make_tensor(shape, dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(t, fill_value, **kwargs)
|
|
|
|
def sample_inputs_multinomial(self, device, dtype, requires_grad, **kwargs):
|
|
cases = [
|
|
([3], 3, {}),
|
|
([10], 3, {}),
|
|
([3, 10], 3, {}),
|
|
([3], 3, dict(replacement=False)),
|
|
([3], 3, dict(replacement=True)),
|
|
([3, 4], 4, dict(replacement=True)),
|
|
([3, 4], 4, dict(replacement=False)),
|
|
]
|
|
|
|
for shape, num_samples, kwargs in cases:
|
|
t = make_tensor(shape, dtype=dtype, device=device,
|
|
low=0, high=None,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(t, num_samples, **kwargs)
|
|
|
|
def sample_inputs_normal_common(self, device, dtype, requires_grad, cases, **kwargs):
|
|
def get_value_or_make_tensor(value_or_shape):
|
|
if isinstance(value_or_shape, list):
|
|
return make_tensor(value_or_shape, dtype=dtype, device=device,
|
|
low=0, high=None,
|
|
requires_grad=requires_grad)
|
|
return value_or_shape
|
|
|
|
for value_or_mean_shape, value_or_std_shape, kwargs in cases:
|
|
mean = get_value_or_make_tensor(value_or_mean_shape)
|
|
std = get_value_or_make_tensor(value_or_std_shape)
|
|
yield SampleInput(mean, std, **kwargs)
|
|
|
|
def sample_inputs_normal_tensor_first(self, device, dtype, requires_grad, **kwargs):
|
|
# value_or_size, value_or_size, kwargs
|
|
cases = [
|
|
([], [], {}),
|
|
([3], [3], {}),
|
|
([3, 4, 2], [3, 4, 2], {}),
|
|
([2, 3], 1.1, {}),
|
|
([1, 2, 3], [5, 2, 3], {}), # broadcasting
|
|
]
|
|
|
|
return sample_inputs_normal_common(self, device, dtype, requires_grad, cases, **kwargs)
|
|
|
|
def sample_inputs_normal_tensor_second(self, device, dtype, requires_grad, **kwargs):
|
|
yield SampleInput(1.6, 0.3, [2, 3], dtype=dtype, device=device)
|
|
yield SampleInput(1.6, 0.3, [2, 2, 2], dtype=dtype, layout=torch.strided, device=device)
|
|
yield SampleInput(2.7, make_tensor([4, 3], dtype=dtype, device=device, low=0, high=None, requires_grad=requires_grad))
|
|
|
|
def sample_inputs_bernoulli(self, device, dtype, requires_grad, **kwargs):
|
|
shapes = [
|
|
[3],
|
|
[],
|
|
[0, 3],
|
|
[2, 3, 4],
|
|
]
|
|
|
|
for shape in shapes:
|
|
t = make_tensor(shape, dtype=dtype, device=device,
|
|
low=0, high=1,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(t)
|
|
|
|
def error_inputs_bernoulli(op_info, device, **kwargs):
|
|
# more than one element of the written-to tensor refers to a single memory location
|
|
x = torch.rand((1,), device=device).expand((6,))
|
|
err_msg = 'unsupported operation'
|
|
yield ErrorInput(SampleInput(torch.rand_like(x), kwargs={'out': x}),
|
|
error_regex=err_msg)
|
|
|
|
def sample_inputs_logcumsumexp(self, device, dtype, requires_grad, **kwargs):
|
|
inputs = (
|
|
((S, S, S), 0),
|
|
((S, S, S), 1),
|
|
((), 0),
|
|
)
|
|
|
|
for large_number in (True, False):
|
|
for shape, dim in inputs:
|
|
t = make_tensor(shape, dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
|
|
if large_number and t.dim() > 0:
|
|
t[0] = 10000
|
|
yield SampleInput(t, dim)
|
|
|
|
def sample_inputs_trace(self, device, dtype, requires_grad, **kwargs):
|
|
yield SampleInput(
|
|
make_tensor((S, S), dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad))
|
|
|
|
|
|
def error_inputs_trace(op, device):
|
|
yield ErrorInput(SampleInput(make_tensor((3, 4, 5), dtype=torch.float32, device=device)), error_regex="expected a matrix")
|
|
|
|
|
|
def sample_inputs_renorm(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
cases = (((S, S, S), (2, 1, 0.5)),
|
|
((S, S, S), (2, -1, 0.5)),
|
|
((S, S, S), (1, 2, 3)),
|
|
((S, S, S), (float('inf'), 2, 0.5)),
|
|
)
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
|
|
def sample_inputs_transpose_swapdims(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (((1, 2, 3), (-1, -2)),
|
|
((1, 2, 3), (-1, 2)),
|
|
((1, 2, 3), (1, -2)),
|
|
((1, 2, 3), (1, 2)),
|
|
((), (0, 0)),
|
|
((1, ), (0, 0)),
|
|
((M, M), (0, 1)),
|
|
((S, S, S), (2, 0)), )
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
def _numpy_ref_transpose(a, dim0, dim1):
|
|
if a.ndim <= 1:
|
|
return a
|
|
|
|
return np.swapaxes(a, dim0, dim1)
|
|
|
|
def sample_inputs_adjoint(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
shapes = ((1, 2, 3), (M, M), (S, S, S), (S, M, S), (M, S, M, S))
|
|
return (SampleInput(make_arg(shape)) for shape in shapes)
|
|
|
|
def sample_inputs_T(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
shapes = ((M, M), (M, L))
|
|
return (SampleInput(make_arg(shape)) for shape in shapes)
|
|
|
|
def error_inputs_T(self, device, has_ndims_error=False):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# Deprecated behavior in regular PyTorch, but throws an error in primTorch:
|
|
# https://github.com/pytorch/pytorch/issues/86968
|
|
if has_ndims_error:
|
|
# ndims == 1
|
|
yield ErrorInput(SampleInput(make_arg(M)),
|
|
error_regex=(r'The use of `x\.T` on tensors of dimension other than 0 or 2 '
|
|
r'to reverse their shape is not supported\.'))
|
|
|
|
# ndims > 2
|
|
yield ErrorInput(SampleInput(make_arg(M, S, L)),
|
|
error_regex=(r'The use of `x\.T` on tensors of dimension other than 0 or 2 '
|
|
r'to reverse their shape is not supported\.'))
|
|
|
|
|
|
def sample_inputs_singular_matrix_factors(op_info, device, dtype, requires_grad=False):
|
|
"""
|
|
This function produces two tensors of shape (*, m, k) and (*, n, k) with k <= min(m, n).
|
|
Their matrix product could be used to generate tensor of shape (*, m, n) of rank k.
|
|
"""
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
batches = [(), (2,)]
|
|
size = [3, 4]
|
|
for batch, m, n in product(batches, size, size):
|
|
k = 2
|
|
a = make_arg((*batch, m, k))
|
|
b = make_arg((*batch, n, k))
|
|
yield a, b
|
|
|
|
|
|
def sample_inputs_svd_lowrank(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
# Function that's well defined on the outputs for complex inputs
|
|
def fn(usv):
|
|
U, S, V = usv
|
|
return U @ V.mH, S
|
|
|
|
for (a, b) in sample_inputs_singular_matrix_factors(op_info, device, dtype, requires_grad):
|
|
*batch, m, k = a.shape
|
|
n = b.shape[-2]
|
|
|
|
# NOTE: since svd_lowrank relies on non rank-revealing SVD,
|
|
# it inherits the problem of unstable behavior with repeated
|
|
# singular values including zeros.
|
|
# Since we want to avoid (repeated) zeros as singular values,
|
|
# we can only use k for q.
|
|
# This issues could be resolved with using a rank-revealing SVD
|
|
# which does not include "zero" singular values.
|
|
yield SampleInput(a, b, q=k, M=None).with_metadata(output_process_fn_grad=fn)
|
|
|
|
for (a, b) in sample_inputs_singular_matrix_factors(op_info, device, dtype, requires_grad):
|
|
*batch, m, k = a.shape
|
|
n = b.shape[-2]
|
|
M = make_tensor((*batch, m, n), dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(a, b, q=k, M=M).with_metadata(output_process_fn_grad=fn)
|
|
|
|
def chunk_iter(iterable, size):
|
|
it = iter(iterable)
|
|
while True:
|
|
chunk = tuple(islice(it, size))
|
|
if not chunk:
|
|
break
|
|
yield chunk
|
|
|
|
def sample_inputs_pca_lowrank(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
# we reuse samples from svd_lowrank which come in group of two with
|
|
# kwarg['M'] = None and with kwarg['M'] = <some tensor>
|
|
samples = sample_inputs_svd_lowrank(op_info, device, dtype, requires_grad, **kwargs)
|
|
for s1, s2 in chunk_iter(samples, 2):
|
|
del s1.kwargs['M']
|
|
del s2.kwargs['M']
|
|
s1.kwargs['center'] = False
|
|
s2.kwargs['center'] = True
|
|
yield s1
|
|
yield s2
|
|
|
|
def np_sinc_with_fp16_as_fp32(x):
|
|
# Wraps numpy's sinc function so that fp16 values are promoted to fp32
|
|
# before sinc is invoked. Context: numpy's sinc returns NaN when evaluated
|
|
# at 0 for fp16.
|
|
if x.dtype == np.float16:
|
|
return np.sinc(x.astype(np.float32))
|
|
else:
|
|
return np.sinc(x)
|
|
|
|
def sample_inputs_broadcast_to(op_info, device, dtype, requires_grad, **kwargs):
|
|
test_cases = (
|
|
((S, 1, 1), (S, S, S)),
|
|
((S, 1, S), (S, S, S)),
|
|
((S, 1), (S, S, S)),
|
|
((1,), (S, S, S)),
|
|
((1, S), (1, 1, S)),
|
|
((), ()),
|
|
((), (1, 3, 2)),
|
|
)
|
|
|
|
return (
|
|
SampleInput(
|
|
make_tensor(size, dtype=dtype, device=device, low=None, high=None, requires_grad=requires_grad),
|
|
shape,
|
|
) for size, shape in test_cases)
|
|
|
|
def sample_inputs_broadcast_tensors(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
test_cases: Tuple[tuple] = (((3,), (1, 2, 1), (1, 1), (5, 1, 1),),)
|
|
|
|
for shape, *other_shapes in test_cases:
|
|
yield SampleInput(make_arg(shape), args=tuple(make_arg(s) for s in other_shapes))
|
|
|
|
def reference_inputs_broadcast_tensors(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_broadcast_tensors(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
m = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
n = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad, noncontiguous=True)
|
|
|
|
cases = (
|
|
((), (1, 1), (1, 1, 7, 1), (3, 1, 1)),
|
|
((3, 5, 6), (1, 3, 5, 6), (1, 1, 1, 1, 6), (8, 3, 5, 6))
|
|
)
|
|
|
|
for a, b, c, d in cases:
|
|
yield SampleInput(m(a), args=(m(b), m(c), m(d)))
|
|
yield SampleInput(n(a), args=(n(b), n(c), n(d)))
|
|
|
|
def sample_inputs_block_diag(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
test_cases: Tuple[tuple] = (
|
|
((1, S), (2, S), (3, S),),
|
|
((S, 1), (S, 2), (S, 3),),
|
|
((1,), (2,), (3,),),
|
|
((2, S), (S,))
|
|
)
|
|
|
|
for shape, *other_shapes in test_cases:
|
|
yield SampleInput(make_arg(shape), args=tuple(make_arg(s) for s in other_shapes))
|
|
# We also want to test mixed complex-non-complex inputs to block_diag
|
|
if dtype == torch.complex32 or dtype == torch.complex64:
|
|
non_complex_dtype = torch.float32 if dtype == torch.complex32 else torch.float64
|
|
make_arg_non_complex = partial(make_tensor, dtype=non_complex_dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg_non_complex(shape), args=tuple(make_arg(s) for s in other_shapes))
|
|
|
|
def sample_inputs_cdist(op_info, device, dtype, requires_grad, **kwargs):
|
|
small_S = 2
|
|
test_cases = (
|
|
((S, S, 2), (S, S + 1, 2)),
|
|
((S, S), (S, S)),
|
|
((S, S, S), (S, S, S)),
|
|
((3, 5), (3, 5)),
|
|
((2, 3, 5), (2, 3, 5)),
|
|
((1, 2, 3), (1, 2, 3)),
|
|
((1, 1), (S, 1)),
|
|
((0, 5), (4, 5)),
|
|
((4, 5), (0, 5)),
|
|
((0, 4, 5), (3, 5)),
|
|
((4, 5), (0, 3, 5)),
|
|
((0, 4, 5), (1, 3, 5)),
|
|
((1, 4, 5), (0, 3, 5)),
|
|
# Using S here would make this one test take 9s
|
|
((small_S, small_S, small_S + 1, 2), (small_S, small_S, small_S + 2, 2)),
|
|
((small_S, 1, 1, small_S), (1, small_S, small_S)),
|
|
((1, 1, small_S), (small_S, 1, small_S, small_S)),
|
|
)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
for cm in ['use_mm_for_euclid_dist', 'donot_use_mm_for_euclid_dist']:
|
|
# FIXME add an override for JIT and revert 0. back to 0
|
|
# since it's accepted by eager
|
|
for p in [0., 1., 2., 3., 0.5, 1.5, 2.5, float("inf")]:
|
|
for t1_size, t2_size in test_cases:
|
|
# The args should never be non-contiguous as this is not supported in the backward
|
|
yield SampleInput(make_arg(t1_size), make_arg(t2_size), p, cm)
|
|
|
|
def _fill_np(a, value):
|
|
a = a.copy()
|
|
a.fill(value)
|
|
return a
|
|
|
|
def _fill_sample_kwargs(device, dtype, input):
|
|
if dtype is torch.bool:
|
|
value = True
|
|
else:
|
|
value = 3
|
|
|
|
return ({'value': value}, {'value': value})
|
|
|
|
def sample_inputs_comparison_ops(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_elementwise_binary(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
# Adds a sample input where both tensors have the same values
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
lhs = make_arg((S, S))
|
|
yield SampleInput(lhs, args=(lhs.clone(),))
|
|
|
|
def sample_inputs_stack(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# shape x number of tensors
|
|
cases = (
|
|
((3, 4), 1),
|
|
((1, 2, 1, 4), 3),
|
|
((0, 1, 0), 2),)
|
|
|
|
for shape, num_tensors in cases:
|
|
tensors = []
|
|
for _ in range(num_tensors):
|
|
tensors.append(make_arg(shape))
|
|
for dim in range(-1, len(shape) - 1):
|
|
yield SampleInput(tensors, args=(dim,))
|
|
|
|
|
|
def sample_inputs_chunk_cat(op_info, device, dtype, requires_grad, **kwargs):
|
|
# 1. If input tensors have different ndims, dim should be non-negative and be less than the ndims of every input tensors.
|
|
# If all input tensors have the same ndims, we support both negative and non-negative dim.
|
|
# 2. For wrapped_dim, all tensors should have the same size for 0,...,wrapped_dim-1 dimensions.
|
|
# No requirements for (wrapped_dim, ...)-th dimension.
|
|
# 3. Expect positive num_chunks
|
|
# 4. Expect non-empty input tensor list and each input tensor should have at least 1 element
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
same_ndim_cases = (
|
|
(
|
|
[
|
|
torch.Size([1, 2, 3]),
|
|
torch.Size([1, 2, 3]),
|
|
], -1, 5
|
|
),
|
|
(
|
|
[
|
|
torch.Size([1, 2, 129]),
|
|
torch.Size([1, 2, 297]),
|
|
], -1, 5
|
|
),
|
|
(
|
|
[
|
|
torch.Size([1, 2, 3]),
|
|
torch.Size([1, 2, 3]),
|
|
], 1, 5
|
|
),
|
|
(
|
|
[
|
|
torch.Size([3, 3, 2, 1]),
|
|
torch.Size([1, 4, 2, 2]),
|
|
torch.Size([2, 1, 3, 3]),
|
|
], 0, 2
|
|
),
|
|
)
|
|
for sizes, dim, num_chunks in same_ndim_cases:
|
|
tensors = []
|
|
for size in sizes:
|
|
tensors.append(make_arg(size))
|
|
yield SampleInput(tensors, args=(dim, num_chunks))
|
|
|
|
different_ndim_case = [
|
|
torch.Size([2, 3, 3]),
|
|
torch.Size([2, 3, 1, 2]),
|
|
torch.Size([2, 3]),
|
|
torch.Size([2, 3, 2]),
|
|
torch.Size([2, 3, 271]),
|
|
]
|
|
max_dim, num_chunks = 2, 3
|
|
for dim in range(max_dim):
|
|
tensors = []
|
|
for size in different_ndim_case:
|
|
tensors.append(make_arg(size))
|
|
yield SampleInput(tensors, args=(dim, num_chunks))
|
|
|
|
|
|
def error_inputs_chunk_cat(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# input tensors have different ndims but dim is negative
|
|
sizes, dim, num_chunks = [torch.Size([2, 3]), torch.Size([4,])], -1, 3
|
|
tensors = [make_arg(size) for size in sizes]
|
|
yield ErrorInput(
|
|
SampleInput(tensors, args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects non-negative dim when input tensors have different ndims',
|
|
)
|
|
|
|
# input tensors have different ndims but dim >= ndim of some input tensors
|
|
sizes, dim, num_chunks = [torch.Size([2, 3]), torch.Size([4,])], 1, 3
|
|
tensors = [make_arg(size) for size in sizes]
|
|
yield ErrorInput(
|
|
SampleInput(tensors, args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects dim < ndim for all input tensors',
|
|
)
|
|
|
|
# some tensors have different sizes for 0, ..., dim-1 dimensions.
|
|
sizes, dim, num_chunks = [torch.Size([2, 3, 4]), torch.Size([4, 3])], 1, 3
|
|
tensors = [make_arg(size) for size in sizes]
|
|
yield ErrorInput(
|
|
SampleInput(tensors, args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects same sizes of 0,...,dim-1 dimensions for all tensors',
|
|
)
|
|
|
|
# negative num_chunks
|
|
sizes, dim, num_chunks = [torch.Size([2,]), torch.Size([3,])], 0, -1
|
|
tensors = [make_arg(size) for size in sizes]
|
|
yield ErrorInput(
|
|
SampleInput(tensors, args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects positive num_chunks',
|
|
)
|
|
|
|
# zero as num_chunks
|
|
sizes, dim, num_chunks = [torch.Size([2,]), torch.Size([3,])], 0, 0
|
|
tensors = [make_arg(size) for size in sizes]
|
|
yield ErrorInput(
|
|
SampleInput(tensors, args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects positive num_chunks',
|
|
)
|
|
|
|
# empty input tensor list
|
|
dim, num_chunks = 0, 1
|
|
yield ErrorInput(
|
|
SampleInput([], args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects a non-empty input tensor list',
|
|
)
|
|
|
|
# empty input tensor with 0 elements
|
|
sizes, dim, num_chunks = [torch.Size([0,]), torch.Size([3,])], 0, 1
|
|
tensors = [make_arg(size) for size in sizes]
|
|
yield ErrorInput(
|
|
SampleInput(tensors, args=(dim, num_chunks)),
|
|
error_regex='_chunk_cat expects non-empty tensor',
|
|
)
|
|
|
|
|
|
def sample_inputs_cat_concat(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases: Tuple[tuple, tuple, dict] = ( # type: ignore[assignment]
|
|
((S, S), (S, S), {'dim': -1}),
|
|
((S, S), (S, S), {'dim': 1}),
|
|
((M, S), (S, S), {'dim': 0}), # different shapes
|
|
((1, 2, 3), (1, 2, 3), {'dim': -2}),
|
|
((0,), (0,), {'dim': 0}), # empty tensor
|
|
((0,), (S, S), {'dim': 1}), # empty tensor with unempty and dim=1 (special case for legacy_cat_wrap_dim)
|
|
((0, S), (S, S), {'dim': 0}),
|
|
((1,), (1,), {}) # dim not passed, fallback to default
|
|
)
|
|
|
|
for input_shape1, input_shape2, kwargs in cases:
|
|
yield SampleInput([make_arg(input_shape1), make_arg(input_shape2)], kwargs=kwargs)
|
|
|
|
# from coat_lite_mini
|
|
yield SampleInput([make_arg((2, 2, 2, 2), memory_format=torch.channels_last)], args=(1,),)
|
|
|
|
def error_inputs_cat(op_info, device, **kwargs):
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for more than one element of the written-to tensor refer to a single memory location
|
|
yield ErrorInput(SampleInput([make_arg((S, S)), make_arg((S, S))],
|
|
kwargs={'out': make_arg((1, S)).expand((2 * S, S))}),
|
|
error_regex='unsupported operation')
|
|
|
|
# error inputs for empty tensors
|
|
yield ErrorInput(SampleInput([], kwargs={'dim': 1}),
|
|
error_regex='non-empty list of Tensors')
|
|
|
|
# error inputs for different sizes
|
|
yield ErrorInput(SampleInput([make_arg((S, S, L, L)), make_arg((S, 0, L - 1, L))], kwargs={'dim': 1}),
|
|
error_regex='Sizes of tensors must match except in dimension')
|
|
yield ErrorInput(SampleInput([make_arg((S, 0, L - 1, L)), make_arg((S, S, L, L))], kwargs={'dim': 1}),
|
|
error_regex='Sizes of tensors must match except in dimension')
|
|
|
|
# error inputs for different dimensions
|
|
yield ErrorInput(SampleInput([make_arg((S - 1, 0)), make_arg((S, 0, L - 1, L))], kwargs={'dim': 1}),
|
|
error_regex='Tensors must have same number of dimensions')
|
|
yield ErrorInput(SampleInput([make_arg((S, 0, L - 1, L)), make_arg((S - 1, 0))], kwargs={'dim': 1}),
|
|
error_regex='Tensors must have same number of dimensions')
|
|
|
|
# error inputs for same memory locations
|
|
x = torch.zeros((0), device=device)
|
|
y = torch.randn((4, 6), device=device)
|
|
|
|
err_msg = "the written-to tensor refer to a single memory location"
|
|
|
|
yield ErrorInput(SampleInput((x, y), kwargs={'dim': 0, 'out': x}),
|
|
error_regex=err_msg)
|
|
yield ErrorInput(SampleInput((x, y), kwargs={'dim': 0, 'out': y}),
|
|
error_regex=err_msg)
|
|
|
|
z = torch.zeros((4, 6), device=device)
|
|
yield ErrorInput(SampleInput((y, z), kwargs={'out': z[:2, :]}),
|
|
error_regex=err_msg)
|
|
|
|
# error inputs for different devices
|
|
if torch.device(device).type == 'cuda':
|
|
x_cuda = make_tensor((3, 3), device=device, dtype=torch.float32)
|
|
y_cpu = make_tensor((3, 3), device='cpu', dtype=torch.float32)
|
|
yield ErrorInput(SampleInput((x_cuda, y_cpu)),
|
|
error_regex='Expected all tensors to be on the same device')
|
|
|
|
# error inputs for different input sizes for more than 2 tensors
|
|
yield ErrorInput(SampleInput([make_arg((L, 1)), make_arg((L, 1, 1)), make_arg((L, 1, 1))]),
|
|
error_regex='Tensors must have same number of dimensions')
|
|
|
|
yield ErrorInput(SampleInput([make_arg((S, 1, M)), make_arg((S, 1, 1)), make_arg((S, M, 1))],
|
|
kwargs={'dim': 1}),
|
|
error_regex='Sizes of tensors must match')
|
|
|
|
# error inputs for None input
|
|
yield ErrorInput(SampleInput((make_arg((S, 1, 1)), None)), error_type=TypeError,
|
|
error_regex='got None')
|
|
|
|
# error inputs for zero-dimensional tensors
|
|
yield ErrorInput(SampleInput([make_arg(()), make_arg(())]),
|
|
error_regex='zero-dimensional.*cannot be concatenated')
|
|
|
|
# error inputs for different dtype of out tensors
|
|
d = make_tensor((2, 3), device=device, dtype=torch.double)
|
|
x = make_tensor((2, 3), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(x, kwargs={'out': d}), error_type=TypeError,
|
|
error_regex='invalid combination of arguments')
|
|
|
|
def reference_inputs_cat(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_cat_concat(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Noncontiguous type promoting tensors
|
|
a = make_arg((3, 4, 2))
|
|
b = make_arg((3, 2, 2), noncontiguous=True, dtype=torch.double)
|
|
c = make_arg((3, 3, 2), dtype=torch.float16).permute(1, 0, 2)
|
|
|
|
yield SampleInput((a, b, c), kwargs={'dim': 1})
|
|
|
|
# Special 1D tensor with dim length of 0 case
|
|
a = make_arg((0,))
|
|
b = make_arg((3, 2, 2))
|
|
|
|
yield SampleInput((a, b, a))
|
|
yield SampleInput((a, a, a))
|
|
|
|
def _elementwise_type_promo_np(*args, type_promotion_kind):
|
|
def _maybe_torch(x):
|
|
if isinstance(x, np.ndarray):
|
|
return torch.from_numpy(x)
|
|
return x
|
|
|
|
flattened = pytree.arg_tree_leaves(*args)
|
|
transformed = tuple(_maybe_torch(a) for a in flattened)
|
|
result_dtype, _ = prims.utils.elementwise_dtypes(
|
|
*transformed,
|
|
type_promotion_kind=type_promotion_kind)
|
|
return torch_to_numpy_dtype_dict[result_dtype]
|
|
|
|
def _cat_np(input_seq, dim=0):
|
|
inputs = tuple(a for a in input_seq if not (a.ndim == 1 and a.size == 0))
|
|
|
|
if len(inputs) == 0:
|
|
np_dtype = _elementwise_type_promo_np(
|
|
input_seq,
|
|
type_promotion_kind=prims.utils.ELEMENTWISE_TYPE_PROMOTION_KIND.NO_OPMATH)
|
|
return np.empty(0, dtype=np_dtype)
|
|
|
|
return np.concatenate(inputs, axis=dim)
|
|
|
|
def _floor_divide_np(a, b):
|
|
dtype = _elementwise_type_promo_np(
|
|
a,
|
|
b,
|
|
type_promotion_kind=prims.utils.ELEMENTWISE_TYPE_PROMOTION_KIND.DEFAULT)
|
|
if isinstance(a, np.ndarray):
|
|
a = a.astype(dtype)
|
|
if isinstance(b, np.ndarray):
|
|
b = b.astype(dtype)
|
|
return np.floor_divide(a, b)
|
|
|
|
def sample_inputs_hstack_dstack_vstack(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
tensor_shapes = (
|
|
# First Tensor being 1-D is special
|
|
# case for hstack
|
|
((S,), (S,), (S,)),
|
|
((S, S), (S, S), (S, S)),
|
|
)
|
|
for s1, s2, s3 in tensor_shapes:
|
|
tensors = (make_arg(s1,), make_arg(s2,), make_arg(s3))
|
|
yield SampleInput(tensors)
|
|
|
|
def error_inputs_hstack_dstack_vstack(op, device):
|
|
make_arg = partial(make_tensor, dtype=torch.int32, device=device, requires_grad=False)
|
|
tensor_shapes = (
|
|
((S,), (S, S, S, S), (S,)),
|
|
)
|
|
for s1, s2, s3 in tensor_shapes:
|
|
tensors = (make_arg(s1,), make_arg(s2,), make_arg(s3))
|
|
# Different dimension tensor
|
|
yield ErrorInput(SampleInput(tensors), error_regex="Tensors must have same number of dimensions")
|
|
|
|
# empty tensor list
|
|
yield ErrorInput(SampleInput(()), error_regex="expects a non-empty TensorList")
|
|
|
|
def sample_inputs_unbind(op_info, device, dtype, requires_grad, **kwargs):
|
|
# Note: we don't do any tests where we unbind along 0-length dims
|
|
# because in that case unbind returns and empty tuple, and that breaks
|
|
# some assumptions in some backward tests in test_ops.py
|
|
shape_dims = (((S,), 0),
|
|
((S, S), 0),
|
|
((S, S), 1),
|
|
((S, S), -1),
|
|
((S, 0, S), 0),
|
|
((S, S, S), 1),
|
|
)
|
|
for shape, dim in shape_dims:
|
|
yield SampleInput(make_tensor(shape, dtype=dtype, device=device,
|
|
requires_grad=requires_grad),
|
|
args=(dim,))
|
|
|
|
def error_inputs_unbind(op_info, device):
|
|
make_arg = partial(make_tensor, dtype=torch.int32, device=device, requires_grad=False)
|
|
yield ErrorInput(SampleInput(make_arg(()), args=(0,)), error_type=IndexError,
|
|
error_regex="Dimension specified as 0 but tensor has no dimensions")
|
|
yield ErrorInput(SampleInput(make_arg((2,)), args=(2,)), error_type=IndexError,
|
|
error_regex="Dimension out of range")
|
|
|
|
def reference_unbind(t, dim):
|
|
"""A numpy implementation of torch.unbind"""
|
|
return tuple(s.squeeze(dim) for s in np.split(t, t.shape[dim], dim))
|
|
|
|
def sample_inputs_gather(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
yield SampleInput(
|
|
make_arg((M, S)),
|
|
0,
|
|
gather_variable((S, S), 1, M, True, device=device))
|
|
yield SampleInput(
|
|
make_arg((M, S)),
|
|
1,
|
|
gather_variable((M, S // 2), 0, S, True, device=device))
|
|
# Empty index tensor case, see: https://github.com/pytorch/pytorch/pull/65006
|
|
yield SampleInput(
|
|
make_arg((S,)),
|
|
0,
|
|
torch.tensor([], dtype=torch.uint8, device=device))
|
|
yield SampleInput(
|
|
make_arg((S,)),
|
|
0,
|
|
torch.tensor([[], []], dtype=torch.uint8, device=device))
|
|
# 0D tensor case
|
|
yield SampleInput(
|
|
make_arg(()),
|
|
0,
|
|
torch.tensor([0], dtype=torch.int64, device=device))
|
|
yield SampleInput(
|
|
make_arg(()),
|
|
0,
|
|
torch.tensor(0, dtype=torch.int64, device=device))
|
|
|
|
def _fill_indices(idx, dim, dim_size, elems_per_row, m, n, o):
|
|
for i in range(1 if dim == 0 else m):
|
|
for j in range(1 if dim == 1 else n):
|
|
for k in range(1 if dim == 2 else o):
|
|
ii = [i, j, k]
|
|
ii[dim] = slice(0, idx.size(dim) + 1)
|
|
idx[tuple(ii)] = torch.randperm(dim_size)[0:elems_per_row]
|
|
|
|
def error_inputs_gather(op_info, device, **kwargs):
|
|
# src is [1, 2]
|
|
# [3, 4]
|
|
src = torch.tensor(((1, 2), (3, 4)), device=device, dtype=torch.float32)
|
|
|
|
# idx is [0, 0]
|
|
# [1, 0]
|
|
idx = torch.tensor(((0, 0), (1, 0)), device=device, dtype=torch.long)
|
|
|
|
# Index should be smaller than self except on dimension 1
|
|
bad_src = make_tensor((1, 1), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(bad_src, args=(1, idx,)),
|
|
error_regex="Size does not match at dimension 0")
|
|
|
|
# Index must have long dtype
|
|
bad_idx = idx.to(torch.int32)
|
|
yield ErrorInput(SampleInput(src, args=(1, bad_idx)),
|
|
error_regex="Expected dtype int64 for index")
|
|
|
|
# TODO: FIXME
|
|
# out.dtype must match src.dtype
|
|
# Creates new src & idx since SampleInputs can't share tensors
|
|
src = torch.tensor(((1, 2), (3, 4)), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((0, 0), (1, 0)), device=device, dtype=torch.long)
|
|
out = torch.empty((2, 2), device=device, dtype=torch.float64)
|
|
yield ErrorInput(SampleInput(src, args=(1, idx), kwargs={'out': out}),
|
|
error_regex="Expected out tensor to have dtype")
|
|
|
|
# src and index tensors must have the same # of dimensions
|
|
# idx too few dimensions
|
|
src = torch.tensor(((1, 2), (3, 4)), device=device, dtype=torch.float32)
|
|
idx = torch.tensor((0, 0), device=device, dtype=torch.long)
|
|
yield ErrorInput(SampleInput(src, args=(1, idx)),
|
|
error_regex="Index tensor must have the same number of dimensions")
|
|
|
|
# src too few dimensions
|
|
src = torch.tensor((1, 2), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((0, 0), (1, 0)), device=device, dtype=torch.long)
|
|
yield ErrorInput(SampleInput(src, args=(0, idx)),
|
|
error_regex="Index tensor must have the same number of dimensions")
|
|
|
|
# index out of bounds
|
|
# NOTE: this ErrorInput is guarded because bounds checking does not occur on CUDA devices
|
|
if torch.device(device).type == 'cpu':
|
|
src = torch.tensor(((1, 2), (3, 4)), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((0, 23), (1, 0)), device=device, dtype=torch.long)
|
|
yield ErrorInput(SampleInput(src, args=(1, idx,)),
|
|
error_regex="index 23 is out of bounds for dimension")
|
|
|
|
x = torch.rand((1,), device=device).expand((3,))
|
|
src = torch.rand((6,), device=device)
|
|
ind = torch.tensor([2, 1, 0], device=device, dtype=torch.int64)
|
|
|
|
yield ErrorInput(SampleInput(src, args=(0, ind,), kwargs=dict(out=x)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
yield ErrorInput(SampleInput(src, args=(0, ind,), kwargs=dict(out=src)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
yield ErrorInput(SampleInput(ind.clone(), args=(0, ind[1:],), kwargs=dict(out=ind[:1])),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
def error_inputs_take(op_info, device, **kwargs):
|
|
x = torch.rand((1,), device=device).expand((3,))
|
|
src = torch.rand((6,), device=device)
|
|
ind = torch.tensor([2, 1, 0], device=device, dtype=torch.int64)
|
|
|
|
yield ErrorInput(SampleInput(src, args=(ind,), kwargs=dict(out=x)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
yield ErrorInput(SampleInput(src, args=(ind,), kwargs=dict(out=src)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
yield ErrorInput(SampleInput(ind.clone(), args=(ind[1:],), kwargs=dict(out=ind[:-1])),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
# Error inputs for scatter
|
|
def error_inputs_scatter_and_scatter_add(op_info, device, **kwargs):
|
|
# Error when self.dtype != src.dtype (and src is not a scalar)
|
|
src = make_tensor((2, 5), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((0, 1), (1, 2)), device=device, dtype=torch.long)
|
|
dst = torch.zeros((3, 5), device=device, dtype=torch.double)
|
|
yield ErrorInput(SampleInput(dst, args=(0, idx, src)),
|
|
error_regex="Expected self.dtype to be equal to src.dtype")
|
|
|
|
# Index dtype must be long
|
|
src = make_tensor((2, 5), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((0, 1), (1, 2)), device=device, dtype=torch.int32)
|
|
dst = torch.zeros((3, 5), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(dst, args=(0, idx, src)),
|
|
error_regex="Expected dtype int64 for index")
|
|
|
|
# Index and destination must have the same number of dimensions
|
|
src = make_tensor((2, 5), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((0, 1), (1, 2)), device=device, dtype=torch.long)
|
|
dst = torch.zeros((3, 5, 3), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(dst, args=(0, idx, src)),
|
|
error_regex="Index tensor must have the same number of dimensions as self tensor")
|
|
|
|
# Index and src must have the same number of dimensions when src is not a scalar
|
|
src = make_tensor((2, 5, 2), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((34, 1), (1, 2)), device=device, dtype=torch.long)
|
|
dst = torch.zeros((3, 5), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(dst, args=(0, idx, src)),
|
|
error_regex="Index tensor must have the same number of dimensions as src tensor")
|
|
|
|
# Index out of bounds
|
|
# NOTE: this ErrorInput is guarded because bounds checking does not occur on CUDA devices
|
|
if torch.device(device).type == 'cpu':
|
|
src = make_tensor((2, 5), device=device, dtype=torch.float32)
|
|
idx = torch.tensor(((34, 1), (1, 2)), device=device, dtype=torch.long)
|
|
dst = torch.zeros((3, 5), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(dst, args=(0, idx, src)),
|
|
error_regex="index 34 is out of bounds for dimension 0 with size 3")
|
|
|
|
def error_inputs_renorm(op_info, device, **kwargs):
|
|
zero_d = torch.randn((), device=device)
|
|
yield ErrorInput(SampleInput(zero_d, args=(0.5, 0, 1.0)), error_type=RuntimeError,
|
|
error_regex="needs at least 2 dimensions, got 0 dimensions")
|
|
|
|
|
|
def error_inputs_ormqr(op_info, device, **kwargs):
|
|
zero_d = torch.randn((), device=device)
|
|
yield ErrorInput(SampleInput(zero_d, args=(zero_d, zero_d)), error_type=RuntimeError,
|
|
error_regex="input must have at least 2 dimensions")
|
|
|
|
# https://github.com/pytorch/pytorch/issues/85218
|
|
tensor_0 = torch.full((5, 0,), 1, device=device)
|
|
tensor_1 = torch.full((5,), 1, device=device)
|
|
tensor_2 = torch.full((5, 5,), 1, device=device)
|
|
bool_3 = True
|
|
bool_4 = True
|
|
yield ErrorInput(SampleInput(tensor_0, args=(tensor_1, tensor_2, bool_3, bool_4)), error_type=RuntimeError,
|
|
error_regex=r"tau.shape\[-1\] must be less than or equal to input.shape\[-1\]")
|
|
|
|
|
|
def error_inputs_diag(op_info, device, **kwargs):
|
|
zero_d = torch.randn((), device=device)
|
|
yield ErrorInput(SampleInput(zero_d, args=(0,)), error_type=RuntimeError,
|
|
error_regex="1D or 2D")
|
|
zero_d = torch.randn(1, 1, 1, device=device)
|
|
yield ErrorInput(SampleInput(zero_d, args=(0,)), error_type=RuntimeError,
|
|
error_regex="1D or 2D")
|
|
|
|
def error_inputs_embedding(op_info, device, **kwargs):
|
|
indices = torch.rand(2, 2, device=device).long()
|
|
weights = [
|
|
torch.tensor(1.0, device=device),
|
|
torch.tensor(1.0, device=device).reshape(1, 1, 1),
|
|
]
|
|
|
|
for weight in weights:
|
|
yield ErrorInput(SampleInput(weight, args=(indices,)), error_type=RuntimeError,
|
|
error_regex="'weight' must be 2-D")
|
|
|
|
|
|
def error_inputs_t(op_info, device, **kwargs):
|
|
yield ErrorInput(
|
|
SampleInput(torch.randn(2, 3, 4, 5, device=device)),
|
|
error_regex="expects a tensor with <= 2",
|
|
)
|
|
|
|
|
|
def error_inputs_multinomial(op_info, device, **kwargs):
|
|
x = torch.empty(1, 2, 3, dtype=torch.double, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(2,)),
|
|
error_regex="prob_dist must be 1 or 2 dim")
|
|
|
|
x = torch.empty(1, 2, dtype=torch.long, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(2,)),
|
|
error_regex="multinomial only supports floating-point dtypes for input")
|
|
|
|
x = torch.empty(1, 2, dtype=torch.double, device=device)
|
|
y = torch.empty(1, 2, dtype=torch.double, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(2,), kwargs=dict(out=y)),
|
|
error_regex="multinomial expects Long tensor out")
|
|
|
|
x = torch.empty(2, dtype=torch.double, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(0,)),
|
|
error_regex="cannot sample n_sample <= 0 samples")
|
|
|
|
x = torch.empty(2, dtype=torch.double, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(-1,)),
|
|
error_regex="cannot sample n_sample <= 0 samples")
|
|
|
|
x = torch.empty(2, dtype=torch.double, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(3, False,)),
|
|
error_regex="cannot sample n_sample > prob_dist")
|
|
|
|
x = torch.empty(16777217, dtype=torch.double, device=device)
|
|
yield ErrorInput(SampleInput(x, args=(3,)),
|
|
error_regex="number of categories cannot exceed")
|
|
|
|
inputs = ((1., -1., 1.), (1., inf, 1.), (1., -inf, 1.), (1., 1., nan))
|
|
|
|
err_msg1 = "probability tensor contains either `inf`, `nan` or element < 0"
|
|
err_msg2 = "invalid multinomial distribution"
|
|
|
|
rep_arg = (False, True) if torch.device(device).type == 'cpu' else (False,)
|
|
|
|
if torch.device(device).type == 'cpu':
|
|
for rep in rep_arg:
|
|
kwargs = {'num_samples': 2, 'replacement': rep}
|
|
|
|
for shape in inputs:
|
|
# error case when input tensor contains `inf`, `nan` or negative element
|
|
yield ErrorInput(SampleInput(torch.tensor(shape), kwargs=kwargs),
|
|
error_regex=err_msg1 if rep is False else err_msg2)
|
|
|
|
# error case for the invalid multinomial distribution (sum of probabilities <= 0), 1-D input
|
|
x = torch.zeros(3, device=device)
|
|
yield ErrorInput(SampleInput(x, kwargs=kwargs),
|
|
error_regex=err_msg2)
|
|
|
|
# error case for the invalid multinomial distribution (sum of probabilities <= 0), 2-D input
|
|
x = torch.zeros(3, 3, device=device)
|
|
yield ErrorInput(SampleInput(x, kwargs=kwargs),
|
|
error_regex=err_msg2)
|
|
|
|
# error case for the invalid multinomial distribution
|
|
x[1, :] = 1
|
|
yield ErrorInput(SampleInput(x, kwargs=kwargs),
|
|
error_regex=err_msg2)
|
|
|
|
def error_inputs_gradient(op_info, device, **kwargs):
|
|
for dtype in [torch.long, torch.float32, torch.complex64]:
|
|
t = torch.tensor([[1, 2, 3], [4, 5, 6], [7, 8, 9]], device=device, dtype=dtype)
|
|
|
|
dim = (1, 0)
|
|
spacing = [0.1]
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(spacing=spacing, dim=dim, edge_order=1)),
|
|
error_type=RuntimeError,
|
|
error_regex='torch.gradient expected spacing to be unspecified, a scalar ')
|
|
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(edge_order=3)),
|
|
error_type=RuntimeError,
|
|
error_regex='torch.gradient only supports edge_order=1 and edge_order=2.')
|
|
|
|
dim = (1, 1)
|
|
spacing = 0.1
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(spacing=spacing, dim=dim, edge_order=1)),
|
|
error_type=RuntimeError,
|
|
error_regex='dim 1 appears multiple times in the list of dims')
|
|
|
|
dim = (0, 1)
|
|
coordinates = [torch.tensor([1, 2, 4], device='cpu'), torch.tensor([1, 2, 4], device='meta')]
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(spacing=coordinates, dim=dim, edge_order=1)),
|
|
error_type=RuntimeError,
|
|
error_regex='torch.gradient expected each tensor to be on the same device,')
|
|
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(dim=3)),
|
|
error_type=IndexError, error_regex='')
|
|
|
|
t = torch.tensor([[1], [2], [3]])
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(edge_order=1)),
|
|
error_type=RuntimeError,
|
|
error_regex='torch.gradient expected each dimension size to be at least')
|
|
|
|
t = torch.tensor([[1, 2], [3, 4]])
|
|
yield ErrorInput(SampleInput(t, kwargs=dict(edge_order=2)),
|
|
error_type=RuntimeError,
|
|
error_regex='torch.gradient expected each dimension size to be at least')
|
|
|
|
def sample_inputs_rrelu(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_elementwise_unary(
|
|
op_info, device, dtype, requires_grad, op_kwargs=dict(lower=0., upper=1., training=True))
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(S))
|
|
yield SampleInput(make_arg(S), training=False)
|
|
|
|
def error_inputs_rrelu(op_info, device, **kwargs):
|
|
input = make_tensor((S, S), device=device, dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(input, kwargs={'lower': 0.3, 'upper': 0.1}),
|
|
error_regex='Lower bound should be less than or equal to the upper bound')
|
|
|
|
def error_inputs_masked_select(op_info, device, **kwargs):
|
|
x = torch.rand((1,), device=device).expand((3,))
|
|
y = torch.rand((6,), device=device)
|
|
mask = torch.tensor([True, False, True, True, False, False], device=device)
|
|
|
|
yield ErrorInput(SampleInput(y, args=(mask,), kwargs=dict(out=x)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
yield ErrorInput(SampleInput(y, args=(mask,), kwargs=dict(out=y)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
yield ErrorInput(SampleInput(mask.clone(), args=(mask,), kwargs=dict(out=mask)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
def error_inputs_median(op_info, device, **kwargs):
|
|
x = torch.tensor([[[[[[[[[[[[[[[[[[[[[[[[[nan],
|
|
[nan]]]]]]]]]]]]]]]]]]]]]]]]], device=device)
|
|
if device == 'cuda':
|
|
yield ErrorInput(SampleInput(x, kwargs=dict(dim=(-1))),
|
|
error_type=RuntimeError,
|
|
error_regex='CUDA Tensors cannot have more than 25 dimensions')
|
|
else:
|
|
return
|
|
|
|
|
|
def error_inputs_index_select(op_info, device, **kwargs):
|
|
x = torch.rand((1, 6), device=device).expand((2, 6))
|
|
y = torch.rand((3, 6), device=device)
|
|
ind = torch.tensor([0, 1], dtype=torch.int64, device=device)
|
|
|
|
yield ErrorInput(SampleInput(y, args=(1, ind,), kwargs=dict(out=x)),
|
|
error_type=RuntimeError,
|
|
error_regex='unsupported operation')
|
|
|
|
def error_inputs_index_add(op_info, device, **kwargs):
|
|
result = torch.tensor([[1., 2.], [4., 5.], [7., 8.]])
|
|
source = torch.tensor([2., 4.])
|
|
|
|
yield ErrorInput(SampleInput(result, args=(0, torch.tensor([0, 2]), source)),
|
|
error_type=RuntimeError,
|
|
error_regex=r'source tensor shape must match self tensor shape, '
|
|
r'excluding the specified dimension. Got self.shape = \[3, 2\] source.shape = \[2\]')
|
|
|
|
def error_inputs_logcumsumexp(op_info, device, **kwargs):
|
|
dim = 3
|
|
srcs = [torch.randn(5, 2, device=device), torch.randn(0, 2, device=device)]
|
|
for src in srcs:
|
|
yield ErrorInput(SampleInput(src, args=(dim,)),
|
|
error_type=IndexError,
|
|
error_regex='Dimension out of range')
|
|
|
|
def sample_inputs_take_along_dim(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
yield SampleInput(
|
|
make_arg((S, S)), gather_variable((S, S), 1, S, True, device=device), 0)
|
|
|
|
# `indices` broadcast
|
|
yield SampleInput(
|
|
make_arg((S, S)), gather_variable((1, S // 2), 0, S, True, device=device), 1)
|
|
|
|
# `self` broadcast
|
|
yield SampleInput(
|
|
make_arg((1, S)), gather_variable((S, S // 2), 0, S, True, device=device), 1)
|
|
|
|
# without `dim` arg
|
|
yield SampleInput(
|
|
make_arg((S, S)), gather_variable((S, S // 2), 0, S, True, device=device))
|
|
|
|
|
|
def error_inputs_aminmax_amax_amin(op_info, device, is_ref=False, **kwargs):
|
|
|
|
# Error Inputs for zero-dim tensors, when 'dim' arg is not provided.
|
|
shape = (S, 0, S)
|
|
err_msg_amax_amin = "reduction"
|
|
err_msg_aminmax = "cannot compute aminmax over an empty dimension as the operation has no identity"
|
|
if op_info.name in ['amax', 'amin', '_refs.amax', '_refs.amin']:
|
|
yield ErrorInput(SampleInput(torch.rand(shape, device=device)), error_regex=err_msg_amax_amin)
|
|
elif op_info.name in ['aminmax']:
|
|
yield ErrorInput(SampleInput(torch.rand(shape, device=device)), error_regex=err_msg_aminmax)
|
|
|
|
# Error Inputs for tensors with more than 64 dimension
|
|
sizes = [1] * 65
|
|
err_msg1 = "only tensors with up to 64 dims are supported"
|
|
yield ErrorInput(SampleInput(torch.randn(sizes, device=device), kwargs={'dim': -1}),
|
|
error_regex=err_msg1)
|
|
yield ErrorInput(SampleInput(torch.randn(sizes, device=device), kwargs={'dim': 64}),
|
|
error_regex=err_msg1)
|
|
|
|
# Error Inputs for repeated 'dim'
|
|
if op_info.name in ['amax', 'amin', '_refs.amax', '_refs.amin']:
|
|
dims = [(0, 0), (0, -4)]
|
|
err_msg2 = "in the list of dims"
|
|
x = torch.randn(S, S, S, S, device=device)
|
|
for dim in dims:
|
|
yield ErrorInput(SampleInput(x, kwargs={'dim': dim}), error_regex=err_msg2)
|
|
|
|
# Error Input for illegal dtype
|
|
input5 = torch.randn(L, L, dtype=torch.float32, device=device)
|
|
max_values = torch.empty(L, dtype=torch.float32, device=device)
|
|
min_values = torch.empty(L, dtype=torch.double, device=device)
|
|
illegal_values = torch.empty(L, dtype=torch.int, device=device)
|
|
|
|
# Unlike regular PyTorch, amax and amin refs don't require input and out
|
|
# dtypes to match exactly:
|
|
# https://github.com/pytorch/pytorch/pull/87765#pullrequestreview-1162023824
|
|
if is_ref:
|
|
err_msg_amax_amin2 = ("Attempting to cast from torch.float32 to out tensor with dtype "
|
|
"torch.int32, but this can't be cast because it is not safe!")
|
|
else:
|
|
err_msg_amax_amin2 = ("Expected the dtype for input and out to match, but got Float "
|
|
"for input's dtype and Int for out's dtype.")
|
|
err_msg_aminmax2 = "Expected out tensor to have dtype float, but got double instead"
|
|
|
|
if op_info.name in ['amax', 'amin', '_refs.amax', '_refs.amin']:
|
|
yield ErrorInput(SampleInput(input5, kwargs={'dim': 0, 'out': illegal_values}),
|
|
error_regex=err_msg_amax_amin2)
|
|
elif op_info.name in ['aminmax']:
|
|
yield ErrorInput(SampleInput(input5, kwargs={'dim': 0, 'out': (max_values, min_values)}),
|
|
error_regex=err_msg_aminmax2)
|
|
|
|
# Error Inputs for functions to raise an error on specified zero'd dimension as reduction dim
|
|
err_msg3 = "reduction"
|
|
# FIXME: eager and ref impl throw different types of errors
|
|
error_type = IndexError if 'refs' not in op_info.name else RuntimeError
|
|
yield ErrorInput(SampleInput(torch.rand(shape, device=device), kwargs={'dim': 1}),
|
|
error_type=error_type, error_regex=err_msg3)
|
|
|
|
def sample_inputs_aminmax(op_info, device, dtype, requires_grad, **kwargs):
|
|
test_cases: Tuple[tuple, dict] = ( # type: ignore[assignment]
|
|
((S, S, S), {}),
|
|
((S, S, S), {'dim': 1}),
|
|
((S, S, S), {'dim': 1, 'keepdim': True}),
|
|
((), {'dim': 0}),
|
|
((), {}),
|
|
((), {'dim': 0, 'keepdim': True}),
|
|
((S, 0, S), {'dim': 0}),
|
|
)
|
|
|
|
for shape, kwargs in test_cases:
|
|
yield SampleInput(
|
|
make_tensor(shape, dtype=dtype, device=device, requires_grad=requires_grad),
|
|
**kwargs)
|
|
|
|
def error_inputs_diff(op_info, device, **kwargs):
|
|
t = torch.rand((1, 3), device=device)
|
|
n = -1
|
|
yield ErrorInput(SampleInput(t, args=(n, ), kwargs=kwargs),
|
|
error_type=RuntimeError,
|
|
error_regex=f'order must be non-negative but got {n}')
|
|
|
|
def sample_inputs_diff(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
test_cases = (
|
|
((1,), 0, None, None),
|
|
((S,), 0, None, None),
|
|
((S, 1), 0, None, None),
|
|
((S, 1), 1, None, None),
|
|
((S, S), 0, None, None),
|
|
((S, S), 1, None, None),
|
|
((S, S), 0, (1, S), (2, S)),
|
|
((S, S), 0, None, (2, S)),
|
|
((XS, XS, XS), 1, None, None),
|
|
((XS, XS, XS), 2, None, None),
|
|
((XS, XS, XS), 1, (XS, 1, XS), (XS, 1, XS)),
|
|
((XS, XS, XS), 2, (XS, XS, 1), (XS, XS, 1)),
|
|
((XS, XS, XS), 2, (XS, XS, XS), (XS, XS, XS)),)
|
|
|
|
for size, dim, size_prepend, size_append in test_cases:
|
|
prepend_size = 0 if (size_prepend is None) else size_prepend[dim]
|
|
append_size = 0 if (size_append is None) else size_append[dim]
|
|
dim_size = size[dim] + prepend_size + append_size
|
|
for n in range(dim_size):
|
|
input_tensor = make_arg(size)
|
|
prepend = make_arg(size_prepend) if size_prepend else None
|
|
append = make_arg(size_append) if size_append else None
|
|
yield SampleInput(input_tensor, n, dim, prepend, append)
|
|
|
|
# add some samples with n > dim_size
|
|
yield SampleInput(make_arg((XS, XS, XS)), S + 1, 1)
|
|
yield SampleInput(make_arg((XS, XS, XS)), S * 3 + 2, 2, make_arg((XS, XS, XS)), make_arg((XS, XS, XS)))
|
|
|
|
def sample_inputs_histogram(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
sizes = ((), (S,), (S, S), (S, S, S), (S, 1, S), (S, 0, S))
|
|
|
|
for size, bin_ct, weighted, density in product(sizes, range(1, 5), [False, True], [False, True]):
|
|
input_tensor = make_arg(size)
|
|
weight_tensor = make_arg(size) if weighted else None
|
|
|
|
yield SampleInput(input_tensor, bin_ct,
|
|
weight=weight_tensor, density=density)
|
|
|
|
bins_tensor = make_arg((bin_ct + 1,))
|
|
sorted_bins, _bins_indices = torch.sort(bins_tensor)
|
|
yield SampleInput(input_tensor, sorted_bins,
|
|
weight=weight_tensor, density=density)
|
|
|
|
def sample_inputs_histogramdd(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
sizes = ((S, S), (S, S, S), (S, 1, S), (S, 0, S))
|
|
bin_ct_patterns = ((1, 1, 1, 1, 1), (2, 3, 2, 3, 2), (3, 2, 3, 2, 3))
|
|
|
|
for size, bin_ct_pattern, weighted, density in product(sizes, bin_ct_patterns, [False, True], [False, True]):
|
|
input_tensor = make_arg(size)
|
|
bin_ct = bin_ct_pattern[:size[-1]]
|
|
weight_tensor = make_arg(size[:-1]) if weighted else None
|
|
|
|
yield SampleInput(input_tensor, bin_ct,
|
|
weight=weight_tensor, density=density)
|
|
|
|
bins_tensor = [make_arg(ct + 1) for ct in bin_ct]
|
|
yield SampleInput(input_tensor, bins_tensor,
|
|
weight=weight_tensor, density=density)
|
|
|
|
def error_inputs_histogramdd(opinfo, device, **kwargs):
|
|
invalid_bins = [1, 1, 1, 1, 1]
|
|
make_arg = partial(make_tensor, dtype=torch.float, device=device, requires_grad=False)
|
|
msg = "histogramdd: The size of bins must be equal to the innermost dimension of the input."
|
|
yield ErrorInput(SampleInput(make_arg(5, 6), invalid_bins), error_regex=msg)
|
|
|
|
def sample_inputs_histc(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
sizes = ((), (S,), (S, S), (S, S, S), (S, 1, S), (S, 0, S))
|
|
|
|
for size, min, max in product(sizes, [0, -10], [0, 10]):
|
|
# construct sample input omitting bins arg
|
|
yield SampleInput(make_arg(size), min=min, max=max)
|
|
|
|
# construct sample inputs with a few different bins values
|
|
for bins in [1, 3, 10]:
|
|
yield SampleInput(make_arg(size), bins=bins, min=min, max=max)
|
|
|
|
def sample_inputs_bincount(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
for size, weighted in product((S, M), [False, True]):
|
|
input_tensor = torch.randint(0, size, (size,), dtype=dtype, device=device)
|
|
weight_tensor = make_arg((size,)) if weighted else None
|
|
|
|
max_val = int(input_tensor.max().item())
|
|
|
|
for minlength in [0, max_val // 2, max_val, 2 * max_val]:
|
|
yield SampleInput(
|
|
input_tensor, weights=weight_tensor, minlength=minlength)
|
|
|
|
def sample_inputs_bucketize(op_info, device, dtype, requires_grad, reference_inputs_mode=False, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
sizes = (((), S), ((S,), S), ((S, S), S), ((S, S, S), S), ((S, 1, S), S), ((S, 0, S), S))
|
|
|
|
if reference_inputs_mode:
|
|
sizes += (((256,), 128), ((128,), 256), ((32, 32), 11), ((32, 4, 32), 33))
|
|
|
|
for (input_shape, nb), out_int32, right in product(sizes, [False, True], [False, True]):
|
|
input_tensor = make_arg(input_shape)
|
|
boundaries = make_arg(nb).msort()
|
|
|
|
yield SampleInput(input_tensor, boundaries,
|
|
out_int32=out_int32, right=right)
|
|
|
|
reference_inputs_bucketize = partial(sample_inputs_bucketize, reference_inputs_mode=True)
|
|
|
|
def error_inputs_bucketize(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=torch.float, device=device, requires_grad=False)
|
|
yield ErrorInput(SampleInput(make_arg((S, S, S)), make_arg((S, S))),
|
|
error_regex="boundaries tensor must be 1 dimension")
|
|
|
|
def sample_inputs_searchsorted(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# (unsorted tensor size, (input sizes,), is_scalar)
|
|
sizes = (
|
|
((0,), ((0,),), False),
|
|
((M,), ((), (M,), (M, M)), False),
|
|
((0, 0), ((0, 0),), False),
|
|
((M, M), ((M, M),), False),
|
|
((0, 0, 0), ((0, 0, 0),), False),
|
|
((M, M, M), ((M, M, M),), False),
|
|
((L,), ((),), True),
|
|
)
|
|
|
|
for (size, input_sizes, is_scalar), noncontiguous, out_int32, right in product(
|
|
sizes, [False, True], [False, True], [False, True]
|
|
):
|
|
unsorted_tensor = make_arg(size, noncontiguous=noncontiguous)
|
|
for input_size in input_sizes:
|
|
input = make_arg(input_size, noncontiguous=noncontiguous)
|
|
if is_scalar:
|
|
input = input.item()
|
|
if np.prod(size) == 0:
|
|
boundary_tensor = unsorted_tensor
|
|
sorter = make_tensor(size, dtype=torch.int64, device=device, noncontiguous=noncontiguous)
|
|
else:
|
|
boundary_tensor, sorter = torch.sort(unsorted_tensor)
|
|
side = "right" if right else "left"
|
|
|
|
yield SampleInput(boundary_tensor, input, out_int32=out_int32, right=right)
|
|
yield SampleInput(boundary_tensor, input, out_int32=out_int32, side=side)
|
|
|
|
yield SampleInput(unsorted_tensor, input, out_int32=out_int32, right=right, sorter=sorter)
|
|
yield SampleInput(unsorted_tensor, input, out_int32=out_int32, side=side, sorter=sorter)
|
|
|
|
def sample_inputs_gradient(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
test_cases_float = (
|
|
((S,), None, None, 1),
|
|
((S,), 2., None, 1),
|
|
((S, S), None, None, 2),
|
|
((S, S), [2.0, 2.1], None, 1),
|
|
((S, S), [2.0, 2.1], (0, 1), 1),
|
|
((4, 4, 4), [2., 1.], (0, 1), 2),
|
|
)
|
|
for size, spacing, dim, edge_order in test_cases_float:
|
|
t = make_arg(size)
|
|
yield SampleInput(t, dim=dim, spacing=spacing, edge_order=edge_order)
|
|
|
|
test_cases_tensor = (
|
|
((3, 3, 3), ((1.1, 2.0, 3.5), (4.0, 2, 6.0)), (0, -1), 1),
|
|
((3, 3, 3), ((1.0, 3.0, 2.0), (8.0, 6.0, 1.0)), (0, 1), 2),
|
|
)
|
|
for size, coordinates, dim, edge_order in test_cases_tensor:
|
|
t = make_arg(size)
|
|
coordinates_tensor_list = []
|
|
for coords in coordinates:
|
|
# `coords` will always contain floating point values and Python 3.10 does not support this
|
|
# implicit conversion to an integer using `__int__`
|
|
# TODO: this can be simplified after https://github.com/pytorch/pytorch/issues/69316 is fixed
|
|
a = torch.tensor(coords, device=device)
|
|
coordinates_tensor_list.append(a.to(dtype))
|
|
yield SampleInput(t, dim=dim, spacing=coordinates_tensor_list, edge_order=edge_order)
|
|
|
|
def sample_inputs_getitem(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
test_args = [
|
|
([1, 2],),
|
|
(slice(0, 3),),
|
|
([slice(0, 3), 1],),
|
|
([[0, 2, 3], [1, 3, 3], [0, 0, 2]],),
|
|
([[0, 0, 3], [1, 1, 3], [0, 0, 2]],),
|
|
([slice(None), slice(None), [0, 3]],),
|
|
([slice(None), [0, 3], slice(None)],),
|
|
([[0, 3], slice(None), slice(None)],),
|
|
([[0, 3], [1, 2], slice(None)],),
|
|
([[0, 3], ],),
|
|
([[0, 3], slice(None)],),
|
|
([[0, 3], Ellipsis],),
|
|
([[0, 2, 3], [1, 3, 3], torch.LongTensor([0, 0, 2])],),
|
|
(index_variable(2, S, device=device),),
|
|
(mask_not_all_zeros((S,)),),
|
|
]
|
|
|
|
for args in test_args:
|
|
yield SampleInput(make_arg((S, S, S)), args=args)
|
|
|
|
yield SampleInput(make_arg((S, S, S, S)), args=([slice(None), [0, 1], slice(None), [0, 1]],))
|
|
|
|
def sample_inputs_index_put(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
for accumulate in [False, True]:
|
|
# Test with indices arg
|
|
yield SampleInput(
|
|
make_arg((S, S,)),
|
|
(index_variable(2, S, device=device),),
|
|
make_arg((2, S)),
|
|
accumulate=accumulate)
|
|
|
|
# Test with mask arg
|
|
mask = torch.zeros(S, dtype=torch.bool) if accumulate else mask_not_all_zeros((S,))
|
|
yield SampleInput(
|
|
make_arg((S, S)), (mask, ), make_arg((S,)), accumulate=accumulate)
|
|
|
|
def sample_inputs_sort(op_info, device, dtype, requires_grad, **kwargs):
|
|
def small_3d_unique():
|
|
res = torch.randperm(S * S * S, dtype=torch.int64, device=device).view(S, S, S)
|
|
res = res.to(dtype).requires_grad_(requires_grad)
|
|
return res
|
|
|
|
def large_1d_unique():
|
|
res = torch.randperm(L * L * L, dtype=torch.int64, device=device)
|
|
res = res.to(dtype).requires_grad_(requires_grad)
|
|
return res
|
|
|
|
# Test case for large tensor.
|
|
yield SampleInput(large_1d_unique())
|
|
|
|
# Test cases for small 3d tensors.
|
|
# Imitates legacy tests from test/test_torch.py
|
|
dims = range(-3, 3)
|
|
flag = [True, False]
|
|
for dim, descending, stable in product(dims, flag, flag):
|
|
# default schema without stable sort
|
|
if not (dtype == torch.bool and torch.device(device).type == 'cuda'):
|
|
# bool and cuda requires stable sort for stable results, at least
|
|
# for the return index
|
|
yield SampleInput(small_3d_unique(), dim, descending)
|
|
# schema with stable sort, no CUDA support yet
|
|
if torch.device(device).type == 'cpu':
|
|
yield SampleInput(
|
|
small_3d_unique(), dim=dim, descending=descending, stable=stable)
|
|
|
|
# Test cases for scalar tensor
|
|
tensor_opt = dict(dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(torch.tensor(1, **tensor_opt))
|
|
yield SampleInput(torch.tensor(1, **tensor_opt), 0)
|
|
yield SampleInput(torch.tensor(1, **tensor_opt), 0, True)
|
|
|
|
# Test cases for empty tensor
|
|
yield SampleInput(torch.tensor((), **tensor_opt))
|
|
yield SampleInput(torch.tensor((), **tensor_opt), 0)
|
|
yield SampleInput(torch.tensor((), **tensor_opt), 0, True)
|
|
|
|
# Test cases for stable sort
|
|
yield SampleInput(small_3d_unique(), stable=True)
|
|
yield SampleInput(small_3d_unique(), dim=0, stable=True)
|
|
yield SampleInput(small_3d_unique(), dim=0, descending=True, stable=True)
|
|
|
|
def sample_inputs_threshold(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
sizes = ((), (S,), (S, S), (S, S, S))
|
|
for x_size in sizes:
|
|
# threshold and values args must be numbers
|
|
yield SampleInput(make_arg(x_size), make_arg(()).item(), make_arg(()).item())
|
|
|
|
def sample_inputs_unique(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
sizes = ((), (S,), (S, S), (S, S, S), (S, 1, S), (S, 0, S))
|
|
|
|
for shape, sorted, return_inverse, return_counts, dim in \
|
|
product(sizes, [False, True], [False, True], [False, True], [None, -2, -1, 0, 1, 2]):
|
|
# torch.unique cannot be called if the input tensor has a zero dimension which isn't the selected dim
|
|
if 0 in shape and shape.index(0) is not dim:
|
|
continue
|
|
|
|
# skip invalid dim args
|
|
if dim is not None and (dim < -len(shape) or dim >= len(shape)):
|
|
continue
|
|
|
|
kwargs = dict(sorted=sorted, return_inverse=return_inverse, return_counts=return_counts, dim=dim)
|
|
|
|
# construct a test case with only one distinct value
|
|
input_t = torch.zeros(shape, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(input_t, **kwargs)
|
|
|
|
# construct a test case with mixed 0s and 1s
|
|
input_t = make_arg(shape, dtype=torch.bool, requires_grad=False)\
|
|
.to(dtype).requires_grad_(requires_grad)
|
|
yield SampleInput(input_t, **kwargs)
|
|
|
|
# construct a test case with many different values
|
|
yield SampleInput(make_arg(shape), **kwargs)
|
|
|
|
def sample_inputs_unique_consecutive(*args, **kwargs):
|
|
for sample_input in sample_inputs_unique(*args, **kwargs):
|
|
if not sample_input.kwargs["sorted"]:
|
|
sample_input.kwargs.pop("sorted")
|
|
yield sample_input
|
|
|
|
def sample_inputs_adaptive_avg_pool1d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as (input shape, output size)
|
|
cases = (
|
|
((0, 8, 8), (5,)),
|
|
((3, 8, 8), 5),
|
|
((3, 8, 8), 1)
|
|
)
|
|
|
|
for input_shape, output_size in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(output_size,))
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(output_size,))
|
|
|
|
|
|
def error_inputs_adaptive_avg_pool1d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for empty output
|
|
yield ErrorInput(SampleInput(make_arg((1, 2, 3)), output_size=()),
|
|
error_regex="'output_size' should contain one int")
|
|
|
|
# error inputs for output_size lesser than 0
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 1)), output_size=(-1,)),
|
|
error_regex="elements of output_size must be greater than or equal to 0")
|
|
|
|
|
|
def sample_inputs_adaptive_avg_pool2d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as (input shape, output size)
|
|
cases = (
|
|
((1, 8, 8, 8), (5, 7)),
|
|
((2, 8, 8, 8), (None, 7)),
|
|
((1, 8, 4, 3), (5, None)),
|
|
((1, 8, 4, 3), (None, None)),
|
|
((1, 8, 4, 3), (5)),
|
|
)
|
|
|
|
for input_shape, output_size in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(output_size,))
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(output_size,))
|
|
|
|
|
|
def error_inputs_adaptive_avg_pool2d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for incorrect input dimension
|
|
yield ErrorInput(SampleInput(make_arg((2, 2)), output_size=(2, 2)),
|
|
error_type=ValueError, error_regex="Input dimension should be at least 3")
|
|
|
|
# error inputs for empty output
|
|
yield ErrorInput(SampleInput(make_arg((1, 2, 3, 4)), output_size=()),
|
|
error_regex="output_size must be 2")
|
|
|
|
# error inputs for output_size lesser than 0
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 1, 1)), output_size=(-1, 0)),
|
|
error_regex="elements of output_size must be greater than or equal to 0")
|
|
|
|
|
|
def sample_inputs_adaptive_avg_pool3d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as (input shape, output size)
|
|
cases = (
|
|
((0, 8, 8, 8, 8), (5, 7, 4)),
|
|
((1, 8, 4, 3, 7), (None, None, None)),
|
|
((1, 8, 4, 3, 7), (1, 1, 1)),
|
|
((3, 3, 8, 8, 6), (5, 7, None)),
|
|
((1, 3, 8, 8, 6), (5, None, 2)),
|
|
((3, 3, 8, 8, 6), (None, 3, 2)),
|
|
)
|
|
|
|
for input_shape, output_size in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(output_size,))
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(output_size,))
|
|
|
|
|
|
def error_inputs_adaptive_avg_pool3d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for incorrect input dimension
|
|
yield ErrorInput(SampleInput(make_arg((2, 2, 2)), output_size=(2, 2, 2)),
|
|
error_type=ValueError, error_regex="Input dimension should be at least 4")
|
|
|
|
# error inputs for empty output
|
|
yield ErrorInput(SampleInput(make_arg((1, 2, 3, 4)), output_size=()),
|
|
error_regex="output_size must be 3")
|
|
|
|
# error inputs for output_size lesser than 0
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 1, 1, 1)), output_size=(-1, 0, 2)),
|
|
error_regex="elements of output_size must be greater than or equal to 0")
|
|
|
|
|
|
def sample_inputs_adaptive_max_pool1d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as (input shape, output size)
|
|
cases = (
|
|
# ((0, 8, 8), (5,)),
|
|
# 0 batch size doesn't work, cannot reshape tensor of 0 elements into shape [0, 8, -1]
|
|
((3, 4, 4), 3),
|
|
((3, 4, 4), 1)
|
|
)
|
|
|
|
for shapes, return_idx in product(cases, (True, False)):
|
|
# Batched
|
|
yield SampleInput(make_arg(shapes[0]), args=(shapes[1], return_idx))
|
|
# Unbatched
|
|
yield SampleInput(make_arg(shapes[0][1:]), args=(shapes[1], return_idx))
|
|
|
|
|
|
def error_inputs_adaptive_max_pool1d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for empty output
|
|
yield ErrorInput(SampleInput(make_arg((1, 2, 3)), output_size=()),
|
|
error_regex="'output_size' should contain one int")
|
|
|
|
# error inputs for output_size lesser than 0
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 1)), output_size=(-1,)),
|
|
error_regex="Trying to create tensor with negative dimension")
|
|
|
|
def sample_inputs_adaptive_max_pool2d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as (input shape, output size)
|
|
cases = (
|
|
# ((0, 8, 8, 8), (5, 7)),
|
|
# 0 batch size doesn't work, cannot reshape tensor of 0 elements into shape [0, 8, -1]
|
|
((1, 4, 4, 4), (2, 3)),
|
|
((2, 4, 4, 4), (None, 3)),
|
|
((2, 4, 4, 4), (1, 1)),
|
|
((1, 4, 4, 3), (3, None)),
|
|
((1, 4, 4, 3), (None, None)),
|
|
((1, 4, 4, 3), (3)),
|
|
)
|
|
|
|
for shapes, return_idx in product(cases, (True, False)):
|
|
# Batched
|
|
yield SampleInput(make_arg(shapes[0]), args=(shapes[1], return_idx))
|
|
# Unbatched
|
|
yield SampleInput(make_arg(shapes[0][1:]), args=(shapes[1], return_idx))
|
|
|
|
def error_inputs_adaptive_max_pool2d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for incorrect input dimension
|
|
yield ErrorInput(SampleInput(make_arg((2, 2)), output_size=(2, 2)),
|
|
error_type=ValueError, error_regex="Input dimension should be at least 3")
|
|
|
|
# error inputs for empty output
|
|
yield ErrorInput(SampleInput(make_arg((1, 2, 3, 4)), output_size=()),
|
|
error_regex="internal error")
|
|
|
|
# error inputs for output_size lesser than 0
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 1, 1)), output_size=(-1, 0)),
|
|
error_regex="Trying to create tensor with negative dimension")
|
|
|
|
|
|
def sample_inputs_adaptive_max_pool3d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as (input shape, output size)
|
|
cases = (
|
|
# ((0, 8, 8, 8, 8), (5, 7, 4)),
|
|
# 0 batch size doesn't work, cannot reshape tensor of 0 elements into shape [0, 8, -1]
|
|
((1, 4, 4, 3, 5), (None, None, None)),
|
|
((1, 4, 4, 3, 5), (1, 1, 1)),
|
|
((3, 3, 4, 4, 6), (2, 3, None)),
|
|
((1, 3, 4, 4, 6), (3, None, 2)),
|
|
((3, 3, 4, 4, 6), (None, 3, 2)),
|
|
)
|
|
|
|
for shapes, return_idx in product(cases, (True, False)):
|
|
# Batched
|
|
yield SampleInput(make_arg(shapes[0]), args=(shapes[1], return_idx))
|
|
# Unbatched
|
|
yield SampleInput(make_arg(shapes[0][1:]), args=(shapes[1], return_idx))
|
|
|
|
def error_inputs_adaptive_max_pool3d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for incorrect input dimension
|
|
yield ErrorInput(SampleInput(make_arg((2, 2, 2)), output_size=(2, 2, 2)),
|
|
error_type=ValueError, error_regex="Input dimension should be at least 4")
|
|
|
|
# error inputs for empty output
|
|
yield ErrorInput(SampleInput(make_arg((1, 2, 3, 4)), output_size=()),
|
|
error_regex="internal error")
|
|
|
|
# error inputs for output_size lesser than 0
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 1, 1, 1)), output_size=(-1, 0, 2)),
|
|
error_regex="Trying to create tensor with negative dimension")
|
|
|
|
|
|
class _TestParamsMaxPoolBase:
|
|
|
|
def __init__(self) -> None:
|
|
self.kwargs = {
|
|
'kernel_size': [3],
|
|
'stride': [2, None],
|
|
'ceil_mode': [True, False],
|
|
'padding': [0, 1],
|
|
'dilation': [1],
|
|
'return_indices': [True, False]
|
|
}
|
|
|
|
self.shapes = [
|
|
[1, 2, None], # batch
|
|
[2], # channels
|
|
[3, 6] # signal
|
|
]
|
|
|
|
def _gen_shape(self):
|
|
for shape in product(*self.shapes):
|
|
# shape[0] is None indicates missing batch dimension
|
|
if shape[0] is None:
|
|
shape = shape[1:]
|
|
|
|
yield shape, torch.contiguous_format
|
|
# only 2d (N, C, H, W) rank 4 tensors support channels_last memory format
|
|
if len(self.shapes) == 4 and len(shape) == 4:
|
|
yield shape, torch.channels_last
|
|
|
|
def _gen_kwargs(self):
|
|
keys = self.kwargs.keys()
|
|
for values in product(*self.kwargs.values()):
|
|
yield dict(zip(keys, values))
|
|
|
|
def gen_input_params(self):
|
|
yield from product(self._gen_shape(), self._gen_kwargs())
|
|
|
|
class _TestParamsMaxPool1d(_TestParamsMaxPoolBase):
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.kwargs['kernel_size'] += [(3,)]
|
|
self.kwargs['stride'] += [(2,)]
|
|
self.kwargs['padding'] += [(1,)]
|
|
self.kwargs['dilation'] += [(1,)]
|
|
|
|
class _TestParamsMaxPool2d(_TestParamsMaxPoolBase):
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.kwargs['kernel_size'] += [(3, 2)]
|
|
self.kwargs['stride'] += [(2, 1)]
|
|
self.kwargs['padding'] += [(1, 1)]
|
|
self.kwargs['dilation'] += [(1, 2)]
|
|
|
|
self.shapes.append([6])
|
|
|
|
class _TestParamsMaxPool3d(_TestParamsMaxPoolBase):
|
|
|
|
def __init__(self) -> None:
|
|
super().__init__()
|
|
self.kwargs['kernel_size'] += [(3, 2, 3)]
|
|
self.kwargs['stride'] += [(2, 1, 2)]
|
|
self.kwargs['dilation'] += [(1, 2, 1)]
|
|
|
|
self.shapes.append([6])
|
|
self.shapes.append([5])
|
|
|
|
def sample_inputs_max_pool(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=False)
|
|
|
|
params_generator_type_dict = {
|
|
'nn.functional.max_pool1d': _TestParamsMaxPool1d,
|
|
'nn.functional.max_pool2d': _TestParamsMaxPool2d,
|
|
'nn.functional.max_pool3d': _TestParamsMaxPool3d,
|
|
'max_pool2d_with_indices_backward': _TestParamsMaxPool2d,
|
|
}
|
|
|
|
params_generator = params_generator_type_dict[op_info.name]()
|
|
for (shape, memory_format), kwargs in params_generator.gen_input_params():
|
|
arg = make_arg(shape).to(memory_format=memory_format).requires_grad_(requires_grad)
|
|
yield SampleInput(arg, kwargs=kwargs)
|
|
|
|
def max_pool2d_backward(*args, kernel_size=(), stride=(), padding=(0,), dilation=(1,), ceil_mode=False, **kwargs):
|
|
out, indices = torch.nn.functional.max_pool2d_with_indices(
|
|
*args, kernel_size=kernel_size, stride=stride, padding=padding, dilation=dilation, ceil_mode=ceil_mode, return_indices=True)
|
|
grad_out = torch.ones_like(out)
|
|
if stride is None:
|
|
stride = kernel_size
|
|
out_b = torch.ops.aten.max_pool2d_with_indices_backward.default(
|
|
grad_out, *args, kernel_size, stride, padding, dilation, ceil_mode, indices)
|
|
return out_b
|
|
|
|
def error_inputs_max_pool1d(op_info, device, **kwargs):
|
|
# Toggle requires_grad because `max_pool1d` has different path
|
|
# based on whether `requires_grad` is set or not.
|
|
for requires_grad in (True, False):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float, requires_grad=requires_grad)
|
|
# error inputs when pad is negative
|
|
x = make_arg((0, 1, 49))
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': -1, 'return_indices': True}),
|
|
error_regex='pad must be non-negative')
|
|
|
|
# error inputs when pad > kernel_size / 2
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 4, 'return_indices': True}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error inputs when pad > ((kernel_size - 1) * dilation + 1) / 2, when dilation is not default
|
|
yield ErrorInput(SampleInput(x,
|
|
kwargs={'kernel_size': 3, 'dilation': 2, 'stride': 1, 'padding': 3, 'return_indices': True}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error inputs for input tensor
|
|
error_msg = r'Expected 2D or 3D \(batch mode\) tensor with optional 0 dim batch size for input'
|
|
yield ErrorInput(SampleInput(make_arg((), requires_grad=requires_grad), kwargs={'kernel_size': 1}),
|
|
error_regex=error_msg)
|
|
|
|
# error inputs for empty input
|
|
yield ErrorInput(SampleInput(torch.tensor([], device=device, requires_grad=requires_grad),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=error_msg)
|
|
|
|
# error: unbatched input with 0 sized non-batch dims.
|
|
yield ErrorInput(SampleInput(make_arg((0, 10), requires_grad=requires_grad),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=error_msg)
|
|
|
|
# error: batched input with 0 sized non-batch dims.
|
|
yield ErrorInput(SampleInput(make_arg((1, 10, 0), requires_grad=requires_grad),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=error_msg)
|
|
|
|
# error inputs for empty input with stride=0
|
|
error_msg = 'stride must be greater than zero, but got 0'
|
|
yield ErrorInput(SampleInput(make_arg((3, 3, 3)), kwargs={'kernel_size': 1, 'stride': 0}),
|
|
error_regex=error_msg)
|
|
|
|
# error inputs for empty input with dilation=0
|
|
error_msg = 'dilation must be greater than zero, but got 0'
|
|
yield ErrorInput(SampleInput(make_arg((3, 3, 3)),
|
|
kwargs={'kernel_size': 1, 'stride': 1, 'padding': 0, 'dilation': 0}),
|
|
error_regex=error_msg)
|
|
|
|
# error inputs for invalid output size
|
|
error_msg = 'Invalid computed output size: -2'
|
|
yield ErrorInput(SampleInput(make_arg((2, 2, 2)),
|
|
kwargs={'kernel_size': 5, 'stride': 1, 'padding': 0, 'dilation': 1}),
|
|
error_regex=error_msg)
|
|
|
|
# error inputs when kernel_size=0
|
|
error_msg = 'kernel_size must be greater than zero'
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 0}),
|
|
error_regex=error_msg)
|
|
|
|
# error inputs for strides > 0
|
|
error_msg = 'stride must be greater than zero'
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 0}),
|
|
error_regex=error_msg)
|
|
|
|
|
|
def error_inputs_max_pool2d(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float, requires_grad=False)
|
|
# error inputs when pad is negative
|
|
x = make_arg((0, 1, 49))
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': -1, 'return_indices': True}),
|
|
error_regex='pad must be non-negative')
|
|
# 2-dimensional kernel
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2), 'stride': 50, 'padding': -1, 'return_indices': True}),
|
|
error_regex='pad must be non-negative')
|
|
|
|
# error inputs when pad > kernel_size / 2 (kernel_size : int)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 4, 'return_indices': True}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error inputs when pad > kernel_size / 2 (kernel_size : tuple)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2), 'stride': 50, 'padding': 4, 'return_indices': True}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error: unbatched input with 0 sized non-batch dims.
|
|
err_msg = r'Expected 3D or 4D \(batch mode\) tensor with optional 0 dim batch size for input'
|
|
yield ErrorInput(SampleInput(make_arg((1, 0, 10)),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=err_msg)
|
|
|
|
# error: batched input with 0 sized non-batch dims.
|
|
yield ErrorInput(SampleInput(make_arg((2, 1, 10, 0)),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=err_msg)
|
|
|
|
|
|
def error_inputs_max_pool3d(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float, requires_grad=False)
|
|
# error inputs when pad is negative
|
|
x = make_arg((0, 1, 49, 50))
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': -1, 'return_indices': True}),
|
|
error_regex='pad must be non-negative')
|
|
# 3-dimensional kernel
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2, 2), 'stride': 50,
|
|
'padding': -1, 'return_indices': True}),
|
|
error_regex='pad must be non-negative')
|
|
|
|
# error inputs when pad > kernel_size / 2 (kernel_size: int)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 4, 'return_indices': True}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error inputs when pad > kernel_size / 2 (kernel_size: tuple)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2, 2), 'stride': 50,
|
|
'padding': 4, 'return_indices': True}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error: unbatched input with 0 sized non-batch dims.
|
|
err_msg = r'Expected input\'s non-batch dimensions to have positive length'
|
|
yield ErrorInput(SampleInput(make_arg((0, 1, 2, 10)),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=err_msg)
|
|
|
|
# error: batched inputs with 0 sized non-batch dims.
|
|
yield ErrorInput(SampleInput(make_arg((2, 1, 0, 1, 2)),
|
|
kwargs={'kernel_size': 1}),
|
|
error_regex=err_msg)
|
|
|
|
|
|
def sample_inputs_normalize(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, low=-1, high=1, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases: Tuple[Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((2, 1, 4, 5), {'p': 1., 'dim': 2}),
|
|
((2, 3, 4, 5), {'p': 2., 'dim': 1}),
|
|
((1, 2, 4, 5), {'p': 0.5, 'dim': 0}),
|
|
((1, 3, 4, 5), {'p': -1., 'dim': 1}),
|
|
((1, 3, 4, 5), {'p': 0., 'dim': -1}),
|
|
((), {'p': 1.2, 'dim': 0}),
|
|
((2, 3, 4, 5), {}),
|
|
((2, 3, 4, 5), {'eps': 1e-4}))
|
|
|
|
for input_shape, kwargs in cases:
|
|
yield SampleInput(make_arg(input_shape), kwargs=kwargs)
|
|
|
|
|
|
def complex_conv(fn, input_size, weight, grad_output, stride, padding, dilation, groups):
|
|
# conv(W, x, b) = conv(Wr, xr, br) - conv(Wi, xi, 0) + i(conv(Wi, xr, bi) + conv(Wr, xi, 0))
|
|
# a = conv(Wr, xr, br),
|
|
# b = conv(Wi, xi, 0),
|
|
# c = conv(Wr + Wi, xr + xi, br + bi)
|
|
# conv(W, x, b) = a - b + i(c - a - b)
|
|
|
|
grad_output_ = torch.view_as_real(grad_output)
|
|
grad_output_r = grad_output_[..., 0]
|
|
grad_output_i = grad_output_[..., 1]
|
|
|
|
weight_ = torch.view_as_real(weight)
|
|
weight_r = weight_[..., 0]
|
|
weight_i = weight_[..., 1]
|
|
|
|
a = fn(input_size, weight_r, grad_output_r, stride, padding, dilation, groups)
|
|
b = fn(input_size, weight_i, grad_output_i, stride, padding, dilation, groups)
|
|
c = fn(input_size, weight_r + weight_i, grad_output_r + grad_output_i, stride, padding, dilation, groups)
|
|
|
|
return (a - b) + 1j * (c - a - b)
|
|
|
|
|
|
def conv_transpose_ref(input, weight, bias, stride=1, padding=0,
|
|
output_padding=0, dilation=1, groups=1,
|
|
fn=None):
|
|
# Derivative of `conv` is `conv_transpose`.
|
|
# To verify the correctness of `conv_transpose`,
|
|
# we rely `torch.nn.grad` implementation (which is tested in test_nn.py)
|
|
# for floating dtypes.
|
|
|
|
assert fn is not None
|
|
|
|
grad_fn_map = {torch.nn.functional.conv_transpose1d: torch.nn.grad.conv1d_input,
|
|
torch.nn.functional.conv_transpose2d: torch.nn.grad.conv2d_input,
|
|
torch.nn.functional.conv_transpose3d: torch.nn.grad.conv3d_input}
|
|
batched_dim_map = {torch.nn.functional.conv_transpose1d: 3,
|
|
torch.nn.functional.conv_transpose2d: 4,
|
|
torch.nn.functional.conv_transpose3d: 5}
|
|
|
|
# Input for `ref` is ndarray.
|
|
input, weight = torch.from_numpy(input), torch.from_numpy(weight)
|
|
|
|
is_batched = len(input.shape) == batched_dim_map[fn]
|
|
if not is_batched:
|
|
input = input.unsqueeze(0)
|
|
|
|
if bias is not None:
|
|
bias = torch.from_numpy(bias)
|
|
unsqueeze_dims = input.ndim - 2
|
|
for _ in range(unsqueeze_dims):
|
|
bias = bias.unsqueeze(1)
|
|
|
|
grad_output = input
|
|
# Get the input shape for grad_fn.
|
|
conv_transpose_output = fn(grad_output.to('meta'), weight.to('meta'), None,
|
|
stride=stride, padding=padding, output_padding=output_padding,
|
|
groups=groups, dilation=dilation)
|
|
input_size = conv_transpose_output.shape
|
|
|
|
grad_fn = grad_fn_map[fn]
|
|
if weight.dtype.is_complex:
|
|
out = complex_conv(grad_fn, input_size, weight, grad_output, stride, padding, dilation, groups)
|
|
else: # Floating
|
|
out = grad_fn(input_size, weight, grad_output, stride, padding, dilation, groups)
|
|
|
|
if bias is not None:
|
|
out = out + bias
|
|
|
|
return out.squeeze(0) if not is_batched else out
|
|
|
|
|
|
def sample_inputs_conv_transpose1d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as shapes for input, weight, bias
|
|
# and a dict of values of (stride, padding, output_padding, groups, dilation)
|
|
cases: Tuple[Tuple[int], Tuple[int], Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((1, 3, 4), (3, 3, 3), (3,),
|
|
{'stride': (2,), 'padding': 2, 'output_padding': (1,), 'groups': 1}),
|
|
((2, 2, 4), (2, 2, 4), (4,),
|
|
{'stride': (3,), 'padding': (1,), 'output_padding': (2,), 'groups': 2, 'dilation': (4,)}),
|
|
((1, 1, 4), (1, 1, 4), (1,),
|
|
{'stride': 2, 'padding': 1, 'output_padding': 1, 'groups': 1, 'dilation': (2,)}),
|
|
((1, 1, 4), (1, 2, 3), None,
|
|
{'stride': 2, 'padding': 1, 'output_padding': 1, 'groups': 1}),
|
|
((1, 4, 5), (4, 8, 3), None,
|
|
{})
|
|
)
|
|
|
|
for input_shape, weight, bias, kwargs in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
|
|
|
|
def sample_inputs_conv_transpose2d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as shapes for input, weight, bias
|
|
# and a dict of values of (stride, padding, output_padding, groups, dilation)
|
|
cases: Tuple[Tuple[int], Tuple[int], Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((1, 3, 4, 4), (3, 3, 3, 3), (3,),
|
|
{'stride': (2, 2), 'padding': 2, 'output_padding': (1, 1), 'groups': 1}),
|
|
((2, 2, 4, 4), (2, 2, 4, 5), (4,),
|
|
{'stride': (3, 2), 'padding': (1, 2), 'output_padding': (2, 3), 'groups': 2, 'dilation': (4, 4)}),
|
|
((1, 1, 4, 5), (1, 1, 4, 3), (1,),
|
|
{'stride': 2, 'padding': 1, 'output_padding': 1, 'groups': 1, 'dilation': (2, 3)}),
|
|
((1, 1, 4, 3), (1, 2, 3, 4), None,
|
|
{'stride': 2, 'padding': 1, 'output_padding': 1, 'groups': 1}),
|
|
((2, 4, 4, 4), (4, 1, 3, 3), None, {'groups': 4}),
|
|
((1, 2, 5, 5), (2, 4, 3, 3), None, {})
|
|
)
|
|
|
|
for input_shape, weight, bias, kwargs in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
|
|
def sample_inputs_conv_transpose3d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as shapes for input, weight, bias
|
|
# and a dict of values of (stride, padding, output_padding, groups, dilation)
|
|
cases: Tuple[Tuple[int], Tuple[int], Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((1, 3, 4, 4, 4), (3, 3, 3, 3, 3), (3,),
|
|
{'stride': (2, 2, 2), 'padding': 2, 'output_padding': (1, 1, 1), 'groups': 1}),
|
|
((2, 2, 4, 4, 4), (2, 2, 4, 5, 6), (4,),
|
|
{'stride': (3, 2, 1), 'padding': (1, 2, 3), 'output_padding': (2, 3, 1), 'groups': 2, 'dilation': (4, 4, 4)}),
|
|
((1, 1, 4, 5, 2), (1, 1, 4, 3, 1), (1,),
|
|
{'stride': 2, 'padding': 1, 'output_padding': 1, 'groups': 1, 'dilation': (2, 3, 2)}),
|
|
((1, 1, 4, 3, 4), (1, 2, 3, 4, 5), None,
|
|
{'stride': 2, 'padding': 1, 'output_padding': 1, 'groups': 1}),
|
|
((1, 4, 5, 5, 5), (4, 8, 3, 3, 3), None,
|
|
{})
|
|
)
|
|
|
|
for input_shape, weight, bias, kwargs in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
|
|
|
|
def sample_inputs_conv1d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as shapes for input, weight, bias,
|
|
# and a dict of values of (stride, padding, dilation, groups)
|
|
cases: Tuple = (
|
|
((1, 3, 4), (3, 3, 3), (3,), {'stride': (2,), 'padding': 2, 'groups': 1}),
|
|
((2, 4, 8), (2, 2, 3), (2,), {'stride': 3, 'padding': 1, 'groups': 2, 'dilation': 2}),
|
|
((1, 4, 5), (1, 4, 3), None, {'stride': (2,), 'padding': 'valid'}),
|
|
((2, 2, 4), (2, 1, 4), (2,), {'stride': (1,), 'padding': 'same', 'groups': 2, 'dilation': (2,)}),
|
|
# With defaults
|
|
((1, 4, 5), (3, 4, 3), None, {}),
|
|
)
|
|
|
|
for input_shape, weight, bias, kwargs in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
|
|
|
|
def error_inputs_conv1d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float64)
|
|
make_int_arg = partial(make_tensor, device=device, dtype=torch.int64)
|
|
make_complex_arg = partial(make_tensor, device=device, dtype=torch.complex128)
|
|
|
|
# error inputs for different dtypes of input tensor and bias
|
|
yield ErrorInput(
|
|
SampleInput(make_int_arg((1, 1, 4)), args=(make_int_arg((1, 1, 2)), make_arg((1,)))),
|
|
error_regex="should be the same")
|
|
|
|
# error inputs for different dtypes of input tensor and bias
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4)), args=(make_arg((1, 1, 2)), make_complex_arg((1,)))),
|
|
error_regex="should be the same")
|
|
|
|
# error inputs for negative strides
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4)), args=(make_arg((1, 2, 2)), make_arg((1,))),
|
|
kwargs={'stride': (-1,)}), error_regex="non-positive stride is not supported")
|
|
|
|
# error inputs for negative padding
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4)), args=(make_arg((1, 2, 2)), make_arg((1,))),
|
|
kwargs={'padding': (-1,)}), error_regex="negative padding is not supported")
|
|
|
|
# error inputs for negative dilation
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4)), args=(make_arg((1, 1, 2)), make_arg((1,))),
|
|
kwargs={'dilation': (-1,)}), error_regex="dilation should be greater than zero")
|
|
|
|
# FIXME: https://github.com/pytorch/pytorch/issues/85656
|
|
# error inputs for bias shape not equal to the output channels
|
|
# yield ErrorInput(SampleInput(make_arg((1, 1, 4)), args=(make_arg((1, 1, 3)), make_arg((2,)))),
|
|
# error_regex="expected bias to be 1-dimensional with 1 elements")
|
|
|
|
# error inputs for input.ndim != weight.ndim
|
|
yield ErrorInput(SampleInput(make_arg((1, 1, 4)), args=(make_arg((1, 2)), make_arg((1,)))),
|
|
error_regex="weight should have at least three dimensions")
|
|
|
|
# error inputs for the weight[0] are less than the number of groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4)), args=(make_arg((2, 2, 2)), make_arg((2,))),
|
|
kwargs={'padding': 'same', 'groups': 3}), error_regex="expected weight to be at least 3 at dimension 0")
|
|
|
|
# error inputs for the weight[0] are less than the number of groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4)), args=(make_arg((2, 2, 2)), make_arg((2,))),
|
|
kwargs={'groups': 3}), error_regex="expected weight to be at least 3 at dimension 0")
|
|
|
|
# error inputs for invalid groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4)), args=(make_arg((2, 2, 2)), make_arg((2,))),
|
|
kwargs={'padding': 'same', 'groups': -1}), error_regex="non-positive groups is not supported")
|
|
|
|
# error inputs for invalid groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4)), args=(make_arg((2, 2, 2)), make_arg((2,))),
|
|
kwargs={'padding': 'same', 'groups': 0}), error_regex="non-positive groups is not supported")
|
|
|
|
|
|
def error_inputs_conv2d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float64)
|
|
make_int_arg = partial(make_tensor, device=device, dtype=torch.int64)
|
|
make_complex_arg = partial(make_tensor, device=device, dtype=torch.complex128)
|
|
|
|
# error inputs for different dtypes of input tensor and bias
|
|
yield ErrorInput(
|
|
SampleInput(make_int_arg((2, 4, 4)), args=(make_int_arg((3, 2, 3, 3)), make_arg((3,)))),
|
|
error_regex="should be the same")
|
|
|
|
# error inputs for different dtypes of input tensor and bias
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 4, 4)), args=(make_arg((3, 2, 3, 3)), make_complex_arg((3,)))),
|
|
error_regex="should be the same")
|
|
|
|
# error inputs for negative strides
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 4)), args=(make_arg((1, 2, 2, 3)), make_arg((1,))),
|
|
kwargs={'stride': (-1,)}), error_regex="non-positive stride is not supported")
|
|
|
|
# error inputs for negative padding
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 3)), args=(make_arg((1, 2, 2, 4)), make_arg((1,))),
|
|
kwargs={'padding': (-1,)}), error_regex="negative padding is not supported")
|
|
|
|
# error inputs for negative dilation
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 2)), args=(make_arg((1, 1, 2, 5)), make_arg((1,))),
|
|
kwargs={'dilation': (-1,)}), error_regex="dilation should be greater than zero")
|
|
|
|
# FIXME: https://github.com/pytorch/pytorch/issues/85656
|
|
# error inputs for bias shape not equal to the output channels
|
|
# yield ErrorInput(SampleInput(make_arg((1, 1, 4, 4)), args=(make_arg((1, 1, 3, 2)), make_arg((2,)))),
|
|
# error_regex="expected bias to be 1-dimensional with 1 elements")
|
|
|
|
# error inputs for input.ndim != weight.ndim
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 3)), args=(make_arg((1, 2, 2)), make_arg((1,))),
|
|
kwargs={'padding': 'same'}), error_regex="Expected 3-dimensional input for 3-dimensional weight")
|
|
|
|
# error inputs for the weight[0] are less than the number of groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4, 3)), args=(make_arg((2, 2, 1, 3)), make_arg((2,))),
|
|
kwargs={'groups': 3}), error_regex="expected weight to be at least 3 at dimension 0")
|
|
|
|
# error inputs for groups the weight[0] are less than the number of groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4, 3)), args=(make_arg((2, 2, 1, 3)), make_arg((2,))),
|
|
kwargs={'padding': 'same', 'groups': 3}), error_regex="expected weight to be at least 3 at dimension 0")
|
|
|
|
# error inputs for invalid groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4, 5)), args=(make_arg((2, 2, 1, 4)), make_arg((2,))),
|
|
kwargs={'padding': 'same', 'groups': -1}), error_regex="non-positive groups is not supported")
|
|
|
|
# error inputs for invalid groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 4, 3)), args=(make_arg((2, 2, 4, 3)), make_arg((2,))),
|
|
kwargs={'padding': 'same', 'groups': 0}), error_regex="non-positive groups is not supported")
|
|
|
|
|
|
def sample_inputs_conv2d(op_info, device, dtype, requires_grad, jit_fail_sample=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as shapes for input, weight, bias
|
|
# and a dict of values of (stride, padding, groups, dilation)
|
|
cases: Tuple = (
|
|
((1, 3, 4, 4), (3, 3, 3, 3), (3,),
|
|
{'stride': (2, 2), 'padding': 2, 'groups': 1}),
|
|
((2, 4, 8, 8), (2, 2, 3, 3), (2,),
|
|
{'stride': (3, 2), 'padding': (2, 1), 'groups': 2, 'dilation': (4, 4)}),
|
|
((1, 4, 5, 5), (1, 4, 2, 3), (1,),
|
|
{'stride': 2, 'padding': 1, 'groups': 1, 'dilation': (2, 3)}),
|
|
((1, 4, 5, 5), (1, 4, 2, 3), (1,),
|
|
{'stride': 2, 'padding': 1, 'groups': 1, 'dilation': (2, 3)}),
|
|
((1, 2, 4, 3), (4, 2, 3, 4), None,
|
|
{'stride': 2, 'padding': 1, 'groups': 1}),
|
|
((1, 4, 5, 5), (1, 4, 2, 3), (1,),
|
|
{'stride': 2, 'padding': "valid"}),
|
|
((1, 4, 5, 5), (1, 4, 2, 3), (1,),
|
|
{'stride': 1, 'padding': "same", 'dilation': 3}),
|
|
# Below are the group related samples from common_nn.py
|
|
((2, 4, 6, 6), (4, 1, 3, 3), (4,), {'groups': 4}),
|
|
((2, 4, 6, 6), (8, 1, 3, 3), (8,), {'groups': 4}),
|
|
((2, 4, 6, 6), (8, 1, 3, 3), None, {'groups': 4}),
|
|
((2, 4, 6, 6), (4, 1, 3, 3), (4,), {'groups': 4, 'stride': (3, 2)}),
|
|
((2, 4, 6, 6), (4, 1, 3, 3), (4,), {'groups': 4, 'padding': (1, 1)}),
|
|
((2, 4, 5, 5), (4, 1, 2, 2), (4,), {'groups': 4, 'dilation': (2, 2)}),
|
|
((2, 4, 6, 5), (6, 2, 3, 2), (6,), {'groups': 2}),
|
|
# With defaults
|
|
((1, 4, 5, 5), (3, 4, 3, 3), None, {}),
|
|
)
|
|
|
|
for input_shape, weight, bias, kwargs in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
|
|
|
|
def sample_inputs_conv3d(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as shapes for input, weight, bias
|
|
# and dict of values of (stride, padding, dilation, groups)
|
|
cases: Tuple = (
|
|
((1, 1, 4, 4, 4), (1, 1, 1, 1, 1), (1,), {'padding': 'same'}),
|
|
((1, 1, 4, 4, 4), (1, 1, 4, 4, 4), (1,), {'stride': (2, 2, 2)}),
|
|
((1, 1, 5, 5, 5), (1, 1, 3, 3, 3), (1,), {'dilation': 2}),
|
|
((1, 1, 1, 1, 10), (1, 1, 1, 1, 4), None, {'padding': 'valid'}),
|
|
((1, 1, 10, 11, 12), (1, 1, 1, 2, 5), None, {'padding': 'same'}),
|
|
((1, 1, 10, 11, 12), (1, 1, 1, 2, 5), None, {'padding': 'same', 'dilation': 2}),
|
|
((1, 1, 10, 11, 12), (1, 1, 4, 4, 4), None, {'padding': 'same', 'dilation': 3}),
|
|
((1, 1, 1, 1, 10), (1, 1, 1, 1, 4), None, {'padding': 'valid'}),
|
|
((3, 9, 3, 1, 9), (3, 3, 3, 1, 9), (3,), {'groups': 3}),
|
|
((3, 9, 3, 1, 9), (3, 3, 3, 1, 9), (3,), {'stride': (2, 2, 2), 'dilation': 1, 'groups': 3}),
|
|
)
|
|
|
|
for input_shape, weight, bias, kwargs in cases:
|
|
# Batched
|
|
yield SampleInput(make_arg(input_shape), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
# Unbatched
|
|
yield SampleInput(make_arg(input_shape[1:]), args=(
|
|
make_arg(weight),
|
|
make_arg(bias) if bias is not None else bias
|
|
), kwargs=kwargs)
|
|
|
|
|
|
def error_inputs_conv3d(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float64)
|
|
make_int_arg = partial(make_tensor, device=device, dtype=torch.int64)
|
|
make_complex_arg = partial(make_tensor, device=device, dtype=torch.complex128)
|
|
|
|
# error inputs for different dtypes of input tensor and bias
|
|
yield ErrorInput(
|
|
SampleInput(make_int_arg((1, 1, 4, 4, 4)), args=(make_int_arg((1, 1, 2, 2, 2)), make_arg((1,)))),
|
|
error_regex="should be the same")
|
|
|
|
# error inputs for different dtypes of input tensor and bias
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 4, 4)), args=(make_arg((1, 1, 2, 2, 2)), make_complex_arg((1,)))),
|
|
error_regex="should be the same")
|
|
|
|
# error inputs for negative strides
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 4, 4)), args=(make_arg((1, 1, 2, 2, 2)), make_arg((1,))),
|
|
kwargs={'stride': (-1,)}), error_regex="non-positive stride is not supported")
|
|
|
|
# error inputs for negative padding
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 4, 4)), args=(make_arg((1, 1, 2, 2, 2)), make_arg((1,))),
|
|
kwargs={'padding': (-1,)}), error_regex="negative padding is not supported")
|
|
|
|
# error inputs for negative dilation
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 4, 4, 4)), args=(make_arg((1, 1, 2, 2, 2)), make_arg((1,))),
|
|
kwargs={'dilation': (-1,)}), error_regex="dilation should be greater than zero")
|
|
|
|
# FIXME: https://github.com/pytorch/pytorch/issues/85656
|
|
# error inputs for bias shape not equal to the output channels
|
|
# yield ErrorInput(SampleInput(make_arg((1, 1, 4, 4, 4)), args=(make_arg((1, 1, 3, 3, 3)), make_arg((2,)))),
|
|
# error_regex="expected bias to be 1-dimensional with 1 elements")
|
|
|
|
# error inputs for input.ndim != weight.ndim
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((1, 1, 3, 4, 5)), args=(make_arg((1, 1, 4, 3)), make_arg((1,))),
|
|
kwargs={'padding': 'same'}), error_regex="Expected 4-dimensional input for 4-dimensional weight")
|
|
|
|
# error inputs for the weight[0] are less than the number of groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 3, 4, 5)), args=(make_arg((2, 2, 4, 3, 3)),
|
|
make_arg((2,))), kwargs={'groups': 3}),
|
|
error_regex="expected weight to be at least 3 at dimension 0")
|
|
|
|
# error inputs for the weight[0] are less than the number of groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 3, 4, 5)), args=(make_arg((2, 2, 4, 3, 3)),
|
|
make_arg((2,))), kwargs={'padding': 'same', 'groups': 3}),
|
|
error_regex="expected weight to be at least 3 at dimension 0")
|
|
|
|
# error inputs for invalid groups
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((2, 2, 3, 4, 5)), args=(make_arg((2, 2, 4, 3, 3)),
|
|
make_arg((2,))), kwargs={'padding': 'same', 'groups': 0}),
|
|
error_regex="non-positive groups is not supported")
|
|
|
|
# error inputs for padding='same' not supported by strided convolutions
|
|
yield ErrorInput(
|
|
SampleInput(make_arg((18, 27, 9, 1, 9)), args=(make_arg((9, 9, 9, 1, 9)),
|
|
make_arg((9,))), kwargs={'stride': 2, 'padding': 'same', 'groups': 3}),
|
|
error_regex="padding='same' is not supported for strided convolutions")
|
|
|
|
|
|
def sample_inputs_group_norm(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as input shape, num groups, and kwargs for eps
|
|
cases: Tuple[Tuple[int], int, float] = ( # type: ignore[assignment]
|
|
((1, 6, 3), 2, {'eps' : 0.5}),
|
|
((2, 6, 3), 2, {'eps' : -0.5}),
|
|
((1, 3), 1, {'eps' : 1e-5}),
|
|
((0, 2), 1, {'eps' : 1e-5}),
|
|
((S, S, S), 1, {'eps' : 0.5}),
|
|
)
|
|
|
|
# num_channels is inferred to be input.shape[1] dimension
|
|
for input_shape, num_groups, kwargs in cases:
|
|
# Shape of weight and bias should be the same as num_channels
|
|
channels = input_shape[1] if len(input_shape) > 1 else 0
|
|
weight_tensor = make_arg(channels)
|
|
bias_tensor = make_arg(channels)
|
|
|
|
# Checking for permutations of weights and biases as `None`
|
|
weights = [weight_tensor, None]
|
|
biases = [bias_tensor, None]
|
|
for weight, bias in itertools.product(weights, biases):
|
|
kwargs = {
|
|
'weight': weight,
|
|
'bias': bias,
|
|
**kwargs
|
|
}
|
|
yield SampleInput(make_arg(input_shape), num_groups, **kwargs)
|
|
|
|
# Without any optional args
|
|
yield SampleInput(make_arg((1, 2)), args=(1,))
|
|
|
|
def reference_inputs_group_norm(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_group_norm(
|
|
op_info, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as input shape, num groups, and kwargs for eps
|
|
cases: Tuple[Tuple[int], int, float] = ( # type: ignore[assignment]
|
|
((20, 6, 10, 10), 3, {'eps' : 1e-5}),
|
|
# equivalent with InstanceNorm
|
|
# GroupNorm(C, num_groups=C) == InstanceNorm(num_features=C)
|
|
((20, 6, 10, 10), 6, {'eps' : 1e-5}),
|
|
# equivalent with LayerNorm
|
|
# GroupNorm(C, num_groups=1, affine=False) == LayerNorm(normalized_shape=[C, H, W], elementwise_affine=False)
|
|
((20, 6, 10, 10), 1, {'eps' : 1e-5}),
|
|
)
|
|
|
|
# num_channels is inferred to be input.shape[1] dimension
|
|
for input_shape, num_groups, kwargs in cases:
|
|
# Shape of weight and bias should be the same as num_channels
|
|
channels = input_shape[1] if len(input_shape) > 1 else 0
|
|
input_tensor = make_arg(input_shape)
|
|
weight_tensor = make_arg(channels)
|
|
bias_tensor = make_arg(channels)
|
|
|
|
# Checking for permutations of weights and biases as `None`
|
|
weights = [weight_tensor, None]
|
|
biases = [bias_tensor, None]
|
|
for weight, bias in itertools.product(weights, biases):
|
|
kwargs = {
|
|
'weight': weight,
|
|
'bias': bias,
|
|
**kwargs
|
|
}
|
|
yield SampleInput(input_tensor, num_groups, **kwargs)
|
|
|
|
|
|
def sample_inputs_instance_norm(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_arg_without_requires_grad = partial(make_tensor, device=device, dtype=dtype, requires_grad=False)
|
|
|
|
# Ordered as: input shape, kwargs for momentum, eps
|
|
cases: Tuple[Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((S, S, S), {'momentum': 0.5, 'eps': 0.6}),
|
|
((S, S, S), {'momentum': 0.5, 'eps': 0.6, 'use_input_stats': True}),
|
|
((3, 2, 4), {'momentum': -1.2}),
|
|
((3, 2, 4), {'momentum': 0.0}),
|
|
((3, 2, 3, 4), {'momentum': -1.0, 'eps': 0.5}),
|
|
((3, 2, 3, 4), {'momentum': -1.0, 'eps': 0.5}),
|
|
)
|
|
|
|
for input_shape, kwargs in cases:
|
|
# args: running mean, running var, weight and bias should necessarily be of shape: (channels,)
|
|
channels = input_shape[1]
|
|
weight = make_arg(channels)
|
|
bias = make_arg(channels)
|
|
running_mean = make_arg_without_requires_grad(channels, low=0)
|
|
running_var = make_arg_without_requires_grad(channels, low=0)
|
|
new_kwargs = {
|
|
'running_mean': running_mean,
|
|
'running_var': running_var,
|
|
'weight': weight,
|
|
'bias': bias,
|
|
**kwargs
|
|
}
|
|
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(),
|
|
kwargs=new_kwargs
|
|
)
|
|
|
|
# Checking for permutations of weights and biases as `None`
|
|
# instance_norm assumes that if there's a bias, there's a weight
|
|
weights = [channels, None]
|
|
biases = [None, None]
|
|
|
|
for weight_channels, bias_channels in zip(weights, biases):
|
|
running_mean = make_arg_without_requires_grad(channels, low=0)
|
|
running_var = make_arg_without_requires_grad(channels, low=0)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(),
|
|
kwargs={
|
|
'running_mean': running_mean,
|
|
'running_var': running_var,
|
|
'weight': make_arg(weight_channels) if weight_channels is not None else None,
|
|
'bias': make_arg(bias_channels) if bias_channels is not None else None
|
|
}
|
|
)
|
|
|
|
# Test case for no optional kwargs
|
|
yield SampleInput(make_arg((1, 2, 3)), kwargs={})
|
|
|
|
def sample_inputs_safe_softmax(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=False)
|
|
|
|
def make_bool_mask(*shape):
|
|
return torch.randint(0, 2, shape, device=device, dtype=torch.bool)
|
|
|
|
def mask_two_rows(rows, cols):
|
|
mask_two_rows = torch.ones((rows, cols), dtype=torch.bool, device=device)
|
|
mask_two_rows[rows - 1] = False
|
|
mask_two_rows[rows - 3] = False
|
|
return mask_two_rows
|
|
|
|
def convert_to_float_mask(mask: torch.Tensor) -> torch.Tensor:
|
|
return torch.where(~mask, float('-inf'), 0.0)
|
|
|
|
def with_requires_grad(tensor):
|
|
return tensor.requires_grad_(requires_grad)
|
|
|
|
def generate_input_from_mask(mask_shape, dim):
|
|
mask = make_bool_mask(*mask_shape)
|
|
input_tensor = make_arg(mask_shape)
|
|
masked_input = input_tensor + convert_to_float_mask(mask)
|
|
return SampleInput(with_requires_grad(masked_input), kwargs={'dim': dim})
|
|
|
|
samples = [
|
|
# Basic 3D tensor with mask
|
|
generate_input_from_mask((2, 3, 4), dim=1),
|
|
# 2D tensor with mask, testing different dim
|
|
generate_input_from_mask((5, 5), dim=0),
|
|
# 4D tensor, testing with a different dim
|
|
generate_input_from_mask((2, 3, 4, 5), dim=2),
|
|
# Edge case: 1D tensor
|
|
generate_input_from_mask((10,), dim=0),
|
|
# Edge case: tensor with one dimension of size 1
|
|
generate_input_from_mask((1, 5, 5), dim=1),
|
|
# Testing with all elements masked
|
|
SampleInput(
|
|
with_requires_grad(
|
|
make_arg((3, 3))
|
|
+ convert_to_float_mask(
|
|
torch.zeros((3, 3), dtype=torch.bool, device=device)
|
|
)
|
|
),
|
|
kwargs={"dim": 1},
|
|
),
|
|
# Testing with no elements masked
|
|
SampleInput(
|
|
with_requires_grad(
|
|
make_arg((3, 3))
|
|
+ convert_to_float_mask(
|
|
torch.ones((3, 3), dtype=torch.bool, device=device)
|
|
)
|
|
),
|
|
kwargs={"dim": 1},
|
|
),
|
|
# Testing with two rows masked
|
|
SampleInput(
|
|
with_requires_grad(
|
|
make_arg((6, 3)) + convert_to_float_mask(mask_two_rows(6, 3))
|
|
),
|
|
kwargs={"dim": 1},
|
|
),
|
|
]
|
|
yield from samples
|
|
|
|
def sample_inputs_layer_norm(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as input shape, normalized_shape and a kwarg dict for eps
|
|
cases: Tuple[Tuple[int], Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((1, 2, 3), (1, 2, 3), {'eps': 0.5}),
|
|
((2, 2, 3), (2, 3), {'eps': -0.5}),
|
|
((1,), (1,), {}),
|
|
((1, 2), (2,), {}),
|
|
((0, 1), (1,), {}),
|
|
)
|
|
|
|
for input_shape, normalized_shape, kwargs in cases:
|
|
# Shape of weight and bias should be the same as normalized_shape
|
|
weight = make_arg(normalized_shape)
|
|
bias = make_arg(normalized_shape)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(normalized_shape, weight, bias),
|
|
kwargs=kwargs
|
|
)
|
|
# Without any optional args
|
|
yield SampleInput(make_arg((1, 2)), args=((2,),))
|
|
|
|
# TODO: @krshrimali, once to_numpy method in SampleInput class is modified to take None inputs,
|
|
# enable these inputs; see https://github.com/pytorch/pytorch/pull/63276#discussion_r691950400
|
|
|
|
# With weight and a `None` bias
|
|
# yield SampleInput(make_arg((1, 2)), args=((2,), make_arg((2,)), None))
|
|
|
|
# With `None` weight and bias (tests failing for this, see the link above)
|
|
# yield SampleInput(make_arg((1, 2)), args=((2,), None, make_arg((2,))))
|
|
|
|
|
|
def sample_inputs_native_layer_norm(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as input shape, normalized_shape, eps
|
|
cases: Tuple[Tuple[int], Tuple[int], float] = ( # type: ignore[assignment]
|
|
((1, 2, 3), (1, 2, 3), 0.5),
|
|
((2, 2, 3), (2, 3), -0.5),
|
|
((1,), (1,), 1e-5),
|
|
((1, 2), (2,), 1e-5),
|
|
((0, 1), (1,), 1e-5),
|
|
)
|
|
|
|
for input_shape, normalized_shape, eps in cases:
|
|
# Shape of weight and bias should be the same as normalized_shape
|
|
weight = make_arg(normalized_shape)
|
|
bias = make_arg(normalized_shape)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(normalized_shape, weight, bias, eps),
|
|
)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(normalized_shape, None, bias, eps),
|
|
)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(normalized_shape, weight, None, eps),
|
|
)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(normalized_shape, None, None, eps),
|
|
)
|
|
|
|
def sample_inputs_rms_norm(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, high=1000)
|
|
|
|
# Ordered as input shape, normalized_shape and a kwarg dict for eps
|
|
cases: Tuple[Tuple[int], Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((1, 2, 3), (1, 2, 3), {'eps': 0.5}),
|
|
((2, 2, 3), (2, 3), {'eps': -0.5}),
|
|
((1,), (1,), {}),
|
|
((1, 2), (2,), {}),
|
|
((0, 1), (1,), {}),
|
|
)
|
|
|
|
for input_shape, normalized_shape, kwargs in cases:
|
|
# Shape of weight and bias should be the same as normalized_shape
|
|
weight = make_arg(normalized_shape)
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
args=(normalized_shape, weight),
|
|
kwargs=kwargs
|
|
)
|
|
# Without any optional args
|
|
yield SampleInput(make_arg((1, 2)), args=((2,),))
|
|
|
|
def error_inputs_group_norm(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32, requires_grad=False)
|
|
|
|
# check that input has minimum number of dimensions
|
|
err_msg1 = "Expected at least 2 dimensions for input tensor but received"
|
|
s1 = SampleInput(make_arg(1), args=(1,))
|
|
yield ErrorInput(s1, error_regex=err_msg1)
|
|
|
|
# check that the channels dimension is compatible with number of groups
|
|
err_msg2 = "Expected number of channels in input to be divisible by num_groups, but got input of shape"
|
|
s2 = SampleInput(make_arg((2, 7, 4)), args=(2,))
|
|
yield ErrorInput(s2, error_regex=err_msg2)
|
|
|
|
def error_inputs_native_layer_norm(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32, requires_grad=False)
|
|
input_shape = (1, 2, 3)
|
|
|
|
err_msg1 = "Expected normalized_shape to be at least 1-dimensional"
|
|
s1 = SampleInput(
|
|
make_arg(input_shape), args=((), None, None, 1e-5)
|
|
)
|
|
yield ErrorInput(s1, error_regex=err_msg1)
|
|
|
|
normalized_shape = (1, 2, 3)
|
|
weight = make_arg((1, 2))
|
|
err_msg2 = "Expected weight to be of same shape as normalized_shape"
|
|
s2 = SampleInput(
|
|
make_arg(input_shape), args=(normalized_shape, weight, None, 1e-5)
|
|
)
|
|
yield ErrorInput(s2, error_regex=err_msg2)
|
|
|
|
bias = make_arg((1, 2))
|
|
err_msg3 = "Expected bias to be of same shape as normalized_shape"
|
|
s3 = SampleInput(
|
|
make_arg(input_shape), args=(normalized_shape, None, bias, 1e-5)
|
|
)
|
|
yield ErrorInput(s3, error_regex=err_msg3)
|
|
|
|
err_msg4 = "Given normalized_shape="
|
|
s4 = SampleInput(
|
|
make_arg((2, 2, 3)), args=((2, 2), None, None, 1e-5)
|
|
)
|
|
yield ErrorInput(s4, error_regex=err_msg4)
|
|
|
|
def error_inputs_rms_norm(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32, requires_grad=False)
|
|
input_shape = (1, 2, 3)
|
|
|
|
err_msg1 = "Expected normalized_shape to be at least 1-dimensional"
|
|
s1 = SampleInput(
|
|
make_arg(input_shape), args=((), None, 1e-5)
|
|
)
|
|
yield ErrorInput(s1, error_regex=err_msg1)
|
|
|
|
normalized_shape = (1, 2, 3)
|
|
weight = make_arg((1, 2))
|
|
err_msg2 = "Expected weight to be of same shape as normalized_shape"
|
|
s2 = SampleInput(
|
|
make_arg(input_shape), args=(normalized_shape, weight, 1e-5)
|
|
)
|
|
yield ErrorInput(s2, error_regex=err_msg2)
|
|
|
|
|
|
err_msg4 = "Given normalized_shape="
|
|
s4 = SampleInput(
|
|
make_arg((2, 2, 3)), args=((2, 2), None, 1e-5)
|
|
)
|
|
yield ErrorInput(s4, error_regex=err_msg4)
|
|
|
|
|
|
def sample_inputs_local_response_norm(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Ordered as input shape, size and a kwarg dict for alpha, beta, and k
|
|
cases: Tuple[Tuple[int], Tuple[int], dict] = ( # type: ignore[assignment]
|
|
((1, 6, 3), 2, {'alpha': 3e-05, 'beta': 0.5, 'k': 1.25}),
|
|
((1, 6, 3), 2, {'beta': 0.5, 'k': 1.25}),
|
|
((1, 6, 3), 2, {'alpha': 3e-05, 'k': 1.25}),
|
|
((1, 6, 3), 2, {'alpha': 3e-05, 'beta': 0.5}),
|
|
((1, 6, 3), 2, {'alpha': 3e-05}),
|
|
((1, 6, 3), 2, {'beta': 0.5}),
|
|
((1, 6, 3), 2, {'k': 1.25}),
|
|
((1, 6, 3), 2, {}),
|
|
((2, 6, 3), 2, {'alpha': 3e-05, 'beta': 0.5, 'k': 1.25}),
|
|
((1, 1, 2), 1, {'alpha': 3e-05, 'beta': 0.5, 'k': 1.25}),
|
|
((0, 1, 2), 1, {'alpha': 3e-05, 'beta': 0.5, 'k': 1.25}),
|
|
)
|
|
|
|
for input_shape, size, kwargs in cases:
|
|
yield SampleInput(make_arg(input_shape), args=(size,), kwargs=kwargs)
|
|
|
|
def sample_inputs_hardswish(self, device, dtype, requires_grad, **kwargs):
|
|
N = 5
|
|
# make sure we are testing -3 -> 3 range. default is -10 -> 10 so maybe unnecessary ?
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype,
|
|
requires_grad=requires_grad, low=-5, high=5)
|
|
return (SampleInput(make_arg((N * 2, N * 2))) for _ in range(1, N))
|
|
|
|
def sample_inputs_linear(self, device, dtype, requires_grad, **kwargs):
|
|
features_options = [[3, 4], [8, 8]]
|
|
batch_options: List[List[int]] = [
|
|
[], # no batch
|
|
[0],
|
|
[8],
|
|
[2, 3],
|
|
]
|
|
create_tensor = partial(make_tensor, device=device, dtype=dtype,
|
|
requires_grad=requires_grad, low=-2, high=2)
|
|
|
|
for has_bias, (in_feat, out_feat), batch_shape in \
|
|
itertools.product([True, False], features_options, batch_options):
|
|
input_tensor = create_tensor(batch_shape + [in_feat])
|
|
weight = create_tensor([out_feat, in_feat])
|
|
if not has_bias:
|
|
yield SampleInput(input_tensor, weight)
|
|
continue
|
|
|
|
bias = create_tensor([out_feat])
|
|
yield SampleInput(input_tensor, weight, bias)
|
|
|
|
# 5D tensor, used to crash on MPS, see https://github.com/pytorch/pytorch/issues/114942
|
|
yield SampleInput(create_tensor(2, 1, 2, 1, 2), create_tensor(4, 2))
|
|
yield SampleInput(create_tensor(2, 1, 2, 1, 2), create_tensor(4, 2), create_tensor(4))
|
|
|
|
def sample_inputs_bilinear(self, device, dtype, requires_grad, **kwargs):
|
|
features_options = [[3, 4, 5], [8, 8, 8]]
|
|
batch_options: List[List[int]] = [
|
|
[], # no batch
|
|
[0],
|
|
[8],
|
|
[2, 3],
|
|
]
|
|
create_tensor = partial(make_tensor, device=device, dtype=dtype,
|
|
requires_grad=requires_grad, low=-2, high=2)
|
|
|
|
for has_bias, (in_feat1, in_feat2, out_feat), batch_shape in \
|
|
itertools.product([True, False], features_options, batch_options):
|
|
input_tensor1 = create_tensor(batch_shape + [in_feat1])
|
|
input_tensor2 = create_tensor(batch_shape + [in_feat2])
|
|
weight = create_tensor([out_feat, in_feat1, in_feat2])
|
|
if not has_bias:
|
|
yield SampleInput(input_tensor1, input_tensor2, weight)
|
|
continue
|
|
bias = create_tensor([out_feat])
|
|
yield SampleInput(input_tensor1, input_tensor2, weight, bias)
|
|
|
|
def sample_inputs_glu(self, device, dtype, requires_grad, **kwargs):
|
|
features_options = [[2], [2, 4], [8, 8], [3, 6, 8], [1, 4, 6, 7]]
|
|
batch_options: List[List[int]] = [
|
|
[], # no batch
|
|
[0],
|
|
[8],
|
|
[2, 3],
|
|
]
|
|
create_tensor = partial(make_tensor, device=device, dtype=dtype,
|
|
requires_grad=requires_grad, low=-2, high=2)
|
|
|
|
for features, batch_shape in itertools.product(features_options, batch_options):
|
|
ndim = len(features) + len(batch_shape)
|
|
for dim in range(ndim):
|
|
input_tensor = create_tensor(batch_shape + features)
|
|
dim_size = input_tensor.size(dim)
|
|
if dim_size > 0 and dim_size % 2 == 0:
|
|
yield SampleInput(input_tensor, dim)
|
|
|
|
def sample_inputs_interpolate(mode, self, device, dtype, requires_grad, **kwargs):
|
|
N, C = 2, 3
|
|
D = 4
|
|
S = 3
|
|
L = 5
|
|
|
|
align_corners_options: Tuple[Any, ...] = (None,)
|
|
if mode in ('linear', 'bilinear', 'bicubic', 'trilinear'):
|
|
align_corners_options = (True, False, None)
|
|
ranks_for_mode = {
|
|
'nearest': [1, 2, 3],
|
|
'nearest-exact': [1, 2, 3],
|
|
'linear': [1],
|
|
'bilinear': [2],
|
|
'bicubic': [2],
|
|
'trilinear': [3],
|
|
'area': [1, 2, 3]
|
|
}
|
|
|
|
def shape(size, rank, with_batch_channel=True):
|
|
if with_batch_channel:
|
|
return tuple([N, C] + ([size] * rank))
|
|
return tuple([size] * rank)
|
|
|
|
if mode in ('bilinear', 'bicubic') and dtype == torch.uint8:
|
|
make_arg = partial(
|
|
make_tensor,
|
|
device=device,
|
|
dtype=dtype,
|
|
requires_grad=requires_grad,
|
|
# we pick more realistic upper bound 256 instead of default 10 for uint8 dtype
|
|
high=256 if dtype == torch.uint8 else None,
|
|
)
|
|
# provide few samples for a more close to typical image processing usage
|
|
rank = 2
|
|
for memory_format in [torch.contiguous_format, torch.channels_last]:
|
|
yield SampleInput(
|
|
make_arg(shape(270, rank), memory_format=memory_format),
|
|
shape(130, rank, False),
|
|
scale_factor=None,
|
|
mode=mode,
|
|
align_corners=False,
|
|
)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
for align_corners in align_corners_options:
|
|
for rank in ranks_for_mode[mode]:
|
|
yield SampleInput(
|
|
make_arg(shape(D, rank)),
|
|
shape(S, rank, False),
|
|
scale_factor=None,
|
|
mode=mode,
|
|
align_corners=align_corners,
|
|
)
|
|
yield SampleInput(
|
|
make_arg(shape(D, rank)),
|
|
shape(L, rank, False),
|
|
scale_factor=None,
|
|
mode=mode,
|
|
align_corners=align_corners,
|
|
)
|
|
for recompute_scale_factor in [False, True]:
|
|
for scale_factor in [1.7, 0.6]:
|
|
yield SampleInput(
|
|
make_arg(shape(D, rank)),
|
|
size=None,
|
|
scale_factor=scale_factor,
|
|
mode=mode,
|
|
align_corners=align_corners,
|
|
recompute_scale_factor=recompute_scale_factor,
|
|
)
|
|
|
|
def reference_inputs_interpolate(mode, self, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_interpolate(mode, self, device, dtype, requires_grad, **kwargs)
|
|
|
|
if mode in ('bilinear', 'bicubic'):
|
|
make_arg = partial(
|
|
make_tensor,
|
|
device=device,
|
|
dtype=dtype,
|
|
requires_grad=requires_grad,
|
|
# we pick more realistic upper bound 256 instead of default 10 for uint8 dtype
|
|
high=256 if dtype == torch.uint8 else None,
|
|
)
|
|
# provide few samples for more typical image processing usage
|
|
for memory_format in [torch.contiguous_format, torch.channels_last]:
|
|
for aa in [True, False]:
|
|
yield SampleInput(
|
|
make_arg((2, 3, 345, 456), memory_format=memory_format),
|
|
(270, 270),
|
|
scale_factor=None,
|
|
mode=mode,
|
|
align_corners=False,
|
|
antialias=aa,
|
|
)
|
|
|
|
def sample_inputs_upsample(mode, self, device, dtype, requires_grad, **kwargs):
|
|
N, C = 2, 3
|
|
D = 4
|
|
S = 3
|
|
L = 5
|
|
|
|
ranks_for_mode = {
|
|
'nearest': [1, 2, 3],
|
|
'bilinear': [2],
|
|
}
|
|
|
|
def shape(size, rank, with_batch_channel=True):
|
|
if with_batch_channel:
|
|
return torch.Size([N, C] + ([size] * rank))
|
|
return torch.Size([size] * rank)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
for rank in ranks_for_mode[mode]:
|
|
yield SampleInput(make_arg(shape(D, rank)), size=shape(S, rank, False))
|
|
yield SampleInput(make_arg(shape(D, rank)), size=shape(L, rank, False))
|
|
yield SampleInput(make_arg(shape(D, rank)), scale_factor=1.7)
|
|
yield SampleInput(make_arg(shape(D, rank)), scale_factor=0.6)
|
|
|
|
def reference_inputs_upsample(mode, self, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_upsample(mode, self, device, dtype, requires_grad, **kwargs)
|
|
|
|
if mode in ('bilinear', ):
|
|
make_arg = partial(
|
|
make_tensor,
|
|
device=device,
|
|
dtype=dtype,
|
|
requires_grad=requires_grad,
|
|
# we pick more realistic upper bound 256 instead of default 10 for uint8 dtype
|
|
high=256 if dtype == torch.uint8 else None,
|
|
)
|
|
# provide a single sample for more typical image processing usage
|
|
for memory_format in [torch.contiguous_format, torch.channels_last]:
|
|
yield SampleInput(
|
|
make_arg((2, 3, 345, 456), memory_format=memory_format),
|
|
(270, 270),
|
|
)
|
|
|
|
def sample_inputs_upsample_aa(mode, self, device, dtype, requires_grad, **kwargs):
|
|
N = 6
|
|
C = 3
|
|
H = 10
|
|
W = 20
|
|
S = 3
|
|
L = 5
|
|
|
|
input_tensor = make_tensor(torch.Size([N, C, H, W]), device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(input_tensor, output_size=torch.Size([S, S]), align_corners=False, scale_factors=None)
|
|
yield SampleInput(input_tensor, output_size=torch.Size([L, L]), align_corners=False, scale_factors=None)
|
|
yield SampleInput(input_tensor, output_size=None, align_corners=False, scale_factors=[1.7, 0.9])
|
|
yield SampleInput(input_tensor, output_size=None, align_corners=True, scale_factors=[0.8, 1.0])
|
|
|
|
yield SampleInput(input_tensor, output_size=torch.Size([S, S]), align_corners=False, scales_h=None, scales_w=None)
|
|
yield SampleInput(input_tensor, output_size=torch.Size([S, S]), align_corners=False, scales_h=1.7, scales_w=0.9)
|
|
yield SampleInput(input_tensor, output_size=torch.Size([S, S]), align_corners=True, scales_h=1.7, scales_w=0.9)
|
|
|
|
def sample_inputs_gelu(self, device, dtype, requires_grad, **kwargs):
|
|
N = 5
|
|
for _ in range(1, N):
|
|
for approximate in ['none', 'tanh']:
|
|
yield SampleInput(
|
|
make_tensor((N * 2, N * 2), device=device, dtype=dtype,
|
|
requires_grad=requires_grad, low=-3, high=3),
|
|
approximate=approximate)
|
|
|
|
|
|
def error_inputs_gelu(op, device, **kwargs):
|
|
# Tests that gelu errors out when passed an approximation we don't know.
|
|
yield ErrorInput(SampleInput(make_tensor((), dtype=torch.float, device=device), kwargs={"approximate": "asdf"}),
|
|
error_regex="approximate argument must be either")
|
|
|
|
|
|
def sample_inputs_max_min_reduction_with_dim(op_info, device, dtype, requires_grad, **kwargs):
|
|
args_for_reduction_with_dim = (
|
|
((S, S, S), (1,),),
|
|
((S, S, S), (1, True, ),),
|
|
((), (0,),),
|
|
((), (0, True,),),
|
|
)
|
|
return ((SampleInput(make_tensor(input_tensor, dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad),
|
|
*args))
|
|
for input_tensor, args in args_for_reduction_with_dim)
|
|
|
|
def sample_inputs_max_min_reduction_no_dim(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
yield SampleInput(make_arg((S, S, S)))
|
|
yield SampleInput(make_arg(()))
|
|
|
|
def _generate_nan_reduction_inputs(device, dtype, requires_grad, **kwargs):
|
|
yield from _generate_reduction_inputs(device, dtype, requires_grad)
|
|
# NaN only exists for floating point numbers
|
|
if dtype.is_complex or dtype.is_floating_point:
|
|
yield torch.tensor([2, torch.nan, -1], device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield torch.tensor([[torch.nan, 2], [0, 1]], device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def sample_inputs_nan_reduction(supports_multiple_dims):
|
|
# Generates sample inputs for reduction ops that contain the input tensor
|
|
# and dim and keepdim kwargs. If a reduction op needs to test additional
|
|
# args/kwargs then create a separate sample_inputs function
|
|
def fn(op_info, device, dtype, requires_grad, **kwargs):
|
|
for t in _generate_nan_reduction_inputs(device, dtype, requires_grad):
|
|
# Add case without dim and keepdim kwargs
|
|
yield SampleInput(t.clone().requires_grad_(requires_grad))
|
|
for kwargs in _generate_reduction_kwargs(t.ndim, supports_multiple_dims):
|
|
yield SampleInput(t.clone().requires_grad_(requires_grad), **kwargs)
|
|
|
|
return fn
|
|
|
|
def sample_inputs_reduction_quantile(op_info, device, dtype, requires_grad, **kwargs):
|
|
test_quantiles = (0.5, make_tensor((2,), dtype=dtype, device=device, low=0, high=1, requires_grad=requires_grad))
|
|
test_interpolations = ['linear', 'midpoint']
|
|
|
|
for quantiles in test_quantiles:
|
|
for t in _generate_reduction_inputs(device, dtype, requires_grad):
|
|
# Add case without dim and keepdim kwargs
|
|
input = t.clone().requires_grad_(requires_grad)
|
|
yield SampleInput(input, quantiles)
|
|
for kwargs in _generate_reduction_kwargs(t.ndim, supports_multiple_dims=False):
|
|
# Interpolation kwarg for now is only supported when providing both dim and keepdim
|
|
kwargs.setdefault('dim', 0)
|
|
kwargs.setdefault('keepdim', False)
|
|
for interpolation in test_interpolations:
|
|
kwargs['interpolation'] = interpolation
|
|
input = t.clone().requires_grad_(requires_grad)
|
|
yield SampleInput(input, quantiles, **kwargs)
|
|
|
|
def sample_inputs_reduction_count_nonzero(*args, **kwargs):
|
|
"""Sample inputs for count_nonzero"""
|
|
# count_nonzero does not support keepdim yet
|
|
for sample in sample_inputs_reduction(*args, **kwargs):
|
|
sample.kwargs.pop('keepdim', None)
|
|
yield sample
|
|
|
|
def sample_inputs_leaky_relu(op_info, device, dtype, requires_grad, **kwargs):
|
|
N = 10
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
return (SampleInput(make_arg((N, N))) for _ in range(1, N))
|
|
|
|
def sample_inputs_fractional_max_pool2d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Order: input_shape, kernel_size
|
|
cases = (((1, 3, 9, 9), 3),
|
|
((1, 3, 9, 9), (4, 4)),
|
|
((1, 3, 9, 9), (6, 6)),
|
|
((2, 3, 9, 9), (3, 3)),
|
|
((1, 1, 4, 4), (2, 2)),
|
|
((1, 2, 6, 6), (4, 4)))
|
|
|
|
for input_shape, kernel_size in cases:
|
|
for return_indices in [False, True]:
|
|
# test case passing a single output size
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
kernel_size,
|
|
output_size=2,
|
|
return_indices=return_indices,
|
|
)
|
|
|
|
# test case passing a tuple output size
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
kernel_size,
|
|
output_size=(2, 3),
|
|
return_indices=return_indices,
|
|
)
|
|
|
|
# test case passing an output ratio
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
kernel_size,
|
|
output_ratio=(0.5, 0.5),
|
|
return_indices=return_indices,
|
|
)
|
|
|
|
def sample_inputs_fractional_max_pool3d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Order: input_shape, kernel_size
|
|
cases = (((2, 3, 5, 5, 5), (2, 2, 2)),
|
|
((1, 2, 6, 5, 4), 2),
|
|
((1, 2, 5, 6, 5), (2, 3, 2)),
|
|
((1, 2, 6, 6, 6), (2, 3, 2)),
|
|
((1, 1, 7, 6, 7), (2, 3, 4)),
|
|
((1, 1, 4, 5, 4), (2, 2, 1)),
|
|
((1, 1, 8, 7, 6), (4, 3, 2)),
|
|
((0, 1, 4, 5, 4), (2, 2, 1)))
|
|
|
|
for input_shape, kernel_size in cases:
|
|
for return_indices in [False, True]:
|
|
# test case passing a single output size
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
kernel_size,
|
|
output_size=2,
|
|
return_indices=return_indices,
|
|
)
|
|
|
|
# test case passing a tuple output size
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
kernel_size,
|
|
output_size=(2, 3, 2),
|
|
return_indices=return_indices,
|
|
)
|
|
|
|
# test case passing an output ratio
|
|
yield SampleInput(
|
|
make_arg(input_shape),
|
|
kernel_size,
|
|
output_ratio=(0.5, 0.5, 0.5),
|
|
return_indices=return_indices,
|
|
)
|
|
|
|
def sample_inputs_avgpool2d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Order: input_shape, kernel_size, stride, padding, ceil_mode, count_include_pad, divisor_override
|
|
cases = (((1, 3, 9, 9), 3, 1, 1, True, False, 2),
|
|
((1, 3, 9, 9), (4, 4), (2, 3), 1, True, False, 2),
|
|
((1, 3, 9, 9), (6, 6), (3, 3), (2, 3), True, True, 2),
|
|
((2, 3, 9, 9), (3, 3), (1, 1), (1, ), True, False, 2),
|
|
((1, 1, 4, 4), (2, 2), (), (0, ), False, True, -2),
|
|
((1, 2, 6, 6), (4, 4), (2, 2), (2, ), True, True, None))
|
|
|
|
for input_shape, kernel_size, stride, padding, ceil_mode, count_include_pad, divisor_override in cases:
|
|
yield SampleInput(make_arg(input_shape),
|
|
args=(kernel_size, stride, padding, ceil_mode, count_include_pad, divisor_override))
|
|
# Case with just input_shape and kernel_size
|
|
yield SampleInput(make_arg((1, 3, 9, 9)), args=((3, 3)))
|
|
|
|
def sample_inputs_avgpool1d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Order: input_shape, kernel_size, kwargs
|
|
cases: List[Tuple[Tuple[int, ...], Union[int, Tuple[int, ...]], Dict]] = [
|
|
((2, 3, 9), (3,), {}),
|
|
((1, 3, 9), 3, dict(stride=1, padding=1, ceil_mode=True, count_include_pad=False)),
|
|
((1, 3, 9), (6,), dict(stride=(3,), padding=(2,), ceil_mode=True, count_include_pad=True)),
|
|
((2, 3, 9), (3,), dict(stride=(1,), padding=(1,), ceil_mode=False, count_include_pad=True)),
|
|
((0, 3, 9), (6,), dict(stride=(3,), padding=(2,), ceil_mode=False, count_include_pad=True)),
|
|
((1, 2, 9), (7,), dict(stride=(3,), padding=(2,), ceil_mode=False)),
|
|
((1, 2, 9), (7,), dict(stride=(3,), padding=(3,), ceil_mode=True)),
|
|
((1, 2, 9), (7,), dict(stride=(3,), ceil_mode=False)),
|
|
((1, 2, 9), (7,), dict(stride=(3,), ceil_mode=True)),
|
|
]
|
|
|
|
for input_shape, kernel_size, kwargs in cases:
|
|
yield SampleInput(make_arg(input_shape), args=(kernel_size,), kwargs=kwargs)
|
|
|
|
def sample_inputs_avgpool3d(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Order: input_shape, kernel_size, stride, padding, ceil_mode, count_include_pad, divisor_override
|
|
cases: List[Tuple[Tuple[int, ...], Union[int, Tuple[int, ...]], Dict]] = [
|
|
((2, 3, 3, 4, 4), (2, 2, 2), {}),
|
|
((1, 2, 4, 4, 4), 2, dict(stride=1, padding=1, ceil_mode=True,
|
|
count_include_pad=False, divisor_override=2)),
|
|
((1, 2, 5, 5, 5), (2, 3, 4), dict(stride=(1, 2, 2), padding=(0, 1, 2), ceil_mode=True,
|
|
count_include_pad=True, divisor_override=2)),
|
|
((1, 2, 5, 5, 5), (2, 3, 4), dict(stride=(1, 2, 2), padding=(0, 1, 2), ceil_mode=False)),
|
|
((1, 1, 7, 5, 7), (6, 3, 4), dict(stride=(2, 3, 2), padding=(3, 1, 0), ceil_mode=False,
|
|
count_include_pad=False, divisor_override=2)),
|
|
((1, 1, 4, 5, 4), (2, 2, 3), dict(stride=(2, 2, 1), padding=0, ceil_mode=False,
|
|
count_include_pad=True, divisor_override=-2)),
|
|
((1, 1, 6, 5, 6), (4, 5, 6), dict(stride=(2, 3, 2), padding=2, ceil_mode=True,
|
|
count_include_pad=True, divisor_override=None)),
|
|
((0, 1, 4, 5, 4), (2, 3, 1), dict(stride=(2, 1, 2), padding=0, ceil_mode=False,
|
|
count_include_pad=True, divisor_override=None)),
|
|
]
|
|
|
|
for input_shape, kernel_size, kwargs in cases:
|
|
yield SampleInput(make_arg(input_shape), args=(kernel_size,), kwargs=kwargs)
|
|
|
|
def error_inputs_avg_pool1d(op_info, device, **kwargs):
|
|
# error inputs when pad is negative
|
|
x = torch.rand([0, 1, 49], dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': -1}),
|
|
error_regex='pad must be non-negative')
|
|
|
|
# error inputs when pad > kernel_size / 2
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 4}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
def error_inputs_avg_pool2d(op_info, device, **kwargs):
|
|
# error inputs when pad is negative
|
|
x = torch.rand([0, 1, 49], dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': -1}),
|
|
error_regex='pad must be non-negative')
|
|
# 2-dimensional kernel
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2), 'stride': 50, 'padding': -1}),
|
|
error_regex='pad must be non-negative')
|
|
|
|
# error inputs when pad > kernel_size / 2
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 4}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
# 2-dimensional kernel
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2), 'stride': 50, 'padding': 4}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error inputs for zero divisor
|
|
x = torch.zeros(3, 3, 3)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (2, 2), 'divisor_override': 0}),
|
|
error_regex='divisor must be not zero')
|
|
|
|
def error_inputs_avg_pool3d(op_info, device, **kwargs):
|
|
# error inputs when pad is negative
|
|
x = torch.rand([0, 1, 49, 50], dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': -1}),
|
|
error_regex='pad must be non-negative')
|
|
# 3-dimensional kernel
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2, 2), 'stride': 50, 'padding': -1}),
|
|
error_regex='pad must be non-negative')
|
|
|
|
# error inputs when pad > kernel_size / 2
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 4}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
# 3-dimensional kernel
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (3, 2, 2), 'stride': 50, 'padding': 4}),
|
|
error_regex='pad should be at most half of effective kernel size')
|
|
|
|
# error inputs for zero divisor
|
|
x = torch.zeros(3, 3, 3, 3)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': (2, 2, 2), 'divisor_override': 0}),
|
|
error_regex='divisor must be not zero')
|
|
|
|
# error inputs for invalid input dimension
|
|
x = torch.rand([0, 1, 49], dtype=torch.float32)
|
|
yield ErrorInput(SampleInput(x, kwargs={'kernel_size': 2, 'stride': 50, 'padding': 0}),
|
|
error_regex='non-empty 4D or 5D')
|
|
|
|
|
|
def sample_inputs_to(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
# test_multiple_devices_to_cuda would fail if we use a different device than given
|
|
devices = [device]
|
|
if torch.device(device).type == 'cpu':
|
|
devices = [torch.device('cpu'), torch.device('cuda:0')] if torch.cuda.is_available() else devices
|
|
memory_formats = [torch.preserve_format, torch.channels_last]
|
|
|
|
# TODO: can't switch `to.device` overload to use positional arguments
|
|
# https://github.com/pytorch/pytorch/issues/84265
|
|
# to.device overload
|
|
for device, nb, cp, mem_f in product(devices, [True, False], [True, False], memory_formats):
|
|
kwargs = {
|
|
"memory_format": mem_f,
|
|
}
|
|
yield SampleInput(make_arg((S, S, S, S)), args=(device, torch.float64, nb, cp), kwargs=kwargs)
|
|
|
|
# to.dtype overload
|
|
for nb, cp, mem_f in product([True, False], [True, False], memory_formats):
|
|
kwargs = {
|
|
"memory_format": mem_f,
|
|
}
|
|
yield SampleInput(make_arg((S, S, S, S)), args=(torch.float64, nb, cp), kwargs=kwargs)
|
|
|
|
# to.other overload
|
|
for device, nb, cp, mem_f in product(devices, [True, False], [True, False], memory_formats):
|
|
kwargs = {
|
|
"memory_format": mem_f,
|
|
}
|
|
other = make_arg((S, S, S, S), dtype=torch.float64, device=device)
|
|
yield SampleInput(make_arg((S, S, S, S)), args=(other, nb, cp), kwargs=kwargs)
|
|
|
|
|
|
def sample_inputs_topk(op_info, device, dtype, requires_grad, **kwargs):
|
|
def get_tensor_input(size):
|
|
return make_tensor(size, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3)
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3, 1)
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3, -2)
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3, 1, True)
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3, -2, True)
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3, 1, True, True)
|
|
yield SampleInput(get_tensor_input((S, M, S)), 3, -2, True, True)
|
|
|
|
yield SampleInput(get_tensor_input(()), 1)
|
|
yield SampleInput(get_tensor_input(()), 1, 0)
|
|
yield SampleInput(get_tensor_input(()), 1, -1)
|
|
yield SampleInput(get_tensor_input(()), 1, 0, True)
|
|
yield SampleInput(get_tensor_input(()), 1, -1, True)
|
|
yield SampleInput(get_tensor_input(()), 1, 0, True, True)
|
|
yield SampleInput(get_tensor_input(()), 1, -1, True, True)
|
|
|
|
def sample_inputs_outer(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(S), make_arg(M))
|
|
|
|
def sample_inputs_dist(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
sizes = ((S, S, S), (S,), (S, 1, S), (), (S, S))
|
|
ps = (2, 4)
|
|
|
|
for size_x, size_y, p in product(sizes, sizes, ps):
|
|
yield SampleInput(make_arg(size_x), args=(make_arg(size_y), p))
|
|
|
|
# Missing to test the nondeterminism of the operation
|
|
# https://github.com/pytorch/pytorch/issues/53352
|
|
def sample_inputs_index(op_info, device, dtype, requires_grad, reference=False, **kwargs):
|
|
# target.index_add(dim, idx, source, *, alpha=1)
|
|
add = "index_add" in op_info.name
|
|
# target.index_copy(dim, idx, source)
|
|
copy = "index_copy" in op_info.name
|
|
# target.index_fill(dim, idx, value)
|
|
fill = "index_fill" in op_info.name
|
|
|
|
# Extended reference inputs. We generate that exercise atomic adds / writing
|
|
# several times to one location
|
|
if reference:
|
|
make_arg = partial(torch.ones, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_idx = partial(torch.zeros, device=device, dtype=torch.int64)
|
|
else:
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
# idx They need to be different for copy and add to be deterministic
|
|
if copy or add:
|
|
make_idx = partial(torch.randperm, device=device, dtype=torch.int64)
|
|
else:
|
|
def make_idx(n):
|
|
return make_tensor((n,), device=device, dtype=torch.int64, low=0, high=n)
|
|
|
|
shapes = [(), (1,), (S, S)]
|
|
# extra parameter for add
|
|
if add:
|
|
if dtype == torch.bool:
|
|
alphas = (True, False)
|
|
else:
|
|
alphas = (-1, 0, 2)
|
|
else:
|
|
alphas = (None,)
|
|
|
|
if fill:
|
|
# A weird number to catch errors.
|
|
# The former one tests `index_fill.int_Scalar`, and the latter one tests `index_fill.int_Tensor`.
|
|
values = (make_arg((1,)).item(), make_arg(()))
|
|
else:
|
|
values = (None,)
|
|
|
|
for shape, alpha, value in product(shapes, alphas, values):
|
|
t = make_arg(shape)
|
|
args = []
|
|
|
|
# dim. We handle the scalar case
|
|
dim = -1 if t.ndim == 2 else 0
|
|
args.append(dim)
|
|
|
|
idx = make_idx(t.shape[dim] if t.ndim != 0 else 1)
|
|
args.append(idx)
|
|
|
|
# source
|
|
if copy or add:
|
|
args.append(make_arg(shape))
|
|
elif fill:
|
|
args.append(value)
|
|
|
|
args = tuple(args)
|
|
kwargs = {} if alpha is None else {"alpha": alpha}
|
|
|
|
yield SampleInput(t, args=args, kwargs=kwargs)
|
|
|
|
def sample_inputs_index_reduce(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_idx(n, m):
|
|
return make_tensor((n,), device=device, dtype=torch.int64, low=0, high=m)
|
|
|
|
shapes = [((), ()), ((1,), (1,)), ((S, S), (S, M)), ((S, S, S), (S, M, S))]
|
|
include_selfs = (True, False)
|
|
reduce = op_info.variant_test_name
|
|
assert reduce in ('prod', 'mean', 'amin', 'amax')
|
|
|
|
for shape, include_self in product(shapes, include_selfs):
|
|
self_shape, src_shape = shape
|
|
# dim. We handle the scalar case
|
|
dim = 1 if len(self_shape) >= 2 else 0
|
|
idx = make_idx(src_shape[dim] if len(src_shape) != 0 else 1,
|
|
self_shape[dim] if len(self_shape) != 0 else 1)
|
|
args = (dim, idx, make_arg(src_shape), reduce)
|
|
yield SampleInput(make_arg(self_shape),
|
|
args=args,
|
|
kwargs={'include_self' : include_self})
|
|
|
|
# Sample inputs to test edge cases for backward
|
|
if requires_grad and reduce == 'prod':
|
|
# Check that gradients are propagated correctly for prod when zeros in self/src are reduced
|
|
# This sample tests gradients for the following cases
|
|
# (a) 1 zero reduced (from source (self[0, 1]), from self (self[0, 0]))
|
|
# (b) 2 zeros reduced (1 from src and 1 from self (self[1, 0], self[1, 1])
|
|
# (c) no zeros reduced (self[2, 1], self[2, 2])
|
|
# (d) 2 zeros reduced (both from src) is tested in test/test_autograd.py
|
|
# test_scatter_index_reduce_prod_gradgrad_error as this case is not supported for gradgrad
|
|
input = torch.tensor([[0, 13], [0, 0], [15, 19]], dtype=dtype, device=device, requires_grad=requires_grad)
|
|
src = torch.tensor([[2, 0], [0, 0], [2, 3], [2, 2]], dtype=dtype, device=device, requires_grad=requires_grad)
|
|
idx = torch.tensor([0, 1, 2, 0], dtype=torch.long, device=device)
|
|
|
|
yield SampleInput(input,
|
|
args=(0, idx, src, reduce),
|
|
kwargs={'include_self': True})
|
|
|
|
def sample_inputs__unsafe_masked_index(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_idx(n, m, dim, d):
|
|
view_shape = [1] * dim
|
|
view_shape[d] = n
|
|
return make_tensor((n,), device=device, dtype=torch.int64, low=0, high=m).view(view_shape)
|
|
|
|
cases = [
|
|
((S, S), S, M),
|
|
((S, S), M, S),
|
|
((S, S, S), S, M),
|
|
]
|
|
|
|
fill_value = make_tensor([], dtype=dtype, device="cpu").item()
|
|
|
|
for c in cases:
|
|
self_shape, high, idx_size = c
|
|
dim = len(self_shape)
|
|
indices = [make_idx(idx_size, high, dim, d) for d in range(dim)]
|
|
masks = [torch.logical_and(idx >= 0, idx < self_shape[i]) for i, idx in enumerate(indices) if idx is not None]
|
|
mask = functools.reduce(torch.logical_and, masks)
|
|
yield SampleInput(make_arg(self_shape), mask, indices, fill_value)
|
|
|
|
masks = [torch.logical_and(idx >= 1, idx < self_shape[i] - 1) for i, idx in enumerate(indices) if idx is not None]
|
|
mask = functools.reduce(torch.logical_and, masks)
|
|
yield SampleInput(make_arg(self_shape), mask, indices, fill_value)
|
|
|
|
def sample_inputs__unsafe_masked_index_put_accumulate(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_idx(n, m, dim, d):
|
|
view_shape = [1] * dim
|
|
view_shape[d] = n
|
|
return make_tensor((n,), device=device, dtype=torch.int64, low=0, high=m).view(view_shape)
|
|
|
|
cases = [
|
|
((S, S), S, (M, M)),
|
|
((S, S), M, (S, S + 1)),
|
|
((S, S, S), S, (M, M - 1, M + 1)),
|
|
]
|
|
|
|
for c in cases:
|
|
self_shape, high, idx_sizes = c
|
|
dim = len(self_shape)
|
|
indices = [make_idx(idx_sizes[d], high, dim, d) for d in range(dim)]
|
|
masks = [torch.logical_and(idx >= 0, idx < self_shape[i]) for i, idx in enumerate(indices) if idx is not None]
|
|
mask = functools.reduce(torch.logical_and, masks)
|
|
values = make_arg(idx_sizes)
|
|
yield SampleInput(make_arg(self_shape), mask, indices, values)
|
|
|
|
masks = [torch.logical_and(idx >= 1, idx < self_shape[i] - 1) for i, idx in enumerate(indices) if idx is not None]
|
|
mask = functools.reduce(torch.logical_and, masks)
|
|
yield SampleInput(make_arg(self_shape), mask, indices, values)
|
|
|
|
|
|
def sample_inputs_mode(op_info, device, dtype, requires_grad, **kwargs):
|
|
args = (
|
|
((S, S, S), (),),
|
|
((S, S, S), (1, ),),
|
|
((S, S, S), (1, True, ),),
|
|
((), (),),
|
|
((), (0,),),
|
|
((), (0, True,),),
|
|
# Non-fused mode kernel on CUDA
|
|
((3000,), ()),
|
|
)
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device,
|
|
requires_grad=requires_grad, low=None, high=None)
|
|
return (SampleInput(make_arg(input_tensor), *args)
|
|
for input_tensor, args in args)
|
|
|
|
# Missing to test the nondeterminism of the operation
|
|
# https://github.com/pytorch/pytorch/issues/53352
|
|
def sample_inputs_put(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
make_idx = partial(make_tensor, low=0, dtype=torch.int64, device=device, requires_grad=False)
|
|
|
|
S = 3
|
|
|
|
# Generic inputs
|
|
idx = torch.randperm(S * S, device=device, dtype=torch.int64)[:S]
|
|
idx_list = [idx, -idx - 1]
|
|
for idx, acc in product(idx_list, (True, False)):
|
|
yield SampleInput(input=make_arg((S, S)),
|
|
args=(idx.clone(),
|
|
make_arg((S,)),
|
|
acc))
|
|
|
|
# Scalar cases
|
|
scalar_sizes = [(), (1,)]
|
|
tgt_gen = (make_arg(size) for size in scalar_sizes)
|
|
idx_gen = (make_idx(size, high=1) for size in scalar_sizes)
|
|
src_gen = (make_arg(size) for size in scalar_sizes)
|
|
for tgt, idx, src, acc in product(tgt_gen, idx_gen, src_gen, (True, False)):
|
|
yield SampleInput(input=tgt.clone().requires_grad_(requires_grad),
|
|
args=(idx.clone(),
|
|
src.clone().requires_grad_(requires_grad),
|
|
acc))
|
|
|
|
# Empty cases
|
|
tgt_sizes = [(0,), (), (1,), (3, 2)]
|
|
tgt_gen = (make_arg(size) for size in tgt_sizes)
|
|
idx = make_idx((0,), high=1)
|
|
src = make_arg((0,))
|
|
for tgt, acc in product(tgt_gen, (True, False)):
|
|
yield SampleInput(input=tgt.clone().requires_grad_(requires_grad),
|
|
args=(idx.clone(),
|
|
src.clone().requires_grad_(requires_grad),
|
|
acc))
|
|
|
|
def sample_inputs_take(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
make_idx = partial(make_tensor, low=0, dtype=torch.int64, device=device, requires_grad=False)
|
|
|
|
S = 3
|
|
|
|
# Generic inputs: take S elements out of S * S
|
|
index = make_idx((S,), high=(S * S))
|
|
for idx in (index, -index - 1):
|
|
yield SampleInput(input=make_arg((S, S)), args=(idx,))
|
|
|
|
# Scalar cases
|
|
scalar_sizes = [(), (1,)]
|
|
src_gen = (make_arg(size) for size in scalar_sizes)
|
|
idx_gen = (make_idx(size, high=1) for size in scalar_sizes)
|
|
for src, idx in product(src_gen, idx_gen):
|
|
yield SampleInput(input=src.clone().requires_grad_(requires_grad),
|
|
args=(idx.clone(),))
|
|
|
|
# Empty cases
|
|
src_sizes = [(0,), (), (1,), (3, 2)]
|
|
src_gen = (make_arg(size) for size in src_sizes)
|
|
|
|
idx = make_idx((0,), high=1)
|
|
for src in src_gen:
|
|
yield SampleInput(input=src.clone().requires_grad_(requires_grad),
|
|
args=(idx.clone(),))
|
|
|
|
def sample_movedim_moveaxis(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg((4, 3, 2, 1)), [0, 1, 2, 3], [3, 2, 1, 0])
|
|
yield SampleInput(make_arg((4, 3, 2, 1)), [0, -1, -2, -3], [-3, -2, -1, -0])
|
|
|
|
def reference_movedim_moveaxis(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_movedim_moveaxis(op_info, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# shape, source, destination
|
|
args = (
|
|
# empty inputs
|
|
((), (), ()),
|
|
# int inputs, negative
|
|
((3, 5, 7, 2), -2, 1),
|
|
# swap bounds
|
|
((3, 5, 7, 2), (-1, 0), (0, -1)),
|
|
# non-sequential, negative
|
|
((2, 3, 4, 5, 6), (3, -3, 4), (1, 0, -1)),
|
|
# idempotence, negative
|
|
((2, 3, 4, 5, 6), (-3, 4, 3, 1), (-3, 4, 3, 1)),
|
|
# reverse, sequential, positive
|
|
((6, 2, 3, 5, 4), (4, 3, 2, 1, 0), (0, 1, 2, 3, 4)),
|
|
# reverse, non-sequential
|
|
((6, 2, 3, 5, 4), (-3, -2, -4, -5, -1), (2, 1, 3, 4, 0)),
|
|
# reverse, sequential, negative
|
|
((6, 2, 3, 5, 4), (4, -2, 2, -4, -5), (-5, 1, 2, -2, -1)),
|
|
)
|
|
|
|
for shape, source, destination in args:
|
|
yield SampleInput(make_arg(shape), args=(source, destination))
|
|
|
|
def error_movedim_moveaxis(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# source length < destination length
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((3, -3), (1, 0, -1))),
|
|
error_regex=(r"movedim: Invalid source or destination dims: source "
|
|
r"\(\[3, -3\] dims\) should contain the same number of "
|
|
r"dims as destination \(\[1, 0, -1\] dims\)"),
|
|
)
|
|
|
|
# source length > destination length
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((3, -3, 4), (1, 0))),
|
|
error_regex=(r"movedim: Invalid source or destination dims: source "
|
|
r"\(\[3, -3, 4\] dims\) should contain the same number of "
|
|
r"dims as destination \(\[1, 0\] dims\)"),
|
|
)
|
|
|
|
# repeated source dim, with negative indices
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((0, 4, -5), (1, 0, 2))),
|
|
error_regex=r"movedim: repeated dim in `source` \(\[0, 4, -5\]\)",
|
|
)
|
|
|
|
# repeated destination dim, with negative indices
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((1, 0, 2), (0, 4, -5))),
|
|
error_regex=r"movedim: repeated dim in `destination` \(\[0, 4, -5\]\)",
|
|
)
|
|
|
|
# repeated dim (both), with negative indices
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((1, 0, -4), (0, 4, -5))),
|
|
error_regex=r"movedim: repeated dim in `source` \(\[1, 0, -4\]\)",
|
|
)
|
|
|
|
# out of bounds source inputs, with negative indices
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((0, 1, -6), (1, 4, 2))),
|
|
error_regex=r"Dimension out of range \(expected to be in range of \[-5, 4\], but got -6\)",
|
|
error_type=IndexError,
|
|
)
|
|
|
|
# out of bounds destination inputs, with negative indices
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=((1, 4, 2), (0, 1, -6))),
|
|
error_regex=r"Dimension out of range \(expected to be in range of \[-5, 4\], but got -6\)",
|
|
error_type=IndexError,
|
|
)
|
|
|
|
# out of bounds source input, int
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=(-6, 1)),
|
|
error_regex=r"Dimension out of range \(expected to be in range of \[-5, 4\], but got -6\)",
|
|
error_type=IndexError,
|
|
)
|
|
|
|
# out of bounds destination input, int
|
|
yield ErrorInput(
|
|
SampleInput(make_arg(2, 3, 4, 5, 6), args=(3, -6)),
|
|
error_regex=r"Dimension out of range \(expected to be in range of \[-5, 4\], but got -6\)",
|
|
error_type=IndexError,
|
|
)
|
|
|
|
def sample_repeat_tile(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
rep_dims = ((), (0, ), (1, ), (0, 2), (1, 1), (2, 3), (2, 3, 2), (0, 2, 3), (2, 1, 1, 1),)
|
|
shapes = ((), (0,), (2,), (3, 0), (3, 2), (3, 0, 1))
|
|
|
|
if requires_grad:
|
|
# Tests for variant_consistency_jit, grad, gradgrad
|
|
# are slower. Use smaller bags of `rep_dims` and `shapes`
|
|
# in this case.
|
|
rep_dims = ((), (0, ), (0, 2), (1, 1), (2, 3), (1, 3, 2), (3, 1, 1)) # type: ignore[assignment]
|
|
shapes = ((), (0,), (2,), (3, 2)) # type: ignore[assignment]
|
|
|
|
is_repeat_op = op_info.name in ['repeat', '_refs.repeat']
|
|
for rep_dim, shape in product(rep_dims, shapes):
|
|
# `torch.repeat` errors for `len(rep_dims) < t.dim()`,
|
|
# so we filter such combinations.
|
|
if is_repeat_op and len(rep_dim) < len(shape):
|
|
continue
|
|
yield SampleInput(make_arg(shape), rep_dim)
|
|
|
|
|
|
def sample_inputs_narrow_narrow_copy(op_info, device, dtype, requires_grad, *, is_narrow, **kwargs):
|
|
shapes_and_args = (
|
|
((S, S, S), 1, 2, 2),
|
|
((S, S, S), -1, 2, 2),
|
|
((S, S, S), 1, 0, 0),
|
|
((S, S, S), -1, 0, 0),
|
|
((S, S, S), 2, 1, 2),
|
|
)
|
|
|
|
for shape, dim, start, length in shapes_and_args:
|
|
tensor = make_tensor(shape, dtype=dtype, device=device, low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(tensor, dim, start, length)
|
|
# narrow also accepts the start argument being a Tensor
|
|
if is_narrow:
|
|
yield SampleInput(tensor, dim, torch.tensor(start), length)
|
|
|
|
def reference_inputs_narrow_narrow_copy(op_info, device, dtype, requires_grad, *, is_narrow, **kwargs):
|
|
yield from sample_inputs_narrow_narrow_copy(op_info, device, dtype, requires_grad, is_narrow=is_narrow, **kwargs)
|
|
|
|
shapes_and_args = (
|
|
# 1-dim
|
|
((M,), 0, 0, 0), # 0 elems from the left
|
|
((M,), -1, -1, 0), # 0 elems from the right
|
|
((M,), 0, 5, 3), # 3 elems from the left
|
|
((M,), 0, -5, 2), # 2 elems from the right
|
|
((M,), -1, 0, M), # M elems from the left
|
|
((M,), 0, -M, M), # M elems from the right
|
|
|
|
# 2-dim
|
|
((M, S), 1, 0, 0), # dim 1, 0 elems from the left
|
|
((S, M), -2, -1, 0), # dim 0, 0 elems from the right
|
|
((L, S), 1, 2, 3), # dim 1, 3 elems from the left
|
|
((L, S), -1, 3, 2), # dim 1, 2 elems from the left
|
|
((M, L), 0, 0, M), # dim 0, M elems from the left
|
|
((M, L), -1, -L, L), # dim 1, L elems from the right
|
|
|
|
# 3-dim
|
|
((L, M, S), 2, 0, 0), # dim 2, 0 elems from the left
|
|
((M, S, L), -1, -1, 0), # dim 2, 0 elems from the right
|
|
((S, L, M), 2, 0, M), # dim 2, M elems from the left
|
|
((L, S, M), -1, -M, M), # dim 2, M elems from the right
|
|
((S, L, M), 1, 0, 0), # dim 1, 0 elems from the left
|
|
((S, L, M), 0, 2, 1), # dim 0, 1 elem from the left
|
|
((M, S, M), -1, -5, 4), # dim 2, 4 elems from the right
|
|
)
|
|
|
|
for shape, dim, start, length in shapes_and_args:
|
|
tensor = make_tensor(shape, dtype=dtype, device=device, low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(tensor, dim, start, length)
|
|
# narrow also accepts the start argument being a Tensor
|
|
if is_narrow:
|
|
yield SampleInput(tensor, dim, torch.tensor(start), length)
|
|
|
|
def error_inputs_narrow_narrow_copy(op_info, device, *, is_narrow, is_ref):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# 0-dim
|
|
yield ErrorInput(SampleInput(make_arg(()), 0, 0, 1),
|
|
error_type=RuntimeError,
|
|
error_regex=r"narrow\(\) cannot be applied to a 0-dim tensor\.")
|
|
|
|
# out of bounds dim
|
|
if not is_narrow and not is_ref and torch.device(device).type == 'cpu':
|
|
# narrow_copy_dense_cpu_out
|
|
yield ErrorInput(SampleInput(make_arg((M, S, L)), 3, 0, 0),
|
|
error_type=RuntimeError,
|
|
error_regex=r"Expected dim < static_cast<int64_t>\(self_sizes.size\(\)\) to be true, but got false\.")
|
|
else:
|
|
yield ErrorInput(SampleInput(make_arg((M, S, L)), 3, 0, 0),
|
|
error_type=IndexError,
|
|
error_regex=r"Dimension out of range \(expected to be in range of \[-3, 2\], but got 3\)")
|
|
# out of bounds dim (negative)
|
|
yield ErrorInput(SampleInput(make_arg((L, S, M)), -4, 0, 0),
|
|
error_type=IndexError,
|
|
error_regex=r"Dimension out of range \(expected to be in range of \[-3, 2\], but got -4\)")
|
|
|
|
# out of bounds start
|
|
yield ErrorInput(SampleInput(make_arg((L, M, S)), 1, M + 1, 0),
|
|
error_type=IndexError,
|
|
error_regex=r"start out of range \(expected to be in range of \[-10, 10\], but got 11\)")
|
|
# out of bounds start (negative)
|
|
yield ErrorInput(SampleInput(make_arg((L, M, S)), 1, -M - 1, 0),
|
|
error_type=IndexError,
|
|
error_regex=r"start out of range \(expected to be in range of \[-10, 10\], but got -11\)")
|
|
|
|
# out of bounds length
|
|
yield ErrorInput(SampleInput(make_arg((S, L, M)), 2, 0, M + 1),
|
|
error_type=RuntimeError,
|
|
error_regex=r"start \(0\) \+ length \(11\) exceeds dimension size \(10\)\.")
|
|
# out of bounds length (negative)
|
|
if not is_narrow and not is_ref and torch.device(device).type == 'cpu':
|
|
# narrow_copy_dense_cpu_out
|
|
yield ErrorInput(SampleInput(make_arg((M,)), 0, 0, -1),
|
|
error_type=RuntimeError,
|
|
error_regex=r"start \(0\) \+ length \(-1\) exceeds dimension size \(10\)\.")
|
|
else:
|
|
yield ErrorInput(SampleInput(make_arg((M,)), 0, 0, -1),
|
|
error_type=RuntimeError,
|
|
error_regex=r"narrow\(\): length must be non-negative\.")
|
|
|
|
# Test Tensor overload that was added for XLA. Start must be an 0-dim
|
|
# integral Tensor. narrow_copy doesn't have this overload.
|
|
# https://github.com/pytorch/pytorch/issues/31558
|
|
if is_narrow:
|
|
# *1-dim* integral Tensor
|
|
yield ErrorInput(SampleInput(make_arg((L, M, S)), 1, make_arg(S, dtype=torch.int), 2),
|
|
error_type=RuntimeError,
|
|
error_regex=r"start must be an 0-dim integral Tensor\.")
|
|
|
|
# 0-dim *bool* Tensor (bools are not allowed)
|
|
yield ErrorInput(SampleInput(make_arg((L, M, S)), -3, make_arg((), dtype=torch.bool), 3),
|
|
error_type=RuntimeError,
|
|
error_regex=r"start must be an 0-dim integral Tensor\.")
|
|
|
|
|
|
def sample_trapezoid(op_info, device, dtype, requires_grad, **kwargs):
|
|
y_shape_x_shape_and_kwargs = [
|
|
((2, 3), (2, 3), {}),
|
|
((2, 3), (2, 3), {'dim': 1}),
|
|
((6,), (6,), {}),
|
|
((6,), None, {}),
|
|
# When 'trapezoid' is called with an empty input, it does not produce an output with requires_grad
|
|
# See Issue #{61619}
|
|
# ((6,0), (6,0), {}),
|
|
((2, 3), (1, 3), {}),
|
|
((3, 3), (3, 3), {}),
|
|
((3, 3), (3, 3), {'dim': -2}),
|
|
((5,), None, {'dx': 2.0}),
|
|
((2, 2), None, {'dx': 3.0})
|
|
]
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
for y_shape, x_shape, kwarg in y_shape_x_shape_and_kwargs:
|
|
y_tensor = make_arg(y_shape)
|
|
if x_shape is not None:
|
|
x_tensor = make_arg(x_shape)
|
|
yield SampleInput(y_tensor, x_tensor, **kwarg)
|
|
else:
|
|
yield SampleInput(y_tensor, **kwarg)
|
|
|
|
def sample_cumulative_trapezoid(op_info, device, dtype, requires_grad, **kwargs):
|
|
|
|
y_shape_x_shape_and_kwargs = [
|
|
((2, 3), (2, 3), {}),
|
|
((2, 3), (2, 3), {'dim': 1}),
|
|
((6,), (6,), {}),
|
|
((6,), None, {}),
|
|
# When 'cumulative_trapezoid' is called with an empty input, it does not produce an output with requires_grad
|
|
# See Issue #{61619}
|
|
# ((6,0), (6,0), {}),
|
|
((2, 3), (1, 3), {}),
|
|
((3, 3), (3, 3), {}),
|
|
((3, 3), (3, 3), {'dim': -2}),
|
|
((5,), None, {'dx': 2.0}),
|
|
((2, 2), None, {'dx': 3.0})
|
|
]
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype,
|
|
requires_grad=requires_grad, low=None, high=None)
|
|
for y_shape, x_shape, kwarg in y_shape_x_shape_and_kwargs:
|
|
y_tensor = make_arg(y_shape)
|
|
if x_shape is not None:
|
|
x_tensor = make_arg(x_shape)
|
|
yield SampleInput(y_tensor, x_tensor, **kwarg)
|
|
else:
|
|
yield SampleInput(y_tensor, **kwarg)
|
|
|
|
def sample_unsqueeze(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes_and_axes = [
|
|
((3, 4, 5), 0),
|
|
((3, 4, 5), 1),
|
|
((3, 4, 5), 3),
|
|
((3, 4, 5), -1),
|
|
((3, 4, 5), -3),
|
|
((), 0),
|
|
((), -1),
|
|
((1,), 0),
|
|
((1,), -1),
|
|
]
|
|
|
|
for shape, axis in shapes_and_axes:
|
|
tensor = make_tensor(shape, dtype=dtype, device=device, low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
yield SampleInput(tensor, axis)
|
|
|
|
|
|
def sample_inputs_nn_unfold(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes = ((0, 1, 5, 5), (2, 3, 5, 5))
|
|
kernel_sizes = (2, (2, 2), (2, 3))
|
|
dilations = (1, 2, (1, 2))
|
|
paddings = (0, 1, (1, 2))
|
|
strides = (1, 2, (1, 2))
|
|
|
|
cases = product(shapes, kernel_sizes, dilations, paddings, strides)
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
for shape, kernel_size, dilation, padding, stride in cases:
|
|
tensor = make_arg(shape)
|
|
yield SampleInput(tensor, kernel_size, dilation, padding, stride)
|
|
|
|
# With default args
|
|
yield SampleInput(make_arg((1, 1, 5, 5)), (3, 3))
|
|
|
|
|
|
def sample_inputs_squeeze(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes_and_args = (
|
|
((S, 1, S, 1), ()),
|
|
((1, 1, 1, 1), ()),
|
|
((1, 1, 1, 1), (0,)),
|
|
((S, 1, S, 1), (1,)),
|
|
((S, 1, S, 1), (-1,)),
|
|
((S, 1, S, 1), (2,)),
|
|
((S, 1, S, 1), (-2,)),
|
|
((), (0, )),
|
|
)
|
|
|
|
for shape, args in shapes_and_args:
|
|
tensor = make_tensor(shape, dtype=dtype, device=device, low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
|
|
yield SampleInput(tensor, args=args)
|
|
|
|
|
|
def sample_inputs_squeeze_multiple(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes_and_args = (
|
|
((1, 1, 1, 1), ()),
|
|
((S, 1, S, 1), (1,)),
|
|
((S, 1, S, 1), (-1,)),
|
|
((S, 1, S, 1), (1, 3)),
|
|
((S, 1, S, 1), (1, 2,)),
|
|
((), (0,)),
|
|
)
|
|
|
|
for shape, dims in shapes_and_args:
|
|
tensor = make_tensor(shape, dtype=dtype, device=device, low=None, high=None,
|
|
requires_grad=requires_grad)
|
|
|
|
yield SampleInput(tensor, dims)
|
|
|
|
|
|
def _squeeze_ref(x, axis=None):
|
|
# NumPy doesn't allow squeezing scalars
|
|
if x.ndim == 0:
|
|
return x
|
|
|
|
if isinstance(axis, Sequence):
|
|
# Numpy doesn't allow specifying non-singular dimensions
|
|
axis = tuple(a for a in axis if x.shape[a] == 1)
|
|
|
|
if isinstance(axis, int) and x.shape[axis] != 1:
|
|
return x
|
|
|
|
return np.squeeze(x, axis)
|
|
|
|
def sample_inputs_nn_pad(op_info, device, dtype, requires_grad, mode, **kwargs):
|
|
assert mode in ('constant', 'reflect', 'replicate', 'circular')
|
|
if mode in ['reflect', 'replicate']:
|
|
cases: tuple = ( # ignore
|
|
((1, 3), (1, 2)),
|
|
((1, 3), (0, 1)),
|
|
((0, 3, 3), (1, 2)),
|
|
((0, 3, 3), (0, 1)),
|
|
((1, 3, 3), (1, 2)),
|
|
((1, 3, 3), (0, 1)),
|
|
((1, 3, 3), (0, 2, 0, 1)),
|
|
((0, 3, 3, 3), (0, 2, 0, 1)),
|
|
((3, 3, 5, 5), (0, 2, 0, 1)),
|
|
((3, 3, 5, 5), (1, 1, 1, 1, 1, 1)),
|
|
((1, 3, 3, 3, 3), (1, 1, 1, 1, 1, 1)),
|
|
((1, 3, 4, 4), (-1, 1, -2, 1)),
|
|
)
|
|
elif mode == 'constant':
|
|
cases = (
|
|
((1, 3), (1, 2)),
|
|
((1, 3), (0, 1)),
|
|
((1, 3), (0, 2, 0, 1)),
|
|
((0, 3, 3), (1, 2)),
|
|
((0, 3, 3), (0, 1)),
|
|
((0, 3, 3), (0, 2, 0, 1)),
|
|
((0, 3, 3), (1, 1, 1, 1, 1, 1)),
|
|
((1, 3, 3), (1, 2)),
|
|
((1, 3, 3), (0, 1)),
|
|
((1, 3, 3), (0, 2, 0, 1)),
|
|
((1, 3, 3), (1, 1, 1, 1, 1, 1)),
|
|
((0, 3, 3, 3), (1, 2)),
|
|
((0, 3, 3, 3), (0, 1)),
|
|
((0, 3, 3, 3), (0, 2, 0, 1)),
|
|
((0, 3, 3, 3), (1, 1, 1, 1, 1, 1)),
|
|
((3, 3, 5, 5), (1, 2)),
|
|
((3, 3, 5, 5), (0, 1)),
|
|
((3, 3, 5, 5), (0, 2, 0, 1)),
|
|
((3, 3, 5, 5), (1, 1, 1, 1, 1, 1)),
|
|
((1, 3, 3, 3, 3), (1, 2)),
|
|
((1, 3, 3, 3, 3), (0, 1)),
|
|
((1, 3, 3, 3, 3), (0, 2, 0, 1)),
|
|
((1, 3, 3, 3, 3), (1, 1, 1, 1, 1, 1)),
|
|
((1, 3, 4, 4), (-1, 1, -2, 1)),
|
|
)
|
|
else: # mode == 'circular'
|
|
if dtype == torch.bool:
|
|
# test_dtypes fails on ASAN with for the case ab
|
|
# runtime error: load of value 190, which is not a valid value for type 'bool'
|
|
# Reference: https://github.com/pytorch/pytorch/pull/62814#issuecomment-894156562
|
|
# Reference Issue: https://github.com/pytorch/pytorch/issues/63034
|
|
cases = (
|
|
((2, 3, 3), (1, 2)),
|
|
((1, 3, 3), (1, 2)),
|
|
)
|
|
else:
|
|
cases = (
|
|
((0, 3, 3), (1, 2)),
|
|
((0, 3, 3), (0, 1)),
|
|
((1, 3, 3), (1, 2)),
|
|
((1, 3, 3), (0, 1)),
|
|
((0, 3, 3, 3), (0, 2, 0, 1)),
|
|
((3, 3, 5, 5), (0, 2, 0, 1)),
|
|
((1, 3, 3, 3, 3), (1, 1, 1, 1, 1, 1)),
|
|
((1, 3, 4, 4), (-1, 1, -2, 1)),
|
|
)
|
|
|
|
make_inp = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
if mode == 'constant':
|
|
# Default args
|
|
yield SampleInput(make_inp((1, 3, 3)), args=((2, 2),))
|
|
|
|
if mode in ['reflect', 'replicate', 'circular']:
|
|
for shape, pad in cases:
|
|
yield SampleInput(make_inp(shape), args=(pad, mode))
|
|
else: # mode == 'constant'
|
|
for pad_value in (1., 2.):
|
|
for shape, pad in cases:
|
|
yield SampleInput(make_inp(shape), args=(pad, mode, pad_value))
|
|
|
|
def sample_inputs_nn_pad_replicate_negative(op_info, device, dtype, requires_grad, **kwargs):
|
|
cases: tuple = (
|
|
((5, 3, 4, 4), (-4, 5, 0, 0)),
|
|
((6, 2, 4, 4), (0, 0, 2, -4)),
|
|
((5, 6, 4, 4), (5, -4, -4, 3)),
|
|
((4, 2, 5, 5), (-2, -1, 4, 6)),
|
|
((2, 6, 5, 5), (8, -1, -1, -3)),
|
|
((8, 1, 5, 5), (-2, -1, -1, -3)),
|
|
)
|
|
make_inp = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
for shape, pad in cases:
|
|
yield SampleInput(make_inp(shape), args=(pad, 'replicate'))
|
|
|
|
def sample_inputs_constant_pad_nd(op_info, device, dtype, *args, **kwargs):
|
|
# Inherit sample inputs from nn.pad, but transform them to fit
|
|
# constant_pad_nd's interface
|
|
nn_samples = sample_inputs_nn_pad(op_info, device, dtype, *args,
|
|
mode='constant', **kwargs)
|
|
|
|
# NOTE: primTorch is more strict about the type of the fill value argument
|
|
# So we must cast it to the correct dtype
|
|
from torch._prims_common import dtype_to_type
|
|
scalar_type = dtype_to_type(dtype)
|
|
|
|
def drop_mode_argument(input, pad, mode=None, value=None):
|
|
if value is None:
|
|
return SampleInput(input, args=(pad,))
|
|
else:
|
|
return SampleInput(input, args=(pad, scalar_type(value)))
|
|
|
|
for sample in nn_samples:
|
|
yield drop_mode_argument(sample.input, *sample.args, **sample.kwargs)
|
|
|
|
def sample_inputs_repeat_interleave(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_input(()), repeats=2)
|
|
yield SampleInput(make_input((2, 3, 4)), repeats=2)
|
|
yield SampleInput(make_input((2, 3, 4)), repeats=2, dim=1)
|
|
yield SampleInput(make_input((2, 3, 4)), repeats=torch.arange(3, device=device), dim=1)
|
|
|
|
|
|
def sample_inputs_stft(op_info, device, dtype, requires_grad, **kwargs):
|
|
def mt(shape, **kwargs):
|
|
return make_tensor(shape, device=device, dtype=dtype,
|
|
requires_grad=requires_grad, **kwargs)
|
|
|
|
yield SampleInput(mt(100), n_fft=10, return_complex=True)
|
|
yield SampleInput(mt(100), n_fft=10, return_complex=False)
|
|
if dtype.is_complex:
|
|
yield SampleInput(mt(100), n_fft=10)
|
|
|
|
for center in [False, True]:
|
|
yield SampleInput(mt(10), n_fft=7, center=center, return_complex=True)
|
|
yield SampleInput(mt((10, 100)), n_fft=16, hop_length=4,
|
|
center=center, return_complex=True)
|
|
|
|
window = mt(16, low=.5, high=2.0)
|
|
yield SampleInput(
|
|
mt((2, 100)), kwargs=dict(n_fft=16, window=window, return_complex=True, center=center))
|
|
yield SampleInput(
|
|
mt((3, 100)), kwargs=dict(n_fft=16, window=window, return_complex=True, center=center))
|
|
if not dtype.is_complex:
|
|
yield SampleInput(
|
|
mt((10, 100)), n_fft=16, window=window, onesided=False,
|
|
return_complex=True)
|
|
|
|
|
|
def sample_inputs_istft(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def mt(shape, **kwargs):
|
|
real_shape = shape if dtype.is_complex else shape + (2,)
|
|
return make_arg(real_shape, **kwargs)
|
|
|
|
yield SampleInput(mt((10, 2)), kwargs=dict(n_fft=10))
|
|
yield SampleInput(mt((6, 3)), kwargs=dict(n_fft=6, onesided=False))
|
|
yield SampleInput(mt((6, 4)), kwargs=dict(n_fft=10, onesided=True))
|
|
|
|
for center in [False, True]:
|
|
yield SampleInput(mt((10, 10, 6)), kwargs=dict(n_fft=10, center=center))
|
|
yield SampleInput(mt((1, 9, 10)), kwargs=dict(n_fft=16, hop_length=4, center=center))
|
|
|
|
window = make_arg(10, low=.5, high=2.0)
|
|
yield SampleInput(mt((10, 10, 6)), kwargs=dict(
|
|
n_fft=10, window=window, center=center, return_complex=dtype.is_complex))
|
|
yield SampleInput(mt((10, 10, 10)), kwargs=dict(
|
|
n_fft=10, window=window[:8], win_length=8, center=center, return_complex=True))
|
|
|
|
real_window = window if not dtype.is_complex else window.real
|
|
yield SampleInput(mt((10, 5, 6)), kwargs=dict(n_fft=8, window=real_window[:8], center=center))
|
|
|
|
def sample_inputs_ormqr(op_info, device, dtype, requires_grad, **kwargs):
|
|
# create a helper function wrapping `make_tensor`
|
|
make_input = partial(make_tensor, dtype=dtype, device=device, low=-1, high=1)
|
|
|
|
batches = [(), (0, ), (2, ), (2, 1)]
|
|
ns = [5, 2, 0]
|
|
tf = [True, False]
|
|
for batch, (m, n), left, transpose in product(batches, product(ns, ns), tf, tf):
|
|
input = make_input((*batch, m, n))
|
|
reflectors, tau = torch.geqrf(input)
|
|
reflectors.requires_grad_(requires_grad)
|
|
tau.requires_grad_(requires_grad)
|
|
other_matrix_shape = (m, n) if left else (n, m)
|
|
other = make_input((*batch, *other_matrix_shape), requires_grad=requires_grad)
|
|
yield SampleInput(reflectors, tau, other, left=left, transpose=transpose)
|
|
|
|
|
|
def sample_inputs_cholesky_solve(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
cholesky_inverse_samples = sample_inputs_linalg_cholesky_inverse(
|
|
op_info, device, dtype, requires_grad=False
|
|
)
|
|
|
|
for sample in cholesky_inverse_samples:
|
|
psd_matrix = sample.input
|
|
sample.input = make_tensor(psd_matrix.shape, dtype=dtype, device=device, requires_grad=requires_grad, low=None, high=None)
|
|
sample.args = (psd_matrix.requires_grad_(requires_grad),)
|
|
yield sample
|
|
|
|
|
|
def sample_inputs_lu(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
make_arg = partial(make_fullrank_matrices_with_distinct_singular_values,
|
|
dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# not needed once OpInfo tests support Iterables
|
|
batch_shapes = ((), (3,), (3, 3))
|
|
for batch_shape, get_infos, size_delta in product(batch_shapes, (True, False), (-2, -1, 0, +1, +2)):
|
|
shape = batch_shape + (S + size_delta, S)
|
|
input = make_arg(*shape)
|
|
yield SampleInput(input, args=(True, get_infos))
|
|
|
|
|
|
def sample_inputs_lu_unpack(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
def out_fn(output):
|
|
return output[1], output[2]
|
|
|
|
for lu_sample in sample_inputs_linalg_lu(op_info, device, dtype, requires_grad, **kwargs):
|
|
lu_data, pivots = torch.linalg.lu_factor(lu_sample.input)
|
|
lu_data.requires_grad_(requires_grad)
|
|
yield SampleInput(lu_data, pivots).with_metadata(output_process_fn_grad=out_fn)
|
|
|
|
|
|
def sample_inputs_roll(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
args = ((0, 0), (1, 2), (0, 2), (2, 0), (-1, 0), (10000, 1), (2,), ((1, 2, -1), (0, 1, 2)))
|
|
|
|
for arg in args:
|
|
yield SampleInput(make_arg((0, 0, 0)), args=arg)
|
|
yield SampleInput(make_arg((S, S, S)), args=arg)
|
|
|
|
# Scalar tensor
|
|
yield SampleInput(make_arg(()), args=(10, ))
|
|
|
|
def error_inputs_roll(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
err_msg1 = "`shifts` required"
|
|
s1 = SampleInput(make_arg((S,)), ())
|
|
yield ErrorInput(s1, error_regex=err_msg1)
|
|
|
|
err_msg2 = ("shifts and dimensions must align")
|
|
s2 = SampleInput(make_arg((S, S)), (2, 1), 0)
|
|
yield ErrorInput(s2, error_regex=err_msg2)
|
|
|
|
err_msg3 = ("out of range")
|
|
s3 = SampleInput(make_arg((S, )), 0, 2)
|
|
yield ErrorInput(s3, error_regex=err_msg3, error_type=IndexError)
|
|
|
|
err_msg4 = ("Dimension specified as 0")
|
|
s4 = SampleInput(make_arg(()), 0, 0)
|
|
yield ErrorInput(s4, error_regex=err_msg4, error_type=IndexError)
|
|
|
|
def sample_inputs_rot90(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
args = itertools.product(range(-5, 6), [(0, 1), (1, 2), (1, -1)])
|
|
|
|
yield SampleInput(make_arg((S, S, S)))
|
|
for arg in args:
|
|
yield SampleInput(make_arg((S, S, S)), args=arg)
|
|
|
|
|
|
def error_inputs_rot90(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
err_msg1 = "expected total rotation dims"
|
|
s1 = SampleInput(make_arg((S, S)), dims=(0,))
|
|
yield ErrorInput(s1, error_regex=err_msg1)
|
|
|
|
err_msg2 = "expected total dims >= 2"
|
|
s2 = SampleInput(make_arg((S,)))
|
|
yield ErrorInput(s2, error_regex=err_msg2)
|
|
|
|
err_msg3 = "expected rotation dims to be different"
|
|
s3 = SampleInput(make_arg((S, S)), dims=(1, 1))
|
|
yield ErrorInput(s3, error_regex=err_msg3)
|
|
|
|
|
|
def sample_inputs_std_var(op_info, device, dtype, requires_grad, **kwargs):
|
|
tensor_nd = partial(make_tensor, (S, S, S), device=device, dtype=dtype,
|
|
requires_grad=requires_grad)
|
|
tensor_1d = partial(make_tensor, (S,), device=device, dtype=dtype,
|
|
requires_grad=requires_grad)
|
|
|
|
yield SampleInput(tensor_nd())
|
|
yield SampleInput(tensor_nd(), dim=1)
|
|
yield SampleInput(tensor_nd(), dim=1, unbiased=True, keepdim=True)
|
|
yield SampleInput(tensor_1d(), dim=0, unbiased=True, keepdim=True)
|
|
yield SampleInput(tensor_1d(), dim=0, unbiased=False, keepdim=False)
|
|
|
|
yield SampleInput(tensor_nd(), dim=(1,), correction=1.3)
|
|
yield SampleInput(tensor_nd(), dim=(1,), correction=S // 2)
|
|
yield SampleInput(tensor_nd(), dim=None, correction=0, keepdim=True)
|
|
yield SampleInput(tensor_nd(), dim=None, correction=None)
|
|
yield SampleInput(tensor_nd(), correction=0, keepdim=True)
|
|
yield SampleInput(make_tensor(3, 4, 5, device=device, dtype=dtype, requires_grad=requires_grad), dim=-3)
|
|
|
|
|
|
def sample_inputs_std_var_unbiased(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype,
|
|
requires_grad=requires_grad)
|
|
|
|
# Test var_mean(Tensor self, bool unbiased=True) -> (Tensor, Tensor)
|
|
yield SampleInput(make_arg((S, S)), True)
|
|
yield SampleInput(make_arg((S,)), False)
|
|
|
|
|
|
def _generate_correlation_inputs(device, dtype, requires_grad, **kwargs):
|
|
shapes = [(2,), (1, 2), (3, 2), (2, 3)]
|
|
for shape in shapes:
|
|
yield make_tensor(shape, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
|
|
def sample_inputs_corrcoef(op_info, device, dtype, requires_grad, **kwargs):
|
|
return (SampleInput(t) for t in _generate_correlation_inputs(device, dtype, requires_grad))
|
|
|
|
|
|
def sample_inputs_cov(op_info, device, dtype, requires_grad, **kwargs):
|
|
for t in _generate_correlation_inputs(device, dtype, requires_grad):
|
|
yield SampleInput(t)
|
|
num_observations = t.numel() if t.ndimension() < 2 else t.size(1)
|
|
fweights = make_tensor((num_observations,), dtype=torch.int, device=device, low=1, high=10)
|
|
aweights = make_tensor((num_observations,), dtype=torch.float, device=device, low=0, high=1, requires_grad=requires_grad)
|
|
for correction, fw, aw in product(range(num_observations), [None, fweights], [None, aweights]):
|
|
yield SampleInput(t.clone().requires_grad_(requires_grad),
|
|
correction=correction, fweights=fw, aweights=aw)
|
|
|
|
|
|
def error_inputs_cov(op_info, device, **kwargs):
|
|
a = torch.rand(S, device=device)
|
|
yield ErrorInput(
|
|
SampleInput(torch.rand(S, S, S, device=device)),
|
|
error_regex="expected input to have two or fewer dimensions")
|
|
yield ErrorInput(
|
|
SampleInput(a, fweights=torch.rand(S, S, device=device)),
|
|
error_regex="expected fweights to have one or fewer dimensions")
|
|
yield ErrorInput(
|
|
SampleInput(a, aweights=torch.rand(S, S, device=device)),
|
|
error_regex="expected aweights to have one or fewer dimensions")
|
|
yield ErrorInput(
|
|
SampleInput(a, fweights=torch.rand(S, device=device)),
|
|
error_regex="expected fweights to have integral dtype")
|
|
yield ErrorInput(
|
|
SampleInput(a, aweights=torch.tensor([1, 1], device=device)),
|
|
error_regex="expected aweights to have floating point dtype")
|
|
yield ErrorInput(
|
|
SampleInput(a, fweights=torch.tensor([1], device=device)),
|
|
error_regex="expected fweights to have the same numel")
|
|
yield ErrorInput(
|
|
SampleInput(a, aweights=torch.rand(1, device=device)),
|
|
error_regex="expected aweights to have the same numel")
|
|
yield ErrorInput(
|
|
SampleInput(a, fweights=torch.tensor([-1, -2, -3, -4 , -5], device=device)),
|
|
error_regex="fweights cannot be negative")
|
|
yield ErrorInput(
|
|
SampleInput(a, aweights=torch.tensor([-1., -2., -3., -4., -5.], device=device)),
|
|
error_regex="aweights cannot be negative")
|
|
|
|
|
|
def sample_inputs_permute(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = [((1, 2, 3, 4), (0, 2, 3, 1)),
|
|
((1, 2, 3, 4), (0, -2, -1, 1)),
|
|
((), ()),
|
|
((1, 2, 3, 4), (2, 1, 3, 0))]
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=(args,))
|
|
|
|
def reference_inputs_permute(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_permute(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
((), ()),
|
|
((1,), (0,)),
|
|
((2, 2), (1, 0)),
|
|
((2, 2), (0, 1)),
|
|
((2, 0, 1), (0, 2, 1)),
|
|
((3, 4, 2), (2, 1, 0)),
|
|
((3, 4, 2), (1, 0, 2)),
|
|
((3, 4, 2), (0, 1, 2)),
|
|
)
|
|
|
|
# Adds tricky permutations and permutations with noncontiguity
|
|
for shape, permutation in cases:
|
|
for p in itertools.permutations(permutation):
|
|
a = make_arg(shape).permute(p)
|
|
yield SampleInput(a, args=(permutation,))
|
|
|
|
a = make_arg(shape, noncontiguous=True).permute(p)
|
|
yield SampleInput(a, args=(permutation,))
|
|
|
|
def error_inputs_softshrink(op, device, **kwargs):
|
|
yield ErrorInput(SampleInput(make_tensor((1,), dtype=torch.float, device=device), kwargs={"lambd": -0.5}),
|
|
error_regex="lambda must be greater or equal to 0, but found to be -0.5")
|
|
|
|
def sample_inputs_softshrink(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# The additional sample is to check additional values of lambd beyond the default
|
|
# value (what is already checked by sample_inputs_elementwise_unary)
|
|
for lbda in (0., 0.5):
|
|
yield SampleInput(make_arg(S, S), kwargs={"lambd": lbda})
|
|
|
|
yield from sample_inputs_elementwise_unary(op_info, device, dtype, requires_grad)
|
|
|
|
def sample_inputs_hardshrink(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# The additional sample is to check additional values of lambd beyond the default
|
|
# value (what is already checked by sample_inputs_elementwise_unary)
|
|
# Note that unlike softshrink, lambd is allowed to be negative for hardshrink
|
|
for lbda in (-0.5, 0., 0.5):
|
|
yield SampleInput(make_arg(S, S), kwargs={"lambd": lbda})
|
|
|
|
yield from sample_inputs_elementwise_unary(op_info, device, dtype, requires_grad)
|
|
|
|
|
|
def sample_inputs_hardtanh(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# The additional sample is to check additional values of min_val and max_val beyond the default
|
|
# value (what is already checked by sample_inputs_elementwise_unary)
|
|
for max_val, min_val in ((0.5, -0.5), (0., 0.)):
|
|
yield SampleInput(make_arg(S, S), kwargs={"min_val": min_val, "max_val": max_val})
|
|
|
|
yield from sample_inputs_elementwise_unary(op_info, device, dtype, requires_grad)
|
|
|
|
def error_inputs_hardtanh(op_info, device, **kwargs):
|
|
# Tests that hardtanh errors out when passed min_val > max_val.
|
|
yield ErrorInput(SampleInput(make_tensor((1,), dtype=torch.float, device=device), kwargs={"min_val": 0.5, "max_val": -0.5}),
|
|
error_type=ValueError, error_regex="min_val cannot be greater than max_val")
|
|
|
|
def sample_inputs_einsum(op_info, device, dtype, requires_grad=False, **kwargs):
|
|
def c(t):
|
|
return t.clone().requires_grad_(requires_grad)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
x = make_arg((3,))
|
|
y = make_arg((4,))
|
|
A = make_arg((2, 3,))
|
|
B = make_arg((1, 3,))
|
|
C = make_arg((1, 2, 3,))
|
|
D = make_arg((1, 3, 4,))
|
|
E = make_arg((4, 4,))
|
|
H = make_arg((3, 3,))
|
|
I = make_arg((1, 3, 1,))
|
|
|
|
# Vector operations
|
|
yield SampleInput([c(x)], 'i->') # sum
|
|
yield SampleInput([c(x), c(y)], 'i,j->ij') # outer
|
|
|
|
# Matrix operations
|
|
yield SampleInput([c(A)], "ij->i") # col sum
|
|
yield SampleInput([c(A), c(B)], "ij,kj->ik") # matmul
|
|
yield SampleInput([c(A), c(E)], "ij,Ab->ijAb") # matrix outer product
|
|
|
|
# Tensor operations
|
|
yield SampleInput([c(C), c(D)], "aij,ajk->aik") # batch matmul
|
|
yield SampleInput([c(D), c(E)], "aij,jk->aik") # tensor matrix contraction
|
|
yield SampleInput([c(C), c(B)], "ijk,ik->j") # non contiguous
|
|
|
|
# Test diagonals
|
|
yield SampleInput([c(I)], 'iji->j') # non-contiguous trace
|
|
|
|
# Test ellipsis
|
|
yield SampleInput([c(H)], "i...->...")
|
|
yield SampleInput([c(C), c(x)], '...ik, ...j -> ij')
|
|
|
|
|
|
def sample_inputs_flip(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
sizes = ((S, M, S), (S, 0, M))
|
|
all_dims = ((0, 1, 2), (0,), (0, 2), (-1,), ())
|
|
|
|
for size, dims in product(sizes, all_dims):
|
|
yield SampleInput(make_arg(size), kwargs={"dims": dims})
|
|
|
|
def sample_inputs_fliplr_flipud(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes = [
|
|
(S, M, S),
|
|
(S, 0, M),
|
|
]
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
return (SampleInput(make_arg(shape, low=None, high=None)) for shape in shapes)
|
|
|
|
def error_inputs_fliplr(op, device, **kwargs):
|
|
yield ErrorInput(SampleInput(make_tensor((1,), dtype=torch.float, device=device)),
|
|
error_regex="Input must be >= 2-d.")
|
|
|
|
def error_inputs_flipud(op, device, **kwargs):
|
|
yield ErrorInput(SampleInput(make_tensor((), dtype=torch.float, device=device)),
|
|
error_regex="Input must be >= 1-d.")
|
|
|
|
def sample_inputs_clamp(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=None, high=None, requires_grad=requires_grad)
|
|
make_integral_arg = partial(make_tensor, dtype=torch.int32, device=device, low=None, high=None, requires_grad=False)
|
|
shape = (S, M, S)
|
|
|
|
yield SampleInput(make_arg(shape), args=(make_arg(shape), make_arg(shape)))
|
|
yield SampleInput(make_arg(shape), args=(make_arg(shape[1:]), make_arg(shape[1:])))
|
|
yield SampleInput(make_arg(shape), args=(make_arg((S, 1, S)),))
|
|
yield SampleInput(make_arg(shape), args=(None, make_arg(shape)))
|
|
yield SampleInput(make_arg(shape), args=(make_arg(shape), None))
|
|
# test type promotion
|
|
yield SampleInput(make_arg(shape), args=(make_integral_arg(shape), None))
|
|
yield SampleInput(make_arg(shape), args=(make_arg(shape), make_integral_arg(shape)))
|
|
|
|
def reference_inputs_elementwise_ternary(op, device, dtype, requires_grad, *, sample_inputs_func, supports_scalars=False, **kwargs):
|
|
yield from sample_inputs_func(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_scalar_tensor = partial(make_tensor, (), device='cpu', dtype=dtype, requires_grad=requires_grad)
|
|
supported_dtypes = op.supported_dtypes(device)
|
|
|
|
# broadcasting and oncontiguous cases
|
|
cases = (
|
|
((4, 4), (4, 4), (4, 4)),
|
|
((4, 4), (1, 4, 4), (4, 4)),
|
|
((4, 4), (1, 4, 4), (4, 1, 4)),
|
|
((4, 4, 1), (1, 4, 4), (4, 4)),
|
|
((4, 1), (1, 4, 4), (1, 4)),
|
|
((4, 4), (), (4, 4)),
|
|
((4, 4), (), ()),
|
|
((), (4, 4), (1, 4, 4)),
|
|
)
|
|
|
|
for a, b, c in cases:
|
|
yield SampleInput(make_arg(a), args=(make_arg(b), make_arg(c)))
|
|
yield SampleInput(make_arg(a, noncontiguous=True),
|
|
args=(make_arg(b).transpose(0, -1), make_arg(c, noncontiguous=True).transpose(0, -1)))
|
|
|
|
# scalar cases
|
|
if supports_scalars:
|
|
cases = [
|
|
((), 1, 2,),
|
|
((), 1., 2),
|
|
((4, 4), 1., 2,),
|
|
((3, 4), make_scalar_tensor(), make_scalar_tensor()),
|
|
]
|
|
|
|
if torch.complex64 in supported_dtypes:
|
|
cases.extend([
|
|
((3, 1, 4), complex(1, 2), 3.),
|
|
])
|
|
|
|
for a, b, c in cases:
|
|
yield SampleInput(make_arg(a), args=(b, c))
|
|
|
|
# type promotion cases
|
|
# int x float
|
|
if torch.float in supported_dtypes and torch.long in supported_dtypes:
|
|
a = make_arg((), dtype=torch.long)
|
|
b = make_arg((1, 4), dtype=torch.float)
|
|
c = make_arg((3, 4))
|
|
|
|
cases = (
|
|
(a, b, c),
|
|
(c, a, b),
|
|
)
|
|
|
|
for a, b, c in cases:
|
|
yield SampleInput(a, args=(b, c))
|
|
|
|
# NaN propagation
|
|
if dtype.is_floating_point or dtype.is_complex:
|
|
nan = float('nan') if dtype.is_floating_point else complex(float('nan'), float('nan'))
|
|
|
|
a = make_arg((12,))
|
|
a[4] = nan
|
|
a[7] = nan
|
|
b = make_arg((12,))
|
|
b[1] = nan
|
|
b[7] = nan
|
|
c = make_arg((12,))
|
|
c[9] = nan
|
|
|
|
yield SampleInput(a, args=(b, c))
|
|
|
|
|
|
def _clamp_min_numpy(a, min=None):
|
|
return np.maximum(a, min)
|
|
|
|
|
|
def _clamp_max_numpy(a, max=None):
|
|
return np.minimum(a, max)
|
|
|
|
|
|
def _clamp_numpy(a, min=None, max=None):
|
|
if min is None:
|
|
return np.minimum(a, max)
|
|
if max is None:
|
|
return np.maximum(a, min)
|
|
|
|
return np.minimum(max, np.maximum(a, min))
|
|
|
|
|
|
def sample_inputs_cumprod(op_info, device, dtype, requires_grad, **kwargs):
|
|
def make_arg(shape):
|
|
# shrink values to be in the interval [-1, +1] for better precision in gradgradcheck
|
|
return make_tensor(shape, dtype=dtype, device=device, low=-1, high=+1, requires_grad=requires_grad)
|
|
|
|
def prod_zeros(dim_select):
|
|
assert len(dim_select) == 2
|
|
result = make_arg(3 * (S,))
|
|
result.narrow(dim_select[0], 0, 1).narrow(dim_select[1], 1, 1).zero_()
|
|
result.narrow(dim_select[0], 2, 1).narrow(dim_select[1], 3, 1).zero_()
|
|
result.narrow(dim_select[0], 4, 1).narrow(dim_select[1], 3, 1).zero_()
|
|
return result
|
|
|
|
for dim in range(3):
|
|
yield SampleInput(make_arg((S, S, S)), args=(dim,))
|
|
# Scalar tensors and empty tensor
|
|
for size in [(), (1,), (0,)]:
|
|
yield SampleInput(make_arg(size), args=(0,))
|
|
|
|
yield SampleInput(prod_zeros([0, 1]), args=(1,))
|
|
yield SampleInput(prod_zeros([0, 2]), args=(1,))
|
|
yield SampleInput(prod_zeros([1, 2]), args=(1,))
|
|
|
|
# test dtype kwarg
|
|
yield SampleInput(prod_zeros([1, 2]), args=(1,), kwargs={'dtype': dtype})
|
|
|
|
def sample_inputs_view_as_complex(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield SampleInput(make_tensor((S, 2), dtype=dtype, device=device, requires_grad=requires_grad))
|
|
|
|
def sample_inputs_view_as_real(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
sizes = ((S, S), ())
|
|
return (SampleInput(make_arg(size)) for size in sizes)
|
|
|
|
def error_inputs_complex(op_info, device, is_ref=False, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=torch.float32, device=device)
|
|
|
|
if is_ref:
|
|
error_float = "Expected both inputs to be Half, Float or Double tensors but got torch.float32 and torch.int32"
|
|
error_dtype = "Expected object of scalar type torch.float32 but got scalar type torch.float64 for second argument"
|
|
error_out = "Expected out tensor to have dtype torch.complex128 but got torch.complex64 instead"
|
|
else:
|
|
error_float = "Expected both inputs to be Half, Float or Double tensors but got Float and Int"
|
|
error_dtype = "Expected object of scalar type Float but got scalar type Double for second argument"
|
|
error_out = "Expected object of scalar type ComplexDouble but got scalar type ComplexFloat for argument 'out'"
|
|
|
|
yield ErrorInput(SampleInput(make_arg(M, S), make_arg(M, S, dtype=torch.int)),
|
|
error_type=RuntimeError, error_regex=error_float)
|
|
|
|
yield ErrorInput(SampleInput(make_arg(M, S), make_arg(M, S, dtype=torch.float64)),
|
|
error_type=RuntimeError, error_regex=error_dtype)
|
|
|
|
yield ErrorInput(SampleInput(make_arg(M, S, dtype=torch.float64), make_arg(M, S, dtype=torch.float64),
|
|
out=make_arg(M, S, dtype=torch.complex64)),
|
|
error_type=RuntimeError, error_regex=error_out)
|
|
|
|
def sample_inputs_logaddexp(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
shape = (S, S)
|
|
yield SampleInput(make_arg(shape), make_arg(shape))
|
|
|
|
def sample_inputs_prod(op_info, device, dtype, requires_grad, **kwargs):
|
|
def make_arg(shape):
|
|
# shrink values to be in the interval [-1, +1] for better precision in gradgradcheck
|
|
return make_tensor(shape, dtype=dtype, device=device, low=-1, high=+1, requires_grad=requires_grad)
|
|
|
|
def prod_single_zero():
|
|
result = make_arg(2 * (S,))
|
|
result[0, 1] = 0
|
|
return result
|
|
|
|
for sample in sample_inputs_cumprod(op_info, device, dtype, requires_grad):
|
|
# only Tensor, ignore other inputs
|
|
yield SampleInput(sample.input.clone().requires_grad_(requires_grad))
|
|
yield sample
|
|
|
|
# Generates samples with keepdim = True
|
|
for sample in sample_inputs_cumprod(op_info, device, dtype, requires_grad):
|
|
sample.kwargs['keepdim'] = True
|
|
yield sample
|
|
|
|
yield SampleInput(prod_single_zero())
|
|
yield SampleInput(make_arg((3, 3, 3)), args=(1,))
|
|
yield SampleInput(make_arg((3, 3, 3)), args=(1,), kwargs={'keepdim': True})
|
|
|
|
yield SampleInput(make_arg((3, 0)), args=(1,))
|
|
yield SampleInput(make_arg((3, 0)), args=(1,), kwargs={'keepdim': True})
|
|
yield SampleInput(torch.tensor([2., 3, 0, 0], dtype=dtype, device=device, requires_grad=requires_grad))
|
|
|
|
# test zero scalar tensor
|
|
zero = make_arg(())
|
|
zero.zero_()
|
|
yield SampleInput(zero.clone().requires_grad_(requires_grad))
|
|
yield SampleInput(zero.clone().requires_grad_(requires_grad), args=(0,))
|
|
yield SampleInput(zero.clone().requires_grad_(requires_grad),
|
|
args=(0,),
|
|
kwargs={'keepdim': True})
|
|
|
|
def error_inputs_neg(op_info, device, **kwargs):
|
|
si = SampleInput(torch.tensor((False, True), device=device))
|
|
msg = ("Negation, the `\\-` operator, on a bool tensor is not supported."
|
|
" If you are trying to invert a mask, use the `\\~` or"
|
|
" `logical_not\\(\\)` operator instead.")
|
|
yield ErrorInput(si, error_regex=msg)
|
|
|
|
def sample_inputs_diag(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
yield SampleInput(make_arg(M))
|
|
|
|
tensors = (
|
|
make_arg((M, M)),
|
|
make_arg((3, 5)),
|
|
make_arg((5, 3)),
|
|
)
|
|
|
|
args = ((), (2,), (-2,), (1,), (2,))
|
|
|
|
for tensor, arg in product(tensors, args):
|
|
yield SampleInput(tensor.clone().requires_grad_(requires_grad), *arg)
|
|
|
|
def reference_inputs_diagonal_diag_embed(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_diagonal_diag_embed(
|
|
op_info, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(
|
|
make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shapes1d = ((0,), (1,))
|
|
shapes2d = ((L, M),)
|
|
shapes3d = ((L, M, S),)
|
|
|
|
kwargs1d = {}
|
|
|
|
kwargs2d = (
|
|
# dim1 > dim2 is allowed
|
|
dict(dim1=1, dim2=0),
|
|
# negative dims are allowed
|
|
dict(dim1=-2, dim2=-1),
|
|
# one dim negative and the other nonnegative is allowed
|
|
dict(dim1=-1, dim2=0),
|
|
# out of bounds offset should return an empty tensor in diagonal and
|
|
# offset the diagonal in diag_embed
|
|
dict(offset=100),
|
|
)
|
|
|
|
kwargs3d = kwargs2d + (
|
|
# make sure we can use non-sequential dims
|
|
dict(offset=-1, dim1=0, dim2=2),
|
|
)
|
|
|
|
samples1d = product(shapes1d, kwargs1d)
|
|
samples2d = product(shapes2d, kwargs2d)
|
|
samples3d = product(shapes3d, kwargs3d)
|
|
|
|
for shape, kwargs in chain(samples1d, samples2d, samples3d):
|
|
if 'diagonal' in op_info.name:
|
|
# these are error inputs for diagonal
|
|
if shape in ((0,), (1,)):
|
|
continue
|
|
yield SampleInput(input=make_arg(shape), kwargs=kwargs)
|
|
|
|
|
|
def sample_inputs_diagonal_scatter(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# Shapes for 2D Tensors
|
|
shapes_2d = ((M, M), (3, 5), (5, 3))
|
|
|
|
# Shapes for 3D Tensors
|
|
shapes_3d = ((M, M, M),)
|
|
|
|
args_2d = ((), (2,), (-2,), (1,))
|
|
args_3d = ((1, 1, 2), (2, 0, 1), (-2, 0, 1))
|
|
|
|
for input_shape, arg in chain(product(shapes_2d, args_2d), product(shapes_3d, args_3d)):
|
|
input_ = make_arg(input_shape)
|
|
# We can programmatically figure out the right shape for src:
|
|
# It should be the same size as input.diagonal(other_args...)
|
|
if not isinstance(arg, tuple):
|
|
arg_tuple = (arg,)
|
|
else:
|
|
arg_tuple = arg
|
|
src_shape = input_.diagonal(*arg_tuple).size()
|
|
src = make_arg(src_shape)
|
|
yield SampleInput(input_, args=(src, *arg_tuple))
|
|
|
|
|
|
def sample_inputs_to_sparse(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, S))).with_metadata(output_process_fn_grad=lambda x: x.to_dense())
|
|
yield SampleInput(make_arg((S, S)), 1).with_metadata(output_process_fn_grad=lambda x: x.to_dense())
|
|
|
|
def sample_inputs_cross_entropy(op_info, device, dtype, requires_grad, **kwargs):
|
|
batch_size, num_classes = shape = (2, 3)
|
|
reductions = ("mean", "sum", "none")
|
|
|
|
input_shape_and_kwargs: List[Tuple[Tuple[int, ...], Dict[str, Any]]] = [
|
|
(shape, {}),
|
|
((*shape, 1), {}),
|
|
((*shape, 1, 2), {}),
|
|
((*shape, 1, 2, 3), {}),
|
|
*[(shape, dict(reduction=reduction)) for reduction in reductions],
|
|
*[
|
|
(
|
|
shape,
|
|
dict(
|
|
weight=make_tensor((num_classes,), device=device, dtype=dtype),
|
|
reduction=reduction,
|
|
),
|
|
)
|
|
for reduction in reductions
|
|
],
|
|
(shape, dict(ignore_index=1)),
|
|
]
|
|
|
|
for (input_shape, kwargs), probabilities_target in itertools.product(input_shape_and_kwargs, (False, True)):
|
|
input = make_tensor(input_shape, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
if probabilities_target:
|
|
# ignore_index is not supported for probabilities target
|
|
if "ignore_index" in kwargs:
|
|
continue
|
|
|
|
target = make_tensor(
|
|
input_shape,
|
|
low=0,
|
|
high=1,
|
|
device=device,
|
|
dtype=dtype,
|
|
requires_grad=requires_grad,
|
|
)
|
|
else:
|
|
target = make_tensor(
|
|
(batch_size, *input_shape[2:]),
|
|
low=0,
|
|
high=num_classes,
|
|
device=device,
|
|
dtype=torch.long,
|
|
)
|
|
|
|
if "ignore_index" in kwargs and torch.all(target == kwargs["ignore_index"]):
|
|
# make sure at least one item in target is not ignored
|
|
target[0] = random.sample(sorted(set(range(num_classes)) - {kwargs["ignore_index"]}), 1)[0]
|
|
|
|
yield SampleInput(input, target, **kwargs)
|
|
|
|
|
|
def sample_inputs_logit(op_info, device, dtype, requires_grad, **kwargs):
|
|
low, high = op_info.domain
|
|
|
|
# Note: Operator is very sensitive at points near the
|
|
# start and end of domain and leads to NaN for float16
|
|
# if domain_eps is 1e-5.
|
|
if dtype.is_floating_point or dtype.is_complex:
|
|
domain_eps = op_info._domain_eps if dtype != torch.float16 else 3e-2
|
|
|
|
low = low + domain_eps
|
|
high = high - domain_eps
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, S, S)))
|
|
yield SampleInput(make_arg((S, S, S)), 0.2)
|
|
yield SampleInput(make_arg(()))
|
|
yield SampleInput(make_arg(()), 0.2)
|
|
|
|
def sample_inputs_isin(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
# isin has two paths based on the size of elements and test_elements.
|
|
# if elements.numel() < 10 * pow(test_elements.numel(), 0.145):
|
|
yield SampleInput(make_arg((L,)), args=(make_arg((S,)),))
|
|
# else:
|
|
yield SampleInput(make_arg((S,)), args=(make_arg((L,)),))
|
|
|
|
def sample_inputs_masked_scatter(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, S)), args=(torch.randn(S, S, device=device) > 0, make_arg((S, S))))
|
|
yield SampleInput(make_arg((S, S)), args=(torch.randn((S,), device=device) > 0, make_arg((S, S))))
|
|
yield SampleInput(make_arg((S, S)), args=(bernoulli_scalar().to(device), make_arg((S, S))))
|
|
yield SampleInput(make_arg((S,)),
|
|
args=(torch.randn(S, S, device=device) > 0, make_arg((S, S))),
|
|
broadcasts_input=True)
|
|
|
|
def error_inputs_masked_scatter(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float)
|
|
for mask_dtype in [torch.float, torch.uint8]:
|
|
yield ErrorInput(SampleInput(make_arg(1, 3), args=(torch.ones(1, 3, device=device, dtype=mask_dtype),
|
|
make_arg(3, 4))),
|
|
error_regex=r"masked_scatter_ only supports boolean masks")
|
|
|
|
def sample_inputs_masked_fill(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, S)), args=(torch.randn(S, S, device=device) > 0, 10))
|
|
yield SampleInput(make_arg((S, S)), args=(torch.randn(S, S, device=device) > 0, make_arg(())))
|
|
yield SampleInput(make_arg((S, S)), args=(torch.randn(S, device=device) > 0, 10))
|
|
yield SampleInput(make_arg(()), args=(torch.randn((), device=device) > 0, 10))
|
|
yield SampleInput(make_arg(()), args=(torch.randn((), device=device) > 0, make_arg(())))
|
|
yield SampleInput(make_arg((S, S)), args=(torch.randn((), device=device) > 0, 10))
|
|
|
|
yield SampleInput(make_arg((S,)),
|
|
args=(torch.randn(S, S, device=device) > 0, make_arg(())),
|
|
broadcasts_input=True)
|
|
yield SampleInput(make_arg((S,)),
|
|
args=(torch.randn(S, S, device=device) > 0, 10),
|
|
broadcasts_input=True)
|
|
|
|
if torch.device(device).type == 'cuda':
|
|
# `self` and `mask` on CUDA but `value` is a CPU scalar tensor.
|
|
yield SampleInput(make_arg((S, S)),
|
|
args=(torch.randn(S, S, device=device) > 0,
|
|
make_tensor((), device="cpu", dtype=dtype)))
|
|
|
|
def error_inputs_masked_fill(op_info, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float, requires_grad=False)
|
|
# `value` is not a 0-D tensor.
|
|
yield ErrorInput(SampleInput(make_arg((2, 2)), args=(make_arg(()) > 0, make_arg((1,)))),
|
|
error_regex="only supports a 0-dimensional value tensor, but got tensor with 1 dimension")
|
|
# downcasting complex value (scalar overload)
|
|
yield ErrorInput(SampleInput(make_arg((2, 2)), args=(make_arg(()) > 0, 1j)),
|
|
error_regex=r"value cannot be converted to type .* without overflow")
|
|
# downcasting complex value (tensor overload)
|
|
yield ErrorInput(SampleInput(torch.ones(2, dtype=torch.long, device=device),
|
|
args=(make_arg(()) > 0, torch.tensor(1j, device=device))),
|
|
error_regex=r"value cannot be converted to type .* without overflow")
|
|
|
|
if torch.device(device).type == 'cuda':
|
|
# `self` and `mask` on CPU but `value` is a CUDA scalar tensor.
|
|
yield ErrorInput(SampleInput(torch.randn((S, S), device='cpu'),
|
|
args=(torch.randn(S, S, device='cpu') > 0,
|
|
torch.randn((), device='cuda'))),
|
|
error_regex=r"to be on same device")
|
|
|
|
|
|
def sample_inputs_masked_select(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(
|
|
make_tensor, device=device, dtype=dtype, requires_grad=requires_grad, low=None, high=None)
|
|
|
|
yield SampleInput(make_arg((M, M)), torch.randn(M, M, device=device) > 0)
|
|
|
|
yield SampleInput(make_arg((M, M)), torch.randn((M,), device=device) > 0)
|
|
yield SampleInput(make_arg((M,)), torch.randn((M, M), device=device) > 0)
|
|
|
|
yield SampleInput(make_arg((M, 1, M)), torch.randn((M, M), device=device) > 0)
|
|
|
|
yield SampleInput(make_arg(()), torch.tensor(1, device=device, dtype=torch.bool))
|
|
|
|
yield SampleInput(make_arg((M, M)), torch.tensor(1, device=device, dtype=torch.bool))
|
|
|
|
yield SampleInput(make_arg(()), torch.randn((M, M), device=device) > 0)
|
|
|
|
def sample_inputs_matrix_exp(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg((S, S)))
|
|
yield SampleInput(make_arg((S, S, S)))
|
|
|
|
def sample_inputs_matmul(op_info, device, dtype, requires_grad, is_rmatmul=False, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=None,
|
|
high=None, requires_grad=requires_grad)
|
|
test_cases = (((L,), (L,)),
|
|
((S, M), (M,)),
|
|
((M,), (M, S)),
|
|
((S, M), (M, S)),
|
|
((S, 0), (0, M)),
|
|
((S, S, M), (M,)),
|
|
((S, S, M), (M, S)),
|
|
((S, S, 0), (0, S)),
|
|
((M,), (S, M, S)),
|
|
((S, M), (S, M, S)),
|
|
((0, 0), (S, 0, 0)),
|
|
((S, S, M, M), (S, S, M, S)),
|
|
((S, S, M, M), (M,)),
|
|
((M,), (S, S, M, S)),
|
|
((S, S, S), (1, S, S))
|
|
)
|
|
for lhs_shape, rhs_shape in test_cases:
|
|
lhs = make_arg(lhs_shape)
|
|
rhs = make_arg(rhs_shape)
|
|
if not is_rmatmul:
|
|
yield SampleInput(lhs, rhs)
|
|
else:
|
|
yield SampleInput(rhs, lhs)
|
|
|
|
|
|
def sample_inputs_meshgrid(op_info: OpInfo, device: torch.device, dtype: torch.dtype,
|
|
requires_grad: bool,
|
|
*, variant: str, **kwargs) -> List[SampleInput]:
|
|
if variant == 'variadic':
|
|
def make_inputs(
|
|
tensors: List[torch.Tensor]) -> Tuple[Union[torch.Tensor,
|
|
List[torch.Tensor]],
|
|
Tuple[torch.Tensor, ...]]:
|
|
return tensors
|
|
elif variant == 'list':
|
|
def make_inputs(
|
|
tensors: List[torch.Tensor]) -> Tuple[Union[torch.Tensor,
|
|
List[torch.Tensor]],
|
|
Tuple[torch.Tensor, ...]]:
|
|
return [tensors]
|
|
else:
|
|
raise ValueError(
|
|
'Unsupported variant, must be one of {"variadic", "list"}. '
|
|
f'Got "{variant}".')
|
|
|
|
SCALAR = torch.Size([])
|
|
VECTOR = torch.Size([3])
|
|
test_cases: List[List[torch.Size]] = [
|
|
[SCALAR],
|
|
[VECTOR],
|
|
[VECTOR, SCALAR],
|
|
[VECTOR, SCALAR, VECTOR],
|
|
[VECTOR, SCALAR, VECTOR, SCALAR],
|
|
]
|
|
|
|
for shapes, indexing in itertools.product(test_cases, {'xy', 'ij'}):
|
|
args = make_inputs(
|
|
[make_tensor(shape, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape in shapes])
|
|
yield SampleInput(*args, indexing=indexing)
|
|
|
|
|
|
def sample_inputs_mvlgamma(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
tensor_shapes = ((S, S), ())
|
|
ns = (1, 2, 3, 4, 5)
|
|
|
|
# Since the accepted lower bound for input
|
|
# to mvlgamma depends on `p` argument,
|
|
# the following function computes the lower bound
|
|
# which we pass to `make_tensor`.
|
|
def compute_min_val(p):
|
|
return (p - 1.) / 2
|
|
|
|
for shape, n in product(tensor_shapes, ns):
|
|
min_val = compute_min_val(n)
|
|
if not dtype.is_floating_point:
|
|
# Round-up minimum value for integral dtypes
|
|
min_val += 1
|
|
else:
|
|
min_val += 2 * torch.finfo(dtype).eps
|
|
yield SampleInput(make_arg(shape, low=min_val), args=(n,))
|
|
|
|
|
|
# Since `mvlgamma` has multiple entries,
|
|
# there are multiple common skips for the additional
|
|
# entries. Following function is a helper to that end.
|
|
def skips_mvlgamma(skip_redundant=False):
|
|
skips = (
|
|
# outside domain values are hard error for mvlgamma op.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_float_domains'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.float16, torch.int8)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
dtypes=(torch.int8,)),
|
|
)
|
|
if skip_redundant:
|
|
# Redundant tests
|
|
skips = skips + ( # type: ignore[assignment]
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon'),
|
|
)
|
|
return skips
|
|
|
|
|
|
# To test reference numerics against multiple values of argument `p`,
|
|
# we make multiple OpInfo entries with each entry corresponding to different value of p.
|
|
# We run the op tests from test_ops.py only for `p=1` to avoid redundancy in testing.
|
|
def make_mvlgamma_opinfo(variant_test_name, domain, skips, sample_kwargs):
|
|
return UnaryUfuncInfo('mvlgamma',
|
|
ref=reference_mvlgamma if TEST_SCIPY else None,
|
|
aliases=('special.multigammaln',),
|
|
variant_test_name=variant_test_name,
|
|
domain=domain,
|
|
decorators=(precisionOverride({torch.float16: 5e-2}),),
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_mvlgamma,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=skips,
|
|
sample_kwargs=sample_kwargs)
|
|
|
|
|
|
def sample_inputs_cumulative_ops(op_info, device, dtype, requires_grad, supports_dtype_kwargs=True, **kwargs):
|
|
def _make_tensor_helper(shape, low=None, high=None):
|
|
return make_tensor(shape, dtype=dtype, device=device, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(_make_tensor_helper((S, S, S)), 0)
|
|
yield SampleInput(_make_tensor_helper((S, S, S)), 1)
|
|
yield SampleInput(_make_tensor_helper(()), 0)
|
|
|
|
if supports_dtype_kwargs:
|
|
# NOTE: if `dtype` is not same as input, then inplace variants fail with
|
|
# `provided dtype must match the dtype of self tensor in cumsum`
|
|
yield SampleInput(_make_tensor_helper((S, S, S)), 1, dtype=dtype)
|
|
|
|
|
|
def sample_inputs_unfold(op_info, device, dtype, requires_grad, **kwargs):
|
|
test_cases = (
|
|
((), (0, 1, 1)),
|
|
((S, S, S, S), (0, 3, 1)),
|
|
((S, S, S, S), (1, 3, 1)),
|
|
((S, S, S, S), (2, 3, 1)),
|
|
((S, S, S, S), (3, 3, 1)),
|
|
((S, S, S, S), (0, 3, 2)),
|
|
((S, S, S, S), (1, 3, 2)),
|
|
((S, S, S, S), (2, 3, 2)),
|
|
((S, S, S, S), (3, 3, 2)),
|
|
((S, S, S, S), (0, 4, 1)),
|
|
((S, S, S, S), (1, 4, 1)),
|
|
((S, S, S, S), (2, 4, 1)),
|
|
((S, S, S, S), (3, 4, 1)),
|
|
((M,), (0, 3, 1)),
|
|
((M,), (0, 3, 2)),
|
|
((M,), (0, 3, 3)),
|
|
((1000,), (0, 3, 11)),
|
|
((1000,), (0, 2, 27)),
|
|
((10, 10), (0, 1, 2)),
|
|
((10, 10), (1, 2, 3)),
|
|
((10, 10), (1, 2, 2)),
|
|
((S, S, S), (2, 3, 2)),
|
|
)
|
|
|
|
for shape, arguments in test_cases:
|
|
yield SampleInput(make_tensor(shape, dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad),
|
|
*arguments)
|
|
|
|
def sample_inputs_split(op_info, device, dtype, requires_grad, *, list_args=False, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
if list_args:
|
|
cases = (
|
|
((S, S, S), (torch.Size([int(S / 3), S - int(S / 3) * 2, int(S / 3)]),)),
|
|
((S, S, S), (torch.Size([int(S / 2), S - int(S / 2) * 2, int(S / 2)]), 2),),
|
|
((S, S, S), (torch.Size([int(S / 2), S - int(S / 2) * 2, int(S / 2)]), -2),)
|
|
)
|
|
else:
|
|
cases = ( # type: ignore[assignment]
|
|
((S, S, S), (2,)),
|
|
((S, S, S), (S, 1)),
|
|
)
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
|
|
def sample_inputs_split_with_sizes(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
cases = (((S, S, S), (torch.Size([int(S / 3), S - int(S / 3) * 2, int(S / 3)]),)),
|
|
((S, S, S), (torch.Size([int(S / 3), S - int(S / 3), 0]),)),
|
|
((S, S, S), (torch.Size([int(S / 3), S - int(S / 3) * 2, int(S / 3)]), 2)),
|
|
((S, S, S), (torch.Size([int(S / 3), S - int(S / 3) * 2, int(S / 3)]), -2)),
|
|
)
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
|
|
def sample_inputs_msort(op_info, device, dtype, requires_grad, **kwargs):
|
|
def apply_grad(t):
|
|
if dtype in floating_types_and(torch.float16, torch.bfloat16):
|
|
t.requires_grad_(requires_grad)
|
|
|
|
def large_1d_unique(dtype, device):
|
|
res = torch.randperm(L * L * L, dtype=torch.int64, device=device)
|
|
res = res.to(dtype)
|
|
apply_grad(res)
|
|
return res
|
|
|
|
# Test case for large tensor.
|
|
yield SampleInput(large_1d_unique(dtype, device))
|
|
|
|
yield SampleInput(make_tensor((S, M, S), dtype=dtype, device=device,
|
|
low=None, high=None,
|
|
requires_grad=requires_grad))
|
|
|
|
def sample_inputs_lerp(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# no broadcast
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, S)), 0.4)
|
|
# broadcast rhs
|
|
yield SampleInput(make_arg((S, S)), make_arg((S,)), 0.4)
|
|
# scalar tensor
|
|
yield SampleInput(make_arg(()), make_arg(()), 0.4)
|
|
# broadcast rhs scalar-tensor
|
|
yield SampleInput(make_arg((S, S)), make_arg(()), 0.4)
|
|
# broadcast rhs with weight tensor
|
|
yield SampleInput(make_arg((S, S)), make_arg((S,)), make_arg((S, S)))
|
|
# broadcast rhs and weight tensor
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, 1)), make_arg((S,)))
|
|
# broadcast lhs
|
|
yield SampleInput(make_arg((S,)), make_arg((S, S)), 0.4).with_metadata(broadcasts_input=True)
|
|
# scalar broadcast_lhs
|
|
yield SampleInput(make_arg(()), make_arg((S, S)), 0.4).with_metadata(broadcasts_input=True)
|
|
# broadcast all
|
|
yield SampleInput(make_arg((S, 1)), make_arg((S, S)), 0.4).with_metadata(broadcasts_input=True)
|
|
# tensor broadcast all
|
|
yield SampleInput(make_arg((S, 1)), make_arg((S, S)), make_arg((S, 1))).with_metadata(
|
|
broadcasts_input=True)
|
|
# no broadcast with weight tensor
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, S)), make_arg((S, S)))
|
|
# broadcast lhs with weight tensor
|
|
yield SampleInput(make_arg((S,)), make_arg((S, S)), make_arg((S, S))).with_metadata(
|
|
broadcasts_input=True)
|
|
# broadcast lhs and weight tensor
|
|
yield SampleInput(make_arg((S,)), make_arg((S, S, S)), make_arg((S, S))).with_metadata(
|
|
broadcasts_input=True)
|
|
# broadcast lhs and weight tensor variant
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, S, S)), make_arg((S,))).with_metadata(
|
|
broadcasts_input=True)
|
|
|
|
if dtype.is_complex:
|
|
# no broadcast
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, S)), 0.4j)
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, S)), 1.2 + 0.1j)
|
|
# broadcast rhs
|
|
yield SampleInput(make_arg((S, S)), make_arg((S,)), 0.4j)
|
|
yield SampleInput(make_arg((S, S)), make_arg((S, S)), 5.4 + 9j)
|
|
# scalar tensor
|
|
yield SampleInput(make_arg(()), make_arg(()), 0.4j)
|
|
yield SampleInput(make_arg(()), make_arg(()), 6.1 + 0.004j)
|
|
# broadcast rhs scalar-tensor
|
|
yield SampleInput(make_arg((S, S)), make_arg(()), 0.4j)
|
|
yield SampleInput(make_arg((S, S)), make_arg(()), 1 + 2j)
|
|
|
|
def sample_inputs_tensordot(self, device, dtype, requires_grad, **kwargs):
|
|
cases = (
|
|
((2, 2, 2), (2, 2, 2), (2)),
|
|
((2, 2, 1), (2, 1, 2), ([0, 1], [2, 0])),
|
|
)
|
|
for first_shape, second_shape, dims in cases:
|
|
yield SampleInput(make_tensor(first_shape, dtype=dtype, device=device,
|
|
requires_grad=requires_grad),
|
|
make_tensor(second_shape, dtype=dtype, device=device,
|
|
requires_grad=requires_grad),
|
|
dims=dims)
|
|
|
|
def sample_inputs_kron(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(
|
|
make_tensor, dtype=dtype, device=device, requires_grad=requires_grad, low=None, high=None)
|
|
test_cases = (
|
|
((S, S), (M, L)),
|
|
)
|
|
|
|
for input_shape, other_shape in test_cases:
|
|
input = make_arg(input_shape)
|
|
other = make_arg(other_shape)
|
|
yield SampleInput(input, other)
|
|
|
|
def sample_inputs_inner(self, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg(S), make_arg(S))
|
|
yield SampleInput(make_arg(), make_arg(S, S))
|
|
|
|
def sample_inputs_scatter(op_info, device, dtype, requires_grad, **kwargs):
|
|
def _tensor(shape, dtype=dtype, low=None, high=None):
|
|
return make_tensor(shape, dtype=dtype, device=device, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
def _gather(shape, index_dim, max_indices):
|
|
return gather_variable(shape, index_dim, max_indices, device=device)
|
|
|
|
zero = torch.tensor(0, dtype=torch.long, device=device)
|
|
test_cases = (
|
|
(_tensor((M, S)), (0, _gather((S, S), 1, M), _tensor((S, S)))),
|
|
(_tensor((M, S)), (1, _gather((S, S), 0, S), _tensor((S, S)))),
|
|
(_tensor((M, S)), (-1, _gather((S, S), 0, S), _tensor((S, S)))),
|
|
(_tensor((M, S)), (0, _gather((M, S // 2), 1, M), _tensor((M, S // 2)))),
|
|
(_tensor((M, S)), (1, _gather((M, S // 2), 0, S), _tensor((M, S // 2)))),
|
|
(_tensor((M, S)), (-1, _gather((M, S // 2), 0, S), _tensor((M, S // 2)))),
|
|
(_tensor(()), (0, zero.clone().detach(), _tensor(()))),
|
|
(_tensor(()), (0, zero.clone().detach(), 2.5)),
|
|
)
|
|
|
|
for tensor, args in test_cases:
|
|
yield SampleInput(tensor, *args)
|
|
|
|
if not requires_grad:
|
|
yield SampleInput(tensor.clone().detach(), *args, reduce='add')
|
|
|
|
if dtype.is_floating_point:
|
|
yield SampleInput(tensor.clone().detach(), *args, reduce='multiply')
|
|
|
|
def sample_inputs_scatter_add(op_info, device, dtype, requires_grad, **kwargs):
|
|
def _tensor(shape, dtype=dtype, low=None, high=None):
|
|
return make_tensor(shape, dtype=dtype, device=device, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
def _gather(shape, index_dim, max_indices):
|
|
return gather_variable(shape, index_dim, max_indices, device=device)
|
|
|
|
zero = torch.tensor(0, dtype=torch.long, device=device)
|
|
yield SampleInput(_tensor((M, S)), 0, _gather((S, S), 1, M), _tensor((S, S)))
|
|
yield SampleInput(_tensor((M, S)), 1, _gather((S, S), 0, S), _tensor((S, S)))
|
|
yield SampleInput(_tensor((M, S)), -1, _gather((S, S), 0, S), _tensor((S, S)))
|
|
yield SampleInput(_tensor((M, S)), 0, _gather((M, S // 2), 1, M), _tensor((M, S // 2)))
|
|
yield SampleInput(_tensor((M, S)), 1, _gather((M, S // 2), 0, S), _tensor((M, S // 2)))
|
|
yield SampleInput(_tensor((M, S)), -1, _gather((M, S // 2), 0, S), _tensor((M, S // 2)))
|
|
yield SampleInput(_tensor(()), 0, zero.clone().detach(), _tensor(()))
|
|
|
|
def sample_inputs_scatter_reduce(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
gather = partial(gather_variable, device=device)
|
|
|
|
zero = torch.tensor(0, dtype=torch.long, device=device)
|
|
test_cases = (
|
|
((M, S), 0, gather((S, S), 1, M), (S, S)),
|
|
((M, S), 1, gather((S, S), 0, S), (S, S)),
|
|
((M, S), -1, gather((S, S), 0, S), (S, S)),
|
|
((M, S), 0, gather((M, S // 2), 1, M), (M, S // 2)),
|
|
((M, S), 1, gather((M, S // 2), 0, S), (M, S // 2)),
|
|
((M, S), -1, gather((M, S // 2), 0, S), (M, S // 2)),
|
|
((), 0, zero.clone().detach(), ()),
|
|
)
|
|
|
|
reduce = op_info.variant_test_name
|
|
for (inp_shape, dim, index, src_shape), include_self in product(test_cases, [False, True, False]):
|
|
yield SampleInput(make_arg(inp_shape),
|
|
args=(dim, index, make_arg(src_shape), reduce),
|
|
kwargs={'include_self': include_self})
|
|
|
|
|
|
# Sample inputs to test edge cases for backward
|
|
# Check that gradients are propagated correctly for prod when zeros in self/src are reduced
|
|
if requires_grad and reduce == 'prod':
|
|
# This sample tests gradients for the following cases
|
|
# (a) 1 zero reduced (from src (self[0, 1], self[1, 1]), from self (self[0, 0], self[2, 0]))
|
|
# (b) 2 zeros reduced (1 from src and 1 from self (self[1, 0])
|
|
# (c) no zeros reduced (self([2, 1]))
|
|
# (d) 2 zeros reduced (both from src) is tested in test/test_autograd.py
|
|
# test_scatter_index_reduce_prod_gradgrad_error as this case is not supported for gradgrad
|
|
input = torch.tensor([[0, 13], [0, 17], [0, 19]], dtype=dtype, device=device, requires_grad=requires_grad)
|
|
src = torch.tensor([[0, 1, 2, 3], [0, 4, 0, 1], [2, 3, 5, 6]], dtype=dtype, device=device, requires_grad=requires_grad)
|
|
idx = torch.tensor([[1, 1, 0, 0], [0, 0, 1, 1], [0, 0, 0, 1]], dtype=torch.long, device=device)
|
|
|
|
yield SampleInput(input,
|
|
args=(1, idx, src, reduce),
|
|
kwargs={'include_self': True})
|
|
|
|
def sample_inputs_segment_reduce(op_info, device, dtype, requires_grad, *, mode='lengths', **kwargs):
|
|
def _tensor(shape, dtype=dtype, low=None, high=None):
|
|
return make_tensor(shape, dtype=dtype, device=device, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
test_cases = (
|
|
# inp_shape, dim, lengths, unsafe
|
|
((S,), 0, [0, 1, 2, 2], False),
|
|
((S,), 0, [0, 1, 2, 2], True),
|
|
((S,), 0, [2, 0, 3, 0], False),
|
|
((S, S), 0, [0, 1, 2, 2], False),
|
|
# test when lengths do not sum to dim size
|
|
((M, S, S), 0, [1, 2, 0, 6, 0], True),
|
|
# test for higher dimensions
|
|
((S, S), 1, [[0, 1, 2, 2] for _ in range(S)], False),
|
|
((S, S), 1, [[2, 0, 3, 0], [0, 1, 2, 2], [3, 0, 2, 0], [1, 1, 1, 2], [0, 1, 2, 2]], False),
|
|
((S, S, S), 1, [[0, 1, 2, 2] for _ in range(S)], False),
|
|
((S, S, S), 1, [[2, 0, 3, 0], [0, 1, 2, 2], [3, 0, 2, 0], [1, 1, 1, 2], [0, 1, 2, 2]], False),
|
|
)
|
|
|
|
reductions = ["max", "mean", "min", "sum", "prod"]
|
|
for args, reduce, initial in product(test_cases, reductions, [1, 2]):
|
|
inp_shape, dim, lengths, unsafe = args
|
|
lengths_t = torch.tensor(lengths, dtype=torch.long, device=device)
|
|
sample_input_kwargs = {'axis': dim, 'unsafe': unsafe, 'initial': initial}
|
|
if mode == 'lengths':
|
|
sample_input_kwargs['lengths'] = lengths_t
|
|
elif mode == 'offsets':
|
|
zeros_shape = list(lengths_t.shape)
|
|
zeros_shape[dim] = 1
|
|
offsets_t = torch.cat((lengths_t.new_zeros(zeros_shape), lengths_t), dim).cumsum_(dim)
|
|
sample_input_kwargs['offsets'] = offsets_t
|
|
else:
|
|
raise RuntimeError(f"mode most be one of 'offsets' or 'lengths' got '{mode}'.")
|
|
yield SampleInput(_tensor(inp_shape),
|
|
args=(reduce,),
|
|
kwargs=sample_input_kwargs)
|
|
|
|
|
|
def sample_inputs_ravel(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device,
|
|
low=None, high=None, requires_grad=requires_grad)
|
|
yield SampleInput(make_arg((S, S, S)))
|
|
yield SampleInput(make_arg(()))
|
|
yield SampleInput(make_arg((S, S, S), noncontiguous=True))
|
|
|
|
def sample_inputs_unravel_index(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield SampleInput(
|
|
torch.tensor(
|
|
[[3, 8, 13], [0, 5, 10]],
|
|
device=device,
|
|
dtype=dtype),
|
|
(4, 5))
|
|
yield SampleInput(
|
|
torch.tensor([[3, 8, 13], [0, 5, 10]], device=device, dtype=dtype),
|
|
(4, 2**30))
|
|
yield SampleInput(
|
|
torch.tensor([[3, 8, 13], [0, 5, 10]], device=device, dtype=dtype),
|
|
(2**30, 4))
|
|
yield SampleInput(
|
|
torch.tensor(2, device=device, dtype=dtype),
|
|
(2, 2))
|
|
max_val = 2**(8 * dtype.itemsize - (1 if dtype.is_signed else 0)) - 1
|
|
yield SampleInput(
|
|
torch.tensor(max_val - 1, device=device, dtype=dtype),
|
|
(1, max_val))
|
|
yield SampleInput(
|
|
torch.tensor([22, 41, 37], device=device, dtype=dtype),
|
|
(7, 6))
|
|
yield SampleInput(
|
|
torch.tensor(min(1621, max_val), device=device, dtype=dtype),
|
|
(6, 7, 8, 9))
|
|
yield SampleInput(
|
|
torch.tensor([], device=device, dtype=dtype),
|
|
(10, 3, 5))
|
|
yield SampleInput(
|
|
torch.tensor(
|
|
[[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0]],
|
|
device=device,
|
|
dtype=dtype),
|
|
(5, 8))
|
|
yield SampleInput(
|
|
torch.tensor(
|
|
[[1, 0, 1, 2, 3, 4], [1, 6, 1, 3, 2, 0], [1, 3, 1, 0, 9, 5]],
|
|
device=device,
|
|
dtype=dtype),
|
|
(5, 8, 10))
|
|
yield SampleInput(
|
|
torch.tensor(0, device=device, dtype=dtype),
|
|
())
|
|
|
|
a = np.array([[2, 4, 5, 6], [7, 8, 1, 15]])
|
|
b = np.array([[3, 2, 7, 6], [10, 12, 8, 9]])
|
|
_, i1, i2 = np.intersect1d(a, b, assume_unique=True, return_indices=True)
|
|
yield SampleInput(torch.tensor(i1, device=device, dtype=dtype), a.shape)
|
|
yield SampleInput(torch.tensor(i2, device=device, dtype=dtype), b.shape)
|
|
|
|
a = np.array([[2, 4, 5, 6, 6], [4, 7, 8, 7, 2]])
|
|
b = np.array([[3, 2, 7, 7], [10, 12, 8, 7]])
|
|
_, i1, i2 = np.intersect1d(a, b, return_indices=True)
|
|
yield SampleInput(torch.tensor(i1, device=device, dtype=dtype), a.shape)
|
|
yield SampleInput(torch.tensor(i2, device=device, dtype=dtype), b.shape)
|
|
|
|
|
|
def sample_inputs_tril_triu(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
cases = (((M, M), ()),
|
|
((M, M), (2,),),
|
|
((M, S), ()),
|
|
((M, S), (-1,)),
|
|
((M, M), (2,),),
|
|
((S, M, S), ()),
|
|
((S, M, S), (2,)),
|
|
((3, 3, S, S), ()),)
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
def error_inputs_tril_triu(opinfo, device, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# error inputs for input.ndim <= 2
|
|
yield ErrorInput(SampleInput(make_arg((4,))), error_regex="input tensor must have at least 2 dimensions")
|
|
|
|
def sample_inputs_trilu_indices(op_info, device, dtype, requires_grad, **kwargs):
|
|
# (row, col, offset)
|
|
args_list = ((0, 0),
|
|
(20, 0),
|
|
(0, 20),
|
|
(20, 21, 0),
|
|
(20, 21, 7),
|
|
(20, 21, -7),
|
|
# Large test cases below are deliberately commented out to speed up CI
|
|
# tests and to avoid OOM error. When modifying implementations of
|
|
# tril_indices and triu_indices, please enable these tests and make sure
|
|
# they pass.
|
|
# (2, 68435455, 3),
|
|
# (5000, 5000),
|
|
# (5000, 5000, 1234),
|
|
# (5000, 5000, -1233),
|
|
)
|
|
for args in args_list:
|
|
yield SampleInput(args[0], args=args[1:], kwargs={"dtype": dtype, "device": device})
|
|
|
|
def sample_inputs_clone_contiguous(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_arg((S, M, S)))
|
|
yield SampleInput(make_arg(()))
|
|
|
|
def reference_inputs_clone_contiguous(op, device, dtype, requires_grad, **kwargs):
|
|
# NOTE: the default memory format for clone is torch.preserve_format, for contiguous it's torch.contiguous_format
|
|
# This exploits that default to test torch.preserve_format for clone, without causing an error when testing contiguous
|
|
yield from sample_inputs_clone_contiguous(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
shapes = (
|
|
(3, 5, 6),
|
|
(1, 1, 3, 5, 6),
|
|
(1, 1, 3, 5, 6, 1, 1),
|
|
(1, 0, 3, 5, 0, 2),
|
|
(1, 0, 3, 5, 0, 0, 1, 1, 2),
|
|
(),
|
|
)
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape in shapes:
|
|
yield SampleInput(make_arg(shape))
|
|
yield SampleInput(make_arg(shape).transpose(0, -1))
|
|
yield SampleInput(make_arg(shape, noncontiguous=True))
|
|
yield SampleInput(make_arg(shape, noncontiguous=True).transpose(0, -1))
|
|
|
|
yield SampleInput(make_arg(shape), kwargs={'memory_format': torch.contiguous_format})
|
|
yield SampleInput(make_arg(shape).transpose(0, -1), kwargs={'memory_format': torch.contiguous_format})
|
|
yield SampleInput(make_arg(shape, noncontiguous=True), kwargs={'memory_format': torch.contiguous_format})
|
|
yield SampleInput(make_arg(shape, noncontiguous=True).transpose(0, -1), kwargs={'memory_format': torch.contiguous_format})
|
|
|
|
# shape, strides, offset
|
|
strided_cases = (
|
|
((5, 6, 2), (1, 1, 7), 2),
|
|
((5, 5, 4), (1, 1, 7), 2),
|
|
((5, 5, 2), (4, 5, 7), 3),
|
|
((5, 5, 2), (5, 5, 7), 3),
|
|
((5, 5, 2), (5, 5, 5), 3),
|
|
((9, 5, 2), (0, 1, 7), 3),
|
|
)
|
|
|
|
for shape, strides, offset in strided_cases:
|
|
yield SampleInput(make_arg(500,).as_strided(shape, strides, offset))
|
|
yield SampleInput(make_arg(500,).as_strided(shape, strides, offset), kwargs={'memory_format': torch.contiguous_format})
|
|
|
|
# channels last 2D
|
|
yield SampleInput(make_arg((2, 2, 2, 2)), kwargs={'memory_format': torch.channels_last})
|
|
a = make_arg((2, 2, 2, 2)).permute(0, 3, 1, 2)
|
|
yield SampleInput(a, kwargs={'memory_format': torch.channels_last})
|
|
|
|
# channels last 3D
|
|
yield SampleInput(make_arg((2, 2, 2, 2, 2)), kwargs={'memory_format': torch.channels_last_3d})
|
|
a = make_arg((2, 2, 2, 2, 2)).permute(0, 4, 1, 2, 3)
|
|
yield SampleInput(a, kwargs={'memory_format': torch.channels_last_3d})
|
|
|
|
|
|
def sample_inputs_sum_to_size(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# list of tuples (shape, shape) defining the shapes of the input and output tensors
|
|
sample_shapes = [
|
|
((), ()),
|
|
((S,), (1,)),
|
|
((S, S), (1, 1)),
|
|
((S, S), (1, S)),
|
|
((S, S), (S, S)),
|
|
((S, S, S), (S, 1, S)),
|
|
]
|
|
|
|
for input_shape, output_shape in sample_shapes:
|
|
yield SampleInput(make_arg(input_shape), args=(output_shape,))
|
|
if output_shape == ():
|
|
continue
|
|
yield SampleInput(make_arg(input_shape), args=(list(output_shape),))
|
|
yield SampleInput(make_arg(input_shape), args=(*output_shape,))
|
|
|
|
|
|
def error_inputs_sum_to_size(op_info, device, **kwargs):
|
|
shape = (M, S, M)
|
|
err_msg = "is not expandable to size"
|
|
si = SampleInput(make_tensor(shape, device=device, dtype=torch.float32), args=(M, M))
|
|
yield ErrorInput(si, error_regex=err_msg)
|
|
|
|
shape = (M + 1, S, S, M)
|
|
err_msg = "is not expandable to size"
|
|
si = SampleInput(make_tensor(shape, device=device, dtype=torch.float32), args=(M + 1, 1))
|
|
yield ErrorInput(si, error_regex=err_msg)
|
|
|
|
|
|
def sample_inputs_resize_ops(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device)
|
|
cases = (((S, S, S), (S * S, S)),
|
|
((), ()),
|
|
((), (1, 1, 1)),
|
|
)
|
|
|
|
for shape, args_or_shape in cases:
|
|
# Update `args` based on operator
|
|
if op_info.name == 'resize_':
|
|
# resize_ takes shape/tuple of ints,
|
|
args = (args_or_shape, )
|
|
elif op_info.name == 'resize_as_':
|
|
# resize_as_ takes another tensor
|
|
args = (make_arg(shape, requires_grad=False), ) # type:ignore[assignment]
|
|
else:
|
|
raise ValueError("sample_inputs_resize_ops is being used with incorrect operator")
|
|
|
|
yield SampleInput(make_arg(shape, requires_grad=requires_grad), args=args)
|
|
|
|
def sample_inputs_view_reshape(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (
|
|
# a, b, is_tensor_supported
|
|
((S, S, S), (S * S, S), True),
|
|
((S * S, S), (S, S, S), True),
|
|
((S * S, S), (S, -1, S), False), # neg index
|
|
((S * S * 2, S), (S, -1), False), # neg index
|
|
((S,), (S,), True),
|
|
((), (), False), # empty
|
|
((), (1,), True),
|
|
)
|
|
|
|
for a, b, is_tensor_supported in cases:
|
|
# skip unsupported cases
|
|
if kwargs.get("tensor_arg") and not is_tensor_supported:
|
|
continue
|
|
|
|
# convert to tensor
|
|
if kwargs.get("tensor_arg"):
|
|
b = make_arg(b, requires_grad=False)
|
|
|
|
yield SampleInput(make_arg(a), args=(b,))
|
|
|
|
def reference_inputs_view_reshape(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_view_reshape(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
cases = (
|
|
# a, b, is_tensor_supported
|
|
((125,), (25, 5), True),
|
|
((25, 25), (1, 5, 5, 1, 5, 1, 5, 1), True),
|
|
((16, 32), (2, 4, 1, 4, 4, 1, 4), True),
|
|
((16, 12), (12, 16), True),
|
|
((1, 16, 12), (12, 16), True),
|
|
((1, 5, 1, 5), (25, 1), True),
|
|
((2, 4, 2), (4, 4), True),
|
|
((1, 4), (1, 1, 2, 1, 2), True),
|
|
((3, 5, 7), (7, 5, 3), True),
|
|
((1,), (), False), # empty
|
|
((5, 0, 2, 3), (5, 0, 2, 3), True),
|
|
((2, 1, 0, 3, 1), (5, 0), True),
|
|
((1,), (), False), # empty
|
|
((4, 5, 6), (4, 5, 6, 1, 1, 1), True),
|
|
((), (1, 1, 1, 1), False), # empty
|
|
)
|
|
|
|
irreversible_cases = (
|
|
((), (-1,), False), # neg index, empty
|
|
((4, 7, 9, 1, 1), (1, 4, 3, -1, 1), False), # neg index
|
|
)
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for a, b, is_tensor_supported in cases:
|
|
# skip unsupported cases
|
|
if kwargs.get("tensor_arg") and not is_tensor_supported:
|
|
continue
|
|
|
|
if kwargs.get("tensor_arg"):
|
|
# convert to tensor
|
|
yield SampleInput(make_arg(a), args=(make_arg(b, requires_grad=False),))
|
|
yield SampleInput(make_arg(b), args=(make_arg(a, requires_grad=False),))
|
|
else:
|
|
yield SampleInput(make_arg(a), args=(b,))
|
|
yield SampleInput(make_arg(b), args=(a,))
|
|
|
|
for a, b, is_tensor_supported in irreversible_cases:
|
|
# skip unsupported cases
|
|
if kwargs.get("tensor_arg") and not is_tensor_supported:
|
|
continue
|
|
|
|
# convert to tensor
|
|
if kwargs.get("tensor_arg"):
|
|
b = make_arg(b, requires_grad=False)
|
|
|
|
yield SampleInput(make_arg(a), args=(b,))
|
|
|
|
def error_inputs_view_reshape(op, device, **kwargs):
|
|
|
|
cases = (
|
|
# a, b, is_tensor_supported
|
|
# Reshape to different numel
|
|
((2,), (), False), # empty
|
|
((1, 3, 0), (), False), # empty
|
|
((4, 3), (4, 2), True),
|
|
((1, 3, 5), (5, 2, 2), True),
|
|
# No valid inference
|
|
((1, 3, 5), (5, -1, 2), False), # neg index
|
|
# Two inferred shapes
|
|
((1, 3, 5), (5, -1, -1), False), # neg index
|
|
((1), (0, -1), False), # neg index
|
|
((0, 5), (0, -1), False), # neg index
|
|
)
|
|
|
|
make_arg = partial(make_tensor, dtype=torch.float32, device=device, requires_grad=False)
|
|
for a, b, is_tensor_supported in cases:
|
|
# skip unsupported cases
|
|
if kwargs.get("tensor_arg") and not is_tensor_supported:
|
|
continue
|
|
|
|
if b == (5, -1, -1):
|
|
error_regex = "only one dimension can be inferred"
|
|
elif a == (0, 5):
|
|
error_regex = (r"cannot reshape tensor of 0 elements into shape "
|
|
r"\[0, -1\] because the unspecified dimension size "
|
|
r"-1 can be any value and is ambiguous")
|
|
else:
|
|
# to avoid having issues with a regex
|
|
shape = ', '.join(map(str, b))
|
|
size = a if type(a) is int else functools.reduce(operator.mul, a, 1)
|
|
error_regex = rf"shape '\[{shape}\]' is invalid for input of size {size}"
|
|
|
|
# convert to tensor
|
|
if kwargs.get("tensor_arg"):
|
|
b = make_arg(b, requires_grad=False)
|
|
|
|
yield ErrorInput(SampleInput(make_arg(a), args=(b,)), error_type=Exception,
|
|
error_regex=error_regex)
|
|
|
|
|
|
def sample_inputs_atleast1d2d3d(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes = ((S, S, S, S), (S, S, S), (S, S), (S, ), (),)
|
|
make_tensor_partial = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape in shapes:
|
|
yield SampleInput(make_tensor_partial(shape))
|
|
yield SampleInput([make_tensor_partial(shape) for shape in shapes])
|
|
|
|
def sample_inputs_column_stack(op_info, device, dtype, requires_grad, **kwargs):
|
|
cases: Tuple[tuple, tuple] = ( # type: ignore[assignment]
|
|
((S, 2, 1), (S, 3, 1)),
|
|
((S), (S, 5)), ((), (1, S))
|
|
)
|
|
make_tensor_partial = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape1, shape2 in cases:
|
|
yield SampleInput([make_tensor_partial(shape1), make_tensor_partial(shape2)])
|
|
|
|
def sample_inputs_flatten(op_info, device, dtype, requires_grad, **kwargs):
|
|
shapes = ((S, S, S), (S, S), (S, ), (),)
|
|
make_tensor_partial = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape in shapes:
|
|
yield SampleInput(make_tensor_partial(shape))
|
|
if len(shape) > 1:
|
|
yield SampleInput(make_tensor_partial(shape), start_dim=1, end_dim=-1)
|
|
|
|
def reference_inputs_flatten(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_flatten(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
# shape x start_dim x end_dim
|
|
cases = (
|
|
((5, 4, 0, 1, 3, 7), 1, 3),
|
|
((5, 4, 0, 1, 3, 7), 4, 5),
|
|
((5, 4, 1, 1, 3, 7), 2, 3),
|
|
((), 0, -1),
|
|
((1,), 0, -1),
|
|
((3, 7, 5), 1, 2),
|
|
((4, 5), 1, 1),
|
|
((1, 5, 5, 1, 5, 1, 5, 1), 0, 2),
|
|
((1, 5, 5, 1, 5, 1, 5, 1), 3, -1),
|
|
((1, 5, 5, 1, 5, 7, 5, 1), -2, -1),
|
|
((2, 4, 2), 0, 1),
|
|
((4, 2, 2), 1, 2),
|
|
((0, 3, 4, 5), 1, 3),
|
|
)
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for shape, start, end in cases:
|
|
yield SampleInput(make_arg(shape), args=(start, end,))
|
|
yield SampleInput(make_arg(shape, noncontiguous=True).transpose(0, -1), args=(start, end,))
|
|
yield SampleInput(make_arg(shape).transpose(0, -1), args=(start, end,))
|
|
|
|
def sample_inputs_unflatten(op_info, device, dtype, requires_grad, **kwargs):
|
|
# in_shape, dim, sizes
|
|
args = (((8,), 0, (8,)),
|
|
((8,), 0, (4, 2)),
|
|
((8,), -1, (2, 2, 2)),
|
|
((8,), -1, (-1, 2)),
|
|
((3, 6, 2), 1, (2, 3)),
|
|
((3, 6, 2), -2, (2, 3)),
|
|
((3, 6, 2), -2, (-1, 3)),
|
|
((3, 2, 12), 2, (3, 2, 2)),
|
|
((4, 0), 0, (2, 2)),
|
|
((4, 0), 1, (2, 0, 0, 0)),
|
|
)
|
|
make_tensor_partial = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
for in_shape, dim, sizes in args:
|
|
yield SampleInput(make_tensor_partial(in_shape), args=(dim, sizes))
|
|
|
|
|
|
def sample_inputs_select(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (((S, S, S), (1, 2)),
|
|
((S, S, S), (-1, 2)),
|
|
((S, S, S), (-1, -1)),
|
|
((S, S, S), (1, -1)),
|
|
((S,), (0, 2))
|
|
)
|
|
|
|
for shape, args in cases:
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
|
|
def sample_inputs_select_scatter(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (((S, S, S), (S, S), (1, 2)),
|
|
((S, S, S), (S, S), (-1, 2)),
|
|
((S, S, S), (S, S), (-1, -1)),
|
|
((S, S, S), (S, S), (1, -1)),
|
|
((S,), (), (0, 2))
|
|
)
|
|
|
|
for input_shape, src_shape, args in cases:
|
|
input_ = make_arg(input_shape)
|
|
src = make_arg(src_shape)
|
|
yield SampleInput(input_, args=(src, *args))
|
|
|
|
|
|
def sample_inputs_slice_scatter(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (((L, L, L), (L, L, L,), (0, 0, L, 1)),
|
|
((L, L, L), (L // 2, L, L,), (0, L // 2, L, 1)),
|
|
((L, L, L), (L // 4, L, L,), (0, L // 2, L, 2)),
|
|
((L, L, L), (L, L, L,), (1, 0, L, 1)),
|
|
((L, L, L), (L, L // 2, L,), (1, L // 2, L, 1)),
|
|
((L, L, L), (L, L // 4, L,), (1, L // 2, L, 2)),
|
|
((L, L, L), (L, L, L,), (2, 0, L, 1)),
|
|
((L, L, L), (L, L, L // 2,), (2, L // 2, L, 1)),
|
|
((L, L, L), (L, L, L // 4,), (2, L // 2, L, 2)),
|
|
)
|
|
|
|
for input_shape, src_shape, args in cases:
|
|
input_ = make_arg(input_shape)
|
|
src = make_arg(src_shape)
|
|
yield SampleInput(input_, args=(src, *args))
|
|
|
|
def sample_inputs_expand(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (((S, 1, 1), (S, S, S)),
|
|
((S, 1, S), (S, S, S)),
|
|
((S, 1, S), (-1, S, -1)),
|
|
((S, 1, S), (-1, S, S)),
|
|
((S, 1), (S, S, S)),
|
|
((1,), (S, S, S)),
|
|
((1, S), (1, 1, S)),
|
|
((), ()),
|
|
((), (1, 3, 2)),
|
|
)
|
|
|
|
for case in cases:
|
|
shape, args = case
|
|
yield SampleInput(make_arg(shape), args=(args,))
|
|
|
|
def sample_inputs_conversion(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
shapes = ((),
|
|
(2, 3))
|
|
memory_format_options = [None, torch.contiguous_format]
|
|
|
|
for shape, memory_format in itertools.product(shapes, memory_format_options):
|
|
yield SampleInput(make_arg(shape),
|
|
kwargs={'memory_format': memory_format} if memory_format else {})
|
|
yield SampleInput(make_arg((2, 3, 2, 3)), kwargs={'memory_format': torch.channels_last})
|
|
|
|
def sample_inputs_byte(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, low=0, high=255, requires_grad=requires_grad)
|
|
|
|
shapes = ((),
|
|
(2, 3))
|
|
memory_format_options = [None, torch.contiguous_format]
|
|
|
|
for shape, memory_format in itertools.product(shapes, memory_format_options):
|
|
yield SampleInput(make_arg(shape),
|
|
kwargs={'memory_format': memory_format} if memory_format else {})
|
|
yield SampleInput(make_arg((2, 3, 2, 3)), kwargs={'memory_format': torch.channels_last})
|
|
|
|
def sample_inputs_expand_as(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device)
|
|
|
|
cases = (((S, 1, 1), (S, S, S)),
|
|
((), ()),
|
|
((), (1, 1)),
|
|
)
|
|
|
|
for shape, shape_other in cases:
|
|
yield SampleInput(make_arg(shape, requires_grad=requires_grad),
|
|
args=(make_arg(shape_other, requires_grad=False),))
|
|
|
|
|
|
def sample_inputs_where(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
def make_bool_mask(shape):
|
|
# Make sure atleast one element is nonzero,
|
|
# except for empty tensor
|
|
mask_t = make_tensor(shape, dtype=torch.bool, device=device, requires_grad=False)
|
|
|
|
if mask_t.numel() == 0:
|
|
return mask_t
|
|
elif mask_t.numel() == 1:
|
|
mask_t.fill_(True)
|
|
return mask_t
|
|
|
|
if mask_t.sum() == 0:
|
|
def random_index(shape):
|
|
return tuple(random.randrange(0, max_idx) for max_idx in shape)
|
|
|
|
mask_t[random_index(mask_t.shape)] = True
|
|
return mask_t
|
|
|
|
return mask_t
|
|
|
|
cases = (((M, M), (M, M), (M, M), False),
|
|
((M, 1, M), (M, M), (M, M, 1), True),
|
|
((), (), (), False),
|
|
((M, 1, M), (), (M, M, 1), True),
|
|
((), (M, M), (), True),
|
|
((), (2), (1, 1), True),
|
|
)
|
|
|
|
for shape, mask_shape, other_shape, broadcasts_input in cases:
|
|
yield SampleInput(make_arg(shape),
|
|
args=(make_bool_mask(mask_shape), make_arg(other_shape)),
|
|
broadcasts_input=broadcasts_input)
|
|
|
|
# TODO: add reference inputs for where(condition) signature
|
|
def reference_inputs_where(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_where(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_cond = partial(make_tensor, dtype=torch.bool, device=device, requires_grad=requires_grad)
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# noncontiguous
|
|
c = make_cond((10, 3), noncontiguous=True)
|
|
a = make_arg((10, 1), noncontiguous=True)
|
|
b = make_arg((3, 10, 3)).transpose(0, -1)
|
|
|
|
# NOTE that the OpInfo for where takes samples of the form a, cond, b
|
|
yield SampleInput(a, args=(c, b))
|
|
|
|
# type promoting
|
|
# FIXME(rec): shouldn't other_dtype be used two lines below?
|
|
other_dtype = torch.double if dtype is not torch.double else torch.long # noqa: F841
|
|
c = make_cond((10, 3), noncontiguous=True)
|
|
a = make_arg((10, 1), dtype=torch.long)
|
|
b = make_arg((10, 1))
|
|
|
|
yield SampleInput(a, args=(c, b))
|
|
|
|
# two python scalars
|
|
c = make_cond((10, 3), noncontiguous=True)
|
|
a = make_arg((1,)).item()
|
|
b = make_arg((1,)).item()
|
|
|
|
yield SampleInput(a, args=(c, b))
|
|
|
|
# NaN propagation
|
|
if dtype.is_floating_point or dtype.is_complex:
|
|
if dtype.is_floating_point:
|
|
nan = float('nan')
|
|
else:
|
|
# dtype.is_complex
|
|
nan = complex(float('nan'), float('nan'))
|
|
c = make_cond((1, 10, 3))
|
|
a = make_arg((10, 3), noncontiguous=True)
|
|
a[2, 1] = nan
|
|
b = make_arg((1, 3))
|
|
b[0, 2] = nan
|
|
|
|
yield SampleInput(a, args=(c, b))
|
|
|
|
# Python scalars type promotion
|
|
for scalar in (0, 0.0, 2j, False):
|
|
yield SampleInput(scalar, args=(c, b))
|
|
yield SampleInput(a, args=(c, scalar))
|
|
|
|
|
|
def error_inputs_where(op_info, device, **kwargs):
|
|
shape = (S,)
|
|
err_msg = "Expected all tensors to be on the same device"
|
|
for devices in product(('cpu', device), repeat=3):
|
|
if len(set(devices)) == 2:
|
|
si = SampleInput(make_tensor(shape, device=devices[0], dtype=torch.float32),
|
|
args=(make_tensor(shape, dtype=torch.bool, device=devices[1]),
|
|
make_tensor(shape, device=devices[2], dtype=torch.float32)))
|
|
yield ErrorInput(si, error_regex=err_msg)
|
|
|
|
def sample_inputs_nonzero(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
sizes = ((), (S,), (S, S), (S, S, S), (S, 1, S), (S, 0, S))
|
|
|
|
inputs = []
|
|
for shape in sizes:
|
|
# construct input without any non-zero elements
|
|
zeros = torch.zeros(shape, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
inputs.append(zeros)
|
|
|
|
# construct input with mixed zero and non-zero elements
|
|
mixed = make_arg(shape).requires_grad_(False)
|
|
mask_t = make_tensor(shape, dtype=torch.bool, device=device, requires_grad=False)
|
|
mixed[mask_t] = 0
|
|
inputs.append(mixed)
|
|
|
|
for input_t, as_tuple in product(inputs, [False, True]):
|
|
yield SampleInput(input_t.clone().requires_grad_(requires_grad),
|
|
kwargs=dict(as_tuple=as_tuple))
|
|
|
|
def sample_inputs_nonzero_static(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
sizes = ((), (S,), (S, S), (S, S, S), (S, 1, S), (S, 0, S))
|
|
|
|
inputs = []
|
|
for shape in sizes:
|
|
# construct input without any non-zero elements
|
|
zeros = torch.zeros(shape, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
inputs.append(zeros)
|
|
|
|
# construct input with mixed zero and non-zero elements
|
|
mixed = make_arg(shape).requires_grad_(False)
|
|
mask_t = make_tensor(shape, dtype=torch.bool, device=device, requires_grad=False)
|
|
mixed[mask_t] = 0
|
|
inputs.append(mixed)
|
|
|
|
nonzero_sizes = [0, 1, XS, S, M]
|
|
|
|
for input_t, nonzero_size in product(inputs, nonzero_sizes):
|
|
yield SampleInput(input_t.clone().requires_grad_(requires_grad),
|
|
kwargs=dict(size=nonzero_size))
|
|
|
|
def sample_inputs_chunk(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
cases = (((S, S, S), (2,)),
|
|
((S, S, S), (S, 1)),
|
|
((S, S, S), (S, -1)))
|
|
|
|
for case in cases:
|
|
shape, args = case
|
|
yield SampleInput(make_arg(shape), args=args)
|
|
|
|
def reference_inputs_chunk(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_chunk(op, device, dtype, requires_grad, **kwargs)
|
|
|
|
make_arg = partial(make_tensor, dtype=dtype, device=device, requires_grad=requires_grad)
|
|
|
|
# shape x chunks x dim
|
|
cases = (
|
|
((13, 9, 11), 17, -1),
|
|
((13, 9, 11), 11, -1),
|
|
((13,), 12, -1),
|
|
((15,), 12, -1),
|
|
((15,), 7, 0),
|
|
((15,), 9, 0),
|
|
((3, 7), 9, 1),
|
|
((3, 7), 9, 0),
|
|
((3, 7), 2, 0),
|
|
((3, 7), 3, 0),
|
|
((3, 7), 1, 0),
|
|
((3, 7), 1, 1),
|
|
((4, 4), 2, 0),
|
|
)
|
|
|
|
for shape, chunks, dim in cases:
|
|
yield SampleInput(make_arg(shape), args=(chunks, dim))
|
|
|
|
def sample_inputs_kthvalue(op_info, device, dtype, requires_grad, **kwargs):
|
|
def _tensor(shape, dtype=dtype, low=None, high=None):
|
|
return make_tensor(shape, dtype=dtype, device=device, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
test_cases = [
|
|
((S, S, S), (2,)),
|
|
((S, S, S), (2, 1,)),
|
|
((S, S, S), (2, -1,)),
|
|
((S, S, S), (2, 1, True,)),
|
|
((S, S, S), (2, -1, True,)),
|
|
((S,), (2, 0,)),
|
|
((S,), (2, 0, True,)),
|
|
((), (1,)),
|
|
((), (1, 0,)),
|
|
((), (1, 0, True)),
|
|
]
|
|
|
|
yield from (SampleInput(_tensor(tensor), *args) for tensor, args in test_cases)
|
|
|
|
def error_inputs_kthvalue(op_info, device, **kwargs):
|
|
# tests overlapping output fails
|
|
t = make_tensor(10, dtype=torch.float32, device=device)
|
|
indices = torch.empty((), device=device, dtype=torch.long)
|
|
yield ErrorInput(SampleInput(t, 5, out=(t, indices)),
|
|
error_regex="unsupported operation")
|
|
|
|
k_out_of_range_err = "selected number k out of range for dimension"
|
|
yield ErrorInput(SampleInput(torch.randn(2, 2, device=device), 3, 0),
|
|
error_regex=k_out_of_range_err)
|
|
yield ErrorInput(SampleInput(torch.randn(2, 2, device=device), 3),
|
|
error_regex=k_out_of_range_err)
|
|
yield ErrorInput(SampleInput(torch.tensor(2, device=device), 3),
|
|
error_regex=k_out_of_range_err)
|
|
|
|
def sample_inputs_dropout(op_info, device, dtype, requires_grad, *,
|
|
train=None, valid_input_dim=None, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
if valid_input_dim:
|
|
cases = ((S,) * i for i in valid_input_dim)
|
|
else:
|
|
cases = ((S, S), (S,), ())
|
|
p_vals = [0.0, 0.5, 1.0]
|
|
# This is to handle special case for feature_alpha_dropout which has different
|
|
# supported dtypes depending on `train` parameter
|
|
training_vals = [train] if train is not None else [True, False]
|
|
|
|
for case, p, training in product(cases, p_vals, training_vals):
|
|
yield SampleInput(make_arg(case), p=p, training=training)
|
|
yield SampleInput(make_arg(case))
|
|
|
|
def sample_inputs_dropout_backward(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
make_mask = partial(make_tensor, device=device, dtype=torch.bool, requires_grad=False)
|
|
|
|
cases = ((S, S, S, S), (S,), ())
|
|
scale_vals = [0.0, 1.0, 2.0]
|
|
|
|
for case, scale in product(cases, scale_vals):
|
|
yield SampleInput(make_arg(case), make_mask(case), scale)
|
|
|
|
def sample_inputs_embedding_bag(op_info, device, dtype, requires_grad, **kwargs):
|
|
def make_input(shape):
|
|
return make_tensor(shape, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_long_input(shape, *, low, high, noncontiguous=False):
|
|
return make_tensor(shape, device=device, dtype=torch.long, low=low, high=high,
|
|
noncontiguous=noncontiguous)
|
|
|
|
def make_per_sample_weight(flag, idx):
|
|
# a tensor of float / double weights, or None
|
|
# to indicate all weights should be taken to be 1
|
|
if flag:
|
|
return make_input(idx.shape)
|
|
return None
|
|
|
|
offsets = torch.tensor([0, 3], device=device, dtype=torch.long)
|
|
for generate_per_sample_weight in (True, False):
|
|
for mode in ('sum', 'mean', 'max'):
|
|
# per_sample_weights is only supported for mode='sum' (got mode='****')
|
|
if generate_per_sample_weight and mode in ('mean', 'max'):
|
|
continue
|
|
|
|
# 1-D index tensor
|
|
idx = make_long_input((S,), low=0, high=M)
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),
|
|
kwargs={'offsets': offsets, 'mode': mode,
|
|
'per_sample_weights': per_sample_weights})
|
|
|
|
idx = make_long_input((S,), low=0, high=M, noncontiguous=True)
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),
|
|
kwargs={'offsets': offsets, 'mode': mode,
|
|
'per_sample_weights': per_sample_weights})
|
|
|
|
# bag with zero length
|
|
idx = make_long_input((S,), low=0, high=M, noncontiguous=True)
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),
|
|
kwargs={'offsets': torch.tensor([0, 0, 3], device=device, dtype=torch.long),
|
|
'mode': mode,
|
|
'per_sample_weights': per_sample_weights})
|
|
|
|
# 2-D index tensor
|
|
idx = make_long_input((S, S), low=0, high=M)
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),
|
|
kwargs={'mode': mode, 'per_sample_weights': per_sample_weights})
|
|
|
|
idx = make_long_input((S, S), low=0, high=M, noncontiguous=True)
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),
|
|
kwargs={'mode': mode, 'per_sample_weights': per_sample_weights})
|
|
|
|
# The gradient vector at `padding_idx` is not updated.
|
|
# Negative padding_idx
|
|
idx = make_long_input((6,), low=0, high=S)
|
|
idx[0] = 4
|
|
idx[4] = 4
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((S, S)), args=(idx,),
|
|
kwargs={'padding_idx': -1, 'offsets': offsets,
|
|
'mode': mode, 'per_sample_weights': per_sample_weights},)
|
|
|
|
idx = make_long_input((3, 3), low=0, high=S)
|
|
# Positive padding_idx
|
|
idx[0, 0] = 2
|
|
idx[1, 1] = 2
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(make_input((S, S)), args=(idx,),
|
|
kwargs={'padding_idx': 2, 'mode': mode,
|
|
'per_sample_weights': per_sample_weights},)
|
|
|
|
idx = make_long_input((6, ), low=0, high=S)
|
|
weights = make_input((S, S))
|
|
offsets_ = torch.tensor([0, 3, 6], device=device, dtype=torch.long)
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'mode': mode, 'offsets': offsets_, 'include_last_offset': True},)
|
|
|
|
if not requires_grad:
|
|
# Following inputs return different gradient from the numerical gradient.
|
|
# This is expected and relevant tests are present in `test_nn.py`.
|
|
|
|
# Due to inplace renorming of weight, the numerical gradient doesn't match the
|
|
# analytical gradient.
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
weights = make_input((S, S)) * 2
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'max_norm': 1., 'mode': mode,
|
|
'per_sample_weights': per_sample_weights},)
|
|
|
|
idx = make_long_input((6, ), low=0, high=S)
|
|
weights = make_input((S, S)) * 2
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'max_norm': 1., 'norm_type': 1.0,
|
|
'mode': mode, 'offsets': offsets,
|
|
'per_sample_weights': per_sample_weights},)
|
|
|
|
if mode != 'max':
|
|
# Scale the gradient based on the inverse frequency of a particular index.
|
|
# Note : smax mode does not support sparse weights
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
idx[0, 0] = 1
|
|
idx[0, 1] = 1
|
|
weights = make_input((S, S))
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'scale_grad_by_freq': True, 'mode': mode,
|
|
'per_sample_weights': per_sample_weights},)
|
|
|
|
# gradcheck not implemented for sparse tensors.
|
|
# Note : max mode does not support sparse weights
|
|
idx = make_long_input((6, ), low=0, high=S)
|
|
weights = make_input((S, S))
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'sparse': True, 'offsets': offsets,
|
|
'mode': mode, 'per_sample_weights': per_sample_weights})
|
|
|
|
idx = make_long_input((6, ), low=0, high=S)
|
|
idx[0] = 1 # freq more than 1
|
|
idx[1] = 1 # freq more than 1
|
|
idx[3] = 0 # padding_idx
|
|
weights = make_input((S, S)) * 2
|
|
per_sample_weights = make_per_sample_weight(generate_per_sample_weight, idx)
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'sparse': True, 'scale_grad_by_freq': True, 'padding_idx': 0,
|
|
'max_norm': 1., 'offsets': offsets,
|
|
'mode': mode, 'per_sample_weights': per_sample_weights})
|
|
|
|
|
|
def sample_inputs_embedding(op_info, device, dtype, requires_grad, **kwargs):
|
|
def make_input(shape):
|
|
return make_tensor(shape, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_long_input(shape, *, low, high):
|
|
return make_tensor(shape, device=device, dtype=torch.long, low=low, high=high)
|
|
|
|
# 0-D index tensor
|
|
idx = make_long_input((), low=0, high=M)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),)
|
|
|
|
# 1-D index tensor
|
|
idx = make_long_input((S,), low=0, high=M)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),)
|
|
|
|
# 2-D index tensor
|
|
idx = make_long_input((S, S), low=0, high=M)
|
|
yield SampleInput(make_input((M, S)), args=(idx,),)
|
|
|
|
if not requires_grad:
|
|
# Following inputs return different gradient from the numerical gradient.
|
|
# This is expected and relevant tests are present in `test_nn.py`.
|
|
|
|
# The gradient vector at `padding_idx` is not updated.
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
idx[0, 0] = 2
|
|
idx[1, 1] = 2
|
|
yield SampleInput(make_input((S, S)), args=(idx,), kwargs={'padding_idx': 2},)
|
|
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
idx[0, 0] = 4
|
|
idx[1, 1] = 4
|
|
yield SampleInput(make_input((S, S)), args=(idx,), kwargs={'padding_idx': -1},)
|
|
|
|
# Due to inplace renorming of weight, the numerical gradient doesn't match the
|
|
# analytical gradient.
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
weights = make_input((S, S)) * 2
|
|
yield SampleInput(weights, args=(idx,), kwargs={'max_norm': 1.},)
|
|
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
weights = make_input((S, S)) * 2
|
|
yield SampleInput(weights, args=(idx,), kwargs={'max_norm': 1., 'norm_type': 1.0},)
|
|
|
|
# Scale the gradient based on the inverse frequency of a particular index.
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
idx[0, 0] = 1
|
|
idx[0, 1] = 1
|
|
weights = make_input((S, S))
|
|
yield SampleInput(weights, args=(idx,), kwargs={'scale_grad_by_freq': True},)
|
|
|
|
# gradcheck not implemented for sparse tensors.
|
|
idx = make_long_input((2, 2), low=0, high=S)
|
|
weights = make_input((S, S))
|
|
yield SampleInput(weights, args=(idx,), kwargs={'sparse': True})
|
|
|
|
idx = make_long_input((3, 3), low=0, high=S)
|
|
idx[0, 0] = 1 # freq more than 1
|
|
idx[0, 1] = 1 # freq more than 1
|
|
idx[1, 0] = 0 # padding_idx
|
|
weights = make_input((S, S)) * 2
|
|
yield SampleInput(weights, args=(idx,),
|
|
kwargs={'sparse': True, 'scale_grad_by_freq': True,
|
|
'padding_idx': 0, 'max_norm': 1.})
|
|
|
|
|
|
def sample_inputs_one_hot(op_info, device, dtype, requires_grad, **kwargs):
|
|
def make_input(shape, *, low, high):
|
|
return make_tensor(shape, device=device, dtype=dtype, low=low, high=high, requires_grad=requires_grad)
|
|
|
|
shapes = ((), (S,), (L, M, S))
|
|
num_classess = (-1, 10)
|
|
|
|
return (
|
|
SampleInput(
|
|
make_input(
|
|
shape,
|
|
low=0,
|
|
high=10 if num_classes == -1 else num_classes // 2,
|
|
),
|
|
kwargs=dict(num_classes=num_classes),
|
|
)
|
|
for shape, num_classes in itertools.product(shapes, num_classess)
|
|
)
|
|
|
|
|
|
def sample_inputs_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
rhs_requires_grad = kwargs.get('rhs_requires_grad', requires_grad)
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# Although most losses also support the reduce and size_average combination instead of reduce, the former is
|
|
# deprecated since 0.4.1 and thus is not tested
|
|
shapes_and_kwargs = (
|
|
((), None),
|
|
((S,), dict(reduction="mean")),
|
|
((S,), dict(reduction="sum")),
|
|
((S,), dict(reduction="none")),
|
|
((S, S), None),
|
|
((S, S, S), None),
|
|
)
|
|
|
|
for shape, kwargs in shapes_and_kwargs:
|
|
yield SampleInput(_make_tensor(shape),
|
|
args=(_make_tensor(shape, requires_grad=rhs_requires_grad),),
|
|
kwargs=kwargs)
|
|
|
|
def sample_inputs_grid_sample(op_info, device, dtype, requires_grad, **kwargs):
|
|
# We get better tests if we change the range of the values to something like [-2,2]
|
|
# because for grid (second tensor argument) the "useful" range is [-1,1] and this way
|
|
# you get a better combination of out-of-range and in-range test cases
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad,
|
|
low=-2, high=2)
|
|
|
|
batch_size = 2
|
|
num_channels = 3
|
|
modes = ("bilinear", "nearest")
|
|
align_cornerss = (False, True)
|
|
padding_modes = ("zeros", "border", "reflection")
|
|
|
|
for dim in (2, 3):
|
|
|
|
modes_ = (*modes, "bicubic") if dim == 2 else modes
|
|
|
|
for mode, padding_mode, align_corners in itertools.product(modes_, padding_modes, align_cornerss):
|
|
yield SampleInput(
|
|
_make_tensor((batch_size, num_channels, *[S] * dim)),
|
|
_make_tensor((batch_size, *[S] * dim, dim)),
|
|
mode=mode,
|
|
padding_mode=padding_mode,
|
|
align_corners=align_corners,
|
|
)
|
|
|
|
def reference_inputs_grid_sample(op_info, device, dtype, requires_grad, **kwargs):
|
|
|
|
batch_size = 2
|
|
num_channels = 3
|
|
height = 345
|
|
width = 456
|
|
modes = ("bilinear", "nearest", "bicubic")
|
|
align_cornerss = (False, True)
|
|
padding_modes = ('zeros', 'border', 'reflection')
|
|
|
|
# Create an affine transformation matrix
|
|
a = torch.deg2rad(torch.tensor(45.0))
|
|
ca, sa = torch.cos(a), torch.sin(a) # rotation angles
|
|
s1, s2 = 1.23, 1.34 # scales
|
|
|
|
theta = torch.tensor([[
|
|
[ca / s1, sa, 0.0],
|
|
[-sa, ca / s2, 0.0],
|
|
]], dtype=dtype, device=device)
|
|
theta = theta.expand(batch_size, 2, 3).contiguous()
|
|
|
|
x = torch.arange(batch_size * num_channels * height * width, device=device)
|
|
x = x.reshape(batch_size, num_channels, height, width).to(torch.uint8)
|
|
x = x.to(dtype=dtype)
|
|
x.requires_grad_(requires_grad)
|
|
|
|
for mode, padding_mode, align_corners in itertools.product(modes, padding_modes, align_cornerss):
|
|
grid = torch.nn.functional.affine_grid(
|
|
theta, size=(batch_size, num_channels, height, width), align_corners=align_corners
|
|
)
|
|
yield SampleInput(
|
|
x,
|
|
grid,
|
|
mode,
|
|
padding_mode,
|
|
align_corners,
|
|
)
|
|
|
|
def sample_inputs_grid_sampler_2d(op_info, device, dtype, requires_grad, **kwargs):
|
|
# We get better tests if we change the range of the values to something like [-2,2]
|
|
# because for grid (second tensor argument) the "useful" range is [-1,1] and this way
|
|
# you get a better combination of out-of-range and in-range test cases
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad,
|
|
low=-2, high=2)
|
|
|
|
batch_size = 2
|
|
num_channels = 3
|
|
modes = (0, 1, 2)
|
|
align_cornerss = (False, True)
|
|
padding_modes = (0, 1, 2)
|
|
|
|
for mode, padding_mode, align_corners in itertools.product(modes, padding_modes, align_cornerss):
|
|
yield SampleInput(
|
|
_make_tensor((batch_size, num_channels, S, L)),
|
|
_make_tensor((batch_size, M + 3, M, 2)),
|
|
mode,
|
|
padding_mode,
|
|
align_corners,
|
|
)
|
|
|
|
def sample_inputs_cosine_embedding_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_target(shape):
|
|
shape = () if len(shape) == 1 else (shape[0], )
|
|
t = torch.randint(0, 2, shape, device=device, dtype=torch.long)
|
|
# Label with -1 or 1
|
|
t = t * 2 - 1
|
|
target = t.to(dtype=dtype).detach_().requires_grad_(requires_grad)
|
|
return target
|
|
|
|
shapes = ((S, S), (S,))
|
|
reductions = ('none', 'mean', 'sum')
|
|
for s, r in product(shapes, reductions):
|
|
yield SampleInput(
|
|
make_input(s),
|
|
args=(make_input(s), make_target(s)),
|
|
kwargs=dict(reduction=r, margin=random.uniform(-1, 1))
|
|
)
|
|
|
|
def sample_inputs_ctc_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
input_length = 50
|
|
batch = 16
|
|
num_char = 20
|
|
target_length = 30
|
|
|
|
def make_log_probs(s):
|
|
t = make_tensor(s, device=device, dtype=dtype)
|
|
log_probs = t.log_softmax(2).to(device=device, dtype=dtype).detach().requires_grad_(requires_grad=requires_grad)
|
|
return log_probs
|
|
|
|
reductions = ('none', 'mean', 'sum')
|
|
zero_inf = (True, False)
|
|
lengths_type = (list, torch.Tensor)
|
|
for r, z, lt in product(reductions, zero_inf, lengths_type):
|
|
log_probs = make_log_probs((input_length, batch, num_char))
|
|
targets = torch.randint(1, num_char, (batch, target_length), dtype=torch.long, device=device)
|
|
input_lengths = torch.full((batch, ), input_length, dtype=torch.long, device=device)
|
|
target_lengths = torch.randint(10, target_length, (batch, ), dtype=torch.long, device=device)
|
|
|
|
# Dont generate int[] types if reduction = "Mean" since this results in non composite compliant calls
|
|
# to ctc_loss.IntList since a tensor needs to be created from the target lengths.
|
|
# Creating such a tensor requires the use of pointers to copy data from int[] -> torch.Tensor
|
|
# e.g. via std::copy. Similarly symbolic/real tracing with fx will also not work
|
|
if lt is list and r in ["none", "sum"]:
|
|
input_lengths = input_lengths.tolist()
|
|
target_lengths = target_lengths.tolist()
|
|
|
|
yield SampleInput(log_probs, args=(targets, input_lengths, target_lengths,), kwargs=dict(reduction=r, zero_infinity=z))
|
|
|
|
def sample_inputs_nll_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
shape = (2, 3)
|
|
num_classes = shape[1]
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
# FIXME: Derivative wrt. weight not implemented
|
|
make_weight = partial(make_tensor, num_classes, device=device, dtype=dtype, requires_grad=False)
|
|
|
|
def make_target(shape, zeros=False):
|
|
s = (shape[0], *shape[2:]) if len(shape) > 1 else ()
|
|
if zeros:
|
|
return torch.zeros(s, device=device, dtype=torch.long)
|
|
else:
|
|
return make_tensor(s,
|
|
low=0,
|
|
high=shape[1] if len(shape) > 1 else shape[0],
|
|
device=device,
|
|
dtype=torch.long)
|
|
|
|
|
|
def gen_shape_kwargs():
|
|
# Batched, non-batched and 2d
|
|
shapes = (shape, (num_classes,), shape + (2, 2))
|
|
reductions = ('none', 'mean', 'sum')
|
|
for reduction, s in product(reductions, shapes):
|
|
yield make_input(s), make_target(s), dict(reduction=reduction)
|
|
yield make_input(s), make_target(s), dict(weight=make_weight(), reduction=reduction)
|
|
yield make_input(s), make_target(s), dict(weight=make_weight(low=0), reduction=reduction)
|
|
yield make_input(s), make_target(s), dict(weight=make_weight(high=0), reduction=reduction)
|
|
t = make_target(s)
|
|
ignore = num_classes // 2
|
|
# If "mean", nll returns NaN, so it's not differentiable at those points
|
|
if t.eq(ignore).all() and reduction == "mean":
|
|
t.fill_(0)
|
|
yield make_input(s), t, dict(ignore_index=num_classes // 2, reduction=reduction)
|
|
yield make_input(s), t, dict(ignore_index=num_classes // 2, reduction=reduction, weight=make_weight())
|
|
# Test ignoring all the targets
|
|
# If "mean", nll returns NaN, so it's not differentiable at those points
|
|
if reduction != "mean":
|
|
yield make_input(s), make_target(s, zeros=True), dict(ignore_index=0, reduction=reduction)
|
|
|
|
for input, target, kwargs in gen_shape_kwargs():
|
|
yield SampleInput(input, args=(target,), kwargs=kwargs)
|
|
|
|
target = torch.tensor([-1, 2], device=device, dtype=torch.long)
|
|
yield SampleInput(make_input(shape), args=(target,), kwargs={'ignore_index': -1})
|
|
|
|
|
|
def sample_inputs_binary_cross_entropy_with_logits(
|
|
op_info, device, dtype, requires_grad, **kwargs
|
|
):
|
|
make = partial(make_tensor, device=device, dtype=dtype)
|
|
make_prob = partial(make, low=0, high=1)
|
|
reductions = ("mean", "sum", "none")
|
|
|
|
def make_weight_shape_kwargs():
|
|
kwargs = []
|
|
for shape in ((1,), (1, S), (S), (S, S)):
|
|
kwargs.extend([((S, S), dict(reduction=reduction, weight=make(shape))) for reduction in reductions])
|
|
return kwargs
|
|
|
|
shapes_and_kwargs = [
|
|
*[(shape, None) for shape in ((), (1,), (S,), (S, S), (S, S, S))],
|
|
*[((S, S), dict(reduction=reduction)) for reduction in reductions],
|
|
*make_weight_shape_kwargs(),
|
|
*[((S, S), dict(reduction=reduction, pos_weight=make((S,), low=0))) for reduction in reductions],
|
|
*[((S, S), dict(reduction=reduction, weight=make((S, S)), pos_weight=make((S,), low=0))) for reduction in reductions],
|
|
]
|
|
|
|
for shape, kwargs in shapes_and_kwargs:
|
|
yield SampleInput(
|
|
make(shape, requires_grad=requires_grad),
|
|
args=(make_prob(shape, requires_grad=requires_grad),),
|
|
kwargs=kwargs,
|
|
)
|
|
|
|
def sample_inputs_argwhere(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield SampleInput(torch.tensor([1, 0, 2, 0], dtype=dtype, device=device, requires_grad=requires_grad))
|
|
mask = torch.tensor([[0, 1, 0, 1, 0],
|
|
[1, 1, 1, 1, 0],
|
|
[0, 0, 0, 1, 0],
|
|
[1, 0, 1, 1, 0],
|
|
[1, 0, 0, 1, 0]], dtype=torch.bool, device=device)
|
|
t = make_tensor((S, S), dtype=dtype, device=device, requires_grad=requires_grad)
|
|
t[mask] = 0
|
|
yield SampleInput(t)
|
|
|
|
t = make_tensor((S, S), dtype=dtype, device=device, requires_grad=requires_grad, noncontiguous=True)
|
|
t[mask] = 0
|
|
yield SampleInput(t)
|
|
|
|
t = make_tensor((S, 0), dtype=dtype, device=device, requires_grad=requires_grad)
|
|
yield SampleInput(t)
|
|
|
|
yield SampleInput(torch.zeros((S,), dtype=dtype, device=device, requires_grad=requires_grad))
|
|
yield SampleInput(make_tensor((), dtype=dtype, device=device, requires_grad=requires_grad))
|
|
|
|
def _generate_sample_shape_reduction():
|
|
shapes = ((S,), (S, S), (S, S, S))
|
|
reductions = ('none', 'mean', 'sum')
|
|
yield from product(shapes, reductions)
|
|
|
|
def sample_inputs_gaussian_nll_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
# Set low slightly above 0 so gradcheck doesn't accidentally dip below 0
|
|
make_var = partial(make_tensor, low=0.1, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def gen_shape(shape):
|
|
yield shape
|
|
# Broadcast
|
|
yield (*shape[:-1], 1)
|
|
yield shape[:-1]
|
|
|
|
def gen_shape_kwargs():
|
|
for s, r in _generate_sample_shape_reduction():
|
|
for t_s, v_s in product(gen_shape(s), gen_shape(s)):
|
|
yield _make_tensor(s), _make_tensor(t_s), make_var(v_s), dict(reduction=r)
|
|
yield (
|
|
_make_tensor(s), _make_tensor(t_s), make_var(v_s),
|
|
dict(full=True, reduction=r)
|
|
)
|
|
yield (
|
|
_make_tensor(s), _make_tensor(t_s), make_var(v_s),
|
|
dict(eps=random.uniform(1e-6, 1e-3), reduction=r)
|
|
)
|
|
yield (
|
|
_make_tensor(s), _make_tensor(t_s), make_var(v_s),
|
|
dict(full=True, eps=random.uniform(1e-6, 1e-3), reduction=r)
|
|
)
|
|
|
|
for input, target, var, kwargs in gen_shape_kwargs():
|
|
yield SampleInput(input, args=(target, var, ), kwargs=kwargs)
|
|
|
|
def error_inputs_gaussian_nll_loss(op_info, device, **kwargs):
|
|
_make = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# invalid reduction value
|
|
yield ErrorInput(SampleInput(_make(10, 2, 3), _make(10, 2, 3), _make((10, 2, 3), low=0), reduction="abc"),
|
|
error_type=ValueError, error_regex="abc is not valid")
|
|
|
|
# var is of incorrect shape
|
|
yield ErrorInput(SampleInput(_make(10, 2, 3), _make(10, 2, 3), _make((10, 2, 2), low=0)),
|
|
error_type=ValueError, error_regex="var is of incorrect size")
|
|
|
|
# target is of incorrect shape
|
|
yield ErrorInput(SampleInput(_make(10, 2, 3), _make(10, 2, 2), _make((10, 2, 3), low=0)),
|
|
error_type=RuntimeError,
|
|
error_regex=(r"The size of tensor a \(3\) must match the size of tensor b \(2\) "
|
|
r"at non-singleton dimension 2"))
|
|
|
|
def _generate_sample_inputs_nn_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
for s, r in _generate_sample_shape_reduction():
|
|
yield _make_tensor(s), _make_tensor(s), dict(reduction=r)
|
|
|
|
def sample_inputs_hinge_embedding_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
for input, target, d in _generate_sample_inputs_nn_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
# target should contain either 1 or -1 as per docs
|
|
mask = torch.rand_like(target) > 0.5
|
|
target[mask] = 1
|
|
target[~mask] = -1
|
|
d['margin'] = random.uniform(-9, 9)
|
|
yield SampleInput(input, args=(target, ), kwargs=d)
|
|
|
|
# scalar input and target.
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(_make_tensor(()), args=(_make_tensor(()), ))
|
|
|
|
def error_inputs_hinge_embedding_loss(op, device, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
# invalid reduction value
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4),), kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError, error_regex='is not a valid value')
|
|
|
|
def reference_inputs_hinge_embedding_loss(op, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_hinge_embedding_loss(op, device, dtype, requires_grad, **kwargs)
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
for reduction in ('sum', 'mean', 'none'):
|
|
if dtype.is_floating_point: # only supports ints and floats
|
|
# NaN propagation
|
|
inp = make_input((10, ))
|
|
inp[2] = float('nan')
|
|
target = make_input((10, ))
|
|
# target should contain either 1 or -1 as per docs
|
|
mask = torch.rand_like(target) > 0.5
|
|
target[mask] = -1
|
|
target[~mask] = 1
|
|
yield SampleInput(inp, args=(target,), kwargs={'reduction': reduction})
|
|
|
|
# Inf Handling
|
|
inp = make_input((10, ))
|
|
inp[4] = float('inf')
|
|
target = make_input((10, ))
|
|
mask = torch.rand_like(target) > 0.5
|
|
target[mask] = -1
|
|
target[~mask] = 1
|
|
yield SampleInput(inp, args=(target,), kwargs={'reduction': reduction})
|
|
|
|
# Broadcasting
|
|
inp = make_input((5, 5))
|
|
target = make_input((1, 5))
|
|
mask = torch.rand_like(target) > 0.5
|
|
target[mask] = -1
|
|
target[~mask] = 1
|
|
yield SampleInput(inp, args=(target,), kwargs={'reduction': reduction})
|
|
|
|
def sample_inputs_huber_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
for input, target, d in _generate_sample_inputs_nn_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
d['delta'] = random.uniform(1e-3, 9)
|
|
yield SampleInput(input, args=(target, ), kwargs=d)
|
|
|
|
def error_inputs_huber_loss(op, device, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
# invalid reduction value
|
|
err = 'is not a valid value for reduction'
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4),), kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError, error_regex=err)
|
|
# delta <= 0
|
|
for delta in (0, -1):
|
|
err = 'huber_loss does not support non-positive values for delta.'
|
|
yield ErrorInput(SampleInput(make_input(5, 4), args=(make_input(5, 4),), kwargs={'delta': delta}),
|
|
error_type=RuntimeError, error_regex=err)
|
|
|
|
def sample_inputs_poisson_nll_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
_make_tensor = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def gen_shape_kwargs():
|
|
for s, r in _generate_sample_shape_reduction():
|
|
for li in (True, False):
|
|
for f in (True, False):
|
|
i1 = _make_tensor(s)
|
|
i2 = _make_tensor(s)
|
|
# For Poisson NLL Loss,
|
|
# target is assumed to be from
|
|
# Poisson Distribution which
|
|
# always has positive samples
|
|
t1 = _make_tensor(s, low=0)
|
|
t2 = _make_tensor(s, low=0)
|
|
|
|
if not li:
|
|
i1.abs_()
|
|
i2.abs_()
|
|
t1.abs_()
|
|
t2.abs_()
|
|
|
|
yield (
|
|
i1, t1,
|
|
dict(log_input=li, full=f, reduction=r)
|
|
)
|
|
yield (
|
|
i2, t2,
|
|
dict(log_input=li, full=f,
|
|
eps=random.uniform(1e-8, 1e-3),
|
|
reduction=r)
|
|
)
|
|
|
|
for input, target, kwargs in gen_shape_kwargs():
|
|
yield SampleInput(input, args=(target, ), kwargs=kwargs)
|
|
|
|
# test INT_TO_FLOAT promotion
|
|
if dtype.is_complex:
|
|
for d in (torch.bool, torch.int64):
|
|
yield SampleInput(_make_tensor(dtype=dtype), args=(_make_tensor(dtype=d),))
|
|
yield SampleInput(_make_tensor(dtype=d), args=(_make_tensor(dtype=dtype),))
|
|
|
|
def error_inputs_poisson_nll_loss(op_info, device, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# invalid reduction value
|
|
yield ErrorInput(SampleInput(make(5, 4), args=(make(5, 4),),
|
|
kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError,
|
|
error_regex='abc is not a valid value for reduction')
|
|
# invalid input shapes
|
|
yield ErrorInput(SampleInput(make(5, 4), args=(make(5,),)),
|
|
error_regex=(r'(Attempting to broadcast a dimension of length|'
|
|
r'The size of tensor a \(5\) must match the '
|
|
r'size of tensor b \(4\) at non-singleton '
|
|
r'dimension 1)'))
|
|
|
|
def error_inputs_soft_margin_loss(op_info, device, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# invalid reduction value
|
|
yield ErrorInput(SampleInput(make(5, 4), args=(make(5, 4),),
|
|
kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError,
|
|
error_regex='abc is not a valid value for reduction')
|
|
# invalid input shapes
|
|
yield ErrorInput(SampleInput(make(5, 4), args=(make(5,),)),
|
|
error_regex=(r'(Attempting to broadcast a dimension of length|'
|
|
r'The size of tensor a \(4\) must match the '
|
|
r'size of tensor b \(5\) at non-singleton '
|
|
r'dimension 1)'))
|
|
|
|
def sample_inputs_triplet_margin_loss(op_info, device, dtype, requires_grad, with_distance=False, **kwargs):
|
|
make = partial(make_tensor, (S, M), device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
kwargss = (
|
|
*[dict(margin=margin) for margin in (1e-6, 1.0, 10.0)],
|
|
dict(swap=True),
|
|
*[dict(reduction=reduction) for reduction in ("mean", "sum", "none")],
|
|
)
|
|
|
|
for kwargs in kwargss:
|
|
input = make()
|
|
args = (make(), make())
|
|
if with_distance:
|
|
kwargs["distance_function"] = torch.nn.PairwiseDistance()
|
|
yield SampleInput(input, args=args, kwargs=kwargs)
|
|
|
|
def error_inputs_triplet_margin_loss(op_info, device, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
samples = (
|
|
# input, args, kwargs, error_type, error_regex
|
|
# invalid reduction
|
|
(make_input(3, 4), (make_input(3, 4), make_input(3, 4)),
|
|
dict(reduction="abc"),
|
|
ValueError, "abc is not a valid value for reduction"),
|
|
|
|
# invalid margin
|
|
(make_input(3, 4), (make_input(3, 4), make_input(3, 4)),
|
|
dict(margin=-1.0),
|
|
ValueError, "margin must be greater than 0, got -1.0"),
|
|
|
|
# shape mismatch
|
|
(make_input(3, 5), (make_input(3, 4), make_input(3, 4)),
|
|
{},
|
|
RuntimeError,
|
|
(r'(Attempting to broadcast a dimension of length|'
|
|
r"The size of tensor a \(5\) must match the size of tensor b \(4\) "
|
|
r"at non-singleton dimension 1)")),
|
|
(make_input(3, 4), (make_input(3, 5), make_input(3, 4)),
|
|
{},
|
|
RuntimeError,
|
|
(r'(Attempting to broadcast a dimension of length|'
|
|
r"The size of tensor a \(4\) must match the size of tensor b \(5\) "
|
|
r"at non-singleton dimension 1)")),
|
|
(make_input(3, 4), (make_input(3, 4), make_input(3, 5)),
|
|
{},
|
|
RuntimeError,
|
|
(r'(Attempting to broadcast a dimension of length|'
|
|
r"The size of tensor a \(4\) must match the size of tensor b \(5\) "
|
|
r"at non-singleton dimension 1)")),
|
|
|
|
# different dimensions
|
|
(make_input(3,), (make_input(3, 4), make_input(3, 4)),
|
|
{},
|
|
RuntimeError,
|
|
(r"The anchor, positive, and negative tensors are expected to have "
|
|
r"the same number of dimensions, but got: anchor 1D, positive 2D, "
|
|
r"and negative 2D inputs")),
|
|
(make_input(3, 4), (make_input(3,), make_input(3, 4)),
|
|
{},
|
|
RuntimeError,
|
|
(r"The anchor, positive, and negative tensors are expected to have "
|
|
r"the same number of dimensions, but got: anchor 2D, positive 1D, "
|
|
r"and negative 2D inputs")),
|
|
(make_input(3, 4), (make_input(3, 4), make_input(3,)),
|
|
{},
|
|
RuntimeError,
|
|
(r"The anchor, positive, and negative tensors are expected to have "
|
|
r"the same number of dimensions, but got: anchor 2D, positive 2D, "
|
|
r"and negative 1D inputs")),
|
|
)
|
|
|
|
for input, args, kwargs, error_type, error_regex in samples:
|
|
yield ErrorInput(SampleInput(input, args=args, kwargs=kwargs),
|
|
error_type=error_type, error_regex=error_regex)
|
|
|
|
def sample_inputs_scaled_mm(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_mat_e4m3 = partial(make_tensor, device=device, dtype=torch.float8_e4m3fn, requires_grad=requires_grad)
|
|
make_mat_e5m2 = partial(make_tensor, device=device, dtype=torch.float8_e5m2, requires_grad=requires_grad)
|
|
make_scale = partial(make_tensor, device=device, dtype=torch.float, requires_grad=False)
|
|
M, N, K = 15, 32, 16
|
|
samples = []
|
|
# two e4m3
|
|
mat1 = make_mat_e4m3((M, K))
|
|
mat2 = make_mat_e4m3((K, N)).t().contiguous().t()
|
|
scale1 = make_scale((1,))
|
|
scale2 = make_scale((1,))
|
|
samples.append(SampleInput(mat1, mat2, scale1, scale2))
|
|
# mat1 e4m3 mat2 e5m2
|
|
mat1 = make_mat_e4m3((M, K))
|
|
mat2 = make_mat_e5m2((K, N)).t().contiguous().t()
|
|
scale1 = make_scale((1,))
|
|
scale2 = make_scale((1,))
|
|
samples.append(SampleInput(mat1, mat2, scale1, scale2))
|
|
# mat1 e5m2 mat2 e4m3
|
|
mat1 = make_mat_e5m2((M, K))
|
|
mat2 = make_mat_e4m3((K, N)).t().contiguous().t()
|
|
scale1 = make_scale((1,))
|
|
scale2 = make_scale((1,))
|
|
samples.append(SampleInput(mat1, mat2, scale1, scale2))
|
|
|
|
yield from samples
|
|
|
|
def sample_inputs_scaled_dot_product_attention(op_info, device, dtype, requires_grad, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
batch, seq_q, seq_kv, num_heads, head_dim = 4, 3, 6, 4, 8
|
|
num_heads_q_gqa, num_heads_kv_gqa = 32, 8
|
|
|
|
dim_3_q_shape = (batch, seq_q, head_dim)
|
|
dim_3_kv_shape = (batch, seq_kv, head_dim)
|
|
dim_4_q_shape = (batch, num_heads, seq_q, head_dim)
|
|
dim_4_kv_shape = (batch, num_heads, seq_kv, head_dim)
|
|
|
|
broadcast_tuple = ((num_heads, seq_q, head_dim), (batch, num_heads, seq_kv, head_dim))
|
|
|
|
qkv_shapes = [(dim_3_q_shape, dim_3_kv_shape), (dim_4_q_shape, dim_4_kv_shape), broadcast_tuple]
|
|
samples = []
|
|
gqa_options = [False] if TEST_WITH_ROCM else [True, False] # TODO: GQA support
|
|
if TEST_WITH_ROCM and dtype == torch.float32:
|
|
causal_options = [False] # FIXME: Large errors with causal+fp32
|
|
else:
|
|
causal_options = [True, False]
|
|
for qkv_shape, is_causal, dropout_p, _enable_gqa in product(
|
|
qkv_shapes, causal_options, [0.0, 0.5], gqa_options):
|
|
shape_q, shape_kv = qkv_shape
|
|
samples.append(SampleInput(
|
|
make(shape_q),
|
|
make(shape_kv),
|
|
make(shape_kv),
|
|
is_causal=is_causal,
|
|
dropout_p=dropout_p
|
|
))
|
|
|
|
# Add non standard shapes
|
|
# FIXME(rec): should diff_v_head_dim be appended to samples?
|
|
diff_v_head_dim = SampleInput( # noqa: F841
|
|
make((batch, num_heads, seq_q, head_dim)),
|
|
make((batch, num_heads, seq_kv, head_dim)),
|
|
make((batch, num_heads, seq_kv, head_dim + 8)),
|
|
is_causal=is_causal,
|
|
dropout_p=dropout_p
|
|
)
|
|
|
|
# Add an attn_mask
|
|
samples.append(
|
|
SampleInput(
|
|
make((batch, num_heads, seq_q, head_dim)),
|
|
make((batch, num_heads, seq_kv, head_dim)),
|
|
make((batch, num_heads, seq_kv, head_dim)),
|
|
attn_mask=make((seq_q, seq_kv)),
|
|
is_causal=False,
|
|
dropout_p=0.0)
|
|
)
|
|
|
|
if not TEST_WITH_ROCM:
|
|
samples.append(
|
|
SampleInput(
|
|
make((batch, num_heads_q_gqa, seq_q, head_dim)),
|
|
make((batch, num_heads_kv_gqa, seq_kv, head_dim)),
|
|
make((batch, num_heads_kv_gqa, seq_kv, head_dim)),
|
|
enable_gqa=True
|
|
)
|
|
)
|
|
|
|
yield from samples
|
|
|
|
|
|
def sample_inputs_efficient_attention_forward(op_info, device, dtype, requires_grad, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
batch, num_heads, head_dim = 4, 4, 8
|
|
seq_q = 11
|
|
seq_kv = 32
|
|
|
|
dim_4_q_shape = (batch, num_heads, seq_q, head_dim)
|
|
dim_4_kv_shape = (batch, num_heads, seq_kv, head_dim)
|
|
|
|
qkv_shapes = [(dim_4_q_shape, dim_4_kv_shape)]
|
|
samples = []
|
|
mask_types = [1, 2] # UpperLeft, LowerRight
|
|
scales = [None, 1.0]
|
|
|
|
for qkv_shape, _is_causal, dropout_p, mask_type, scale in product(
|
|
qkv_shapes, [True, False], [0.0, 0.5], mask_types, scales):
|
|
shape_q, shape_kv = qkv_shape
|
|
samples.append(SampleInput(
|
|
make(shape_q).transpose(1, 2),
|
|
make(shape_kv).transpose(1, 2),
|
|
make(shape_kv).transpose(1, 2),
|
|
bias=None,
|
|
cu_seqlens_q=None,
|
|
cu_seqlens_k=None,
|
|
max_seqlen_q=None,
|
|
max_seqlen_k=None,
|
|
dropout_p=dropout_p,
|
|
custom_mask_type=mask_type,
|
|
compute_log_sumexp=requires_grad,
|
|
scale=scale,
|
|
seqlen_k=None
|
|
))
|
|
|
|
# Add non standard shapes
|
|
# FIXME(rec): should diff_v_head_dim be appended to samples?
|
|
diff_v_head_dim = SampleInput( # noqa: F841
|
|
make((batch, seq_q, num_heads, head_dim)),
|
|
make((batch, seq_kv, num_heads, head_dim)),
|
|
make((batch, seq_kv, num_heads, head_dim + 8)),
|
|
bias=None,
|
|
cu_seqlens_q=None,
|
|
cu_seqlens_k=None,
|
|
max_seqlen_q=None,
|
|
max_seqlen_k=None,
|
|
dropout_p=dropout_p,
|
|
custom_mask_type=0, # No Mask
|
|
compute_log_sumexp=requires_grad,
|
|
scale=None,
|
|
seqlen_k=None
|
|
)
|
|
|
|
# Add an attn_mask
|
|
samples.append(
|
|
SampleInput(
|
|
make((batch, seq_q, num_heads, head_dim)),
|
|
make((batch, seq_kv, num_heads, head_dim)),
|
|
make((batch, seq_kv, num_heads, head_dim)),
|
|
bias=make(batch, num_heads, seq_q, seq_kv),
|
|
cu_seqlens_q=None,
|
|
cu_seqlens_k=None,
|
|
max_seqlen_q=None,
|
|
max_seqlen_k=None,
|
|
dropout_p=dropout_p,
|
|
custom_mask_type=0, # No Mask
|
|
compute_log_sumexp=requires_grad,
|
|
scale=None,
|
|
seqlen_k=None
|
|
)
|
|
)
|
|
|
|
# jagged (with query/keys offsets)
|
|
cu_seqlens_k = torch.arange(-1, 32 * 2 + 1, 2, dtype=torch.int32, device=device)
|
|
cu_seqlens_k[-1] = 62
|
|
cu_seqlens_k[0] = 0
|
|
samples.append(
|
|
SampleInput(
|
|
make((32, 2, 64)).view(-1, 8, 8).unsqueeze(0),
|
|
make((64, 64)).view(-1, 8, 8).unsqueeze(0),
|
|
make((64, 64)).view(-1, 8, 8).unsqueeze(0),
|
|
bias=None,
|
|
cu_seqlens_q=torch.arange(0, 32 * 2 + 2, 2, dtype=torch.int32, device=device),
|
|
cu_seqlens_k=cu_seqlens_k,
|
|
max_seqlen_q=2,
|
|
max_seqlen_k=2,
|
|
dropout_p=0.0,
|
|
custom_mask_type=0, # No Mask
|
|
compute_log_sumexp=requires_grad,
|
|
scale=None,
|
|
seqlen_k=None,
|
|
)
|
|
)
|
|
|
|
yield from samples
|
|
|
|
def sample_inputs_flash_attention_forward(op_info, device, dtype, requires_grad, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
batch, num_heads, head_dim = 4, 4, 8
|
|
seq_q = 11
|
|
seq_kv = 32
|
|
|
|
dim_4_q_shape = (batch, num_heads, seq_q, head_dim)
|
|
dim_4_kv_shape = (batch, num_heads, seq_kv, head_dim)
|
|
|
|
qkv_shapes = [(dim_4_q_shape, dim_4_kv_shape)]
|
|
samples = []
|
|
scales = [None, 1.0]
|
|
|
|
for qkv_shape, is_causal, dropout_p, scale in product(
|
|
qkv_shapes, [True, False], [0.0, 0.5], scales):
|
|
shape_q, shape_kv = qkv_shape
|
|
samples.append(SampleInput(
|
|
make(shape_q).transpose(1, 2),
|
|
make(shape_kv).transpose(1, 2),
|
|
make(shape_kv).transpose(1, 2),
|
|
cum_seq_q=None,
|
|
cum_seq_k=None,
|
|
max_q=seq_q,
|
|
max_k=seq_kv,
|
|
dropout_p=dropout_p,
|
|
is_causal=is_causal,
|
|
return_debug_mask=False,
|
|
scale=scale,
|
|
))
|
|
|
|
yield from samples
|
|
|
|
def sample_inputs_pairwise_distance(op_info, device, dtype, requires_grad, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shape = (3,)
|
|
batched_shape = (2, *shape)
|
|
shapes_and_kwargs = [
|
|
(shape, None),
|
|
(batched_shape, None),
|
|
(shape, dict(keepdim=True)),
|
|
(batched_shape, dict(keepdim=True)),
|
|
(shape, dict(p=5.0)),
|
|
(shape, dict(p=-1.0)),
|
|
(shape, dict(eps=1.0)),
|
|
]
|
|
|
|
return (
|
|
SampleInput(make(shape), args=(make(shape),), kwargs=kwargs) for shape, kwargs in shapes_and_kwargs
|
|
)
|
|
|
|
def sample_inputs_pixel_shuffle(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield from (
|
|
SampleInput(make_arg((1, 9, 2, 2)), upscale_factor=upscale_factor)
|
|
for upscale_factor in (1, 3)
|
|
)
|
|
yield from (
|
|
SampleInput(make_arg(shape), upscale_factor=1)
|
|
for shape in [
|
|
(1, 0, 1, 1),
|
|
(1, 1, 0, 1),
|
|
(1, 1, 1, 0),
|
|
]
|
|
)
|
|
|
|
def sample_inputs_pixel_unshuffle(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield from (
|
|
SampleInput(make_arg((1, 1, 6, 6)), downscale_factor=downscale_factor)
|
|
for downscale_factor in (1, 3)
|
|
)
|
|
yield from (
|
|
SampleInput(make_arg(shape), downscale_factor=1)
|
|
for shape in [
|
|
(1, 0, 1, 1),
|
|
(1, 1, 0, 1),
|
|
(1, 1, 1, 0),
|
|
]
|
|
)
|
|
|
|
def sample_inputs_channel_shuffle(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_arg = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
shapes_groups = [
|
|
((1, 4, 10, 10), 2),
|
|
((2, 6, 8, 8), 3),
|
|
((2, 8, 5, 5), 4),
|
|
]
|
|
|
|
yield from (
|
|
SampleInput(make_arg(shape), args=(groups,))
|
|
for shape, groups in shapes_groups
|
|
)
|
|
|
|
def sample_inputs_binary_cross_entropy(op_info, device, dtype, requires_grad, logits=False, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=dtype)
|
|
# Lower bounds must be greater than 'eps' defined in gradcheck.py::gradgradcheck() -> eps
|
|
# otherwise perturbation calculation causes Tensor value to become negative triggering
|
|
# a device-side hardware assertion
|
|
make_prob = partial(make, low=1e-6, high=1)
|
|
|
|
reductions = ("mean", "sum", "none")
|
|
|
|
shapes_and_kwargs = [
|
|
*[(shape, None) for shape in ((), (1,), (S,), (S, S), (S, S, S))],
|
|
*[((S, S), dict(reduction=reduction)) for reduction in reductions],
|
|
*[((S, S), dict(reduction=reduction, weight=make((S, S)))) for reduction in reductions],
|
|
]
|
|
|
|
if logits:
|
|
shapes_and_kwargs.extend(
|
|
[((S, S), dict(reduction=reduction, pos_weight=make((S,), low=0))) for reduction in reductions]
|
|
)
|
|
|
|
for shape, kwargs in shapes_and_kwargs:
|
|
yield SampleInput(
|
|
(make if logits else make_prob)(shape, requires_grad=requires_grad),
|
|
args=(make_prob(shape, requires_grad=requires_grad),),
|
|
kwargs=kwargs,
|
|
)
|
|
|
|
def sample_inputs_allclose(op_info, device, dtype, requires_grad, **kwargs):
|
|
sample_shapes = [(), (S), (S, S, S)]
|
|
atols = [1e-2, 1e-16]
|
|
rtols = [1e-1, 0.5]
|
|
for s, rtol, atol in product(sample_shapes, rtols, atols):
|
|
# close sample
|
|
t = make_tensor(s, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
close = (t + atol).detach().requires_grad_(requires_grad)
|
|
yield SampleInput(t, close, rtol=rtol, atol=atol)
|
|
|
|
# random sample
|
|
a = make_tensor(s, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
b = make_tensor(s, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
yield SampleInput(a, b, rtol=rtol, atol=atol)
|
|
|
|
|
|
def sample_inputs_l1_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_loss(op_info, device, dtype, requires_grad, **kwargs)
|
|
|
|
# test COMPLEX_TO_FLOAT promotion
|
|
if dtype.is_complex:
|
|
make = partial(make_tensor, (), device=device, requires_grad=requires_grad)
|
|
yield SampleInput(make(dtype=dtype), args=(make(dtype=torch.double),))
|
|
yield SampleInput(make(dtype=torch.double), args=(make(dtype=dtype),))
|
|
|
|
def error_inputs_l1_loss(op_info, device, **kwargs):
|
|
make = partial(make_tensor, device=device, dtype=torch.float32)
|
|
|
|
# invalid reduction value
|
|
yield ErrorInput(SampleInput(make(5, 4), args=(make(5, 4),),
|
|
kwargs={'reduction': 'abc'}),
|
|
error_type=ValueError,
|
|
error_regex='abc is not a valid value for reduction')
|
|
# invalid input shapes
|
|
yield ErrorInput(SampleInput(make(5, 4), args=(make(5,),)),
|
|
error_regex=(r'(Attempting to broadcast a dimension of length|'
|
|
r'The size of tensor a \(4\) must match the '
|
|
r'size of tensor b \(5\) at non-singleton '
|
|
r'dimension 1)')
|
|
)
|
|
|
|
def sample_inputs_smooth_l1_loss(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield from sample_inputs_loss(op_info, device, dtype, requires_grad, **kwargs)
|
|
|
|
make = partial(make_tensor, (S, S), device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
# This test case always triggers the smooth condition, since absolute difference of input and target
|
|
# is smaller than beta
|
|
yield SampleInput(make(low=0, high=2), args=(make(low=-2, high=0),), kwargs=dict(beta=5))
|
|
yield SampleInput(make(), args=(make(),), kwargs=dict(beta=0))
|
|
|
|
def sample_inputs_kl_div(op_info, device, dtype, requires_grad, **kwargs):
|
|
# kl_div works with inputs in [0, 1] (aka the pdf of a probability measure)
|
|
# Then log [0, 1] = (-inf, 0], so this is the log space
|
|
make_arg = partial(make_tensor, low=0., device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
def make_log(shape):
|
|
out = torch.nn.functional.log_softmax(make_arg(shape), -1)
|
|
out.requires_grad_(requires_grad)
|
|
return out
|
|
|
|
def make_prob(shape):
|
|
out = torch.nn.functional.softmax(make_arg(shape), -1)
|
|
out.requires_grad_(requires_grad)
|
|
return out
|
|
|
|
shapes = ((2,), (2, 3))
|
|
reductions = ("none", "mean", "batchmean", "sum")
|
|
for shape, reduction, log_target in product(shapes, reductions, (True, False)):
|
|
input = make_log(shape)
|
|
target = make_log(shape) if log_target else make_prob(shape)
|
|
yield SampleInput(input, args=(target,), kwargs=dict(reduction=reduction, log_target=log_target))
|
|
|
|
def sample_inputs_pdist(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield from (SampleInput(make_input((n, m))) for n, m in itertools.product((1, S), repeat=2))
|
|
yield from (SampleInput(make_input((S, S)), kwargs=dict(p=p)) for p in (0.0, 1.0, 2.0, 10.0, float("inf")))
|
|
|
|
def reference_pdist(input, p=2):
|
|
pdist = scipy.spatial.distance.pdist
|
|
if p == 0:
|
|
output = pdist(input, "hamming") * input.shape[1]
|
|
elif p == float("inf"):
|
|
output = pdist(input, lambda x, y: np.abs(x - y).max())
|
|
else:
|
|
output = pdist(input, "minkowski", p=p)
|
|
return output.astype(input.dtype)
|
|
|
|
def sample_inputs_diagflat(op_info, device, dtype, requires_grad, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
yield SampleInput(make_input(()))
|
|
yield SampleInput(make_input((2,)))
|
|
yield SampleInput(make_input((2, 2)))
|
|
yield SampleInput(make_input((2,)), offset=1)
|
|
yield SampleInput(make_input((2,)), offset=-1)
|
|
|
|
def sample_inputs_max_unpool(op_info, device, dtype, requires_grad, **kwargs):
|
|
unpool_name_to_pool_method_dict = {
|
|
'nn.functional.max_unpool1d': torch.nn.functional.max_pool1d,
|
|
'nn.functional.max_unpool2d': torch.nn.functional.max_pool2d,
|
|
'nn.functional.max_unpool3d': torch.nn.functional.max_pool3d
|
|
}
|
|
|
|
unpool_name_to_dim = {
|
|
'nn.functional.max_unpool1d': 1,
|
|
'nn.functional.max_unpool2d': 2,
|
|
'nn.functional.max_unpool3d': 3
|
|
}
|
|
|
|
unpool_to_pool_name_dict = {k: f'nn.functional.{v.__name__}' for k, v in unpool_name_to_pool_method_dict.items()}
|
|
|
|
pool_dim = unpool_name_to_dim[op_info.name]
|
|
pool_method = unpool_name_to_pool_method_dict[op_info.name]
|
|
|
|
pool_op_info = copy.copy(op_info)
|
|
pool_op_info.name = unpool_to_pool_name_dict[op_info.name]
|
|
|
|
for sample in sample_inputs_max_pool(pool_op_info, device, dtype, requires_grad, **kwargs):
|
|
# shapes (C, ...) do not work as of now,
|
|
# see https://github.com/pytorch/pytorch/issues/68337
|
|
# TODO: remove once the issue is resolved
|
|
if sample.input.dim() != pool_dim + 2:
|
|
continue
|
|
|
|
# No dilation > 1 for max_unpool,
|
|
# see https://github.com/pytorch/pytorch/issues/68420
|
|
if sample.kwargs['dilation'] != 1:
|
|
continue
|
|
|
|
# Can't unpool without indices
|
|
if sample.kwargs['return_indices']:
|
|
pool, indices = pool_method(sample.input, **sample.kwargs)
|
|
# arg has to be a leaf
|
|
arg = pool.detach().requires_grad_(requires_grad)
|
|
sample_kwargs = {
|
|
'kernel_size': sample.kwargs['kernel_size'],
|
|
'stride': sample.kwargs['stride'],
|
|
'padding': sample.kwargs['padding'],
|
|
# output_size could be None but we specify it explicitly
|
|
# to compensate for the information lose in pool due
|
|
# to the floor/ceil operation used to compute the shapes
|
|
'output_size': sample.input.size()
|
|
}
|
|
|
|
yield SampleInput(arg, args=(indices,), kwargs=sample_kwargs)
|
|
|
|
def sample_inputs_max_unpool_grad(op_info, device, dtype, requires_grad, **kwargs):
|
|
for sample in sample_inputs_max_unpool(op_info, device, dtype, requires_grad, **kwargs):
|
|
indices = sample.args[0]
|
|
# The samples for max_unpool are generated with max_pool.
|
|
# It could be that a single element from the max_pool's
|
|
# input is mapped to several locations in its output.
|
|
# This situation leads to failed gradchecks because
|
|
# the finite difference algorithm perturbs the elements
|
|
# of the output one by one, and not in classes of
|
|
# equivalences determined by whether two elements
|
|
# in the output are coming from the same location in the
|
|
# input (simply put, they have the same corresponding index).
|
|
# So, there are two ways to resolve this issue:
|
|
# 1. Extract a perturbation for one element and apply it all
|
|
# the elements from the same equivalence class, or
|
|
# 2. Make sure that the equivalence classes are all singletons,
|
|
# i.e. the index tensor has to be comprised of only unique
|
|
# indices.
|
|
# Here we go with the solution 2, the easiest of all.
|
|
if indices.unique().numel() == indices.numel():
|
|
yield sample
|
|
|
|
def sample_inputs_multi_head_attention_forward(opinfo, device, dtype, requires_grad, **kwargs):
|
|
make_input = partial(make_tensor, device=device, dtype=dtype, requires_grad=requires_grad)
|
|
|
|
if requires_grad:
|
|
# backward tests would take too long to complete, causing the job timeout.
|
|
bsz = 2
|
|
is_batcheds = (True,)
|
|
use_separate_proj_weights = (False,)
|
|
emb_sizes = (2,)
|
|
src_lens = (XS,)
|
|
tgt_lens = (XS,)
|
|
heads = (2,)
|
|
dropouts = (0.5,)
|
|
mask_types = ("2d",)
|
|
else:
|
|
bsz = 2
|
|
is_batcheds = (False, True)
|
|
use_separate_proj_weights = (False, True)
|
|
emb_sizes = (2, 4)
|
|
src_lens = (XS,)
|
|
tgt_lens = (XS, S)
|
|
heads = (1, 2)
|
|
dropouts = (0.0, 0.5)
|
|
mask_types = (None, "2d", "3d")
|
|
|
|
for is_batched, use_separate_proj_weight, mask_type, emb_size, src_len, tgt_len, num_heads, dropout_p in itertools.product(
|
|
is_batcheds, use_separate_proj_weights, mask_types, emb_sizes, src_lens, tgt_lens, heads, dropouts
|
|
):
|
|
attn_mask = None
|
|
if mask_type == "2d":
|
|
attn_mask = make_input(src_len, tgt_len)
|
|
elif mask_type == "3d":
|
|
attn_mask = make_input((bsz if is_batched else 1) * num_heads, src_len, tgt_len)
|
|
|
|
if is_batched:
|
|
q = make_input(src_len, bsz, emb_size)
|
|
k = make_input(tgt_len, bsz, emb_size)
|
|
v = make_input(tgt_len, bsz, emb_size)
|
|
else:
|
|
q = make_input(src_len, emb_size)
|
|
k = make_input(tgt_len, emb_size)
|
|
v = make_input(tgt_len, emb_size)
|
|
if use_separate_proj_weight:
|
|
in_proj_weight = None
|
|
q_proj_weight = make_input(emb_size, emb_size)
|
|
k_proj_weight = make_input(emb_size, emb_size)
|
|
v_proj_weight = make_input(emb_size, emb_size)
|
|
else:
|
|
in_proj_weight = make_input(emb_size * 3, emb_size)
|
|
q_proj_weight = None
|
|
k_proj_weight = None
|
|
v_proj_weight = None
|
|
|
|
bias_k = make_input(emb_size)
|
|
bias_v = make_input(emb_size)
|
|
in_proj_bias = make_input(emb_size * 3)
|
|
out_proj_weight = make_input(emb_size, emb_size)
|
|
out_proj_bias = make_input(emb_size)
|
|
sample_args = (
|
|
k, v, emb_size, num_heads, in_proj_weight,
|
|
in_proj_bias, bias_k, bias_v, False,
|
|
dropout_p, out_proj_weight, out_proj_bias
|
|
)
|
|
sample_kwargs = {
|
|
"q_proj_weight" : q_proj_weight,
|
|
"k_proj_weight" : k_proj_weight,
|
|
"v_proj_weight" : v_proj_weight,
|
|
"attn_mask" : attn_mask,
|
|
"training" : True if dropout_p > 0.0 else False,
|
|
"use_separate_proj_weight" : use_separate_proj_weight
|
|
}
|
|
|
|
yield SampleInput(q, args=sample_args, kwargs=sample_kwargs)
|
|
|
|
|
|
# Includes some values such that N * N won't be a multiple of 4,
|
|
# which should ensure we test the vectorized and non-vectorized
|
|
# kernel code paths.
|
|
NUM_SIZE0_TENSORS = 10000
|
|
foreach_num_tensors = [20, 23] if not TEST_WITH_SLOW else [23, 30, 300]
|
|
_foreach_inputs_default_kwargs = {"noncontiguous": False, "same_size": False, "low": None, "high": None}
|
|
|
|
|
|
class ForeachRightmostArgType(enum.Enum):
|
|
TensorList = enum.auto()
|
|
ScalarList = enum.auto()
|
|
Scalar = enum.auto()
|
|
Tensor = enum.auto()
|
|
|
|
|
|
class ForeachSampleInput(SampleInput):
|
|
# For TensorList <op> Scalar/Tensor, we compute the reference
|
|
# by converting it into TensorList <op> ScalarList/TensorList and
|
|
# then converting into multiple Tensor <op> Scalar/Tensor.
|
|
# ref_args contains the args converted to TensorList <op> ScalarList/TensorList
|
|
ref_args: Any
|
|
disable_fastpath: bool
|
|
|
|
def __init__(self, *args, disable_fastpath=False, ref_args=None, **kwargs):
|
|
super().__init__(*args, **kwargs)
|
|
self.ref_args = ref_args or self.args
|
|
self.disable_fastpath = disable_fastpath
|
|
|
|
|
|
class foreach_inputs_sample_func:
|
|
def __init__(
|
|
self,
|
|
arity: int,
|
|
rightmost_supports_scalar: bool,
|
|
rightmost_supports_scalarlist: bool,
|
|
rightmost_supports_tensor: bool = False,
|
|
) -> None:
|
|
self.arity = arity
|
|
self._set_rightmost_arg_types(
|
|
rightmost_supports_scalar, rightmost_supports_scalarlist, rightmost_supports_tensor,
|
|
)
|
|
self._intersperse_empty = (True, False)
|
|
|
|
def _set_rightmost_arg_types(
|
|
self,
|
|
rightmost_supports_scalar: bool,
|
|
rightmost_supports_scalarlist: bool,
|
|
rightmost_supports_tensor: bool,
|
|
) -> None:
|
|
self._rightmost_arg_types = [ForeachRightmostArgType.TensorList]
|
|
if self.arity > 1:
|
|
if rightmost_supports_scalar:
|
|
self._rightmost_arg_types.append(ForeachRightmostArgType.Scalar)
|
|
if rightmost_supports_scalarlist:
|
|
self._rightmost_arg_types.append(ForeachRightmostArgType.ScalarList)
|
|
if rightmost_supports_tensor:
|
|
self._rightmost_arg_types.append(ForeachRightmostArgType.Tensor)
|
|
|
|
def _sample_rightmost_arg(
|
|
self,
|
|
opinfo,
|
|
rightmost_arg_type,
|
|
device,
|
|
dtype,
|
|
num_tensors,
|
|
allow_higher_dtype_scalars,
|
|
**_foreach_inputs_kwargs,
|
|
):
|
|
if rightmost_arg_type == ForeachRightmostArgType.TensorList:
|
|
return [sample_inputs_foreach(None, device, dtype, num_tensors, **_foreach_inputs_kwargs)]
|
|
if rightmost_arg_type == ForeachRightmostArgType.Tensor:
|
|
return [make_tensor(
|
|
(), device=device, dtype=dtype,
|
|
noncontiguous=_foreach_inputs_kwargs["noncontiguous"],
|
|
requires_grad=_foreach_inputs_kwargs.get("requires_grad", False),
|
|
)]
|
|
should_use_simpler_scalars = opinfo.name == "_foreach_pow" and dtype in (torch.float16, torch.bfloat16)
|
|
|
|
def sample_float():
|
|
s = random.random()
|
|
if should_use_simpler_scalars:
|
|
return 1.0 if s > 0.5 else 2.0
|
|
else:
|
|
return 1.0 - s
|
|
|
|
high = 2 if should_use_simpler_scalars else 9
|
|
if rightmost_arg_type == ForeachRightmostArgType.ScalarList:
|
|
scalarlist_list = []
|
|
scalarlist_list.append([random.randint(0, high) + 1 for _ in range(num_tensors)])
|
|
|
|
if allow_higher_dtype_scalars or dtype.is_floating_point:
|
|
scalarlist_list.append([sample_float() for _ in range(num_tensors)])
|
|
if allow_higher_dtype_scalars or dtype.is_complex:
|
|
scalarlist_list.append([complex(sample_float(), sample_float()) for _ in range(num_tensors)])
|
|
scalarlist_list.append([1, 2.0, 3.0 + 4.5j] + [3.0 for _ in range(num_tensors - 3)])
|
|
scalarlist_list.append([True, 1, 2.0, 3.0 + 4.5j] + [3.0 for _ in range(num_tensors - 4)])
|
|
return scalarlist_list
|
|
if rightmost_arg_type == ForeachRightmostArgType.Scalar:
|
|
scalars = []
|
|
scalars.append(random.randint(1, high + 1))
|
|
if allow_higher_dtype_scalars or dtype.is_floating_point:
|
|
scalars.append(sample_float())
|
|
if allow_higher_dtype_scalars or dtype.is_complex:
|
|
scalars.append(complex(sample_float(), sample_float()))
|
|
scalars.append(True)
|
|
return scalars
|
|
raise AssertionError(f"Invalid rightmost_arg_type of {rightmost_arg_type}")
|
|
|
|
def _should_disable_fastpath(self, opinfo, rightmost_arg, rightmost_arg_type, dtype):
|
|
if self.arity == 1:
|
|
if "foreach_abs" in opinfo.name and dtype in complex_types():
|
|
return True
|
|
# unary
|
|
if opinfo.ref in (torch.abs, torch.neg):
|
|
return False
|
|
if opinfo.ref_inplace in (torch.Tensor.zero_,):
|
|
return False
|
|
return dtype in integral_types_and(torch.bool)
|
|
if self.arity < 2 or rightmost_arg_type == ForeachRightmostArgType.Tensor:
|
|
return None
|
|
if "foreach_pow" in opinfo.name and dtype in integral_types_and(torch.bool):
|
|
return True
|
|
if any(
|
|
foreach_name in opinfo.name
|
|
for foreach_name in ("foreach_clamp_max", "foreach_clamp_min", "foreach_maximum", "foreach_minimum")
|
|
) and dtype in integral_types_and(torch.bool):
|
|
return True
|
|
if rightmost_arg_type == ForeachRightmostArgType.TensorList:
|
|
disable_fastpath = "foreach_div" in opinfo.name and dtype in integral_types_and(torch.bool)
|
|
if "foreach_add" in opinfo.name and dtype == torch.bool:
|
|
disable_fastpath = True
|
|
return disable_fastpath
|
|
elif rightmost_arg_type == ForeachRightmostArgType.Scalar:
|
|
disable_fastpath = "foreach_div" in opinfo.name and dtype in integral_types_and(torch.bool)
|
|
if isinstance(rightmost_arg, bool):
|
|
disable_fastpath |= dtype == torch.bool
|
|
if opinfo.ref in (torch.add, torch.mul):
|
|
disable_fastpath = False
|
|
elif isinstance(rightmost_arg, int):
|
|
disable_fastpath |= dtype == torch.bool
|
|
elif isinstance(rightmost_arg, float):
|
|
disable_fastpath |= dtype in integral_types_and(torch.bool)
|
|
elif isinstance(rightmost_arg, complex):
|
|
disable_fastpath |= dtype not in complex_types()
|
|
else:
|
|
raise AssertionError(f"Invalid scalar of type {rightmost_arg_type} - {rightmost_arg}")
|
|
return disable_fastpath
|
|
elif rightmost_arg_type == ForeachRightmostArgType.ScalarList:
|
|
disable_fastpath = opinfo.ref == torch.div and dtype in integral_types_and(torch.bool)
|
|
elmt_t = type(rightmost_arg[0])
|
|
has_same_type = all(isinstance(v, elmt_t) for v in rightmost_arg)
|
|
if not has_same_type:
|
|
return dtype not in complex_types()
|
|
if isinstance(rightmost_arg[0], bool):
|
|
if ("foreach_add" in opinfo.name or "foreach_mul" in opinfo.name) and dtype == torch.bool:
|
|
disable_fastpath = False
|
|
elif isinstance(rightmost_arg[0], int):
|
|
disable_fastpath |= dtype == torch.bool
|
|
elif isinstance(rightmost_arg[0], float):
|
|
disable_fastpath |= dtype in integral_types_and(torch.bool)
|
|
elif isinstance(rightmost_arg[0], complex):
|
|
disable_fastpath |= dtype not in complex_types()
|
|
else:
|
|
raise AssertionError(f"Invalid scalarlist of {rightmost_arg}")
|
|
return disable_fastpath
|
|
else:
|
|
raise AssertionError(f"Invalid rightmost_arg_type of {rightmost_arg_type}")
|
|
|
|
def _sample_kwargs(self, opinfo, rightmost_arg, rightmost_arg_type, dtype):
|
|
kwargs = {}
|
|
if rightmost_arg_type == ForeachRightmostArgType.TensorList and opinfo.supports_alpha_param:
|
|
if dtype in integral_types_and(torch.bool):
|
|
kwargs["alpha"] = 3
|
|
elif dtype.is_complex:
|
|
kwargs["alpha"] = complex(3, 3)
|
|
else:
|
|
kwargs["alpha"] = 3.14
|
|
if self.arity > 1:
|
|
kwargs["disable_fastpath"] = self._should_disable_fastpath(opinfo, rightmost_arg, rightmost_arg_type, dtype)
|
|
return kwargs
|
|
|
|
def sample_zero_size_tensor_inputs(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
assert "num_input_tensors" not in kwargs
|
|
_foreach_inputs_kwargs = {k: kwargs.pop(k, v) for k, v in _foreach_inputs_default_kwargs.items()}
|
|
_foreach_inputs_kwargs["requires_grad"] = requires_grad
|
|
allow_higher_dtype_scalars = kwargs.pop("allow_higher_dtype_scalars", False)
|
|
for _rightmost_arg_type in self._rightmost_arg_types:
|
|
zero_size_foreach_inputs_kwargs = copy.deepcopy(_foreach_inputs_kwargs)
|
|
zero_size_foreach_inputs_kwargs["zero_size"] = True
|
|
input = sample_inputs_foreach(None, device, dtype, NUM_SIZE0_TENSORS, **zero_size_foreach_inputs_kwargs)
|
|
if self.arity > 1:
|
|
args = [
|
|
sample_inputs_foreach(None, device, dtype, NUM_SIZE0_TENSORS, **zero_size_foreach_inputs_kwargs)
|
|
for _ in range(self.arity - 2)
|
|
]
|
|
args.append(
|
|
self._sample_rightmost_arg(
|
|
opinfo,
|
|
ForeachRightmostArgType.TensorList,
|
|
device,
|
|
dtype,
|
|
NUM_SIZE0_TENSORS,
|
|
allow_higher_dtype_scalars=allow_higher_dtype_scalars,
|
|
**zero_size_foreach_inputs_kwargs,
|
|
)[0])
|
|
kwargs = self._sample_kwargs(
|
|
opinfo, args[-1], ForeachRightmostArgType.TensorList, dtype)
|
|
else:
|
|
args = []
|
|
kwargs = {}
|
|
if opinfo.ref in (torch.abs, torch.neg):
|
|
kwargs["disable_fastpath"] = False
|
|
else:
|
|
kwargs["disable_fastpath"] = dtype in integral_types_and(torch.bool)
|
|
yield ForeachSampleInput(input, *args, **kwargs)
|
|
|
|
def __call__(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
num_input_tensors_specified = "num_input_tensors" in kwargs
|
|
num_input_tensors = kwargs.pop("num_input_tensors") if num_input_tensors_specified else foreach_num_tensors
|
|
assert isinstance(num_input_tensors, list)
|
|
_foreach_inputs_kwargs = {k: kwargs.pop(k, v) for k, v in _foreach_inputs_default_kwargs.items()}
|
|
_foreach_inputs_kwargs["requires_grad"] = requires_grad
|
|
_foreach_inputs_kwargs["zero_size"] = False
|
|
allow_higher_dtype_scalars = kwargs.pop("allow_higher_dtype_scalars", False)
|
|
|
|
# add empty tensor interspersion to test fully fixing #100701
|
|
for num_tensors, rightmost_arg_type, intersperse_empty_tensors in itertools.product(
|
|
num_input_tensors, self._rightmost_arg_types, self._intersperse_empty):
|
|
if intersperse_empty_tensors and (num_tensors != max(num_input_tensors) or str(device) == 'cpu'):
|
|
# generate interspersed empty tensors for only 1 N on non-cpu device to lessen redundancy
|
|
continue
|
|
_foreach_inputs_kwargs["intersperse_empty_tensors"] = intersperse_empty_tensors
|
|
input = sample_inputs_foreach(
|
|
None, device, dtype, num_tensors, **_foreach_inputs_kwargs)
|
|
args = []
|
|
if self.arity > 1:
|
|
args = [
|
|
sample_inputs_foreach(
|
|
None, device, dtype, num_tensors, **_foreach_inputs_kwargs)
|
|
for _ in range(self.arity - 2)
|
|
]
|
|
rightmost_arg_list = self._sample_rightmost_arg(
|
|
opinfo, rightmost_arg_type, device, dtype, num_tensors, allow_higher_dtype_scalars,
|
|
**_foreach_inputs_kwargs)
|
|
for rightmost_arg in rightmost_arg_list:
|
|
args.append(rightmost_arg)
|
|
kwargs = self._sample_kwargs(opinfo, rightmost_arg, rightmost_arg_type, dtype)
|
|
ref_args = args
|
|
if rightmost_arg_type in (ForeachRightmostArgType.Scalar, ForeachRightmostArgType.Tensor):
|
|
ref_args = args[:-1] + [[args[-1] for _ in range(num_tensors)]]
|
|
sample = ForeachSampleInput(input, *args, ref_args=ref_args, **kwargs)
|
|
yield sample
|
|
args.pop()
|
|
else:
|
|
yield ForeachSampleInput(
|
|
input,
|
|
*args,
|
|
disable_fastpath=self._should_disable_fastpath(opinfo, None, None, dtype),
|
|
)
|
|
|
|
|
|
class foreach_max_sample_func(foreach_inputs_sample_func):
|
|
def __init__(
|
|
self,
|
|
arity: int,
|
|
rightmost_supports_scalar: bool,
|
|
rightmost_supports_scalarlist: bool,
|
|
rightmost_supports_tensor: bool = False,
|
|
) -> None:
|
|
super().__init__(arity, rightmost_supports_scalar, rightmost_supports_scalarlist, rightmost_supports_tensor)
|
|
self._intersperse_empty = (False,)
|
|
|
|
def sample_zero_size_tensor_inputs(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
return []
|
|
|
|
def _should_disable_fastpath(self, opinfo, rightmost_arg, rightmost_arg_type, dtype):
|
|
return False
|
|
|
|
|
|
class foreach_norm_sample_func(foreach_inputs_sample_func):
|
|
def sample_zero_size_tensor_inputs(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
assert "num_input_tensors" not in kwargs
|
|
_foreach_inputs_kwargs = {k: kwargs.pop(k, v) for k, v in _foreach_inputs_default_kwargs.items()}
|
|
_foreach_inputs_kwargs["requires_grad"] = requires_grad
|
|
for ord in (0, 1, 2, -1, -2, float('inf'), float('-inf')):
|
|
input = sample_inputs_foreach(None, device, dtype, NUM_SIZE0_TENSORS, zero_size=True, **_foreach_inputs_kwargs)
|
|
disable_fastpath = True
|
|
if ord in (1, 2, float('inf')) and dtype in floating_types_and(torch.half, torch.bfloat16):
|
|
disable_fastpath = False
|
|
yield ForeachSampleInput(input, ord=ord, disable_fastpath=disable_fastpath)
|
|
|
|
def __call__(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
num_input_tensors = kwargs.pop("num_input_tensors", foreach_num_tensors)
|
|
assert isinstance(num_input_tensors, list)
|
|
_foreach_inputs_kwargs = {k: kwargs.pop(k, v) for k, v in _foreach_inputs_default_kwargs.items()}
|
|
_foreach_inputs_kwargs["requires_grad"] = requires_grad
|
|
_allow_higher_dtype_scalars = kwargs.pop("allow_higher_dtype_scalars", False)
|
|
|
|
for num_tensors, ord, out_dtype in product(
|
|
num_input_tensors,
|
|
(0, 1, 2, -1, -2, float('inf'), float('-inf')),
|
|
(None,) + (torch.complex128,) if dtype in complex_types() else (torch.float64,),
|
|
):
|
|
input = sample_inputs_foreach(None, device, dtype, num_tensors, zero_size=False, **_foreach_inputs_kwargs)
|
|
disable_fastpath = True
|
|
if ord in (1, 2, float('inf')) and dtype in floating_types_and(torch.half, torch.bfloat16):
|
|
disable_fastpath = False
|
|
yield ForeachSampleInput(input, ord=ord, disable_fastpath=disable_fastpath, dtype=out_dtype)
|
|
|
|
# Also test nan propagation with a single tensor, but skip autograd testing
|
|
if not requires_grad:
|
|
nan_inputs = [
|
|
[float('nan')],
|
|
[float('nan'), 1.0],
|
|
[1.0, float('nan')],
|
|
[1.0, 2.0, 3.0, float('nan'), float('nan'), 7.0, float('nan'), float('nan'), -1.5, 6.0],
|
|
[7.0, 3.0, float('nan'), float('nan'), -1.5, 6.0],
|
|
[3.0, float('nan'), float('nan'), -1.5, 6.0],
|
|
]
|
|
for input in nan_inputs:
|
|
x = torch.tensor(input, device=device)
|
|
disable_fastpath = True
|
|
if ord in (1, 2, float('inf')) and dtype in floating_types_and(torch.half, torch.bfloat16):
|
|
disable_fastpath = False
|
|
yield ForeachSampleInput([x], ord=ord, disable_fastpath=disable_fastpath)
|
|
|
|
|
|
class foreach_pointwise_sample_func(foreach_inputs_sample_func):
|
|
|
|
def __init__(
|
|
self,
|
|
arity: int = 3,
|
|
rightmost_supports_scalar: bool = False,
|
|
rightmost_supports_scalarlist: bool = False,
|
|
):
|
|
super().__init__(arity, rightmost_supports_scalar, rightmost_supports_scalarlist)
|
|
|
|
def _should_disable_fastpath(self, opinfo, rightmost_arg, rightmost_arg_type, dtype):
|
|
return dtype in integral_types_and(torch.bool) and opinfo.ref in (torch.addcmul,)
|
|
|
|
def sample_zero_size_tensor_inputs(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
assert "num_input_tensors" not in kwargs
|
|
_foreach_inputs_kwargs = {k: kwargs.pop(k, v) for k, v in _foreach_inputs_default_kwargs.items()}
|
|
_foreach_inputs_kwargs["requires_grad"] = requires_grad
|
|
# zero_size tensor
|
|
input = sample_inputs_foreach(None, device, dtype, NUM_SIZE0_TENSORS, zero_size=True, **_foreach_inputs_kwargs)
|
|
args = [
|
|
sample_inputs_foreach(None, device, dtype, NUM_SIZE0_TENSORS, zero_size=True, **_foreach_inputs_kwargs)
|
|
for _ in range(2)
|
|
]
|
|
if "scalars" in kwargs:
|
|
del kwargs["scalars"]
|
|
kwargs.update(self._sample_kwargs(opinfo, args[-1], ForeachRightmostArgType.TensorList, dtype))
|
|
yield ForeachSampleInput(input, *args, **kwargs)
|
|
|
|
def __call__(self, opinfo, device, dtype, requires_grad, **kwargs):
|
|
num_input_tensors_specified = "num_input_tensors" in kwargs
|
|
num_input_tensors = kwargs.pop("num_input_tensors") if num_input_tensors_specified else foreach_num_tensors
|
|
assert isinstance(num_input_tensors, list)
|
|
_foreach_inputs_kwargs = {k: kwargs.pop(k, v) for k, v in _foreach_inputs_default_kwargs.items()}
|
|
_foreach_inputs_kwargs["requires_grad"] = requires_grad
|
|
allow_higher_dtype_scalars = kwargs.pop("allow_higher_dtype_scalars", False)
|
|
|
|
for num_tensors, rightmost_arg_type in itertools.product(num_input_tensors, self._rightmost_arg_types):
|
|
input = sample_inputs_foreach(None, device, dtype, num_tensors, zero_size=False, **_foreach_inputs_kwargs)
|
|
args = [
|
|
sample_inputs_foreach(None, device, dtype, num_tensors, zero_size=False, **_foreach_inputs_kwargs)
|
|
for _ in range(2 - int(rightmost_arg_type == ForeachRightmostArgType.TensorList))
|
|
]
|
|
rightmost_arg_list = self._sample_rightmost_arg(
|
|
opinfo,
|
|
rightmost_arg_type,
|
|
device,
|
|
dtype,
|
|
num_tensors,
|
|
zero_size=False,
|
|
allow_higher_dtype_scalars=allow_higher_dtype_scalars,
|
|
**_foreach_inputs_kwargs,
|
|
)
|
|
for rightmost_arg in rightmost_arg_list:
|
|
kwargs = {}
|
|
if rightmost_arg_type == ForeachRightmostArgType.TensorList:
|
|
args.append(rightmost_arg)
|
|
elif rightmost_arg_type in [ForeachRightmostArgType.Tensor, ForeachRightmostArgType.ScalarList]:
|
|
kwargs["scalars"] = rightmost_arg
|
|
else:
|
|
kwargs["value"] = rightmost_arg
|
|
kwargs.update(self._sample_kwargs(opinfo, rightmost_arg, rightmost_arg_type, dtype))
|
|
assert len(args) == 2, f"{len(args)=}"
|
|
sample = ForeachSampleInput(input, *args, **kwargs)
|
|
yield sample
|
|
if rightmost_arg_type == ForeachRightmostArgType.TensorList:
|
|
args.pop()
|
|
|
|
|
|
foreach_unary_op_db: List[OpInfo] = [
|
|
ForeachFuncInfo(
|
|
'exp',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32),
|
|
backward_requires_result=True,
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'acos',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'asin',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'atan',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'cos',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'cosh',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'log',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'log10',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'log2',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'tan',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
backward_requires_result=True,
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
# due to https://github.com/pytorch/pytorch/pull/102427 enabling jiterator for complex
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride(
|
|
{
|
|
torch.complex64: tol(atol=3e-04, rtol=2e-05)
|
|
}
|
|
),
|
|
'TestForeach',
|
|
'test_parity',
|
|
device_type='cuda'
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'tanh',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
backward_requires_result=True,
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride(
|
|
{torch.complex64: tol(atol=5e-03, rtol=1e-04)}
|
|
),
|
|
'TestForeach',
|
|
'test_parity',
|
|
device_type='cuda'
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'sin',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'sinh',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'neg',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_unary_op_tensors_on_different_devices",
|
|
device_type="cuda",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'sqrt',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
backward_requires_result=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'ceil',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'erf',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'erfc',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'expm1',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
backward_requires_result=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'floor',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'log1p',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'round',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'frac',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool) + complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'reciprocal',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
backward_requires_result=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'sigmoid',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
backward_requires_result=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'trunc',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'abs',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
device_type="cpu",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
device_type="cpu",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
device_type="cpu",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
device_type="cpu",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
device_type="cpu",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
device_type="cpu",
|
|
dtypes=(torch.bool,),
|
|
),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace", dtypes=complex_types()),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'zero',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_out=False,
|
|
),
|
|
ForeachFuncInfo(
|
|
'sign',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
'lgamma',
|
|
sample_inputs_func=foreach_inputs_sample_func(1, False, False),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.skip("In-place lgamma not supported for integral tensors"), "TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace", dtypes=integral_types_and(torch.bool)),
|
|
# DecorateInfo(unittest.skip("In-place lgamma not supported for integral tensors"), "TestMeta",
|
|
# "test_dispatch_meta_inplace", dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.skip("In-place lgamma not supported for integral tensors"), "TestMeta",
|
|
"test_meta_inplace", dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=complex_types() + integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types() + integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_inplace",
|
|
dtypes=complex_types() + integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=complex_types(),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
),
|
|
),
|
|
]
|
|
|
|
foreach_binary_op_db: List[OpInfo] = [
|
|
ForeachFuncInfo(
|
|
"add",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16, torch.int32),
|
|
supports_alpha_param=True,
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
# These tests fail with aten._local_scalar_dense not being implemented.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16)),
|
|
# Samples have complex types and inplace only works if the dtype is complex.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=integral_types() + complex_types_and(torch.bool, torch.bfloat16, torch.float16, torch.float64)),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"sub",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_alpha_param=True,
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides"),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"),
|
|
DecorateInfo(unittest.skip("consistently fails internally and causes other tests to appear flaky"),
|
|
"TestForeach", "test_parity", dtypes=(torch.complex128,),
|
|
active_if=lambda kwargs: IS_FBCODE and not kwargs["noncontiguous"]),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"mul",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
# Samples have complex types and inplace only works if the dtype is complex.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.skip("consistently fails internally and causes other tests to appear flaky"),
|
|
"TestForeach", "test_parity", dtypes=(torch.complex128,),
|
|
active_if=lambda kwargs: IS_FBCODE and not kwargs["noncontiguous"]),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"div",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16, torch.int32, torch.int8),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
# Samples have complex types and inplace only works if the dtype is complex.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"clamp_min",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16, torch.int64, torch.int32, torch.int8, torch.bool),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_binary_op_scalar_with_overlapping_tensors",
|
|
dtypes=complex_types(),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"clamp_max",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16, torch.int64, torch.int32, torch.int8, torch.bool),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_binary_op_scalar_with_overlapping_tensors",
|
|
dtypes=complex_types(),
|
|
),
|
|
),
|
|
),
|
|
# note(crcrpar): forward ad not implemented.
|
|
ForeachFuncInfo(
|
|
"minimum",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=False,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_binary_op_scalar_with_overlapping_tensors",
|
|
dtypes=complex_types(),
|
|
),
|
|
),
|
|
),
|
|
# note(crcrpar): forward ad not implemented.
|
|
ForeachFuncInfo(
|
|
"maximum",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_autograd=True,
|
|
supports_forward_ad=False,
|
|
supports_inplace_autograd=False,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
dtypes=complex_types_and(torch.bool)),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex128,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_binary_op_scalar_with_overlapping_tensors",
|
|
dtypes=complex_types(),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"pow",
|
|
supports_alpha_param=False,
|
|
supports_scalar_self_arg=True,
|
|
sample_inputs_func=foreach_inputs_sample_func(2, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16, torch.int32, torch.int8, torch.bool),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=(torch.bool,),),
|
|
DecorateInfo(unittest.skip("flaky"), "TestForeach", "test_parity", device_type="cpu", dtypes=(torch.complex64,)),
|
|
DecorateInfo(
|
|
unittest.skip("failed starting on ROCm 6.2"),
|
|
"TestForeach",
|
|
"test_parity",
|
|
device_type="cuda",
|
|
dtypes=(torch.complex64,),
|
|
active_if=TEST_WITH_ROCM),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_binary_op_with_scalar_self_support",
|
|
device_type="cuda",
|
|
dtypes=(torch.bool,),
|
|
active_if=lambda kwargs: kwargs["is_fastpath"],
|
|
),
|
|
),
|
|
backward_requires_result=True,
|
|
),
|
|
ForeachFuncInfo(
|
|
"copy",
|
|
sample_inputs_func=foreach_inputs_sample_func(2, False, False),
|
|
supports_out=False,
|
|
supports_forward_ad=False,
|
|
supports_autograd=False,
|
|
supports_inplace_autograd=False,
|
|
)
|
|
]
|
|
|
|
foreach_pointwise_op_db: List[ForeachFuncInfo] = [
|
|
ForeachFuncInfo(
|
|
"addcmul",
|
|
sample_inputs_func=foreach_pointwise_sample_func(4, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
dtypes=(torch.bool,)),
|
|
# # Samples have complex types and inplace only works if the dtype is complex.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace", dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=integral_types() + complex_types_and(torch.bool)),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"addcdiv",
|
|
sample_inputs_func=foreach_pointwise_sample_func(4, True, True),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
# Samples have complex types and inplace only works if the dtype is complex.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides",
|
|
dtypes=integral_types() + complex_types_and(torch.bool)),
|
|
# fails with div_cpu is not implemented with ComplexHalf
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
dtypes=integral_types() + complex_types_and(torch.bool)),
|
|
),
|
|
),
|
|
]
|
|
|
|
foreach_reduce_op_db: List[ForeachFuncInfo] = [
|
|
ForeachFuncInfo(
|
|
"max",
|
|
sample_inputs_func=foreach_max_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
# no complex support for ordering ops like max
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_autodiff",
|
|
dtypes=(torch.complex128, torch.complex64),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_foreach_reduce_large_input",
|
|
dtypes=(torch.complex128, torch.complex64),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=(torch.complex128, torch.complex64),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=(torch.complex128, torch.complex64),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=(torch.complex128, torch.complex64),
|
|
),
|
|
),
|
|
),
|
|
ForeachFuncInfo(
|
|
"norm",
|
|
sample_inputs_func=foreach_norm_sample_func(1, False, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_inplace"),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace"),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace"),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_inplace_all_strides"),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestForeach",
|
|
"test_foreach_reduce_large_input",
|
|
device_type="cuda",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
),
|
|
),
|
|
]
|
|
|
|
foreach_other_op_db: List[ForeachFuncInfo] = [
|
|
ForeachFuncInfo(
|
|
"lerp",
|
|
sample_inputs_func=foreach_inputs_sample_func(3, True, False),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_autograd=True,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_outplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestMeta",
|
|
"test_dispatch_symbolic_meta_inplace",
|
|
dtypes=integral_types_and(torch.bool),
|
|
),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_inplace", dtypes=integral_types_and(torch.bool)),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_meta_outplace", dtypes=integral_types_and(torch.bool)),
|
|
),
|
|
),
|
|
]
|
|
|
|
def reference_sign(x):
|
|
if x.dtype == np.bool_:
|
|
# `np.sign` doesn't support `bool`.
|
|
# >>> np.sign(True)
|
|
# ufunc 'sign' did not contain a loop
|
|
# with signature matching types dtype('bool') -> dtype('bool')
|
|
return np.sign(x, dtype=np.uint8).astype(np.bool_)
|
|
return np.sign(x)
|
|
|
|
|
|
def reference_sgn(x):
|
|
# NumPy doesn't have an equivalent to `torch.sgn` when the dtype is complex.
|
|
# For complex inputs, `np.sign` returns sign(x.real) + 0j if x.real != 0 else sign(x.imag) + 0j.
|
|
# while `torch.sgn` returns, 0 if abs(input) == 0 else input/abs(input)
|
|
if x.dtype not in [np.complex64, np.complex128]:
|
|
return reference_sign(x)
|
|
|
|
out = (x / np.abs(x))
|
|
if out.ndim == 0:
|
|
# Handle x == 0 case
|
|
if (x == 0):
|
|
# Can't assign to np.complex object
|
|
# So make a new one.
|
|
return np.array(complex(0, 0), dtype=x.dtype)
|
|
return out
|
|
|
|
# Handle x == 0 case
|
|
mask = (x == 0)
|
|
out[mask] = complex(0, 0)
|
|
return out
|
|
|
|
|
|
def reference_sigmoid(x):
|
|
# 'scipy.special.expit' not supported for the input types
|
|
if x.dtype in [np.complex64, np.complex128]:
|
|
return (1 / (1 + np.exp(-x)))
|
|
return scipy.special.expit(x)
|
|
|
|
|
|
def reference_logsigmoid(x):
|
|
return np.where(
|
|
x < 0,
|
|
x - np.log1p(np.exp(x)),
|
|
-np.log1p(np.exp(-x)))
|
|
|
|
|
|
def reference_hardsigmoid(x):
|
|
intermediate = x / 6 + 0.5
|
|
y = np.clip(intermediate, 0, None)
|
|
return np.where(y > 1, 1, y).astype(x.dtype)
|
|
|
|
|
|
def reference_lgamma(x):
|
|
# scipy.special.gammaln returns `-inf` when input is `-inf`.
|
|
# While Pytorch, C and C++, all return `inf` when input is `-inf`.
|
|
# Reference:
|
|
# https://en.cppreference.com/w/cpp/numeric/math/lgamma
|
|
# https://en.cppreference.com/w/c/numeric/math/lgamma
|
|
|
|
# To handle the above discrepancy,
|
|
# we replace -inf with inf so values
|
|
# that were originally -inf map to inf as expected
|
|
if x.dtype.kind == 'f':
|
|
x = np.where(x == float('-inf'), np.array(float('inf'), dtype=x.dtype), x)
|
|
|
|
out = scipy.special.gammaln(x)
|
|
|
|
if x.dtype == np.float16:
|
|
# `scipy.special.gammaln` returns output of float32 when input is float16,
|
|
# while `torch.lgamma` preserves `float16`. But due to smaller range of float16,
|
|
# Pytorch version outputs `inf` while SciPy returns finite values.
|
|
out = out.astype(np.float16)
|
|
|
|
return out
|
|
|
|
|
|
def reference_mvlgamma(x, d):
|
|
if x.dtype == np.float16:
|
|
return scipy.special.multigammaln(x, d).astype(np.float16)
|
|
|
|
return scipy.special.multigammaln(x, d)
|
|
|
|
def reference_softplus(input, beta=1, threshold=20):
|
|
non_linear = input * beta <= threshold
|
|
output = input.copy()
|
|
output[non_linear] = np.log(1 + np.exp(beta * input[non_linear])) / beta
|
|
return output
|
|
|
|
def reference_gelu(X, *, approximate='none'):
|
|
def _gelu_ref(X):
|
|
return X * stats.norm.cdf(X)
|
|
|
|
def _tanh_gelu_ref(X):
|
|
M_SQRT_2_PI = math.sqrt(2 / math.pi)
|
|
Z = M_SQRT_2_PI * (X + 0.044715 * np.power(X, 3.0))
|
|
return 0.5 * X * (1.0 + np.tanh(Z))
|
|
|
|
if approximate == 'tanh':
|
|
return _tanh_gelu_ref(X)
|
|
else:
|
|
return _gelu_ref(X)
|
|
|
|
|
|
def reference_one_hot(a: npt.NDArray, num_classes: int = -1) -> npt.NDArray:
|
|
if num_classes == -1:
|
|
num_classes = int(np.amax(a) + 1)
|
|
|
|
idcs = a.reshape(-1) + np.arange(0, a.size, dtype=np.int64) * num_classes
|
|
one_hot = np.zeros((a.size, num_classes), dtype=a.dtype)
|
|
np.put(one_hot, idcs, 1)
|
|
return one_hot.reshape(*a.shape, -1)
|
|
|
|
|
|
def reference_mse_loss(input, target, reduction="mean"):
|
|
se = (input - target) ** 2
|
|
if reduction == "mean":
|
|
return np.mean(se)
|
|
elif reduction == "sum":
|
|
return np.sum(se)
|
|
else: # reduction == "none"
|
|
return se
|
|
|
|
|
|
def reference_layer_norm(inp: npt.NDArray, normalized_shape: Tuple[int], weight=None, bias=None, eps=1e-5):
|
|
return reference_native_layer_norm(inp, normalized_shape, weight, bias, eps)[0]
|
|
|
|
|
|
def reference_native_layer_norm(inp: npt.NDArray, normalized_shape: Tuple[int], weight, bias, eps):
|
|
feature_size = np.prod(normalized_shape)
|
|
inp_view = inp.reshape(-1, feature_size) # type: ignore[call-overload]
|
|
mean = inp_view.mean(axis=-1, keepdims=True)
|
|
var = inp_view.var(axis=-1, ddof=0, keepdims=True)
|
|
Y = (inp_view - mean) / np.sqrt(var + eps)
|
|
if weight is None and bias is not None:
|
|
Y = Y + bias.reshape(-1)
|
|
elif weight is not None and bias is None:
|
|
Y = Y * weight.reshape(-1)
|
|
elif weight is not None and bias is not None:
|
|
Y = Y * weight.reshape(-1) + bias.reshape(-1)
|
|
axis = inp.ndim - len(normalized_shape)
|
|
stat_shape = inp.shape[:axis] + (1,) * len(normalized_shape)
|
|
return Y.reshape(*inp.shape), mean.reshape(stat_shape), (1.0 / np.sqrt(var + eps)).reshape(stat_shape)
|
|
|
|
|
|
def reference_rms_norm(inp: npt.NDArray, normalized_shape: Tuple[int], weight=None, eps=None):
|
|
if eps is None:
|
|
eps = torch.finfo(numpy_to_torch_dtype(inp.dtype)).eps
|
|
feature_size = np.prod(normalized_shape)
|
|
inp_view = inp.reshape(-1, feature_size) # type: ignore[call-overload]
|
|
rms = np.sqrt((inp_view**2).mean(axis=-1, keepdims=True) + eps)
|
|
Y = inp_view / rms
|
|
if weight is not None:
|
|
Y = Y * weight.reshape(-1)
|
|
return Y.reshape(*inp.shape)
|
|
|
|
|
|
def reference_group_norm(inp: npt.NDArray, num_groups: int, weight=None, bias=None, eps=1e-5):
|
|
inp_view = inp
|
|
if np.prod(inp.shape) != 0:
|
|
inp_view = inp.reshape((inp.shape[0], num_groups, -1))
|
|
mean = inp_view.mean(axis=-1, keepdims=True)
|
|
var = inp_view.var(axis=-1, ddof=0, keepdims=True)
|
|
Y = (inp_view - mean) / np.sqrt(var + eps)
|
|
Y = Y.reshape(inp.shape)
|
|
if weight is not None:
|
|
# weight is a vector of length equal to the channel
|
|
if len(Y.shape) > 2:
|
|
weight = np.expand_dims(weight, [0] + [idx + 2 for idx in range(inp.ndim - 2)])
|
|
Y = Y * weight
|
|
if bias is not None:
|
|
# bias is a vector of length equal to the channel
|
|
if len(Y.shape) > 2:
|
|
bias = np.expand_dims(bias, [0] + [idx + 2 for idx in range(inp.ndim - 2)])
|
|
Y = Y + bias
|
|
return Y
|
|
|
|
|
|
# using a custom reference function since numpy only has a string side arg (instead of right and side) and doesn't
|
|
# have an out_int32 arg. Additionally, numpy doesn't support searchsorted with ND arrays, so this splits those into
|
|
# stacked 1D cases
|
|
def reference_searchsorted(sorted_sequence, boundary, out_int32=False, right=False, side='left', sorter=None):
|
|
side = 'right' if (right or side == 'right') else 'left'
|
|
if len(sorted_sequence.shape) == 1 :
|
|
ret = np.searchsorted(sorted_sequence, boundary, side=side, sorter=sorter)
|
|
return ret.astype(np.int32) if out_int32 else ret
|
|
elif sorted_sequence.shape[0] == 0:
|
|
if sorter is not None:
|
|
sorter = sorter.flatten()
|
|
ret = np.searchsorted(sorted_sequence.flatten(), boundary.flatten(), side=side, sorter=sorter)
|
|
ret = ret.astype(np.int32) if out_int32 else ret
|
|
return ret.reshape(boundary.shape)
|
|
else:
|
|
# numpy searchsorted only supports 1D inputs so we split up ND inputs
|
|
orig_shape = boundary.shape
|
|
num_splits = np.prod(sorted_sequence.shape[:-1])
|
|
splits = range(0, num_splits)
|
|
sorted_sequence, boundary = sorted_sequence.reshape(num_splits, -1), boundary.reshape(num_splits, -1)
|
|
if sorter is not None:
|
|
sorter = sorter.reshape(num_splits, -1)
|
|
|
|
split_sequence = [sorted_sequence[i] for i in splits]
|
|
split_boundary = [boundary[i] for i in splits]
|
|
split_sorter = [sorter[i] if (sorter is not None) else None for i in splits]
|
|
|
|
split_ret = [np.searchsorted(s_seq, b, side=side, sorter=s_sort)
|
|
for (s_seq, b, s_sort) in zip(split_sequence, split_boundary, split_sorter)]
|
|
split_ret = [i.astype(np.int32) for i in split_ret] if out_int32 else split_ret
|
|
return np.stack(split_ret).reshape(orig_shape)
|
|
|
|
def loss_reference_reduction_wrapper(fn):
|
|
def wrapper(input, target, *, size_average=None, reduce=None, reduction="mean", **other_kwargs):
|
|
if size_average is not None or reduce is not None:
|
|
raise RuntimeError(
|
|
"The keyword arguments 'size_average' and 'reduce' are deprecated and not supported by this wrapper"
|
|
)
|
|
output = fn(input, target, **other_kwargs)
|
|
if reduction == "mean":
|
|
return np.mean(output)
|
|
elif reduction == "sum":
|
|
return np.sum(output)
|
|
else: # reduction == "none"
|
|
return output
|
|
|
|
return wrapper
|
|
|
|
@loss_reference_reduction_wrapper
|
|
def reference_smooth_l1_loss(input, target, beta=1.0):
|
|
diff = input - target
|
|
abs_diff = np.abs(diff)
|
|
above_threshold = abs_diff >= beta
|
|
|
|
loss = np.empty_like(input)
|
|
loss[above_threshold] = abs_diff[above_threshold] - 0.5 * beta
|
|
loss[~above_threshold] = diff[~above_threshold] ** 2 / (2 * beta)
|
|
|
|
return loss
|
|
|
|
def reference_std_var(f):
|
|
"""Forwards unbiased/correction kwargs as NumPy's equivalent ddof"""
|
|
g = reference_reduction_numpy(f)
|
|
|
|
@wraps(g)
|
|
def wrapper(x: npt.NDArray, *args, **kwargs):
|
|
assert not ('unbiased' in kwargs and 'correction' in kwargs)
|
|
|
|
if 'unbiased' in kwargs:
|
|
kwargs['ddof'] = int(kwargs.pop('unbiased'))
|
|
elif 'correction' in kwargs:
|
|
kwargs['ddof'] = kwargs.pop('correction')
|
|
|
|
return g(x, *args, **kwargs)
|
|
|
|
return wrapper
|
|
|
|
def generate_std_var_kwargs(t: torch.Tensor, **kwargs):
|
|
"""Generates unbiased/correction kwargs for std/var operators"""
|
|
yield ((), {'unbiased': True})
|
|
yield ((), {'unbiased': False})
|
|
|
|
# Currently, calling std with correction is only enabled when
|
|
# both dim and keepdim are provided.
|
|
if 'dim' in kwargs and 'keepdim' in kwargs:
|
|
yield ((), {'correction': 0})
|
|
yield ((), {'correction': 1})
|
|
|
|
numel = torch.tensor(t.shape)[kwargs.get('dim')].prod()
|
|
yield ((), {'correction': numel // 2})
|
|
|
|
def error_inputs_mean(op_info, device, is_ref=False, **kwargs):
|
|
if is_ref:
|
|
err_msg1 = (r"mean\(\): could not infer output dtype. "
|
|
r"Input dtype must be either a floating point or complex dtype. "
|
|
r"Got: torch.int64")
|
|
else:
|
|
err_msg1 = (r"mean\(\): could not infer output dtype. "
|
|
r"Input dtype must be either a floating point or complex dtype. "
|
|
r"Got: Long")
|
|
yield ErrorInput(
|
|
SampleInput(make_tensor((3, 4, 5), dtype=torch.int64, device=device), []),
|
|
error_regex=err_msg1,
|
|
)
|
|
|
|
if is_ref:
|
|
err_msg2 = (r"mean\(\): could not infer output dtype. "
|
|
r"Optional dtype must be either a floating point or complex dtype. "
|
|
r"Got: torch.int64")
|
|
else:
|
|
err_msg2 = (r"mean\(\): could not infer output dtype. "
|
|
r"Optional dtype must be either a floating point or complex dtype. "
|
|
r"Got: Long")
|
|
yield ErrorInput(
|
|
SampleInput(
|
|
make_tensor((3, 4, 5), dtype=torch.float32, device=device),
|
|
[],
|
|
dtype=torch.int64),
|
|
error_regex=err_msg2
|
|
)
|
|
|
|
if is_ref:
|
|
err_msg3 = "Expected out tensor to have dtype torch.float64, but got torch.float32 instead"
|
|
else:
|
|
err_msg3 = "Expected out tensor to have dtype double, but got float instead"
|
|
yield ErrorInput(
|
|
SampleInput(
|
|
make_tensor((3, 4, 5), dtype=torch.int64, device=device),
|
|
[],
|
|
dtype=torch.float64,
|
|
out=make_tensor([], dtype=torch.float32, device=device),
|
|
),
|
|
error_regex=err_msg3
|
|
)
|
|
|
|
# numpy implementation of torch.flatten
|
|
# unfortunately there's no np.flatten. we figure out the desired shape and call np.reshape
|
|
def reference_flatten(input, start_dim=0, end_dim=-1):
|
|
in_shape = input.shape
|
|
in_rank = len(in_shape)
|
|
for d in start_dim, end_dim:
|
|
if not ((in_rank == 0 and d in (-1, 0)) or -in_rank <= d < in_rank):
|
|
raise IndexError(f"Dimension out of range (expected to be in range of [{-in_rank}, {in_rank - 1}], but got {d}")
|
|
end_dim = end_dim if end_dim >= 0 else in_rank + end_dim
|
|
start_dim = start_dim if start_dim >= 0 else in_rank + start_dim
|
|
if in_rank == 0:
|
|
end_dim = start_dim
|
|
if end_dim < start_dim:
|
|
raise RuntimeError("flatten() has invalid args: start_dim cannot come after end_dim")
|
|
flatten_bit_dim = functools.reduce(operator.mul, in_shape[start_dim:end_dim + 1], 1)
|
|
out_shape = in_shape[:start_dim] + (flatten_bit_dim,) + in_shape[end_dim + 1:]
|
|
return np.reshape(input, out_shape)
|
|
|
|
|
|
def sample_inputs_alias_copy(op_info, device, dtype, requires_grad, **kwargs):
|
|
yield SampleInput(make_tensor((S,), dtype=dtype, device=device, requires_grad=requires_grad))
|
|
yield SampleInput(make_tensor((), dtype=dtype, device=device, requires_grad=requires_grad))
|
|
|
|
|
|
# Operator database (sorted alphabetically)
|
|
op_db: List[OpInfo] = [
|
|
UnaryUfuncInfo('abs',
|
|
aliases=('absolute', ),
|
|
ref=np.abs,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("In-place abs not supported for complex tensors"), 'TestBwdGradients',
|
|
'test_inplace_grad', dtypes=(torch.cdouble,)),
|
|
DecorateInfo(unittest.skip("In-place abs not supported for complex tensors"), 'TestBwdGradients',
|
|
'test_inplace_gradgrad', dtypes=(torch.cdouble,)),
|
|
DecorateInfo(unittest.skip("In-place abs not supported for complex tensors"), 'TestFwdGradients',
|
|
'test_inplace_forward_mode_AD', dtypes=(torch.cdouble,)),
|
|
DecorateInfo(unittest.skip("In-place abs not supported for complex tensors"), "TestSparseUnaryUfuncs",
|
|
"test_inplace", dtypes=(torch.cdouble, torch.cfloat, torch.chalf)),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/49224
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
dtypes=[torch.int8], active_if=TEST_WITH_ASAN),
|
|
# TODO: Fix test_out_arg_all_dtypes as torch.empty_like(expected_output) where expected_output=op(input)
|
|
# We can break the logic of the loop over all possible types but it is OK.
|
|
# https://github.com/pytorch/pytorch/blob/master/test/test_unary_ufuncs.py#L440-L449
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_out_arg_all_dtypes',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_meta_inplace',
|
|
dtypes=(torch.cdouble, torch.cfloat, torch.chalf)),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_meta_inplace',
|
|
dtypes=(torch.cdouble, torch.cfloat, torch.chalf)),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_inplace',
|
|
dtypes=(torch.cdouble, torch.cfloat, torch.chalf)),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_inplace_all_strides',
|
|
dtypes=(torch.cdouble, torch.cfloat, torch.chalf)),
|
|
),
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_forward_ad=True),
|
|
# NOTE: CPU complex acos produces incorrect outputs (https://github.com/pytorch/pytorch/issues/42952)
|
|
UnaryUfuncInfo('acos',
|
|
aliases=('arccos', ),
|
|
ref=np.arccos,
|
|
domain=(-1, 1),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.bfloat16: 1e-1,
|
|
torch.complex64: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
device_type='cuda', dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
# Failing with wrong imaginary sign on at least some Windows jobs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
# Failing with wrong imaginary sign on at least some Windows jobs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_grad',
|
|
dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_method_grad',
|
|
dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_inplace_grad',
|
|
dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD',
|
|
dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_inplace_forward_mode_AD',
|
|
dtypes=[torch.cdouble], active_if=IS_WINDOWS),)),
|
|
# NOTE: the derivative for inplace acosh is not implemented
|
|
UnaryUfuncInfo('acosh',
|
|
aliases=('arccosh', ),
|
|
ref=np.arccosh,
|
|
domain=(1, None),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
device_type='cuda', dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
# Failing with wrong imaginary sign on at least some Windows jobs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
# acosh is not defined at x < 1 (real)
|
|
reference_numerics_filter=NumericsFilter(
|
|
condition=lambda x: (x < 1 if not x.is_complex() else torch.zeros_like(x, dtype=torch.bool)),
|
|
safe_val=2)),
|
|
BinaryUfuncInfo('add',
|
|
# NumPy has no builtin reference for the alpha kwarg, but it is easy enough to emulate
|
|
ref=lambda input, other, *, alpha=1: np.add(input, other) if alpha == 1 \
|
|
else np.add(input, np.multiply(alpha, other)),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16,
|
|
torch.float16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=sample_inputs_add_sub,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
supports_two_python_scalars=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=0)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
),
|
|
skips=(
|
|
# boolean alpha not handled properly
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=(torch.bool,)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestCommon',
|
|
'test_numpy_refs',
|
|
dtypes=(torch.complex128,)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
)),
|
|
OpInfo('item',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.item, inp, *args, **kwargs),
|
|
ref=np.ndarray.item,
|
|
method_variant=None,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.chalf, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
error_inputs_func=error_inputs_item,
|
|
sample_inputs_func=sample_inputs_item,
|
|
skips=(
|
|
# Error testing item function variant
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.float32, torch.complex64)),
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# RuntimeError: Composite compliance check failed with the above error.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_operator'),
|
|
# Booleans mismatch: AssertionError: False is not true
|
|
DecorateInfo(unittest.expectedFailure, 'TestFakeTensor', 'test_fake_autocast'),
|
|
# Booleans mismatch: AssertionError: False is not true
|
|
DecorateInfo(unittest.expectedFailure, 'TestFakeTensor', 'test_fake'),
|
|
)),
|
|
OpInfo('arange',
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
is_factory_function=True,
|
|
error_inputs_func=error_inputs_arange,
|
|
sample_inputs_func=sample_inputs_arange,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/81774
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
|
|
# Lazy tensor failures
|
|
DecorateInfo(unittest.expectedFailure, 'TestLazyOpInfo', 'test_dispatched_to_lazy'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestLazyOpInfo', 'test_correctness'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestLazyOpInfo', 'test_correctness_with_reusing_ir'),
|
|
|
|
# Exception raised from analyzeImpl at ../torch/csrc/jit/ir/alias_analysis.cpp:608
|
|
# We don't have an op for aten::arange but it isn't a special case.
|
|
# Argument types: bool, bool, bool, int, int, Device, boo
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
|
|
# Captured graph does not contain aten::arange (succeeds on complex!)
|
|
# g: graph():
|
|
# %25 : Long(1, strides=[1], requires_grad=0, device=cpu) = prim::Constant[value={1}]()
|
|
# return (%25)
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
)),
|
|
OpInfo('cauchy',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.cauchy_, inp, *args, **kwargs),
|
|
inplace_variant=torch.Tensor.cauchy_,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
sample_inputs_func=sample_inputs_cauchy,
|
|
error_inputs_func=error_inputs_cauchy,
|
|
skips=(
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
|
|
# vmap: calling random operator not supported
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
|
|
DecorateInfo(unittest.skip("make_traced() doesn't set seed properly!"), 'TestCommon', 'test_python_ref_executor'),
|
|
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
)),
|
|
OpInfo('exponential',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.exponential_, inp, *args, **kwargs),
|
|
inplace_variant=torch.Tensor.exponential_,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
sample_inputs_func=sample_inputs_exponential,
|
|
error_inputs_func=error_inputs_exponential,
|
|
skips=(
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
|
|
# vmap: calling random operator not supported
|
|
DecorateInfo(unittest.expectedFailure, "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('geometric',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.geometric_, inp, *args, **kwargs),
|
|
inplace_variant=torch.Tensor.geometric_,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16, torch.int8, torch.int16, torch.int32, torch.int64, torch.uint8),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
sample_inputs_func=sample_inputs_geometric,
|
|
error_inputs_func=error_inputs_geometric,
|
|
skips=(
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
|
|
# vmap: calling random operator not supported
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
)),
|
|
OpInfo('log_normal',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.log_normal_, inp, *args, **kwargs),
|
|
inplace_variant=torch.Tensor.log_normal_,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
sample_inputs_func=sample_inputs_log_normal,
|
|
error_inputs_func=error_inputs_log_normal,
|
|
skips=(
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
|
|
# vmap: calling random operator not supported
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
)),
|
|
OpInfo('normal',
|
|
variant_test_name='in_place',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.normal_, inp, *args, **kwargs),
|
|
inplace_variant=torch.Tensor.normal_,
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
sample_inputs_func=sample_inputs_normal,
|
|
error_inputs_func=error_inputs_normal,
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestCommon", "test_noncontiguous_samples"),
|
|
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# vmap: calling random operator not supported
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
)),
|
|
OpInfo('uniform',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.Tensor.uniform_, inp, *args, **kwargs),
|
|
method_variant=None,
|
|
inplace_variant=torch.Tensor.uniform_,
|
|
dtypes=floating_and_complex_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
is_factory_function=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
sample_inputs_func=sample_inputs_uniform,
|
|
error_inputs_func=error_inputs_uniform,
|
|
skips=(
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# aten.uniform was not decomposed
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
BinaryUfuncInfo('clamp_max',
|
|
ref=_clamp_max_numpy,
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_forward_ad=True,
|
|
supports_rhs_python_scalar=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=False),
|
|
skips=(
|
|
# RuntimeError: "max_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion',
|
|
device_type='cuda'),
|
|
# dispatch to lazy test failed
|
|
DecorateInfo(unittest.expectedFailure, 'TestLazyOpInfo', 'test_dispatched_to_lazy'),
|
|
# test error disabled since rhs non-tensor python scalar is supported
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_errors'),
|
|
)),
|
|
BinaryUfuncInfo('clamp_min',
|
|
ref=_clamp_min_numpy,
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_forward_ad=True,
|
|
supports_rhs_python_scalar=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=False),
|
|
skips=(
|
|
# RuntimeError: "min_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion',
|
|
device_type='cuda'),
|
|
# dispatch to lazy test failed
|
|
DecorateInfo(unittest.expectedFailure, 'TestLazyOpInfo', 'test_dispatched_to_lazy'),
|
|
# test error disabled since rhs non-tensor python scalar is supported
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_errors'),
|
|
)),
|
|
BinaryUfuncInfo('mul',
|
|
aliases=('multiply',),
|
|
dtypes=all_types_and_complex_and(torch.chalf, torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_two_python_scalars=True,
|
|
error_inputs_sparse_func=error_inputs_sparse_mul,
|
|
sample_inputs_sparse_coo_func=partial(sample_inputs_sparse_mul, layout=torch.sparse_coo),
|
|
sample_inputs_sparse_csr_func=partial(sample_inputs_sparse_mul, layout=torch.sparse_csr),
|
|
sample_inputs_sparse_csc_func=partial(sample_inputs_sparse_mul, layout=torch.sparse_csc),
|
|
sample_inputs_sparse_bsr_func=partial(sample_inputs_sparse_mul, layout=torch.sparse_bsr),
|
|
sample_inputs_sparse_bsc_func=partial(sample_inputs_sparse_mul, layout=torch.sparse_bsc)),
|
|
BinaryUfuncInfo('sub',
|
|
# NumPy has no builtin reference for the alpha kwarg, but it is easy enough to emulate
|
|
ref=lambda input, other, *, alpha=1: np.subtract(input, np.multiply(alpha, other)),
|
|
aliases=('subtract',),
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_add_sub,
|
|
supports_two_python_scalars=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-2, rtol=0),
|
|
torch.bfloat16: tol(atol=1e-5, rtol=5e-3),
|
|
torch.complex32: tol(atol=1e-5, rtol=1e-3)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=0)}),
|
|
'TestCommon', 'test_complex_half_reference_testing', device_type='cpu'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=5e-3, rtol=0)}),
|
|
'TestDecomp', 'test_comprehensive', device_type='cpu'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=5e-3, rtol=0)}),
|
|
'TestDecomp', 'test_quick', device_type='cpu'),
|
|
),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.uint8,)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.uint8,)),
|
|
)),
|
|
OpInfo('addmm',
|
|
# This addmm OpInfo is for when alpha and beta are not both equal to 1.
|
|
# alpha=beta=1 is tested in the following opinfo, because that special case will
|
|
# trigger addmm being decomposed by a jit pass.
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfROCM=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=sample_inputs_addmm,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
)),
|
|
OpInfo('addmm',
|
|
# When alpha=beta=1 as compile-time constants, JIT will decompose addmm into mm and add.
|
|
variant_test_name='decomposed',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
autodiff_nonfusible_nodes=['aten::add', 'aten::mm'],
|
|
sample_inputs_func=partial(sample_inputs_addmm, alpha=1, beta=1),
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
# https://github.com/pytorch/pytorch/issues/71784
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
device_type='cpu', dtypes=(torch.float16,)),
|
|
)),
|
|
OpInfo('addmv',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.complex64, torch.complex128,
|
|
torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=1e-5, rtol=3e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu'),
|
|
],
|
|
sample_inputs_func=sample_inputs_addmv),
|
|
OpInfo('addbmm',
|
|
ref=lambda M, batch1, batch2, beta=1, alpha=1: np.add(np.multiply(np.asarray(beta, dtype=M.dtype), M),
|
|
np.multiply(np.asarray(alpha, dtype=batch1.dtype),
|
|
np.sum(np.matmul(batch1, batch2), axis=0))),
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16,
|
|
*[torch.bfloat16]
|
|
if SM53OrLater or TEST_WITH_ROCM else []),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1.3e-05, rtol=1.3e-05),
|
|
torch.complex64: tol(atol=1e-05, rtol=1.2e-03)}),
|
|
'TestCommon', 'test_numpy_refs'),
|
|
# MPS has slightly worse precision. Is this acceptable?
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1.3e-04, rtol=1.3e-04),
|
|
torch.complex64: tol(atol=1e-05, rtol=1.2e-03)}),
|
|
'TestCommon', 'test_numpy_ref_mps'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-5, rtol=1e-5)}),
|
|
'TestConsistency',
|
|
'test_output_match',
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1.5e-05, rtol=1e-05)}),
|
|
'TestCommon', 'test_out'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=6e-3, rtol=1e-2)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu'),
|
|
],
|
|
skips=(
|
|
# NVIDIA only assures that bfloat16 is supported by bmm if SM >= 5.3
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes', device_type='cuda', active_if=not SM53OrLater),
|
|
# addbmm does not correctly warn when resizing out= inputs
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# https://github.com/pytorch/pytorch/issues/55907
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
),
|
|
sample_inputs_func=sample_inputs_addbmm),
|
|
OpInfo('baddbmm',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.complex64, torch.complex128,
|
|
torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_types_and(torch.float16,
|
|
*[torch.bfloat16] if SM53OrLater or TEST_WITH_ROCM else [],
|
|
torch.complex64, torch.complex128),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-05, rtol=1.2e-03)}),
|
|
'TestCommon', 'test_variant_consistency_eager', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-05, rtol=1.2e-03)}),
|
|
'TestMathBits', 'test_conj_view', device_type='cuda'),
|
|
],
|
|
sample_inputs_func=sample_inputs_baddbmm,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
)),
|
|
OpInfo('dot',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=sample_inputs_dot_vdot,
|
|
error_inputs_func=error_inputs_dot_vdot,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
)),
|
|
OpInfo('vdot',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_dot_vdot,
|
|
error_inputs_func=error_inputs_dot_vdot,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
)),
|
|
OpInfo('bmm',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16,
|
|
*[torch.bfloat16]
|
|
if SM53OrLater or TEST_WITH_ROCM else []),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
assert_jit_shape_analysis=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# NVIDIA only assures that bfloat16 is supported by bmm if SM >= 5.3
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes', device_type='cuda', active_if=not SM53OrLater),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-5, rtol=1e-5)}),
|
|
"TestCommon", "test_out")
|
|
),
|
|
sample_inputs_func=sample_inputs_bmm),
|
|
OpInfo('mv',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_mv),
|
|
OpInfo('addr',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/50747
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/50747
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16)),
|
|
),
|
|
sample_inputs_func=sample_inputs_addr,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL),
|
|
OpInfo('addcmul',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# TODO: update sample inputs with for_inplace_variant kwarg to support this test
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
),
|
|
sample_inputs_func=sample_inputs_addcmul_addcdiv,
|
|
reference_inputs_func=partial(
|
|
reference_inputs_elementwise_ternary, sample_inputs_func=reference_inputs_addcmul_addcdiv)),
|
|
OpInfo('addcdiv',
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# TODO: update sample inputs with for_inplace_variant kwarg to support this test
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestCommon',
|
|
'test_variant_consistency_eager'),
|
|
),
|
|
sample_inputs_func=sample_inputs_addcmul_addcdiv,
|
|
reference_inputs_func=partial(
|
|
reference_inputs_elementwise_ternary, sample_inputs_func=reference_inputs_addcmul_addcdiv)),
|
|
UnaryUfuncInfo('asin',
|
|
aliases=('arcsin', ),
|
|
ref=np.arcsin,
|
|
domain=(-1, 1),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-05, rtol=1e-03)}),
|
|
'TestUnaryUfuncs', device_type='cuda'
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=8e-5, rtol=4e-5)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda'
|
|
),
|
|
precisionOverride({torch.bfloat16: 1e-2}),
|
|
],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
# NOTE: derivative for inplace asinh is not implemented
|
|
UnaryUfuncInfo('asinh',
|
|
aliases=('arcsinh', ),
|
|
ref=np.arcsinh,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
UnaryUfuncInfo('atan',
|
|
aliases=('arctan', ),
|
|
ref=np.arctan,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
BinaryUfuncInfo('atan2',
|
|
aliases=('arctan2',),
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.half),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# Incorrectly attempts to use a scalar for the second argument
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_jit_alias_remapping'),
|
|
)),
|
|
UnaryUfuncInfo('atanh',
|
|
aliases=('arctanh', ),
|
|
ref=np.arctanh,
|
|
domain=(-1, 1),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
decorators=[
|
|
precisionOverride({torch.bfloat16: 1e-2}),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=9e-3, rtol=8e-5)}),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
],
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cfloat],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
OpInfo('allclose',
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
ref=np.allclose,
|
|
supports_autograd=False,
|
|
supports_forward_ad=False,
|
|
sample_inputs_func=sample_inputs_allclose,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCudaFuserOpInfo'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('broadcast_to',
|
|
ref=np.broadcast_to,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_broadcast_to),
|
|
OpInfo('broadcast_shapes',
|
|
op=torch.broadcast_shapes,
|
|
ref=np.broadcast_shapes if np.lib.NumpyVersion(np.__version__) >= '1.20.0' else None,
|
|
dtypes=_dispatch_dtypes((torch.float32,)),
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
assert_autodiffed=False,
|
|
supports_autograd=False,
|
|
supports_scripting=False,
|
|
sample_inputs_func=sample_inputs_broadcast_shapes,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/64997
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# skip dtype tests since broadcast_shape is not device dependent.
|
|
# having dtypes limited to torch.float32 would cause test_dtypes to report unexpected success
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_dtypes'),
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), "TestCommon", "test_noncontiguous_samples"),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('broadcast_tensors',
|
|
ref=np.broadcast_arrays,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_broadcast_tensors,
|
|
reference_inputs_func=reference_inputs_broadcast_tensors,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/64997
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# JIT does not support variadic tensors.
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":252,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=[torch.float32]),
|
|
)),
|
|
OpInfo('block_diag',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# Default batching rule in core doesn't work for ops with TensorList args
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/64997
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# JIT does not support variadic tensors.
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":252,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=[torch.float32]),
|
|
),
|
|
sample_inputs_func=sample_inputs_block_diag),
|
|
UnaryUfuncInfo('bitwise_not',
|
|
ref=np.bitwise_not,
|
|
dtypes=integral_types_and(torch.bool),
|
|
dtypesIfHpu=custom_types(torch.bool),
|
|
operator_variant=operator.invert,
|
|
supports_autograd=False),
|
|
BinaryUfuncInfo('bitwise_left_shift',
|
|
op=torch.bitwise_left_shift,
|
|
dtypes=integral_types(),
|
|
dtypesIfCUDA=integral_types(),
|
|
dtypesIfHpu=custom_types(torch.int32, torch.int8, torch.bool),
|
|
operator_variant=operator.lshift,
|
|
inplace_operator_variant=operator.ilshift,
|
|
supports_autograd=False,
|
|
supports_one_python_scalar=True,
|
|
rhs_make_tensor_kwargs=dict(low=0),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
# https://github.com/pytorch/pytorch/issues/70904
|
|
DecorateInfo(unittest.skip("Some inputs produce undefined outputs"), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
BinaryUfuncInfo('bitwise_right_shift',
|
|
op=torch.bitwise_right_shift,
|
|
dtypes=integral_types(),
|
|
dtypesIfCUDA=integral_types(),
|
|
dtypesIfHpu=custom_types(torch.int32, torch.int8, torch.bool),
|
|
operator_variant=operator.rshift,
|
|
inplace_operator_variant=operator.irshift,
|
|
supports_autograd=False,
|
|
supports_one_python_scalar=True,
|
|
rhs_make_tensor_kwargs=dict(low=0),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
# https://github.com/pytorch/pytorch/issues/70904
|
|
DecorateInfo(unittest.skip("Some inputs produce undefined outputs"), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('combinations',
|
|
op=torch.combinations,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_combinations),
|
|
OpInfo('cartesian_prod',
|
|
op=torch.cartesian_prod,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_cartesian_prod,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
)),
|
|
OpInfo('cdist',
|
|
dtypes=floating_types(),
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
assert_autodiffed=False,
|
|
sample_inputs_func=sample_inputs_cdist),
|
|
UnaryUfuncInfo('ceil',
|
|
ref=np.ceil,
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=tuple(t for t in integral_types() if t != torch.uint8)),
|
|
),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
assert_autodiffed=True),
|
|
OpInfo('cholesky',
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_linalg_cholesky,
|
|
gradcheck_wrapper=gradcheck_wrapper_hermitian_input,
|
|
decorators=[skipCUDAIfNoMagma, skipCPUIfNoLapack],),
|
|
OpInfo('cholesky_inverse',
|
|
dtypes=floating_and_complex_types(),
|
|
backward_dtypes=floating_and_complex_types(),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
check_batched_gradgrad=True,
|
|
sample_inputs_func=sample_inputs_linalg_cholesky_inverse,
|
|
gradcheck_wrapper=gradcheck_wrapper_triangular_input_real_positive_diagonal,
|
|
decorators=[skipCUDAIfNoMagma, skipCPUIfNoLapack],
|
|
skips=(
|
|
# Strides are not the same! Original strides were ((4, 2, 1),) and strides are now ((4, 1, 2),)
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),)),
|
|
OpInfo('cholesky_solve',
|
|
op=torch.cholesky_solve,
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_cholesky_solve,
|
|
check_batched_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_wrapper=lambda *args, **kwargs: gradcheck_wrapper_triangular_input(*args, idx=1, **kwargs),
|
|
decorators=[skipCUDAIfNoMagma, skipCPUIfNoLapack]),
|
|
OpInfo('chunk',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
sample_inputs_func=sample_inputs_chunk,
|
|
reference_inputs_func=reference_inputs_chunk,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('unsafe_chunk',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_chunk,
|
|
check_batched_forward_grad=False,
|
|
reference_inputs_func=reference_inputs_chunk,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('clone',
|
|
ref=np.copy,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
sample_inputs_func=sample_inputs_clone_contiguous,
|
|
reference_inputs_func=reference_inputs_clone_contiguous,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
skips=(
|
|
# TypeError: _copy_dispatcher() got an unexpected keyword argument 'memory_format'
|
|
# (NumPy reference needs to be extended with memory_format)
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref_mps'),
|
|
),),
|
|
OpInfo('contiguous',
|
|
op=lambda x, *args, **kwargs: x.contiguous(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_clone_contiguous,
|
|
reference_inputs_func=reference_inputs_clone_contiguous,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_fusible_nodes=['aten::contiguous'],
|
|
assert_jit_shape_analysis=True,
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
)),
|
|
OpInfo('sum_to_size',
|
|
op=lambda x, *args, **kwargs: x.sum_to_size(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_sum_to_size,
|
|
error_inputs_func=error_inputs_sum_to_size,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float,)),
|
|
)),
|
|
OpInfo('clamp',
|
|
aliases=('clip',),
|
|
ref=_clamp_numpy,
|
|
dtypes=all_types_and(torch.bfloat16, torch.half),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
sample_inputs_func=sample_inputs_clamp,
|
|
reference_inputs_func=partial(reference_inputs_elementwise_ternary, sample_inputs_func=sample_inputs_clamp),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# NNC appear to not handle boolean clamp
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=(torch.bool,)),
|
|
# MPS does not support float64, while numpy does internal computations in float64.
|
|
# See https://github.com/pytorch/pytorch/blob/3c1cf03fde145bdbe1f5ffb81765d076c10b4c04/test/test_ops.py#L260-L264
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestCommon',
|
|
'test_numpy_ref_mps'),
|
|
)),
|
|
UnaryUfuncInfo('positive',
|
|
ref=np.positive,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
),
|
|
UnaryUfuncInfo('conj',
|
|
ref=np.conj,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16,
|
|
torch.half, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.int32),
|
|
supports_sparse=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
supports_out=False),
|
|
UnaryUfuncInfo('conj_physical',
|
|
decomp_aten_name='_conj_physical',
|
|
ref=np.conj,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16,
|
|
torch.half, torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
skips=(
|
|
# RuntimeError: inputSet && outputSet
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":118,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32, )),
|
|
DecorateInfo(unittest.skip("Skipped! conj_physical_ not implemented for sparse"),
|
|
'TestSparseUnaryUfuncs', 'test_inplace'),
|
|
)),
|
|
OpInfo('resolve_conj',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_view_as_real,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
),
|
|
OpInfo('resolve_neg',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_view_as_real,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
),
|
|
OpInfo('view_as_real',
|
|
dtypes=complex_types(),
|
|
supports_forward_ad=True,
|
|
supports_out=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_view_as_real,
|
|
test_conjugated_samples=False,
|
|
),
|
|
OpInfo('view_as_complex',
|
|
dtypes=floating_types_and(torch.half),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
test_neg_view=False,
|
|
sample_inputs_func=sample_inputs_view_as_complex,
|
|
skips=(
|
|
# RuntimeError: Tensor must have a last dimension with stride 1
|
|
DecorateInfo(unittest.expectedFailure, "TestCommon", "test_noncontiguous_samples"),
|
|
# RuntimeError: "eq_cpu" not implemented for 'ComplexHalf'
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness', dtypes=(torch.half,)),
|
|
# RuntimeError: view size is not compatible with input tensor's size and stride
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"),
|
|
)),
|
|
BinaryUfuncInfo('complex',
|
|
dtypes=floating_types_and(torch.half),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_rhs_python_scalar=False,
|
|
error_inputs_func=error_inputs_complex,
|
|
skips=(
|
|
# Tests don't account for complex's type promotion semantics
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out', device_type='mps'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),)),
|
|
BinaryUfuncInfo('copysign',
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
promotes_int_to_float=True,
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True),
|
|
OpInfo('corrcoef',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_corrcoef,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
),
|
|
supports_out=False),
|
|
UnaryUfuncInfo('cos',
|
|
ref=np.cos,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
handles_large_floats=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.cfloat, torch.cdouble,), device_type='cpu', active_if=IS_WINDOWS),
|
|
# This fails on CUDA but passes on ROCm
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.cdouble,), device_type='cuda'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_MACOS),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: nan at index (700,) (up to 1e-05 allowed)
|
|
# Greatest relative difference: nan at index (700,) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda',
|
|
dtypes=(torch.chalf,), active_if=IS_WINDOWS),
|
|
)),
|
|
UnaryUfuncInfo('cosh',
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(np.cosh),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48641
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.int8]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_MACOS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_MACOS),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: nan at index (6000,) (up to 1e-05 allowed)
|
|
# Greatest relative difference: nan at index (6000,) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda',
|
|
dtypes=(torch.chalf,), active_if=IS_WINDOWS),
|
|
)),
|
|
OpInfo('cov',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_cov,
|
|
error_inputs_func=error_inputs_cov,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
# Float did not match double
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_fn_grad'),
|
|
# Jacobian mismatch
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
DecorateInfo(unittest.skip("Barely fails"), 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
# JIT test not working for tensor kwargs (https://github.com/pytorch/pytorch/issues/58507)
|
|
# RuntimeError:
|
|
# undefined value tensor:
|
|
# File "<string>", line 3
|
|
# def the_method(i0):
|
|
# return torch.cov(i0, correction=0, fweights=None, aweights=tensor([0.0518, 0.4681], dtype=torch.float32, requires_grad=True)) # noqa: B950
|
|
# ~~~~~~ <--- HERE
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=8e-3, rtol=1.4e-3)}),
|
|
"TestInductorOpInfo", "test_comprehensive", device_type="cpu"),
|
|
)),
|
|
OpInfo('cross',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
sample_inputs_func=sample_inputs_cross,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=True,
|
|
supports_forward_ad=True),
|
|
OpInfo('cumsum',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# cumsum does not handle correctly out= dtypes
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
),
|
|
sample_inputs_func=sample_inputs_cumulative_ops),
|
|
OpInfo('cumprod',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# cumprod does not handle correctly out= dtypes
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
),
|
|
# gradgradcheck fails in fast_mode=True: #56275
|
|
sample_inputs_func=sample_inputs_cumprod,
|
|
gradcheck_fast_mode=False),
|
|
OpInfo('cummax',
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_cumulative_ops, supports_dtype_kwargs=False),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL),
|
|
OpInfo('cummin',
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_cumulative_ops, supports_dtype_kwargs=False),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL),
|
|
UnaryUfuncInfo('deg2rad',
|
|
ref=np.radians,
|
|
decorators=(precisionOverride({torch.bfloat16: 7e-1,
|
|
torch.float16: 7e-1}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True),
|
|
OpInfo('diff',
|
|
op=torch.diff,
|
|
# np.diff has np._NoValue as default values for prepend and append, compare_with_reference breaks if prepend/append
|
|
# are set as None when converting to numpy
|
|
ref=lambda input, n=1, dim=-1, prepend=np._NoValue, append=np._NoValue: (
|
|
np.diff(input, n, dim, np._NoValue if prepend is None else prepend, np._NoValue if append is None else append)
|
|
),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_diff,
|
|
error_inputs_func=error_inputs_diff,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
)),
|
|
BinaryUfuncInfo('div',
|
|
aliases=('divide',),
|
|
variant_test_name='no_rounding_mode',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
promotes_int_to_float=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_two_python_scalars=True,
|
|
assert_autodiffed=True,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=True),),
|
|
BinaryUfuncInfo('div',
|
|
aliases=('divide',),
|
|
variant_test_name='trunc_rounding',
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
sample_inputs_func=partial(sample_inputs_elementwise_binary, sample_kwargs=dict(rounding_mode="trunc")),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_two_python_scalars=True,
|
|
assert_autodiffed=True,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=True),
|
|
decorators=(
|
|
# See https://github.com/pytorch/pytorch/issues/111126
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
),
|
|
skips=(
|
|
# RuntimeError: MALFORMED INPUT: Unhandled node kind (in computeValue): aten::div
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_working'),
|
|
# FIXME:
|
|
# torch.autograd.gradcheck.GradcheckError: Jacobian mismatch for
|
|
# output 0 with respect to input 1,
|
|
# numerical:tensor(-17746.9307, dtype=torch.float64)
|
|
# analytical:tensor(0., dtype=torch.float64)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients',
|
|
'test_fn_grad', device_type='cpu',
|
|
dtypes=(torch.float64,)),
|
|
)),
|
|
BinaryUfuncInfo('div',
|
|
aliases=('divide',),
|
|
variant_test_name='floor_rounding',
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
sample_inputs_func=partial(sample_inputs_elementwise_binary, sample_kwargs=dict(rounding_mode="floor")),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_two_python_scalars=True,
|
|
assert_autodiffed=True,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=True),
|
|
decorators=(
|
|
# See https://github.com/pytorch/pytorch/issues/111126
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
),
|
|
skips=(
|
|
# RuntimeError: MALFORMED INPUT: Unhandled node kind (in computeValue): aten::div
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_working'),
|
|
# FIXME:
|
|
# torch.autograd.gradcheck.GradcheckError: Jacobian mismatch for
|
|
# output 0 with respect to input 1,
|
|
# numerical:tensor(-17746.9307, dtype=torch.float64)
|
|
# analytical:tensor(0., dtype=torch.float64)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients',
|
|
'test_fn_grad',
|
|
dtypes=(torch.float64,),
|
|
device_type='cpu'),
|
|
)),
|
|
BinaryUfuncInfo('true_divide',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_forward_ad=True,
|
|
promotes_int_to_float=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_two_python_scalars=True,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=True)),
|
|
OpInfo('equal',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
ref=lambda input, other: (input == other).all(),
|
|
sample_inputs_func=sample_inputs_equal,
|
|
supports_autograd=False,
|
|
supports_tracing=False,
|
|
skips=(
|
|
)),
|
|
UnaryUfuncInfo('exp',
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(np.exp),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48010
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True),
|
|
OpInfo('expand',
|
|
op=lambda self, shape: self.expand(shape),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
sample_inputs_func=sample_inputs_expand,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
)),
|
|
OpInfo('expand_as',
|
|
op=lambda self, other: self.expand_as(other),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_expand_as,
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),),
|
|
),
|
|
OpInfo('expand_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_expand,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
supports_out=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
)),
|
|
OpInfo('diag',
|
|
ref=np.diag,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_diag,
|
|
error_inputs_func=error_inputs_diag),
|
|
OpInfo('diag_embed',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=False,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_diagonal_diag_embed,
|
|
reference_inputs_func=reference_inputs_diagonal_diag_embed,
|
|
error_inputs_func=error_inputs_diagonal_diag_embed),
|
|
OpInfo('diagonal',
|
|
aten_backward_name='diagonal_backward',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_diagonal_diag_embed,
|
|
reference_inputs_func=reference_inputs_diagonal_diag_embed,
|
|
error_inputs_func=error_inputs_diagonal_diag_embed),
|
|
OpInfo('diagonal_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_diagonal_diag_embed,
|
|
reference_inputs_func=reference_inputs_diagonal_diag_embed,
|
|
error_inputs_func=error_inputs_diagonal_diag_embed),
|
|
OpInfo('diagonal_scatter',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_diagonal_scatter),
|
|
OpInfo('alias_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_alias_copy,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=True),
|
|
BinaryUfuncInfo('eq',
|
|
ref=np.equal,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
always_returns_bool=True,
|
|
supports_autograd=False,
|
|
sample_inputs_func=sample_inputs_comparison_ops,
|
|
skips=(
|
|
)),
|
|
BinaryUfuncInfo('fmax',
|
|
op=torch.fmax,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# RuntimeError: "max_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
)),
|
|
BinaryUfuncInfo('fmin',
|
|
op=torch.fmin,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# RuntimeError: "min_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
)),
|
|
BinaryUfuncInfo('fmod',
|
|
ref=np.fmod,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=None,
|
|
rhs_make_tensor_kwargs={'exclude_zero': True},
|
|
decorators=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_contig_vs_every_other',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_non_contig',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.uint8,)),
|
|
# FIXME:
|
|
# torch.autograd.gradcheck.GradcheckError: Jacobian mismatch for
|
|
# output 0 with respect to input 1,
|
|
# numerical:tensor(101.6283, dtype=torch.float64)
|
|
# analytical:tensor(-18.3575, dtype=torch.float64)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients',
|
|
'test_fn_grad',
|
|
dtypes=(torch.float64,),
|
|
device_type='cpu'),
|
|
)),
|
|
BinaryUfuncInfo('remainder',
|
|
ref=np.remainder,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=None,
|
|
operator_variant=operator.mod,
|
|
inplace_operator_variant=operator.imod,
|
|
supports_one_python_scalar=True,
|
|
rhs_make_tensor_kwargs={'exclude_zero': True},
|
|
decorators=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_contig_vs_every_other',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_non_contig',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.uint8,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=(torch.bfloat16,)),
|
|
# Fails on XLA
|
|
# False is not true : Tensors failed to compare as equal!
|
|
# Attempted to compare equality of tensors with different dtypes
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOpInfo', device_type='xla', dtypes=(torch.long,)),
|
|
# FIXME:
|
|
# torch.autograd.gradcheck.GradcheckError: Jacobian mismatch for
|
|
# output 0 with respect to input 1,
|
|
# numerical:tensor(102.4676, dtype=torch.float64)
|
|
# analytical:tensor(-17.5182, dtype=torch.float64)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients',
|
|
'test_fn_grad', device_type='cpu',
|
|
dtypes=(torch.float64,)),
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=5e-4, rtol=3e-3),
|
|
}),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
)),
|
|
UnaryUfuncInfo('frac',
|
|
ref=lambda x: np.modf(x)[0],
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=(torch.bfloat16, torch.float16, torch.float32, torch.float64)),
|
|
# 76047
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
dtypes=(torch.bfloat16, torch.float32, torch.float64)),
|
|
)),
|
|
OpInfo('stft',
|
|
decorators=[
|
|
skipCPUIfNoFFT,
|
|
DecorateInfo(unittest.skip("Skipped! stft does not match the native function"),
|
|
'TestJit', 'test_variant_consistency_jit'),
|
|
],
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_stft,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
supports_out=False,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
),
|
|
OpInfo('istft',
|
|
dtypes=complex_types(),
|
|
sample_inputs_func=sample_inputs_istft,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
supports_out=False,
|
|
decorators=(
|
|
DecorateInfo(unittest.skip("Skipped! istft does not match the native function"),
|
|
'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
skips=(
|
|
skipCPUIfNoFFT,
|
|
# gradcheck fails on ROCm (gh-68429)
|
|
# grad is computed improperly (probably for weights tensor)
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_fn_grad'),
|
|
# Pre-existing condition (calls .item); needs to be fixed
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_backward'),
|
|
)),
|
|
UnaryUfuncInfo('floor',
|
|
ref=np.floor,
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=tuple(t for t in integral_types() if t != torch.uint8)),
|
|
),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
assert_autodiffed=True),
|
|
OpInfo('flip',
|
|
op=torch.flip,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
sample_inputs_func=sample_inputs_flip,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('fliplr',
|
|
op=torch.fliplr,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_fliplr_flipud,
|
|
error_inputs_func=error_inputs_fliplr,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('flipud',
|
|
op=torch.flipud,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_fliplr_flipud,
|
|
error_inputs_func=error_inputs_flipud,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('sparse.sampled_addmm',
|
|
dtypes=floating_and_complex_types(),
|
|
supports_autograd=True,
|
|
sample_inputs_func=sample_inputs_sparse_sampled_addmm,
|
|
decorators=[
|
|
skipCUDAIf(not ((_get_torch_cuda_version() >= (11, 3))
|
|
or (_get_torch_rocm_version() >= (5, 2))),
|
|
"cusparseSDDMM was added in 11.2.1"),
|
|
skipCPUIfNoMklSparse, ],
|
|
skips=(
|
|
# NotImplementedError: Tensors of type SparseCsrTensorImpl do not have is_contiguous
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestTags', 'test_tags'),
|
|
# RuntimeError: sampled_addmm: Expected result to have sparse csr layout, but got Strided
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out_warning'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_operator'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_backward'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: unsupported memory format option Preserve
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: sparse_mask does not support automatic differentiation for outputs with complex dtype
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
# ValueError: Sparse output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) ...
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_grad'),
|
|
# RuntimeError: sparse_mask does not support automatic differentiation for outputs with complex dtype.
|
|
# RuntimeError: Sparse CSR tensors do not have is_contiguous
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
# ValueError: Sparse output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) ...
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# NotImplementedError: Could not run 'aten::sparse_sampled_addmm' with arguments from the 'SparseCsrMeta' backend.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_meta_outplace'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_symbolic_meta_outplace'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_meta_outplace'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_symbolic_meta_outplace_all_strides'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFakeTensor', 'test_fake_crossref_backward_no_amp'),
|
|
)),
|
|
OpInfo('sparse.mm',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
variant_test_name='reduce',
|
|
supports_autograd=True,
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
supports_forward_ad=False,
|
|
sample_inputs_func=sample_inputs_sparse_mm_reduce,
|
|
decorators=[onlyCPU],
|
|
skips=(
|
|
# NotImplementedError: Tensors of type SparseCsrTensorImpl do not have is_contiguous
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestTags', 'test_tags'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_operator'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_backward'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: unsupported memory format option Preserve
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# ValueError: Sparse output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) ...
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
# RuntimeError: Sparse CSR tensors do not have is_contiguou
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_grad'),
|
|
# ValueError: Sparse output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) ...
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
# RuntimeError: Sparse CSR tensors do not have strides
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# ValueError: Sparse output is not supported at gradcheck yet. Please call to_dense(masked_grad=...) ...
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_fail_gradgrad'),
|
|
# NotImplementedError: Could not run 'aten::_sparse_mm_reduce_impl' with arguments from the 'SparseCsrMeta' backend
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_meta_outplace'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_symbolic_meta_outplace'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_meta_outplace'),
|
|
)),
|
|
UnaryUfuncInfo('i0',
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(
|
|
scipy.special.i0) if TEST_SCIPY else None,
|
|
aliases=('special.i0',),
|
|
decorators=(precisionOverride({torch.bfloat16: 3e-1,
|
|
torch.float16: 5e-1}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
sample_inputs_func=sample_inputs_i0_i1,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.int8,)),
|
|
)),
|
|
BinaryUfuncInfo('floor_divide',
|
|
ref=_floor_divide_np,
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
|
|
supports_autograd=False,
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=True),
|
|
supports_two_python_scalars=True,
|
|
skips=(
|
|
# AssertionError: Results of original model and exported/imported version of model differed
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
# bfloat16 floor_divide compared with a float32 reference works inconsistently
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs',
|
|
dtypes=(torch.bfloat16,)),
|
|
# int8 floor divide has different results for -128 // -1 vs. NumPy
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs', 'test_reference_numerics_small_values',
|
|
dtypes=(torch.int8,)),
|
|
# The following tests fails on some jobs
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs', 'test_reference_numerics_extremal_values',
|
|
dtypes=(torch.float16,)),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-3, rtol=5e-3)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
)),
|
|
UnaryUfuncInfo('frexp',
|
|
op=torch.frexp,
|
|
ref=np.frexp,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
# skip testing torch.frexp as it is not supported by ROCm platform yet
|
|
decorators=[],
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# skips below tests as torch.frexp returns tuple-like (mantissa, exponent) as outputs,
|
|
# while theses tests currently requires output to a single tensor.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_batch_vs_slicing'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_contig_vs_every_other'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_contig_vs_transposed'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_non_contig_expand'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_variant_consistency'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_out_arg_all_dtypes'),
|
|
|
|
# skips test_reference_numerics due to error in Windows CI.
|
|
# The np.frexp returns exponent as np.intc dtype on Windows platform,
|
|
# and np.intc does not have the correspond torch dtype
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
active_if=IS_WINDOWS),
|
|
)),
|
|
UnaryUfuncInfo('log1p',
|
|
ref=np.log1p,
|
|
aliases=('special.log1p',),
|
|
domain=(-1, None),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-1}),),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
assert_autodiffed=True,
|
|
promotes_int_to_float=True),
|
|
BinaryUfuncInfo('ge',
|
|
ref=np.greater_equal,
|
|
aliases=('greater_equal',),
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
always_returns_bool=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('geqrf',
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_linalg_qr_geqrf,
|
|
decorators=[skipCUDAIfNoMagmaAndNoCusolver, skipCPUIfNoLapack],
|
|
supports_autograd=False,
|
|
skips=(
|
|
# FIXME: geqrf can't forward with complex inputs that require grad
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_dtypes'),
|
|
# Strides are not the same!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
)),
|
|
BinaryUfuncInfo('gt',
|
|
ref=np.greater,
|
|
aliases=('greater',),
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
always_returns_bool=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
UnaryUfuncInfo('imag',
|
|
ref=np.imag,
|
|
dtypes=complex_types_and(torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
# RuntimeError: view_as_real doesn't work on unresolved conjugated tensors.
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# Skip since real and imag don't have out variants.
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs', 'test_out_arg_all_dtypes'),
|
|
)),
|
|
OpInfo('gradient',
|
|
dtypes=floating_and_complex_types_and(torch.int8, torch.int16,
|
|
torch.int32, torch.int64,
|
|
torch.bfloat16, torch.half),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# following tests give a runtime error with undefined value tensor
|
|
# see discussion : https://github.com/pytorch/pytorch/issues/56660
|
|
# RuntimeError:
|
|
# Arguments for call are not valid.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32, torch.complex64)), # noqa: B950
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCudaFuserOpInfo'),
|
|
),
|
|
supports_inplace_autograd=False,
|
|
sample_inputs_func=sample_inputs_gradient,
|
|
error_inputs_func=error_inputs_gradient),
|
|
OpInfo('isin',
|
|
dtypes=all_types_and(torch.bfloat16, torch.half),
|
|
supports_autograd=False,
|
|
sample_inputs_func=sample_inputs_isin),
|
|
OpInfo('kthvalue',
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_kthvalue,
|
|
error_inputs_func=error_inputs_kthvalue),
|
|
BinaryUfuncInfo('le',
|
|
ref=np.less_equal,
|
|
aliases=('less_equal',),
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.float16),
|
|
always_returns_bool=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('linspace',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
is_factory_function=True,
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
error_inputs_func=error_inputs_linspace,
|
|
sample_inputs_func=sample_inputs_linspace,
|
|
skips=(
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# UserWarning: CUDA caching allocator reports a memory leak not verified by the driver API
|
|
# in __main__.TestJitCUDA.test_variant_consistency_jit_logspace_cuda_complex64!
|
|
# Caching allocator allocated memory was 0 and is now reported as 307200 on device 0.
|
|
# CUDA driver allocated memory was 1254555648 and is now 1242955776.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.cfloat,), device_type="cuda"),
|
|
)),
|
|
OpInfo('linspace',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
is_factory_function=True,
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
error_inputs_func=error_inputs_linspace,
|
|
sample_inputs_func=sample_inputs_linspace_tensor_overload,
|
|
variant_test_name="tensor_overload",
|
|
skips=(
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# TypeError: 'int' object is not subscriptable
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# UserWarning: CUDA caching allocator reports a memory leak not verified by the driver API
|
|
# in __main__.TestJitCUDA.test_variant_consistency_jit_logspace_cuda_complex64!
|
|
# Caching allocator allocated memory was 0 and is now reported as 307200 on device 0.
|
|
# CUDA driver allocated memory was 1254555648 and is now 1242955776.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.cfloat,), device_type="cuda"),
|
|
)),
|
|
OpInfo('logspace',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
is_factory_function=True,
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
error_inputs_func=error_inputs_linspace,
|
|
sample_inputs_func=sample_inputs_logspace,
|
|
skips=(
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
|
|
# Off-by-one issue when casting floats to ints
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick',
|
|
dtypes=(torch.int16, torch.int32, torch.int64), device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_comprehensive',
|
|
dtypes=(torch.int16, torch.int32, torch.int64), device_type="cuda"),
|
|
# UserWarning: CUDA caching allocator reports a memory leak not verified by the driver API
|
|
# in __main__.TestJitCUDA.test_variant_consistency_jit_logspace_cuda_complex64!
|
|
# Caching allocator allocated memory was 0 and is now reported as 307200 on device 0.
|
|
# CUDA driver allocated memory was 1254555648 and is now 1242955776.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.cfloat,), device_type="cuda"),
|
|
)),
|
|
OpInfo('logspace',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
is_factory_function=True,
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
error_inputs_func=error_inputs_linspace,
|
|
sample_inputs_func=sample_inputs_logspace_tensor_overload,
|
|
variant_test_name="tensor_overload",
|
|
skips=(
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# TypeError: 'int' object is not subscriptable
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
|
|
# Off-by-one issue when casting floats to ints
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick',
|
|
dtypes=(torch.int16, torch.int32, torch.int64), device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_comprehensive',
|
|
dtypes=(torch.int16, torch.int32, torch.int64), device_type="cuda"),
|
|
# UserWarning: CUDA caching allocator reports a memory leak not verified by the driver API
|
|
# in __main__.TestJitCUDA.test_variant_consistency_jit_logspace_cuda_complex64!
|
|
# Caching allocator allocated memory was 0 and is now reported as 307200 on device 0.
|
|
# CUDA driver allocated memory was 1254555648 and is now 1242955776.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.cfloat,), device_type="cuda"),
|
|
)),
|
|
UnaryUfuncInfo('log',
|
|
ref=np.log,
|
|
domain=(0, None),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
# log(z)->-inf for |z|->0
|
|
reference_numerics_filter=NumericsFilter(condition=lambda x: torch.abs(x) < 0.1, safe_val=1)),
|
|
UnaryUfuncInfo('log10',
|
|
ref=np.log10,
|
|
domain=(0, None),
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
# log10(z)->-inf for |z|->0
|
|
reference_numerics_filter=NumericsFilter(condition=lambda x: torch.abs(x) < 0.1, safe_val=1)),
|
|
UnaryUfuncInfo('log2',
|
|
ref=np.log2,
|
|
domain=(0, None),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-1}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
# log2(z)->-inf for |z|->0
|
|
reference_numerics_filter=NumericsFilter(condition=lambda x: torch.abs(x) < 0.1, safe_val=1)),
|
|
BinaryUfuncInfo('ldexp',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_inplace_autograd=False,
|
|
promotes_int_to_float=True,
|
|
supports_out=True,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# RuntimeError: mul(): functions with out=... arguments don't support
|
|
# automatic differentiation, but one of the arguments requires grad
|
|
# https://github.com/pytorch/pytorch/issues/68966
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.complex64: tol(atol=1e-05, rtol=1e-05)
|
|
}),
|
|
'TestCommon', device_type='cpu',
|
|
),
|
|
], ),
|
|
BinaryUfuncInfo('logaddexp',
|
|
dtypes=floating_and_complex_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# TODO: FIXME: RuntimeError: not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion', device_type='cuda'),
|
|
)),
|
|
OpInfo('logaddexp2',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_logaddexp),
|
|
UnaryUfuncInfo('logical_not',
|
|
ref=np.logical_not,
|
|
decorators=(precisionOverride({torch.bfloat16: 7e-1,
|
|
torch.float16: 5e-1}),),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int8, torch.bool),
|
|
supports_autograd=False,
|
|
skips=(
|
|
# The function variant always returns BoolTensor
|
|
# while the inplace variant preserves the input dtype.
|
|
# >>> t = torch.randn(3)
|
|
# >>> torch.logical_not(t)
|
|
# tensor([False, False, False])
|
|
# >>> torch.logical_not(t).dtype
|
|
# torch.bool
|
|
# >>> t.logical_not_().dtype
|
|
# torch.float32
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_variant_consistency',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16)),
|
|
)),
|
|
BinaryUfuncInfo('lt',
|
|
ref=np.less,
|
|
aliases=('less',),
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int8, torch.int32),
|
|
always_returns_bool=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('lu_unpack',
|
|
op=torch.lu_unpack,
|
|
dtypes=floating_and_complex_types(),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(skipCPUIfNoLapack,),
|
|
sample_inputs_func=sample_inputs_lu_unpack),
|
|
OpInfo('lu',
|
|
op=torch.lu,
|
|
dtypes=floating_and_complex_types(),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_lu,
|
|
decorators=[skipCUDAIfNoMagmaAndNoCusolver, skipCPUIfNoLapack],
|
|
skips=(
|
|
# we skip jit tests because `lu` is a torch function
|
|
# RuntimeError:
|
|
# 'Tensor (inferred)' object has no attribute or method 'lu'.:
|
|
# File "<string>", line 3
|
|
# def the_method(i0):
|
|
# return i0.lu(True, True)
|
|
# ~~~~~ <--- HERE
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError not raised: Expected RuntimeError when calling with input.device=cpu and out.device=cuda
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
)),
|
|
OpInfo('lu_solve',
|
|
op=torch.lu_solve,
|
|
dtypes=floating_and_complex_types(),
|
|
supports_forward_ad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_lu_solve,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Tests different backward paths"),
|
|
"TestCommon", "test_floating_inputs_are_differentiable"),),
|
|
decorators=[skipCPUIfNoLapack, skipCUDAIfNoMagmaAndNoCusolver]),
|
|
OpInfo('masked_fill',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int8, torch.bool, torch.int32),
|
|
sample_inputs_func=sample_inputs_masked_fill,
|
|
error_inputs_func=error_inputs_masked_fill,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_out=False),
|
|
OpInfo('masked_scatter',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int8, torch.bool, torch.int32),
|
|
sample_inputs_func=sample_inputs_masked_scatter,
|
|
error_inputs_func=error_inputs_masked_scatter,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
supports_out=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('masked_select',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_masked_select,
|
|
error_inputs_func=error_inputs_masked_select,
|
|
skips=(
|
|
# Compiler issue on ROCm. Might need to skip until ROCm5.5
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], active_if=TEST_WITH_ROCM),
|
|
)),
|
|
OpInfo('matrix_exp',
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
aliases=('linalg.matrix_exp',),
|
|
sample_inputs_func=sample_inputs_matrix_exp,
|
|
# Needs to construct a 2nx2n matrix by copy_ ing into it
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# mexp does not support bf16 and fp16
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestInductorOpInfo', 'test_comprehensive',
|
|
dtypes=[torch.half], device_type="cpu"),
|
|
),
|
|
supports_out=False,
|
|
),
|
|
OpInfo('matmul',
|
|
aliases=('linalg.matmul',),
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16,
|
|
*[torch.bfloat16]
|
|
if SM53OrLater or TEST_WITH_ROCM else []),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
assert_jit_shape_analysis=True,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=partial(sample_inputs_matmul, is_rmatmul=False),
|
|
decorators=[
|
|
# NVIDIA only assures that bfloat16 is supported by bmm if SM >= 5.3
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes', device_type='cuda', active_if=not SM53OrLater),
|
|
# ROCm intermittently fails the test with standard atol/rtol
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-4, rtol=0)}),
|
|
'TestCommon', 'test_noncontiguous_samples', device_type='cuda',
|
|
active_if=TEST_WITH_ROCM),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-4, rtol=0)}),
|
|
'TestCommon', 'test_out', device_type='cuda',
|
|
active_if=TEST_WITH_ROCM),
|
|
# mv for the sample with shapes (S, S, M, M), (M,) has some variance in the
|
|
# backward on CPU
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=0, rtol=1e-5)}),
|
|
'TestCommon', 'test_noncontiguous_samples',
|
|
device_type='cpu'),
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float32: tol(atol=1e-5, rtol=1e-5),
|
|
torch.complex64: tol(atol=1e-5, rtol=1e-5),
|
|
}),
|
|
"TestDecomp", "test_comprehensive", device_type="cuda",
|
|
),
|
|
],
|
|
skips=(
|
|
# Strides are not the same!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# https://github.com/pytorch/pytorch/issues/67470
|
|
DecorateInfo(unittest.skip("67470!"),
|
|
'TestCommon', 'test_noncontiguous_samples',
|
|
device_type='cpu', dtypes=(torch.long,)),
|
|
# AssertionError: False is not true : Tensors failed to compare as equal!
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOpInfo',
|
|
device_type='xla', dtypes=(torch.long,)),
|
|
# https://github.com/pytorch/pytorch/issues/71774
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
device_type='cpu', dtypes=(torch.long,)),
|
|
)),
|
|
OpInfo('max',
|
|
variant_test_name='reduction_with_dim',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
sample_inputs_func=sample_inputs_max_min_reduction_with_dim,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
),
|
|
supports_forward_ad=True),
|
|
OpInfo('max',
|
|
variant_test_name='reduction_no_dim',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_max_min_reduction_no_dim,
|
|
skips=(
|
|
)),
|
|
OpInfo('median',
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
# TODO: some signatures of median do support out
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
error_inputs_func=error_inputs_median,
|
|
sample_inputs_func=partial(sample_inputs_reduction, supports_multiple_dims=False)),
|
|
OpInfo('nanmedian',
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
# TODO: some signatures of nanmedian do support out
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=partial(sample_inputs_reduction, supports_multiple_dims=False)),
|
|
OpInfo('var_mean',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var,
|
|
# TODO: some signatures of var_mean do support out
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.float64: tol(atol=2e-7, rtol=2e-7)}),
|
|
"TestDecomp", "test_comprehensive", device_type="cuda"),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-3, rtol=2e-3)}),
|
|
"TestInductorOpInfo", "test_comprehensive", device_type="cuda"),
|
|
)),
|
|
OpInfo('var_mean',
|
|
variant_test_name='unbiased',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var_unbiased,
|
|
# TODO: some signatures of var_mean do support out
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.float64: tol(atol=2e-7, rtol=2e-7)}),
|
|
"TestDecomp", "test_comprehensive", device_type="cuda"),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-3, rtol=2e-3)}),
|
|
"TestInductorOpInfo", "test_comprehensive", device_type="cuda"),
|
|
)),
|
|
OpInfo('std_mean',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var,
|
|
# TODO: some signatures of std_mean do support out
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.float64: tol(atol=2e-7, rtol=2e-7)}),
|
|
"TestDecomp", "test_comprehensive", device_type="cuda"),
|
|
)),
|
|
OpInfo('std_mean',
|
|
variant_test_name='unbiased',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var_unbiased,
|
|
# TODO: some signatures of var_mean do support out
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=4e-5, rtol=9e-3),
|
|
torch.float64: tol(atol=2e-7, rtol=2e-7),
|
|
}),
|
|
"TestDecomp",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=4e-5, rtol=9e-3),
|
|
torch.float64: tol(atol=2e-7, rtol=2e-7),
|
|
}),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
)),
|
|
OpInfo('meshgrid',
|
|
variant_test_name='variadic_tensors',
|
|
ref=np.meshgrid,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.bool, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_meshgrid, variant='variadic'),
|
|
skips=[
|
|
# JIT does not support variadic tensors.
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":252,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# meshgrid is defined in torch.functional to take a
|
|
# variadic list of tensors. Variadic parameters are not
|
|
# compatible with the normalize operator tests.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Skip operator schema test because this is a functional and not an operator
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
],
|
|
supports_out=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,),
|
|
OpInfo('meshgrid',
|
|
variant_test_name='list_of_tensors',
|
|
# Unlike the variant above, we do not use np.meshgrid as a
|
|
# ref since it does not officially support list of numpy
|
|
# arrays.
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.bool, torch.float16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_meshgrid, variant='list'),
|
|
skips=[
|
|
# meshgrid is defined in torch.functional to take a
|
|
# variadic list of tensors. Variadic parameters are not
|
|
# compatible with the normalize operator tests.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
],
|
|
assert_autodiffed=True,
|
|
supports_out=False,
|
|
autodiff_nonfusible_nodes=[],
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,),
|
|
OpInfo('min',
|
|
variant_test_name='reduction_with_dim',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
sample_inputs_func=sample_inputs_max_min_reduction_with_dim,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
skips=(
|
|
)),
|
|
OpInfo('min',
|
|
variant_test_name='reduction_no_dim',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_max_min_reduction_no_dim,
|
|
skips=(
|
|
)),
|
|
OpInfo('quantile',
|
|
dtypes=floating_types(),
|
|
sample_inputs_func=sample_inputs_reduction_quantile,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
# Relies on copy_ to broadcast, but the forward AD path calls broadcast_to which
|
|
# does not have a batching rule in core
|
|
check_batched_forward_grad=False),
|
|
OpInfo('nanquantile',
|
|
dtypes=floating_types(),
|
|
sample_inputs_func=sample_inputs_reduction_quantile,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
# Relies on copy_ to broadcast, but the forward AD path calls broadcast_to which
|
|
# does not have a batching rule in core
|
|
check_batched_forward_grad=False),
|
|
BinaryUfuncInfo(
|
|
'max',
|
|
aliases=('maximum',),
|
|
variant_test_name='binary',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
ref=np.maximum,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# Incorrectly attempts to use a scalar for the second argument
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_jit_alias_remapping'),
|
|
# TODO: FIXME: RuntimeError: "max_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion', device_type='cuda'),
|
|
)),
|
|
BinaryUfuncInfo(
|
|
'maximum',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
ref=np.maximum,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# TODO: FIXME: RuntimeError: "max_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion', device_type='cuda'),
|
|
)),
|
|
BinaryUfuncInfo(
|
|
'min',
|
|
aliases=('minimum',),
|
|
variant_test_name='binary',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
ref=np.minimum,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# Incorrectly attempts to use a scalar for the second argument
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_jit_alias_remapping'),
|
|
# TODO: FIXME: RuntimeError: "min_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion',
|
|
device_type='cuda'),
|
|
)),
|
|
BinaryUfuncInfo(
|
|
'minimum',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
ref=np.minimum,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# TODO: FIXME: RuntimeError: "min_elementwise_cuda" not implemented for 'ComplexFloat'
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion',
|
|
device_type='cuda'),
|
|
),
|
|
),
|
|
BinaryUfuncInfo('logical_and',
|
|
ref=np.logical_and,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
supports_autograd=False,
|
|
always_returns_bool=True,
|
|
supports_rhs_python_scalar=False),
|
|
BinaryUfuncInfo('logical_or',
|
|
ref=np.logical_or,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int8, torch.bool),
|
|
supports_autograd=False,
|
|
always_returns_bool=True,
|
|
supports_rhs_python_scalar=False),
|
|
BinaryUfuncInfo('logical_xor',
|
|
ref=np.logical_xor,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int8, torch.bool),
|
|
supports_autograd=False,
|
|
always_returns_bool=True,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
)),
|
|
BinaryUfuncInfo('bitwise_and',
|
|
ref=np.bitwise_and,
|
|
dtypes=integral_types_and(torch.bool),
|
|
dtypesIfHpu=custom_types(torch.bool),
|
|
operator_variant=operator.and_,
|
|
inplace_operator_variant=operator.iand,
|
|
supports_autograd=False,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
# RuntimeError: "bitwise_and_cuda" not implemented for 'Half'
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs',
|
|
'test_type_promotion', device_type='cuda'),
|
|
)),
|
|
BinaryUfuncInfo('bitwise_or',
|
|
ref=np.bitwise_or,
|
|
dtypes=integral_types_and(torch.bool),
|
|
dtypesIfHpu=custom_types(torch.bool),
|
|
operator_variant=operator.or_,
|
|
inplace_operator_variant=operator.ior,
|
|
supports_autograd=False,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
# TODO: FIXME: RuntimeError: "bitwise_or_cuda" not implemented for 'Half'
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion',
|
|
device_type='cuda'),
|
|
)),
|
|
BinaryUfuncInfo('bitwise_xor',
|
|
ref=np.bitwise_xor,
|
|
dtypes=integral_types_and(torch.bool),
|
|
dtypesIfHpu=custom_types(torch.bool),
|
|
operator_variant=operator.xor,
|
|
inplace_operator_variant=operator.ixor,
|
|
supports_autograd=False,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
# TODO: FIXME: RuntimeError: "bitwise_xor_cuda" not implemented for 'Half'
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion',
|
|
device_type='cuda'),
|
|
)),
|
|
BinaryUfuncInfo('heaviside',
|
|
ref=lambda a, b: (
|
|
# necessary because np.heaviside incorrectly returns float64 when passed args of dtype int64
|
|
np.int64(np.heaviside(a, b)) if a.dtype == np.int64 and b.dtype == np.int64 else np.heaviside(a, b)
|
|
),
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32),
|
|
supports_autograd=False,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# RuntimeError: heaviside is not yet implemented for tensors with different dtypes.
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
# PyTorch's heaviside does not appear to propagate NaNs
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values'),
|
|
)),
|
|
BinaryUfuncInfo('lcm',
|
|
ref=np.lcm,
|
|
dtypes=integral_types_and(),
|
|
supports_autograd=False,
|
|
supports_rhs_python_scalar=False),
|
|
BinaryUfuncInfo('gcd',
|
|
ref=np.gcd,
|
|
dtypes=integral_types_and(),
|
|
supports_autograd=False,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.int8,)),)),
|
|
BinaryUfuncInfo('isclose',
|
|
ref=np.isclose,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_isclose,
|
|
error_inputs_func=error_inputs_isclose,
|
|
supports_autograd=False,
|
|
supports_out=False,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestCommon',
|
|
'test_numpy_refs', dtypes=(torch.complex128,)),
|
|
# RuntimeError: Short did not match Int
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values'),
|
|
)),
|
|
# `softmax` supports different dtypes based on whether `dtype` argument,
|
|
# is passed or not. Hence two OpInfo entries, one with dtype and other without.
|
|
# https://github.com/pytorch/pytorch/issues/68752
|
|
OpInfo('softmax',
|
|
aliases=('special.softmax', 'nn.functional.softmax',),
|
|
aten_name='softmax',
|
|
aten_backward_name='_softmax_backward_data',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_softmax_variant,
|
|
assert_jit_shape_analysis=True,
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=True),
|
|
OpInfo('softmax',
|
|
aliases=('special.softmax', 'nn.functional.softmax',),
|
|
variant_test_name="with_dtype",
|
|
aten_name='softmax',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_softmax_variant, with_dtype=True),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=True),
|
|
OpInfo(
|
|
'_softmax_backward_data',
|
|
op=torch.ops.aten._softmax_backward_data,
|
|
aten_name='_softmax_backward_data',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_softmax_backward_data,
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples', device_type='cpu'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
),
|
|
),
|
|
# `softmin` supports different dtypes based on whether `dtype` argument,
|
|
# is passed or not. Hence two OpInfo entries, one with dtype and other without.
|
|
# https://github.com/pytorch/pytorch/issues/68752
|
|
OpInfo('nn.functional.softmin',
|
|
aten_name='softmin',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_softmax_variant,
|
|
assert_jit_shape_analysis=False,
|
|
assert_autodiffed=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('nn.functional.softmin',
|
|
variant_test_name="with_dtype",
|
|
aten_name='softmin',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_softmax_variant, with_dtype=True),
|
|
assert_autodiffed=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo(
|
|
"nn.functional.cross_entropy",
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_cross_entropy,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=3e-3, rtol=1e-3)}),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
device_type="cpu",
|
|
),
|
|
),
|
|
skips=(
|
|
# AssertionError: False is not true : Scalars failed to compare as equal! 0 != 1536
|
|
# test_ops.TestJitCUDA.test_variant_consistency_jit_nn_functional_cross_entropy_cuda_float32 leaked
|
|
# 1536 bytes CUDA memory on device 0
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
device_type="cuda",
|
|
),
|
|
DecorateInfo(unittest.skip("FP16 corss_entropy cases have not been enabled on MPS yet"),
|
|
dtypes=(torch.half,), device_type="mps"),
|
|
|
|
)
|
|
),
|
|
OpInfo('nn.functional.normalize',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_normalize,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True),
|
|
OpInfo('aminmax',
|
|
ref=lambda x, dim=None, keepdim=False: (np.amin(x, axis=dim, keepdims=keepdim), np.amax(x, axis=dim, keepdims=keepdim)),
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8),
|
|
decorators=(onlyNativeDeviceTypes,),
|
|
supports_autograd=False,
|
|
sample_inputs_func=sample_inputs_aminmax,
|
|
error_inputs_func=error_inputs_aminmax_amax_amin),
|
|
OpInfo('as_strided',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_as_strided,
|
|
skips=(
|
|
# Note: This xfail is fine -- it's inherent to how as_strided works
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples'),
|
|
# AssertionError: False is not true : Scalars failed to compare as equal!
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"),
|
|
'TestCommon', 'test_variant_consistency_eager'),
|
|
# Not close
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
# Not close
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Numerous errors"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Numerous errors"), 'TestBwdGradients'),
|
|
)),
|
|
OpInfo('as_strided',
|
|
variant_test_name='partial_views',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.int32, torch.int8, torch.bool),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_as_strided_partial_views,
|
|
skips=(
|
|
# Note: This xfail is fine -- it's inherent to how as_strided works
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples'),
|
|
# These fail because the test changes the input's in-memory layout
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_fn_fwgrad_bwgrad',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_inplace_forward_mode_AD'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_inplace_grad'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_inplace_gradgrad'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestProxyTensorOpInfo',
|
|
'test_make_fx_symbolic_exhaustive_inplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
# Fail but are also flaky
|
|
DecorateInfo(unittest.skip("Test changes in memory layout"), 'TestMathBits'),
|
|
DecorateInfo(unittest.skip("Modifies input strides and storage_offset"), 'TestCommon',
|
|
'test_non_standard_bool_values'),
|
|
# RuntimeError: setStorage: sizes [2, 2], strides [1, 2], storage offset 10, and itemsize 2 requiring a
|
|
# storage size of 28 are out of bounds for storage of size 20
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_meta_inplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_meta_inplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_inplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_inplace_all_strides'),
|
|
)),
|
|
OpInfo('as_strided_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_as_strided,
|
|
skips=(
|
|
# Note: This xfail is fine -- it's inherent to how as_strided works
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples'),
|
|
# AssertionError: False is not true : Scalars failed to compare as equal!
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"),
|
|
'TestCommon', 'test_variant_consistency_eager'),
|
|
# Not close
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
# Not close
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Numerous errors"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Numerous errors"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDTensorOps', 'test_dtensor_op_db'),
|
|
)),
|
|
OpInfo('as_strided_scatter',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_as_strided_scatter,
|
|
error_inputs_func=error_inputs_as_strided_scatter,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Works for int64, fails for everything else'), 'TestCommon', 'test_noncontiguous_samples'), # noqa: B950
|
|
DecorateInfo(unittest.skip('Fails in most cases, passes on LAZY for some reason'), 'TestCommon', 'test_variant_consistency_eager'), # noqa: B950
|
|
DecorateInfo(unittest.skip('Fails on cuda + rocm'), 'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_fn_grad'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
DecorateInfo(unittest.skip('Passes on complex128 and float64 only'), 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
# AssertionError: Tensor-likes are not close! (new_empty_strided.default)
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"), 'TestDecomp', 'test_comprehensive'),)),
|
|
OpInfo('native_layer_norm',
|
|
aten_name='native_layer_norm',
|
|
ref=reference_native_layer_norm,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_native_layer_norm,
|
|
error_inputs_func=error_inputs_native_layer_norm,
|
|
skips=(
|
|
# IndexError: tuple index out of range
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# Tests fail when weight=None and bias is defined
|
|
# https://github.com/pytorch/pytorch/issues/79705
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
# JIT test also tries to compute double backward, which fails
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Unsupported on MPS for now"), 'TestCommon', 'test_numpy_ref_mps'),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=2e-03, rtol=5e-03)}),
|
|
"TestDecomp", "test_comprehensive", device_type="cpu"),
|
|
)),
|
|
OpInfo('native_batch_norm',
|
|
aten_name='native_batch_norm',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
allow_cow_input_materialize_forward=[3, 4],
|
|
allow_cow_input_materialize_backward=[3, 4],
|
|
sample_inputs_func=sample_inputs_native_batch_norm,
|
|
skips=(
|
|
# NotImplementedError: Could not run
|
|
# 'aten::native_batch_norm.out' with arguments from the 'CPU' backend.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning', device_type="cpu"),
|
|
# RuntimeError: out_invstd.dim() == 1 && out_invstd.is_contiguous() && out_invstd.sizes()[0]
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type="cuda"),
|
|
# Problem with _get_numerical_jacobian
|
|
# IndexError: tuple index out of range
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# RuntimeError: deepEquals(input.iValue, deepCopiedInput) INTERNAL ASSERT FAILED
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# https://github.com/pytorch/pytorch/issues/85960
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_compare_cpu'),
|
|
# AssertionError: Booleans mismatch: True is not False
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFakeTensor', 'test_fake_autocast'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFakeTensor', 'test_fake'),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=5e-5, rtol=5e-5)}),
|
|
"TestCompositeCompliance", "test_forward_ad"),
|
|
)
|
|
),
|
|
OpInfo('_native_batch_norm_legit',
|
|
aten_name='_native_batch_norm_legit',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
allow_cow_input_materialize_forward=[3, 4],
|
|
allow_cow_input_materialize_backward=[3, 4],
|
|
sample_inputs_func=sample_inputs__native_batch_norm_legit,
|
|
skips=(
|
|
# NotImplementedError: Could not run
|
|
# 'aten::native_batch_norm.out' with arguments from the 'CPU' backend.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning', device_type="cpu"),
|
|
# RuntimeError: out_invstd.dim() == 1 && out_invstd.is_contiguous() && out_invstd.sizes()[0]
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type="cuda"),
|
|
# Problem with _get_numerical_jacobian
|
|
# IndexError: tuple index out of range
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# RuntimeError: deepEquals(input.iValue, deepCopiedInput) INTERNAL ASSERT FAILED
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# https://github.com/pytorch/pytorch/issues/85960
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=5e-5, rtol=5e-5)}),
|
|
"TestCompositeCompliance", "test_forward_ad"),
|
|
)
|
|
),
|
|
OpInfo('_batch_norm_with_update',
|
|
op=torch.ops.aten._batch_norm_with_update,
|
|
aten_name='_batch_norm_with_update',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
allow_cow_input_materialize_forward=[3, 4],
|
|
allow_cow_input_materialize_backward=[3, 4],
|
|
sample_inputs_func=sample_inputs__batch_norm_with_update,
|
|
skips=(
|
|
# NotImplementedError: Could not run
|
|
# 'aten::native_batch_norm.out' with arguments from the 'CPU' backend.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning', device_type="cpu"),
|
|
# RuntimeError: out_invstd.dim() == 1 && out_invstd.is_contiguous() && out_invstd.sizes()[0]
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type="cuda"),
|
|
# Problem with _get_numerical_jacobian
|
|
# IndexError: tuple index out of range
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# RuntimeError: deepEquals(input.iValue, deepCopiedInput) INTERNAL ASSERT FAILED
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=5e-5, rtol=5e-5)}),
|
|
"TestCompositeCompliance", "test_forward_ad"),
|
|
# _batch_norm_with_update expects contiguous inputs for cudnn and miopen
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples', device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestMeta', 'test_dispatch_symbolic_meta_outplace_all_strides', device_type="cuda"),
|
|
# _batch_norm_with_update does not have python bindings
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# aten out variants do not accept out= kwarg, only python out variants
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
)
|
|
),
|
|
OpInfo('nn.functional.cosine_similarity',
|
|
aten_name="cosine_similarity",
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1.3e-5, rtol=2e-2)}),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
],
|
|
sample_inputs_func=sample_inputs_cosine_similarity),
|
|
OpInfo('nn.functional.adaptive_avg_pool1d',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_adaptive_avg_pool1d,
|
|
sample_inputs_func=sample_inputs_adaptive_avg_pool1d),
|
|
OpInfo('nn.functional.adaptive_avg_pool2d',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
decorators=(
|
|
# RuntimeError:
|
|
# adaptive_avg_pool2d(Tensor input, int[2] output_size) -> (Tensor):
|
|
# Expected a value of type 'List[int]' for argument 'output_size' but
|
|
# instead found type 'Tuple[NoneType, int]'. :
|
|
# File "<string>", line 3
|
|
# def the_method(i0):
|
|
# return torch.nn.functional.adaptive_avg_pool2d(i0, (None, 7))
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_adaptive_avg_pool2d,
|
|
sample_inputs_func=sample_inputs_adaptive_avg_pool2d),
|
|
OpInfo('nn.functional.adaptive_avg_pool3d',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
decorators=(
|
|
# RuntimeError:
|
|
# adaptive_avg_pool3d(Tensor input, int[3] output_size) -> (Tensor):
|
|
# Expected a value of type 'List[int]' for argument 'output_size' but
|
|
# instead found type 'Tuple[NoneType, NoneType, NoneType]'. :
|
|
# File "<string>", line 3
|
|
#
|
|
# def the_method(i0):
|
|
# return torch.nn.functional.adaptive_avg_pool3d(i0, (None, None, None))
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
|
|
#
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_adaptive_avg_pool3d,
|
|
sample_inputs_func=sample_inputs_adaptive_avg_pool3d),
|
|
OpInfo('nn.functional.adaptive_max_pool1d',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# got: Batching rule not implemented for aten::flatten.using_ints
|
|
check_batched_forward_grad=False,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_adaptive_max_pool1d,
|
|
sample_inputs_func=sample_inputs_adaptive_max_pool1d),
|
|
OpInfo('nn.functional.adaptive_max_pool2d',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
decorators=(
|
|
# RuntimeError:
|
|
# adaptive_max_pool2d(Tensor input, int[2] output_size) -> (Tensor):
|
|
# Expected a value of type 'List[int]' for argument 'output_size' but
|
|
# instead found type 'Tuple[NoneType, int]'. :
|
|
# File "<string>", line 3
|
|
# def the_method(i0):
|
|
# return torch.nn.functional.adaptive_max_pool2d(i0, (None, 7))
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# got: Batching rule not implemented for aten::flatten.using_ints
|
|
check_batched_forward_grad=False,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_adaptive_max_pool2d,
|
|
sample_inputs_func=sample_inputs_adaptive_max_pool2d),
|
|
OpInfo('nn.functional.adaptive_max_pool3d',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
decorators=(
|
|
# RuntimeError:
|
|
# adaptive_max_pool3d(Tensor input, int[3] output_size) -> (Tensor):
|
|
# Expected a value of type 'List[int]' for argument 'output_size' but
|
|
# instead found type 'Tuple[NoneType, NoneType, NoneType]'. :
|
|
# File "<string>", line 3
|
|
#
|
|
# def the_method(i0):
|
|
# return torch.nn.functional.adaptive_max_pool3d(i0, (None, None, None))
|
|
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ <--- HERE
|
|
#
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# got: Batching rule not implemented for aten::flatten.using_ints
|
|
check_batched_forward_grad=False,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_adaptive_max_pool3d,
|
|
sample_inputs_func=sample_inputs_adaptive_max_pool3d),
|
|
OpInfo('nn.functional.avg_pool1d',
|
|
aten_name='avg_pool1d',
|
|
supports_autograd=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_avg_pool1d,
|
|
sample_inputs_func=sample_inputs_avgpool1d),
|
|
OpInfo('nn.functional.avg_pool3d',
|
|
aten_name='avg_pool3d',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.int64),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_avg_pool3d,
|
|
sample_inputs_func=sample_inputs_avgpool3d,
|
|
skips=(
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type='cpu'),
|
|
)),
|
|
OpInfo(
|
|
"nn.functional.binary_cross_entropy_with_logits",
|
|
aten_name="binary_cross_entropy_with_logits",
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=sample_inputs_binary_cross_entropy_with_logits,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestJit',
|
|
'test_variant_consistency_jit',
|
|
dtypes=(torch.float32,)
|
|
),
|
|
),
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.relu',
|
|
aten_name="relu",
|
|
ref=lambda a: np.where(a <= 0, 0, a),
|
|
supports_autograd=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_nn_activation_relu,
|
|
supports_out=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True),
|
|
OpInfo('nn.functional.conv_transpose1d',
|
|
# `ref` for this function is backward of
|
|
# corresponding `conv*d`
|
|
ref=partial(conv_transpose_ref, fn=torch.nn.functional.conv_transpose1d),
|
|
aten_name='conv_transpose1d',
|
|
aliases=('conv_transpose1d',),
|
|
dtypes=floating_and_complex_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.chalf,
|
|
torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_conv_transpose1d,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-04, rtol=1.3e-06), }),
|
|
'TestCommon', 'test_variant_consistency_eager', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=5e-2, rtol=5e-2), }),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float: tol(atol=1.5e-5, rtol=1.5e-5), }),
|
|
'TestCommon', 'test_numpy_ref_mps'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=1e-3, rtol=5e-3), }),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu'),
|
|
),
|
|
skips=(
|
|
# Reason for Skip: https://github.com/pytorch/pytorch/pull/79694#issuecomment-1186949486
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.complex64,)),
|
|
# RuntimeError: UNSUPPORTED DTYPE: complex
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
# RuntimeError: !lhs.isAliasOf(rhs)INTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":104, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.float,)),
|
|
# RuntimeError: "slow_conv2d_cpu_grad_input" not implemented for 'Long'
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref',
|
|
dtypes=(torch.int64,)),
|
|
),
|
|
supports_out=False,),
|
|
OpInfo('nn.functional.conv_transpose2d',
|
|
aten_name='conv_transpose2d',
|
|
aliases=('conv_transpose2d',),
|
|
# `ref` for this function is backward of
|
|
# corresponding `conv*d`
|
|
ref=partial(conv_transpose_ref, fn=torch.nn.functional.conv_transpose2d),
|
|
dtypes=floating_and_complex_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.chalf,
|
|
torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_conv_transpose2d,
|
|
# Runs very slowly on slow-gradcheck for complex.
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-04, rtol=1.3e-06), }),
|
|
'TestCommon', 'test_variant_consistency_eager', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=2e-05, rtol=5e-05), }),
|
|
'TestCommon', 'test_noncontiguous_samples', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=8e-2, rtol=8e-2), }),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=1e-3, rtol=4e-3), }),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu')],
|
|
skips=(
|
|
# RuntimeError: !lhs.isAliasOf(rhs)INTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":104, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: UNSUPPORTED DTYPE: complex
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
# RuntimeError: "slow_conv2d_cpu_grad_input" not implemented for 'Long'
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref',
|
|
dtypes=(torch.int64,)),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/86356
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref',
|
|
dtypes=(torch.double, torch.cdouble)),
|
|
DecorateInfo(unittest.skip("Unsupported on MPS for now"), 'TestCommon', 'test_numpy_ref_mps'),
|
|
# AssertionError: None mismatch: torch.complex64 is not None
|
|
DecorateInfo(unittest.expectedFailure, 'TestDtypeCustomRules', 'test_custom_rules',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
),
|
|
supports_out=False,),
|
|
OpInfo('nn.functional.conv_transpose3d',
|
|
aten_name='conv_transpose3d',
|
|
aliases=('conv_transpose3d',),
|
|
# `ref` for this function is backward of
|
|
# corresponding `conv*d`
|
|
ref=partial(conv_transpose_ref, fn=torch.nn.functional.conv_transpose3d),
|
|
dtypes=floating_and_complex_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(
|
|
torch.float16, torch.chalf, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_conv_transpose3d,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
# Runs very slowly on slow-gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=5e-2, rtol=5e-2), }),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-04, rtol=1.3e-06),
|
|
torch.complex64: tol(atol=1.3e-04, rtol=1.3e-05)}),
|
|
'TestCommon', 'test_variant_consistency_eager', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=2e-04, rtol=2e-04), }),
|
|
'TestCompositeCompliance', 'test_operator', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1.3e-04, rtol=1.3e-06),
|
|
torch.complex64: tol(atol=1.3e-04, rtol=1.3e-05)}),
|
|
'TestCommon', 'test_noncontiguous_samples', device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-04, rtol=2e-05), }),
|
|
'TestCompositeCompliance', 'test_forward_ad', device_type='cuda',
|
|
active_if=TEST_CUDNN),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-4, rtol=1e-4)}),
|
|
"TestMathBits", "test_conj_view", device_type='cuda'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=9e-2, rtol=9e-2), }),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=9e-3, rtol=2e-1), }),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu')],
|
|
skips=(
|
|
# RuntimeError: !lhs.isAliasOf(rhs)INTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":104, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: "slow_conv3d_cpu_grad_input" not implemented for 'Long'
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref',
|
|
dtypes=(torch.int64,)),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/86356
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref',
|
|
dtypes=(torch.double, torch.cdouble)),
|
|
DecorateInfo(unittest.skip("Unsupported on MPS for now"), 'TestCommon', 'test_numpy_ref_mps'),
|
|
# RuntimeError: UNSUPPORTED DTYPE: complex
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip('Skipped for ROCm!'), 'TestCommon', 'test_complex_half_reference_testing',
|
|
dtypes=[torch.complex32], active_if=TEST_WITH_ROCM),
|
|
),
|
|
supports_out=False,),
|
|
OpInfo('nn.functional.conv1d',
|
|
aliases=('conv1d',),
|
|
aten_name='conv1d',
|
|
dtypes=floating_and_complex_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.chalf,
|
|
torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_conv1d,
|
|
error_inputs_func=error_inputs_conv1d,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=5e-2)}),
|
|
'TestCommon', 'test_complex_half_reference_testing'
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=2e-3, rtol=1e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda',
|
|
),
|
|
),
|
|
skips=(
|
|
# RuntimeError: !lhs.isAliasOf(rhs)INTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":103, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Ref: https://github.com/pytorch/pytorch/issues/75309
|
|
# AssertionError: None mismatch: torch.complex128 is not None
|
|
DecorateInfo(unittest.expectedFailure, 'TestDtypeCustomRules',
|
|
'test_custom_rules', dtypes=(torch.complex64, torch.complex128)),
|
|
# Ref: https://github.com/pytorch/pytorch/issues/75309
|
|
# RuntimeError: UNSUPPORTED DTYPE: complex
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo',
|
|
'test_nnc_correctness', dtypes=(torch.complex64, torch.complex128)),
|
|
),
|
|
supports_expanded_weight=True,
|
|
supports_out=False,),
|
|
OpInfo('nn.functional.conv2d',
|
|
aliases=('conv2d',),
|
|
aten_name='conv2d',
|
|
dtypes=floating_and_complex_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.chalf,
|
|
torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_conv2d),
|
|
error_inputs_func=error_inputs_conv2d,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=6e-2, rtol=5e-2)}),
|
|
'TestCommon', 'test_complex_half_reference_testing',
|
|
),
|
|
),
|
|
skips=(
|
|
# RuntimeError: !lhs.isAliasOf(rhs)INTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":103, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Works on some configs!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Ref: https://github.com/pytorch/pytorch/issues/75309
|
|
# AssertionError: None mismatch: torch.complex128 is not None
|
|
DecorateInfo(unittest.expectedFailure, 'TestDtypeCustomRules',
|
|
'test_custom_rules', dtypes=(torch.complex64, torch.complex128)),
|
|
# RuntimeError: UNSUPPORTED DTYPE: complex
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo',
|
|
'test_nnc_correctness', dtypes=(torch.complex64, torch.complex128)),
|
|
),
|
|
supports_expanded_weight=True,
|
|
supports_out=False,),
|
|
OpInfo('nn.functional.conv3d',
|
|
aliases=('conv3d',),
|
|
aten_name='conv3d',
|
|
dtypes=floating_and_complex_types_and(torch.int64, torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.chalf, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_conv3d,
|
|
error_inputs_func=error_inputs_conv3d,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=6e-2, rtol=5e-2)}),
|
|
'TestCommon', 'test_complex_half_reference_testing',
|
|
),
|
|
# TF32
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=5e-3, rtol=1e-3),
|
|
torch.complex64: tol(atol=5e-3, rtol=1e-3)}),
|
|
'TestCommon', 'test_noncontiguous_samples',
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=5e-5, rtol=5e-6)}),
|
|
'TestMathBits', 'test_conj_view',
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=5e-5, rtol=5e-6)}),
|
|
'TestOperators', 'test_vjpvmap',
|
|
),
|
|
),
|
|
skips=(
|
|
# RuntimeError: !lhs.isAliasOf(rhs) INTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":103, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: UNSUPPORTED DTYPE: complex
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo',
|
|
'test_nnc_correctness', dtypes=(torch.complex64, torch.complex128)),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# break slow tests
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
supports_expanded_weight=True,
|
|
supports_out=False,),
|
|
OpInfo('nn.functional.group_norm',
|
|
aten_name='group_norm',
|
|
aliases=('group_norm',),
|
|
ref=reference_group_norm,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
error_inputs_func=error_inputs_group_norm,
|
|
decorators=[
|
|
# RuntimeError: Cannot insert a Tensor that requires grad as a constant.
|
|
# Consider making it a parameter or input, or detaching the gradient
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=5e-05, rtol=3e-03)}),
|
|
"TestDecomp",
|
|
"test_comprehensive",
|
|
device_type="cpu"
|
|
),
|
|
],
|
|
sample_inputs_func=sample_inputs_group_norm,
|
|
reference_inputs_func=reference_inputs_group_norm,
|
|
supports_expanded_weight=True,),
|
|
OpInfo('nn.functional.instance_norm',
|
|
# no ref because instance_norm will often have numerical instability (large numbers or nan)
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
allow_cow_input_materialize_forward=['running_mean', 'running_var'],
|
|
decorators=[
|
|
# RuntimeError: Cannot insert a Tensor that requires grad as a constant.
|
|
# Consider making it a parameter or input, or detaching the gradient
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
],
|
|
sample_inputs_func=sample_inputs_instance_norm,
|
|
supports_expanded_weight=True,),
|
|
OpInfo('nn.functional.layer_norm',
|
|
aten_name='layer_norm',
|
|
aten_backward_name='layer_norm_backward',
|
|
aliases=('layer_norm',),
|
|
ref=reference_layer_norm,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-05, rtol=1e-03)}),
|
|
'TestCommon', 'test_numpy_refs'
|
|
),
|
|
DecorateInfo(unittest.skip("Bug in MPS backend!"), 'TestCommon', 'test_numpy_ref_mps'),
|
|
],
|
|
sample_inputs_func=sample_inputs_layer_norm,
|
|
supports_expanded_weight=True,),
|
|
OpInfo('nn.functional.rms_norm',
|
|
aten_name='rms_norm',
|
|
aliases=('rms_norm',),
|
|
ref=reference_rms_norm,
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_rms_norm,
|
|
error_inputs_func=error_inputs_rms_norm,),
|
|
OpInfo('nn.functional.local_response_norm',
|
|
dtypes=floating_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=[
|
|
# RuntimeError: falseINTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
],
|
|
sample_inputs_func=sample_inputs_local_response_norm,),
|
|
OpInfo('constant_pad_nd',
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half),
|
|
sample_inputs_func=sample_inputs_constant_pad_nd,
|
|
supports_out=False,
|
|
skips=(
|
|
# bool can't be passed to Scalar arguments in JIT tracer because
|
|
# BoolType is not a subtype of ScalarType.
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestNNCOpInfo',
|
|
'test_nnc_correctness', dtypes=(torch.bool,)),
|
|
)),
|
|
OpInfo('nn.functional.pad',
|
|
variant_test_name='constant',
|
|
aten_name='constant_pad_nd',
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half),
|
|
sample_inputs_func=partial(sample_inputs_nn_pad, mode='constant'),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.pad',
|
|
variant_test_name='reflect',
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half),
|
|
sample_inputs_func=partial(sample_inputs_nn_pad, mode='reflect'),
|
|
skips=(
|
|
# Doesn't have a corresponding aten operator.
|
|
# RuntimeError: falseINTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_out=False),
|
|
OpInfo('nn.functional.pad',
|
|
variant_test_name='replicate',
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_nn_pad, mode='replicate'),
|
|
skips=(
|
|
# Doesn't have a corresponding aten operator.
|
|
# RuntimeError: falseINTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_out=False),
|
|
OpInfo('nn.functional.pad',
|
|
variant_test_name='replicate_negative',
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_nn_pad_replicate_negative,
|
|
skips=(
|
|
# Doesn't have a corresponding aten operator.
|
|
# RuntimeError: falseINTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
# Some negative padding cases cause a segfault on MPS
|
|
DecorateInfo(unittest.skip("Not fully supported on MPS"), 'TestConsistency'),
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_out=False),
|
|
OpInfo('nn.functional.pad',
|
|
variant_test_name='circular',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half),
|
|
sample_inputs_func=partial(sample_inputs_nn_pad, mode='circular'),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_grad=False,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# Doesn't have a corresponding aten operator.
|
|
# RuntimeError: falseINTERNAL ASSERT FAILED at
|
|
# "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
# Difference from <type> is larger with decomposition new_empty_strided.default than original on output 0
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"), 'TestDecomp', 'test_comprehensive'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.hardswish',
|
|
aten_name="hardswish",
|
|
aten_backward_name='hardswish_backward',
|
|
supports_autograd=True,
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=sample_inputs_hardswish,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_gradgrad=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
autodiff_nonfusible_nodes=["aten::hardswish"]),
|
|
OpInfo('nn.functional.unfold',
|
|
aten_name='im2col',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16, torch.bool),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16, torch.bool),
|
|
sample_inputs_func=sample_inputs_nn_unfold,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
skips=(
|
|
# NOTE: this failure may not reproduce consistently on different systems
|
|
# false INTERNAL ASSERT FAILED at "...torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185
|
|
DecorateInfo(unittest.skip("Internal assert failed!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='nearest',
|
|
supports_autograd=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
dtypes=floating_types_and(torch.uint8, torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'nearest'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='nearest-exact',
|
|
supports_autograd=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16, torch.uint8),
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'nearest-exact'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: aten::_upsample_nearest_exact*d hit the vmap fallback which is currently disabled
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperators', 'test_vmapjvpall_has_batch_rule'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperators', 'test_vmapvjp_has_batch_rule'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestVmapOperatorsOpInfo', 'test_op_has_batch_rule'),
|
|
# NotImplementedError: The operator 'aten::_upsample_nearest_exact3d.out' is not currently implemented
|
|
# for the MPS device.
|
|
DecorateInfo(unittest.expectedFailure, 'TestConsistency'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='linear',
|
|
supports_autograd=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'linear'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='bilinear',
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
dtypes=floating_types_and(torch.uint8, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'bilinear'),
|
|
reference_inputs_func=partial(reference_inputs_interpolate, 'bilinear'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='bicubic',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.uint8, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'bicubic'),
|
|
reference_inputs_func=partial(reference_inputs_interpolate, 'bicubic'),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='trilinear',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'trilinear'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.interpolate',
|
|
aten_name="interpolate",
|
|
variant_test_name='area',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=partial(sample_inputs_interpolate, 'area'),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('nn.functional.upsample_bilinear',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.uint8, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=partial(sample_inputs_upsample, 'bilinear'),
|
|
reference_inputs_func=partial(reference_inputs_upsample, 'bilinear'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo('_upsample_bilinear2d_aa',
|
|
op=torch.ops.aten._upsample_bilinear2d_aa,
|
|
aten_name='_upsample_bilinear2d_aa',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.uint8),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=partial(sample_inputs_upsample_aa, 'bilinear'),
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDTensorOps', 'test_dtensor_op_db'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestEagerFusionOpInfo', 'test_aot_autograd_symbolic_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestInductorOpInfo', 'test_comprehensive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
OpInfo(
|
|
"nn.functional.soft_margin_loss",
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
# doesn't support grad on target
|
|
sample_inputs_func=partial(sample_inputs_loss, rhs_requires_grad=False),
|
|
error_inputs_func=error_inputs_soft_margin_loss,
|
|
),
|
|
OpInfo('nn.functional.upsample_nearest',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.uint8, torch.half, torch.bfloat16),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=partial(sample_inputs_upsample, 'nearest'),
|
|
skips=(
|
|
# RuntimeError: false
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":185,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
supports_out=False),
|
|
OpInfo(
|
|
"nn.functional.margin_ranking_loss",
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_margin_ranking_loss,
|
|
error_inputs_func=error_inputs_margin_ranking_loss,
|
|
reference_inputs_func=reference_inputs_margin_ranking_loss,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True),
|
|
OpInfo(
|
|
"nn.functional.multi_margin_loss",
|
|
dtypes=floating_types(),
|
|
dtypesIfCUDA=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
sample_inputs_func=sample_inputs_multi_margin_loss,
|
|
reference_inputs_func=reference_inputs_multi_margin_loss,
|
|
error_inputs_func=error_inputs_multi_margin_loss,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-4, rtol=1e-4)}),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.multilabel_margin_loss",
|
|
dtypes=floating_types(),
|
|
dtypesIfCUDA=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
sample_inputs_func=sample_inputs_multilabel_margin_loss,
|
|
reference_inputs_func=reference_inputs_multilabel_margin_loss,
|
|
error_inputs_func=error_inputs_multilabel_margin_loss,
|
|
),
|
|
OpInfo('nn.functional.leaky_relu',
|
|
aliases=None,
|
|
aten_name="leaky_relu",
|
|
aten_backward_name='leaky_relu_backward',
|
|
sample_inputs_func=sample_inputs_leaky_relu,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
inplace_variant=lambda x, negative_slope=0.01:
|
|
torch.nn.functional.leaky_relu(x, negative_slope, inplace=True),
|
|
supports_autograd=True,
|
|
assert_autodiffed=True,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=["aten::leaky_relu"]),
|
|
OpInfo(
|
|
"nn.functional.multilabel_soft_margin_loss",
|
|
supports_out=False,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_multilabel_soft_margin_loss,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-4, rtol=1e-4)}),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=4e-3, rtol=1.3e-3)}),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
),
|
|
skips=(
|
|
# AssertionError: False is not true : Scalars failed to compare as equal! 0 != 4096
|
|
# __main__.TestJitCUDA.test_variant_consistency_jit_nn_functional_multilabel_soft_margin_loss_cuda_float32
|
|
# leaked 4096 bytes CUDA memory on device 0
|
|
DecorateInfo(
|
|
# Skip instead of expectedFailure because this fails
|
|
# locally for me but passes in CI.
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
device_type="cuda",
|
|
),
|
|
),
|
|
),
|
|
OpInfo('nn.functional.avg_pool2d',
|
|
aten_name='avg_pool2d',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.int64, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
error_inputs_func=error_inputs_avg_pool2d,
|
|
sample_inputs_func=sample_inputs_avgpool2d,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type='cuda'),
|
|
)),
|
|
OpInfo('nn.functional.fractional_max_pool2d',
|
|
supports_autograd=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.fractional_max_pool2d, input, *args, **kwargs),
|
|
# vmap does not support random operations
|
|
check_batched_forward_grad=False,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
test_neg_view=False,
|
|
sample_inputs_func=sample_inputs_fractional_max_pool2d,
|
|
decorators=(
|
|
# FIXME: AssertionError: False is not true : Tensors failed to compare as equal!
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit')),
|
|
skips=(
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),)),
|
|
OpInfo('nn.functional.fractional_max_pool3d',
|
|
supports_autograd=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.fractional_max_pool3d, input, *args, **kwargs),
|
|
# vmap does not support random operations
|
|
check_batched_forward_grad=False,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
test_neg_view=False,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
sample_inputs_func=sample_inputs_fractional_max_pool3d,
|
|
decorators=(
|
|
# FIXME: both derivatives are implemented incorrectly
|
|
# https://github.com/pytorch/pytorch/issues/69322
|
|
# FIXME: AssertionError: False is not true : Tensors failed to compare as equal!
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit')),
|
|
skips=(
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),)),
|
|
OpInfo('nn.functional.max_pool1d',
|
|
aten_name='max_pool1d',
|
|
supports_autograd=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# got: Batching rule not implemented for aten::flatten.using_ints
|
|
check_batched_forward_grad=False,
|
|
# TODO: add shape checks
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# Pre-existing condition; Needs to be fixed
|
|
DecorateInfo(unittest.skip("Works on some configs"), 'TestNNCOpInfo',
|
|
'test_nnc_correctness', dtypes=(torch.bfloat16,)),
|
|
# RuntimeError: The tensor has a non-zero number of elements, but its data is not allocated yet.
|
|
# Caffe2 uses a lazy allocation, so you will need to call mutable_data() or raw_mutable_data()
|
|
# to actually allocate memory
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestTags', 'test_tags'),
|
|
),
|
|
error_inputs_func=error_inputs_max_pool1d,
|
|
sample_inputs_func=sample_inputs_max_pool),
|
|
OpInfo('nn.functional.max_pool2d',
|
|
aten_name='max_pool2d',
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
# Vmap is not happy with non-contiguous (channels_last) inputs
|
|
check_batched_gradgrad=False,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# got: Batching rule not implemented for aten::flatten.using_ints
|
|
check_batched_forward_grad=False,
|
|
assert_jit_shape_analysis=True,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
error_inputs_func=error_inputs_max_pool2d,
|
|
sample_inputs_func=sample_inputs_max_pool),
|
|
OpInfo('max_pool2d_with_indices_backward',
|
|
op=max_pool2d_backward,
|
|
# We've defined a custom op, so there's no corresponding aten op
|
|
aten_name=None,
|
|
method_variant=None,
|
|
inplace_variant=None,
|
|
operator_variant=None,
|
|
inplace_operator_variant=None,
|
|
check_batched_gradgrad=False,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_max_pool,
|
|
skips=(
|
|
# We've defined a custom op here, and we don't handle the case where we receive an out kwarg
|
|
DecorateInfo(unittest.skip("Skipped!"), "TestCommon", "test_out"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# object has no attribute max_pool2d_with_indices_backward (It's not available on torch -- so expected)
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit')
|
|
)),
|
|
OpInfo('nn.functional.max_pool3d',
|
|
aten_name='max_pool3d',
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# got: Batching rule not implemented for aten::flatten.using_ints
|
|
check_batched_forward_grad=False,
|
|
# TODO: add shape checks
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
# TODO: investigate nondeterminism
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
error_inputs_func=error_inputs_max_pool3d,
|
|
sample_inputs_func=sample_inputs_max_pool),
|
|
OpInfo('nn.functional.max_unpool1d',
|
|
aten_name='max_unpool1d',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_max_unpool,
|
|
skips=(
|
|
# Gradients are tested in `variant_test_name=grad` below.
|
|
# We skip tests here because there is non-determinism in backward
|
|
# with gather, when there are writes into the same memory location,
|
|
# and if there are several indices pointing to the same memory,
|
|
# gradcheck is oblivious about that and cannot perturb them all at once
|
|
# (see sample_inputs_max_unpool_grad to find out more).
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_grad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD',
|
|
active_if=(not IS_MACOS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_forward_ad',
|
|
device_type='cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_quick_core_backward'),
|
|
)),
|
|
OpInfo('nn.functional.max_unpool1d',
|
|
variant_test_name='grad',
|
|
aten_name='max_unpool1d',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_max_unpool_grad),
|
|
OpInfo('nn.functional.max_unpool2d',
|
|
aten_name='max_unpool2d',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_max_unpool,
|
|
skips=(
|
|
# Gradients are tested in `variant_test_name=grad` below.
|
|
# We skip tests here because there is non-determinism in backward
|
|
# with gather, when there are writes into the same memory location,
|
|
# and if there are several indices pointing to the same memory,
|
|
# gradcheck is oblivious about that and cannot perturb them all at once
|
|
# (see sample_inputs_max_unpool_grad to find out more).
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD',
|
|
active_if=(not IS_MACOS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_grad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_forward_ad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_quick_core_backward'),
|
|
)),
|
|
OpInfo('nn.functional.max_unpool2d',
|
|
variant_test_name='grad',
|
|
aten_name='max_unpool2d',
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# Vmap is not happy with non-contiguous (channels_last) inputs
|
|
check_batched_grad=False,
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_max_unpool_grad),
|
|
OpInfo('nn.functional.max_unpool3d',
|
|
aten_name='max_unpool3d',
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_max_unpool,
|
|
skips=(
|
|
# Gradients are tested in `variant_test_name=grad` below.
|
|
# We skip tests here because there is non-determinism in backward
|
|
# with gather, when there are writes into the same memory location,
|
|
# and if there are several indices pointing to the same memory,
|
|
# gradcheck is oblivious about that and cannot perturb them all at once
|
|
# (see sample_inputs_max_unpool_grad to find out more).
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD',
|
|
active_if=(not IS_MACOS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_grad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_forward_ad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_quick_core_backward'),
|
|
)),
|
|
OpInfo('nn.functional.max_unpool3d',
|
|
variant_test_name='grad',
|
|
aten_name='max_unpool3d',
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
assert_jit_shape_analysis=False,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_max_unpool_grad),
|
|
OpInfo('nn.functional.linear',
|
|
aten_name='linear',
|
|
supports_autograd=True,
|
|
supports_gradgrad=True,
|
|
sample_inputs_func=sample_inputs_linear,
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfROCM=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
# linear calls mm under the hood which is nondeterministic on CUDA
|
|
# https://pytorch.org/docs/stable/generated/torch.use_deterministic_algorithms.html#torch.use_deterministic_algorithms
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
supports_expanded_weight=True,
|
|
decorators=(
|
|
# Strides are not the same!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
)),
|
|
OpInfo('nn.functional.bilinear',
|
|
aten_name='bilinear',
|
|
supports_autograd=True,
|
|
sample_inputs_func=sample_inputs_bilinear,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16,
|
|
*[torch.bfloat16] if SM53OrLater or TEST_WITH_ROCM else []),
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=2e-03, rtol=1.3e-03)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu'),
|
|
),
|
|
skips=(
|
|
# NVIDIA only assures that bfloat16 is supported by bmm if SM >= 5.3
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes', device_type='cuda', active_if=not SM53OrLater),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness', dtypes=(torch.bfloat16,)),
|
|
),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('nn.functional.glu',
|
|
aten_name='glu',
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
sample_inputs_func=sample_inputs_glu,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.elu',
|
|
aten_backward_name='elu_backward',
|
|
ref=lambda x, alpha=1.0, inplace=False:
|
|
np.maximum(0., x) + np.minimum(0., alpha * (np.exp(x) - 1)),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
sample_kwargs=lambda device, dtype, input:
|
|
({'alpha': 0.8}, {'alpha': 0.8}),
|
|
inplace_variant=lambda x, alpha=1.0:
|
|
torch.nn.functional.elu(x, alpha, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-03, rtol=1.2e-03),
|
|
torch.bfloat16: tol(atol=1e-03, rtol=1.2e-03)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
),
|
|
# Marked as a Unary function because it has some rather odd broadcasting semantics in its
|
|
# second argument
|
|
UnaryUfuncInfo(
|
|
'nn.functional.prelu',
|
|
aten_backward_name='_prelu_kernel_backward',
|
|
ref=lambda x, weight:
|
|
np.maximum(0., x) + np.minimum(0., x) *
|
|
(weight if x.ndim == 1 else weight.reshape([weight.size if i == 1 else 1 for i in range(0, x.ndim)])),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
# test_reference_numerics only tests the case when the weight tensor is a scalar
|
|
sample_kwargs=sample_kwargs_prelu_scalar_weight,
|
|
error_inputs_func=error_inputs_prelu,
|
|
sample_inputs_func=sample_inputs_prelu,
|
|
reference_inputs_func=reference_inputs_prelu,
|
|
decorators=[
|
|
# RuntimeError: Cannot insert a Tensor that requires grad as a constant.
|
|
# Consider making it a parameter or input, or detaching the gradient
|
|
# https://github.com/pytorch/pytorch/issues/68752
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'), ],
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.celu',
|
|
ref=lambda x, alpha=1.0, inplace=False:
|
|
np.maximum(0., x) + np.minimum(0., alpha * (np.exp(x / alpha) - 1)),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
sample_kwargs=lambda device, dtype, input:
|
|
({'alpha': 0.8}, {'alpha': 0.8}),
|
|
inplace_variant=lambda x, alpha=1.0:
|
|
torch.nn.functional.celu(x, alpha, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-03, rtol=1.2e-03),
|
|
torch.bfloat16: tol(atol=1e-03, rtol=1.2e-03)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.rrelu',
|
|
aten_backward_name='rrelu_with_noise_backward',
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.rrelu, input, *args, **kwargs),
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.rrelu, input, *args, inplace=True, **kwargs),
|
|
dtypes=floating_types_and(torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
gradcheck_wrapper=wrapper_set_seed,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
sample_kwargs=lambda device, dtype, input:
|
|
(dict(lower=0., upper=1., training=True), dict(lower=0., upper=1., training=True)),
|
|
sample_inputs_func=sample_inputs_rrelu,
|
|
error_inputs_func=error_inputs_rrelu,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-03, rtol=1.2e-03),
|
|
torch.bfloat16: tol(atol=1e-03, rtol=1.2e-03)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
),),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# In-place operations do not play well with forward AD
|
|
# https://github.com/pytorch/pytorch/issues/77447
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients',
|
|
'test_inplace_forward_mode_AD'),
|
|
# The noise vector that's generated in these tests is not the same elementwise
|
|
DecorateInfo(unittest.skip("Different noise"), 'TestUnaryUfuncs', 'test_batch_vs_slicing'),
|
|
DecorateInfo(unittest.skip("Different noise"), 'TestUnaryUfuncs', 'test_contig_vs_every_other'),
|
|
DecorateInfo(unittest.skip("Different noise"), 'TestUnaryUfuncs', 'test_non_contig_expand'),
|
|
DecorateInfo(unittest.skip("Different noise"), 'TestUnaryUfuncs', 'test_contig_vs_transposed'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu')),
|
|
skip_correctness_check_compile_vs_eager=True,
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.selu',
|
|
ref=lambda x, inplace=False:
|
|
1.0507009873554804934193349852946 * (
|
|
np.maximum(0., x) + np.minimum(0., 1.6732632423543772848170429916717 * (np.exp(x) - 1))
|
|
),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True, # depends on 'elu'
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
inplace_variant=lambda x: torch.nn.functional.selu(x, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-2, rtol=1.8e-2),
|
|
torch.bfloat16: tol(atol=1e-2, rtol=1.8e-2)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
),
|
|
OpInfo(
|
|
'torch._scaled_mm',
|
|
sample_inputs_func=sample_inputs_scaled_mm,
|
|
dtypes=empty_types(),
|
|
dtypesIfCUDA=empty_types() + (torch.float8_e4m3fn,),
|
|
supports_out=True,
|
|
supports_forward_ad=False,
|
|
supports_autograd=False,
|
|
decorators=[skipCUDAIf(not SM90OrLater or TEST_WITH_ROCM, 'Requires CUDA SM >= 9.0')],
|
|
skips=(
|
|
# Sample inputs isn't really parametrized on dtype
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes',
|
|
device_type='cuda'),
|
|
# "mul_cuda" not implemented for float8_e4m3fn
|
|
# https://github.com/pytorch/pytorch/issues/107256
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestSchemaCheckModeOpInfo', 'test_schema_correctness',
|
|
dtypes=(torch.float8_e4m3fn,)),
|
|
)
|
|
),
|
|
OpInfo(
|
|
'torch.ops.aten._safe_softmax.default',
|
|
dtypes=all_types_and(torch.half, torch.bfloat16, torch.bool),
|
|
sample_inputs_func=sample_inputs_safe_softmax,
|
|
assert_jit_shape_analysis=True,
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
supports_cow_input_no_materialize_backward=False,
|
|
decorators=[],
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
),
|
|
OpInfo(
|
|
'nn.functional.scaled_dot_product_attention',
|
|
op=lambda *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.scaled_dot_product_attention, *args, **kwargs),
|
|
sample_inputs_func=sample_inputs_scaled_dot_product_attention,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
decorators=[DecorateInfo(toleranceOverride(
|
|
{torch.float32: tol(atol=5e-05, rtol=5e-6)}), 'TestCommon',), ],
|
|
skips=(
|
|
# When attn mask is a composite tensor this fails backward by returning a none
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_backward', device_type='cuda'),
|
|
# This is only failing on Linux Bionic 3.10 Cuda 11.6
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes',
|
|
device_type='cuda', active_if=_get_torch_cuda_version() >= (11, 6)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples',
|
|
dtypes=(torch.float32,)),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Forward works for dtype=float64 which is the math path
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
# Not implemented for Forward AD
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_fn_fwgrad_bwgrad',
|
|
device_type='cpu'),
|
|
# Not implemented for backward derivative
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients', 'test_fn_gradgrad',
|
|
device_type='cpu'),
|
|
# CPU and CUDA have inconsistencies for intermediate outputs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_meta_outplace',
|
|
device_type='cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_symbolic_meta_outplace',
|
|
device_type='cpu'),
|
|
# When changing input from Tensor to CompositeCompliantTensor, input.requires_grad() changes from true to false
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_backward',
|
|
device_type='cpu'),
|
|
# OpInfo was implemented with a lambda
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# TODO Need to understand what this is testing and why it doesn't work
|
|
DecorateInfo(unittest.skip("Skipped"), 'TestDecomp', 'test_comprehensive'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic (when dropout_p > 0)'), 'TestCommon', 'test_compare_cpu'),
|
|
# TODO skip this for now since we can't skip on runtime arch support
|
|
DecorateInfo(unittest.skip('This is '), 'TestInductorOpInfo', 'test_comprehensive'),
|
|
# skip for sm < 80
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestSchemaCheckModeOpInfo', 'test_schema_correctness',
|
|
device_type='cuda', dtypes=(torch.bfloat16,), active_if=not SM80OrLater),
|
|
# FIXME
|
|
DecorateInfo(unittest.skip('test_cow_input does not work with efficient attention on ROCM'),
|
|
'TestCompositeCompliance', 'test_cow_input',
|
|
device_type='cuda', dtypes=(torch.bfloat16, torch.float16, torch.float32),
|
|
active_if=TEST_WITH_ROCM and PLATFORM_SUPPORTS_MEM_EFF_ATTENTION),
|
|
DecorateInfo(unittest.skip('test_fake_crossref_backward_amp does not work with efficient attention on ROCM'),
|
|
'TestFakeTensor', 'test_fake_crossref_backward_amp',
|
|
device_type='cuda', dtypes=(torch.bfloat16, torch.float16, torch.float32),
|
|
active_if=TEST_WITH_ROCM and PLATFORM_SUPPORTS_MEM_EFF_ATTENTION),
|
|
DecorateInfo(unittest.skip('test_fake_crossref_backward_no_amp does not work with efficient attention on ROCM'),
|
|
'TestFakeTensor', 'test_fake_crossref_backward_no_amp',
|
|
device_type='cuda', dtypes=(torch.bfloat16, torch.float16, torch.float32),
|
|
active_if=TEST_WITH_ROCM and PLATFORM_SUPPORTS_MEM_EFF_ATTENTION),
|
|
# for element 1, was torch.Size([4, 4, 0]) but real shape was torch.Size([16, 3, 0])
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_meta_outplace", device_type="cuda",
|
|
dtypes=[torch.float16, torch.bfloat16, torch.float32],
|
|
active_if=TEST_WITH_ROCM and PLATFORM_SUPPORTS_FLASH_ATTENTION),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace", device_type="cuda",
|
|
dtypes=[torch.float16, torch.bfloat16, torch.float32],
|
|
active_if=TEST_WITH_ROCM and PLATFORM_SUPPORTS_FLASH_ATTENTION),
|
|
# for element 1, was torch.Size([4, 4, 11]) but real shape was torch.Size([16, 11])
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides",
|
|
device_type="cuda", dtypes=[torch.float32],
|
|
active_if=TEST_WITH_ROCM and PLATFORM_SUPPORTS_FLASH_ATTENTION),),
|
|
),
|
|
OpInfo(
|
|
'torch.ops.aten._flash_attention_forward',
|
|
sample_inputs_func=sample_inputs_flash_attention_forward,
|
|
dtypes=empty_types(),
|
|
dtypesIfCUDA=custom_types(torch.float16)
|
|
if not SM80OrLater
|
|
else custom_types(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=True,
|
|
supports_fwgrad_bwgrad=False,
|
|
supports_forward_ad=False,
|
|
check_batched_forward_grad=False,
|
|
decorators=[skipCUDAIf(not PLATFORM_SUPPORTS_FLASH_ATTENTION, "This platform doesn't support Flash Attention")],
|
|
skips=(
|
|
# Checking the scalar value of the philox seed and offset
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_operator', device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples', device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', device_type='cuda'),
|
|
# None Mismatch Tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_backward', device_type='cuda'),
|
|
)
|
|
),
|
|
OpInfo(
|
|
'torch.ops.aten._efficient_attention_forward',
|
|
sample_inputs_func=sample_inputs_efficient_attention_forward,
|
|
dtypes=empty_types(),
|
|
dtypesIfCUDA=custom_types(torch.float16, torch.float32)
|
|
if not SM80OrLater
|
|
else custom_types(torch.float16, torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=True,
|
|
supports_fwgrad_bwgrad=False,
|
|
supports_forward_ad=False,
|
|
check_batched_forward_grad=False,
|
|
# TODO: Skip because it produces a CUDA illegal memory access for some reason
|
|
skip_cow_input_backward=True,
|
|
# FIXME: mask_type == 2 (LowerRight)
|
|
decorators=[
|
|
skipCUDAIf(not PLATFORM_SUPPORTS_MEM_EFF_ATTENTION, "This platform doesn't support efficient attention"),
|
|
skipCUDAIf(TEST_WITH_ROCM, "Efficient attention on ROCM doesn't support custom_mask_type==2")],
|
|
skips=(
|
|
# Checking the scaler value of the philox seed and offset
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_operator', device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_noncontiguous_samples', device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', device_type='cuda'),
|
|
# None Mismatch Tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_backward', device_type='cuda'),
|
|
)
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.silu',
|
|
aten_backward_name='silu_backward',
|
|
ref=lambda x, inplace=False: x / (1 + np.exp(-x)),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_autograd=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
supports_out=False,
|
|
inplace_variant=lambda x: torch.nn.functional.silu(x, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-3, rtol=1e-3),
|
|
torch.bfloat16: tol(atol=1e-4, rtol=1e-4)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
dtypes=(torch.cfloat,), device_type='cpu'),
|
|
),
|
|
autodiff_nonfusible_nodes=["aten::silu"],
|
|
),
|
|
# TODO: combine this with the nn.functional.silu OpInfo when
|
|
# complex autodiff for silu is supported or when
|
|
# the forward bug is fixed
|
|
# Note: silu errors when given inputs that require grad
|
|
# but it doesn't support grad in their dtype
|
|
# This is why the dtypes list above passes test_dtypes,
|
|
# because it's getting lucky and failing in forward
|
|
# because test_dtypes sets requires_grad to True
|
|
# THIS IS A BUG
|
|
UnaryUfuncInfo(
|
|
'nn.functional.silu',
|
|
variant_test_name='complex',
|
|
ref=lambda x, inplace=False:
|
|
x / (1 + np.exp(-x)),
|
|
dtypes=complex_types(),
|
|
dtypesIfCUDA=complex_types(),
|
|
supports_forward_ad=False,
|
|
supports_autograd=False,
|
|
assert_autodiffed=False,
|
|
supports_out=False,
|
|
inplace_variant=lambda x: torch.nn.functional.silu(x, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-3, rtol=1e-3),
|
|
torch.bfloat16: tol(atol=1e-4, rtol=1e-4)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
dtypes=(torch.cfloat,)),
|
|
# FIXME: intentionally misreports dtypes
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_dtypes'),
|
|
# FIXME: numpy reference diverges: Comparing (nan+nanj) and (-0+0j)
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.complex64, torch.cdouble)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
dtypes=(torch.complex64,)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=(torch.complex64,)))),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.hardsigmoid',
|
|
aten_backward_name='hardsigmoid_backward',
|
|
ref=reference_hardsigmoid,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_out=False,
|
|
inplace_variant=partial(torch.nn.functional.hardsigmoid, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-04, rtol=0.001)}), 'TestUnaryUfuncs', device_type='cuda',), ],
|
|
skips=[
|
|
# still want to test that first derivative works though second derivative isn't supported
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', "test_inplace_gradgrad"),
|
|
# produces 0 instead of nan on ROCM
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestUnaryUfuncs', "test_reference_numerics_extremal",
|
|
device_type='cuda',
|
|
active_if=(TEST_WITH_ROCM)), ]
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.logsigmoid',
|
|
aten_name="log_sigmoid",
|
|
aten_backward_name='log_sigmoid_backward',
|
|
ref=reference_logsigmoid,
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_gradgrad=True,
|
|
# autodiff_nonfusible_nodes=["aten::log_sigmoid"],
|
|
decorators=[
|
|
DecorateInfo(
|
|
precisionOverride({torch.float16: 1e-2, torch.bfloat16: 5e-3}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_small'),
|
|
DecorateInfo(
|
|
precisionOverride({torch.float16: 1e-2, torch.bfloat16: 5e-3}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_large'),
|
|
DecorateInfo(
|
|
precisionOverride({torch.float16: 1e-2, torch.bfloat16: 5e-3}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal'),
|
|
],
|
|
skips=(
|
|
# Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning', device_type='cpu'),
|
|
),
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.mish',
|
|
aten_backward_name='mish_backward',
|
|
ref=lambda x: x * np.tanh(reference_softplus(x)),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
inplace_variant=partial(torch.nn.functional.mish, inplace=True),
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-02, rtol=1e-03)}), 'TestUnaryUfuncs',), ],
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.softsign',
|
|
ref=lambda x: x / (np.abs(x) + 1),
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.float16, torch.bfloat16, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-03, rtol=1.3e-04)}), 'TestUnaryUfuncs',), ],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
dtypes=(torch.int, torch.int8)),),
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.tanhshrink',
|
|
ref=lambda x: x - np.tanh(x),
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
decorators=[
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.bfloat16: tol(atol=1e-02, rtol=1.6e-02)}), 'TestUnaryUfuncs',),
|
|
DecorateInfo(toleranceOverride({torch.complex64: tol(atol=6e-04, rtol=1e-05),
|
|
torch.bfloat16: tol(atol=1e-02, rtol=1.6e-02)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal', device_type='cuda'),
|
|
],
|
|
skips=(
|
|
# in each case, pytorch will produce a nan while numpy will not
|
|
DecorateInfo(unittest.skip("Fails on some jobs works on others!"),
|
|
'TestUnaryUfuncs', "test_reference_numerics_large",
|
|
dtypes=(torch.complex64, torch.complex128), active_if=(IS_MACOS)),
|
|
DecorateInfo(unittest.skip("Fails on some jobs works on others!"),
|
|
'TestUnaryUfuncs', "test_reference_numerics_extremal",
|
|
dtypes=(torch.complex64, torch.complex128), device_type='cpu',
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
),
|
|
# tan(j * pi/2 * odd_number) is nan which also make tanhshrink nan.
|
|
reference_numerics_filter=NumericsFilter(
|
|
condition=lambda x: (close_to_int(x / (math.pi * 0.5j))
|
|
if x.is_complex() else x.new_tensor(False, dtype=torch.bool)),
|
|
safe_val=0)
|
|
),
|
|
UnaryUfuncInfo(
|
|
'nn.functional.threshold',
|
|
ref=lambda x, threshold, value: np.where(x <= threshold, value, x).astype(x.dtype),
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
inplace_variant=lambda x, threshold, value:
|
|
torch.nn.functional.threshold(x, threshold, value, inplace=True),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=False,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
sample_kwargs=lambda device, dtype, input: ({'threshold': float.fromhex('0x1.3ap-3'),
|
|
'value': -9},
|
|
{'threshold': float.fromhex('0x1.3ap-3'),
|
|
'value': -9}),
|
|
# TODO(whc) should not need sample_inputs_func, but without it
|
|
# kwargs aren't being hooked up properly
|
|
sample_inputs_func=sample_inputs_threshold,
|
|
),
|
|
OpInfo(
|
|
"nn.functional.triplet_margin_loss",
|
|
sample_inputs_func=sample_inputs_triplet_margin_loss,
|
|
error_inputs_func=error_inputs_triplet_margin_loss,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
),
|
|
OpInfo(
|
|
"nn.functional.triplet_margin_with_distance_loss",
|
|
sample_inputs_func=partial(sample_inputs_triplet_margin_loss, with_distance=True),
|
|
error_inputs_func=error_inputs_triplet_margin_loss,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# This test cannot handle a callable passed to `distance_function`. If we would use
|
|
# `distance_function=None`, the test would pass fine.
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestNormalizeOperators",
|
|
"test_normalize_operator_exhaustive",
|
|
),
|
|
),
|
|
),
|
|
BinaryUfuncInfo('nextafter',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_autograd=False,
|
|
supports_rhs_python_scalar=False),
|
|
OpInfo(
|
|
"to",
|
|
op=lambda x, *args, **kwargs: x.to(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_to,
|
|
skips=(
|
|
# RuntimeError: undefined value cpu
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
device_type="cpu",
|
|
),
|
|
# NotImplementedError: Cannot copy out of meta tensor; no data!
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestMeta",
|
|
"test_meta_outplace",
|
|
),
|
|
# https://github.com/pytorch/pytorch/issues/84335
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestProxyTensorOpInfo",
|
|
"test_make_fx_symbolic_exhaustive",
|
|
),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestNormalizeOperators",
|
|
"test_normalize_operator_exhaustive",
|
|
),
|
|
),
|
|
),
|
|
OpInfo('topk',
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
sample_inputs_func=sample_inputs_topk),
|
|
# Multiple variants for batch_norm to test with and without cuDNN disabled
|
|
# See https://github.com/pytorch/pytorch/pull/63218#discussion_r688549391 for more details
|
|
OpInfo('nn.functional.batch_norm',
|
|
aten_name='batch_norm',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
allow_cow_input_materialize_forward=[1, 2],
|
|
allow_cow_input_materialize_backward=[1, 2],
|
|
sample_inputs_func=sample_inputs_batch_norm,
|
|
skips=(
|
|
# see https://github.com/pytorch/pytorch/issues/71286
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
device_type='cpu', dtypes=(torch.bfloat16, torch.float16)),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=5e-05, rtol=1e-05)}),
|
|
'TestCompositeCompliance', 'test_forward_ad', device_type="cpu"),
|
|
)),
|
|
# This variant tests batch_norm with cuDNN disabled only on CUDA devices
|
|
OpInfo('nn.functional.batch_norm',
|
|
variant_test_name='without_cudnn',
|
|
aten_name='batch_norm',
|
|
dtypes=empty_types(),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
allow_cow_input_materialize_forward=[1, 2],
|
|
allow_cow_input_materialize_backward=[1, 2],
|
|
decorators=[onlyCUDA, disablecuDNN],
|
|
skips=(
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-03, rtol=1e-04)}),
|
|
'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
sample_inputs_func=sample_inputs_batch_norm),
|
|
OpInfo(
|
|
"nn.functional.binary_cross_entropy",
|
|
aten_backward_name='binary_cross_entropy_backward',
|
|
sample_inputs_func=sample_inputs_binary_cross_entropy,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
gradcheck_fast_mode=False,
|
|
supports_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
# RuntimeError: expected int at position 0, but got: Tensor
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestCudaFuserOpInfo",
|
|
),
|
|
# RuntimeError: expected int at position 0, but got: Tensor
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestNNCOpInfo",
|
|
"test_nnc_correctness",
|
|
),
|
|
# Fails for unknown reason: https://github.com/pytorch/pytorch/issues/120783
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestCompositeCompliance",
|
|
"test_cow_input",
|
|
device_type='cuda',
|
|
),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=1e-3, rtol=1e-3)}),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
),
|
|
# RuntimeError: output with shape [] doesn't match the broadcast shape [5, 5]
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_meta_outplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_outplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_outplace_all_strides'),
|
|
),
|
|
skips=(
|
|
# RuntimeError: expected int at position 0, but got: Tensor
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
),
|
|
),
|
|
),
|
|
# We have to add 2 OpInfo entry for `igamma` and `igammac`.First is the
|
|
# standard entry, second is to run gradcheck tests on the second argument.
|
|
BinaryUfuncInfo('igamma',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
aliases=('torch.special.gammainc',),
|
|
dtypesIfCUDA=floating_types(),
|
|
# TODO: FIXME
|
|
supports_rhs_python_scalar=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# FIXME: incorrectly tries to pass a rhs scalar
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit',
|
|
'test_jit_alias_remapping'),
|
|
)),
|
|
# TODO: FIXME, ideally by implemented grad for both inputs
|
|
# BinaryUfuncInfo('igamma',
|
|
# variant_test_name='grad_other',
|
|
# # Since autograd formula is implemented only for other and
|
|
# # gradcheck test verifies the formula for input in SampleInput,
|
|
# # we permute the arguments.
|
|
# op=lambda self, other, **kwargs: torch.igamma(other, self, **kwargs),
|
|
# inplace_variant=None,
|
|
# method_variant=None,
|
|
# supports_rhs_python_scalar=False,
|
|
# rhs_make_tensor_kwargs=dict(requires_grad=False),
|
|
# dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
# backward_dtypesIfCPU=floating_types_and(torch.bfloat16),
|
|
# dtypesIfCUDA=floating_types(),
|
|
# backward_dtypesIfCUDA=floating_types(),
|
|
# supports_inplace_autograd=False,
|
|
# skips=(
|
|
# # Derivative wrt first tensor not implemented
|
|
# DecorateInfo(unittest.expectedFailure, "TestCommon",
|
|
# "test_floating_inputs_are_differentiable"),"),
|
|
# # test does not work with passing lambda for op
|
|
# # AssertionError: False is not true : Tensors failed to compare as equal!
|
|
# DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# # test fails are we permute the arguments function variant
|
|
# # but not for inplace or method.
|
|
# DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# # TypeError: igamma(): argument 'input' (position 1) must be Tensor, not float
|
|
# DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs'),
|
|
# )),
|
|
BinaryUfuncInfo('igammac',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
aliases=('torch.special.gammaincc',),
|
|
dtypesIfCUDA=floating_types(),
|
|
supports_autograd=False,
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# FIXME: incorrectly tries to pass a rhs scalar
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit',
|
|
'test_jit_alias_remapping'),
|
|
)),
|
|
# TODO: FIXME, ideally by implementing grad for both inputs
|
|
# BinaryUfuncInfo('igammac',
|
|
# variant_test_name='grad_other',
|
|
# # Since autograd formula is implemented only for other and
|
|
# # gradcheck test verifies the formula for input in SampleInput,
|
|
# # we permute the arguments
|
|
# op=lambda self, other, **kwargs: torch.igammac(other, self, **kwargs),
|
|
# inplace_variant=None,
|
|
# method_variant=None,
|
|
# supports_rhs_python_scalar=False,
|
|
# rhs_make_tensor_kwargs=dict(requires_grad=False),
|
|
# dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
# backward_dtypesIfCPU=floating_types_and(torch.bfloat16),
|
|
# dtypesIfCUDA=floating_types(),
|
|
# backward_dtypesIfCUDA=floating_types(),
|
|
# supports_inplace_autograd=False,
|
|
# decorators=[
|
|
# # Derivative wrt first tensor not implemented
|
|
# DecorateInfo(unittest.expectedFailure, "TestCommon",
|
|
# "test_floating_inputs_are_differentiable"),
|
|
# ],
|
|
# skips=(
|
|
# # test does not work with passing lambda for op
|
|
# # AssertionError: False is not true : Tensors failed to compare as equal!
|
|
# DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# # test fails are we permute the arguments function variant
|
|
# # but not for inplace or method.
|
|
# DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# # TypeError: igammac(): argument 'input' (position 1) must be Tensor, not float
|
|
# DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs'),
|
|
# )),
|
|
UnaryUfuncInfo('nn.functional.softshrink',
|
|
aten_name="softshrink",
|
|
aten_backward_name='softshrink_backward',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=False,
|
|
sample_inputs_func=sample_inputs_softshrink,
|
|
error_inputs_func=error_inputs_softshrink),
|
|
UnaryUfuncInfo('nn.functional.hardshrink',
|
|
aten_name="hardshrink",
|
|
aten_backward_name='hardshrink_backward',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=sample_inputs_hardshrink,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=["aten::hardshrink"]),
|
|
UnaryUfuncInfo('nn.functional.hardtanh',
|
|
aten_name="hardtanh",
|
|
aten_backward_name='hardtanh_backward',
|
|
dtypes=floating_types_and(torch.int8, torch.int16, torch.int32, torch.int64, torch.half, torch.bfloat16),
|
|
backward_dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=sample_inputs_hardtanh,
|
|
error_inputs_func=error_inputs_hardtanh,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=["aten::hardtanh"]),
|
|
OpInfo('nn.functional.gelu',
|
|
aten_name="gelu",
|
|
aten_backward_name='gelu_backward',
|
|
ref=reference_gelu if TEST_SCIPY else None,
|
|
error_inputs_func=error_inputs_gelu,
|
|
supports_autograd=True,
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=sample_inputs_gelu,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_gradgrad=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=["aten::gelu"],
|
|
skips=(
|
|
# AssertionError: Tensor-likes are not close!
|
|
# May not replicate in CI
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out'),
|
|
DecorateInfo(unittest.skip("Unsupported on MPS for now"), 'TestCommon', 'test_numpy_ref_mps'),
|
|
)),
|
|
UnaryUfuncInfo('nn.functional.relu6',
|
|
aten_name="relu6",
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
backward_dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=["aten::relu6"]),
|
|
OpInfo('mm',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_mm,
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
)),
|
|
OpInfo('mode',
|
|
op=torch.mode,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Resized a non-empty tensor but did not warn about it
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# FIXME:
|
|
# Expected 2114 but got 1123.
|
|
# Absolute difference: 991 (up to 0.001 allowed)
|
|
# Relative difference: 0.46877956480605487 (up to 0.001 allowed)
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestCommon",
|
|
"test_compare_cpu",
|
|
dtypes=(torch.float32,),
|
|
device_type="cuda",
|
|
),
|
|
),
|
|
sample_inputs_func=sample_inputs_mode,),
|
|
make_mvlgamma_opinfo(variant_test_name='mvlgamma_p_1',
|
|
domain=(1, None),
|
|
skips=skips_mvlgamma(),
|
|
sample_kwargs=lambda device, dtype, input: ({'p': 1}, {'d': 1})),
|
|
make_mvlgamma_opinfo(variant_test_name='mvlgamma_p_3',
|
|
domain=(2, None),
|
|
skips=skips_mvlgamma(),
|
|
sample_kwargs=lambda device, dtype, input: ({'p': 3}, {'d': 3})),
|
|
make_mvlgamma_opinfo(variant_test_name='mvlgamma_p_5',
|
|
domain=(3, None),
|
|
skips=skips_mvlgamma(),
|
|
sample_kwargs=lambda device, dtype, input: ({'p': 5}, {'d': 5})),
|
|
BinaryUfuncInfo('ne',
|
|
ref=np.not_equal,
|
|
aliases=('not_equal',),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
always_returns_bool=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('narrow',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=partial(sample_inputs_narrow_narrow_copy, is_narrow=True),
|
|
reference_inputs_func=partial(reference_inputs_narrow_narrow_copy, is_narrow=True),
|
|
error_inputs_func=partial(error_inputs_narrow_narrow_copy, is_narrow=True, is_ref=False),
|
|
skips=(
|
|
# Use of .item()
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_operator'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_backward'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_forward_ad'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
OpInfo('narrow_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=True,
|
|
supports_forward_ad=False,
|
|
supports_fwgrad_bwgrad=False,
|
|
supports_autograd=False,
|
|
# https://github.com/pytorch/pytorch/issues/86931
|
|
sample_inputs_func=partial(sample_inputs_narrow_narrow_copy, is_narrow=False),
|
|
reference_inputs_func=partial(reference_inputs_narrow_narrow_copy, is_narrow=False),
|
|
error_inputs_func=partial(error_inputs_narrow_narrow_copy, is_narrow=False, is_ref=False),
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/84577
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# Could not run 'aten::narrow_copy.out' with arguments from the 'CUDA' backend
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_meta_outplace',
|
|
device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_meta_outplace',
|
|
device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_outplace',
|
|
device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_outplace_all_strides'),
|
|
)),
|
|
OpInfo('view_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
ref=lambda x, newshape: np.reshape(x, newshape).copy(),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_autograd=True,
|
|
sample_inputs_func=sample_inputs_view_reshape,
|
|
error_inputs_func=error_inputs_view_reshape,
|
|
skips=(
|
|
# RuntimeError: view size is not compatible with input tensor's size and stride
|
|
# (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
|
|
DecorateInfo(
|
|
unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"
|
|
),
|
|
)),
|
|
UnaryUfuncInfo('neg',
|
|
aliases=('negative', ),
|
|
ref=np.negative,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16, torch.chalf),
|
|
error_inputs_func=error_inputs_neg,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
assert_autodiffed=True),
|
|
OpInfo('dist',
|
|
op=torch.dist,
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
# torch.autograd.gradcheck.GradcheckError: While computing batched gradients, got:
|
|
# Could not allocate memory to change Tensor SizesAndStrides!
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_dist),
|
|
OpInfo('outer',
|
|
op=torch.outer,
|
|
aliases=('ger', ),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_outer,),
|
|
OpInfo('ormqr',
|
|
op=torch.ormqr,
|
|
dtypes=floating_and_complex_types(),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=False,
|
|
supports_fwgrad_bwgrad=False,
|
|
sample_inputs_func=sample_inputs_ormqr,
|
|
error_inputs_func=error_inputs_ormqr,
|
|
decorators=[skipCUDAIfNoCusolver, skipCPUIfNoLapack],
|
|
skips=(
|
|
# Strides are not the same!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
)),
|
|
OpInfo('permute',
|
|
ref=np.transpose,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
assert_autodiffed=True,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
assert_jit_shape_analysis=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_varargs=True,
|
|
sample_inputs_func=sample_inputs_permute,
|
|
reference_inputs_func=reference_inputs_permute),
|
|
OpInfo('permute_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
assert_autodiffed=True,
|
|
assert_jit_shape_analysis=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_varargs=False, # torch.permute is also not varargs
|
|
sample_inputs_func=sample_inputs_permute,
|
|
reference_inputs_func=reference_inputs_permute,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=(torch.float32,)),
|
|
)),
|
|
BinaryUfuncInfo('pow',
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.half, torch.bfloat16, torch.chalf),
|
|
ref=np.power,
|
|
# Due to AVX2 currently not being fully supported for Float16, log_vml_cpu can't be enabled
|
|
# for Float16, causing this test to fail. pow's autograd for Float16 is thus currently
|
|
# unsupported on CPU.
|
|
backward_dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.bfloat16, torch.half, torch.chalf),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
supports_one_python_scalar=True,
|
|
# Integer types do not support negative exponentes
|
|
rhs_make_tensor_kwargs=dict(low=0),
|
|
# Raising negative real numbers to fractional powers is not supported
|
|
lhs_make_tensor_kwargs=dict(low=0),
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.complex64: tol(atol=1e-4, rtol=1.3e-05)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
DecorateInfo(toleranceOverride({torch.complex64: tol(atol=1e-4, rtol=1.3e-05),
|
|
torch.complex128: tol(atol=1e-4, rtol=1.3e-05)}),
|
|
'TestBinaryUfuncs', 'test_scalar_support'),
|
|
),
|
|
skips=(
|
|
# Skipping integers because they are being raised to negative powers causing an error
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_reference_numerics_small_values',
|
|
dtypes=[torch.int8, torch.int16, torch.int32, torch.int64]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_reference_numerics_large_values',
|
|
dtypes=[torch.int16, torch.int32, torch.int64]),
|
|
# FIXME Complex values error with: Greatest absolute difference: nan at index
|
|
# Ref: https://github.com/pytorch/pytorch/issues/76853
|
|
# For `chalf`, reference computation in `numpy` is computed in `cfloat`.
|
|
# Output of `chalf` saturates to `inf` quicker than reference due to its small range
|
|
# which leads to failure of this test.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_quick',
|
|
dtypes=(torch.complex32,), active_if=TEST_WITH_ROCM),
|
|
# FIXME:
|
|
# Mismatched elements: 1 / 500 (0.2%)
|
|
# Greatest absolute difference: nan at index (7, 9, 0) (up to 1e-05 allowed)
|
|
# Greatest relative difference: nan at index (7, 9, 0) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_comprehensive',
|
|
dtypes=(torch.complex32,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_complex_half_reference_testing',
|
|
dtypes=(torch.complex32,), active_if=TEST_WITH_ROCM),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_batch_vs_slicing',
|
|
dtypes=(torch.complex32,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_non_contig',
|
|
dtypes=(torch.complex32,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics',
|
|
dtypes=(torch.complex32,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics_small_values',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics_large_values',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics_extremal_values',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128)),
|
|
)),
|
|
BinaryUfuncInfo('float_power',
|
|
ref=np.float_power,
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16, torch.bool),
|
|
promotes_int_to_float=True,
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_one_python_scalar=True,
|
|
# Integer types do not support negative exponentes
|
|
rhs_make_tensor_kwargs=dict(low=0),
|
|
# Raising negative real numbers to fractional powers is not supported
|
|
lhs_make_tensor_kwargs=dict(low=0),
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.complex64: tol(atol=1e-4, rtol=1.3e-05),
|
|
torch.complex128: tol(atol=1e-4, rtol=1.3e-05)}),
|
|
'TestBinaryUfuncs', 'test_scalar_support'),
|
|
),
|
|
skips=(
|
|
# FIXME
|
|
# AssertionError: Object comparison failed: torch.float64 != torch.float32
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
# -3.43399e+38 is outside the range of representable values of type 'float'
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Complex values error with: Greatest absolute difference: nan at index
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics_small_values',
|
|
dtypes=[torch.complex64, torch.complex128]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics_large_values',
|
|
dtypes=[torch.complex64, torch.complex128]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_reference_numerics_extremal_values',
|
|
dtypes=[torch.complex64, torch.complex128]),
|
|
# Inplace always promotes to double and thus other floating dtypes are not supported
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_meta_inplace',
|
|
dtypes=[torch.bfloat16, torch.float16, torch.float32]),
|
|
)),
|
|
OpInfo('qr',
|
|
op=torch.qr,
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_linalg_qr_geqrf,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# In-place ops
|
|
check_batched_gradgrad=False,
|
|
decorators=[skipCUDAIfNoCusolver, skipCPUIfNoLapack]),
|
|
UnaryUfuncInfo('rad2deg',
|
|
ref=np.degrees,
|
|
decorators=(precisionOverride({torch.bfloat16: 7e-1,
|
|
torch.float16: 7e-1}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True),
|
|
UnaryUfuncInfo('real',
|
|
ref=np.real,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# Skip since real and imag don't have out variants.
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs', 'test_out_arg_all_dtypes'),
|
|
)),
|
|
OpInfo(
|
|
"roll",
|
|
ref=np.roll,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
error_inputs_func=error_inputs_roll,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_roll,
|
|
decorators=(onlyNativeDeviceTypes,),
|
|
),
|
|
OpInfo(
|
|
"rot90",
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half),
|
|
error_inputs_func=error_inputs_rot90,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_rot90,
|
|
),
|
|
# To test reference numerics against multiple values of argument `decimals`,
|
|
# we make multiple OpInfo entries with each entry corresponding to different value of decimals.
|
|
UnaryUfuncInfo('round',
|
|
ref=np.round,
|
|
aliases=('special.round',),
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=tuple(t for t in integral_types() if t != torch.uint8)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=(torch.bfloat16,)),
|
|
),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
assert_autodiffed=True,
|
|
),
|
|
UnaryUfuncInfo('round',
|
|
ref=np.round,
|
|
variant_test_name='decimals_0',
|
|
aliases=('special.round',),
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_kwargs=lambda device, dtype, input: ({'decimals': 0}, {'decimals': 0}),
|
|
sample_inputs_func=partial(sample_inputs_elementwise_unary, op_kwargs={'decimals': 0}),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=False,
|
|
supports_sparse_csr=False),
|
|
UnaryUfuncInfo('round',
|
|
ref=np.round,
|
|
variant_test_name='decimals_3',
|
|
aliases=('special.round',),
|
|
dtypes=floating_types_and(torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_kwargs=lambda device, dtype, input: ({'decimals': 3}, {'decimals': 3}),
|
|
sample_inputs_func=partial(sample_inputs_elementwise_unary, op_kwargs={'decimals': 3}),
|
|
skips=(
|
|
# test_ops already tested for this overload with `decimals_0` opinfo entry
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits'),
|
|
DecorateInfo(toleranceOverride({torch.bfloat16: tol(atol=1e-3, rtol=0.016)}),
|
|
"TestUnaryUfuncs", "test_reference_numerics_extremal",
|
|
device_type="cuda"),
|
|
DecorateInfo(toleranceOverride({torch.bfloat16: tol(atol=1e-3, rtol=0.016)}),
|
|
"TestUnaryUfuncs", "test_reference_numerics_normal",
|
|
device_type="cuda"),
|
|
),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=False,
|
|
supports_sparse_csr=False),
|
|
UnaryUfuncInfo('round',
|
|
ref=np.round,
|
|
variant_test_name='decimals_neg_3',
|
|
aliases=('special.round',),
|
|
dtypes=floating_types_and(torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
sample_kwargs=lambda device, dtype, input: ({'decimals': -3}, {'decimals': -3}),
|
|
sample_inputs_func=partial(sample_inputs_elementwise_unary, op_kwargs={'decimals': -3}),
|
|
skips=(
|
|
# test_ops already tested for this overload with `decimals_0` opinfo entry
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits'),
|
|
),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=False,
|
|
supports_sparse_csr=False),
|
|
UnaryUfuncInfo('sin',
|
|
ref=np.sin,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
handles_large_floats=False,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
# Fails on CUDA but passes on ROCm
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.cdouble,), device_type='cuda'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=(torch.cfloat, torch.cdouble,), device_type='cpu', active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.cfloat, torch.cdouble,), device_type='cpu', active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
),
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),)),
|
|
UnaryUfuncInfo('sinc',
|
|
ref=np_sinc_with_fp16_as_fp32,
|
|
aliases=('special.sinc',),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
handles_large_floats=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True),
|
|
UnaryUfuncInfo('sinh',
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(np.sinh),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.float16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.cdouble,)),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48641
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.int8]),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
UnaryUfuncInfo('sign',
|
|
ref=reference_sign,
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.half),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.bfloat16, torch.half),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/41245
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.bfloat16, torch.float16, torch.float32, torch.float64]),
|
|
)),
|
|
UnaryUfuncInfo('sgn',
|
|
ref=reference_sgn,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
backward_dtypes=floating_and_complex_types_and(torch.bfloat16, torch.half),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.bfloat16, torch.half, torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/41245
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.bfloat16, torch.float16, torch.float32, torch.float64]),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
OpInfo('split',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool, torch.chalf),
|
|
sample_inputs_func=partial(sample_inputs_split, list_args=False),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
assert_autodiffed=True),
|
|
OpInfo('split',
|
|
# Cannot declare this aten_name because of
|
|
# test_variant_consistency_jit_split_list_args_cpu_float32
|
|
decomp_aten_name='split_with_sizes',
|
|
variant_test_name='list_args',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool),
|
|
sample_inputs_func=partial(sample_inputs_split, list_args=True),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
# `unsafe_split` supports only `int` for split_size argument
|
|
OpInfo('unsafe_split',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool, torch.chalf),
|
|
sample_inputs_func=partial(sample_inputs_split, list_args=False),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
assert_autodiffed=True,
|
|
check_batched_forward_grad=False),
|
|
OpInfo('split_with_sizes',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool, torch.chalf),
|
|
sample_inputs_func=sample_inputs_split_with_sizes,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True),
|
|
OpInfo('split_with_sizes_copy',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool, torch.chalf),
|
|
sample_inputs_func=sample_inputs_split_with_sizes,
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# No error raised
|
|
DecorateInfo(unittest.expectedFailure, "TestCommon", "test_out_requires_grad_error"),
|
|
)),
|
|
BinaryUfuncInfo('__radd__',
|
|
op=torch.Tensor.__radd__,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool),
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
|
|
),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=['aten::add'],),
|
|
BinaryUfuncInfo('__rdiv__',
|
|
op=torch.Tensor.__rdiv__,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool),
|
|
promotes_int_to_float=True,
|
|
lhs_make_tensor_kwargs={'exclude_zero': True},
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/76806
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
autodiff_nonfusible_nodes=['aten::mul', 'aten::reciprocal'],),
|
|
BinaryUfuncInfo('__rmul__',
|
|
op=torch.Tensor.__rmul__,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool),
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
autodiff_nonfusible_nodes=['aten::mul'],),
|
|
BinaryUfuncInfo('__rand__',
|
|
op=torch.Tensor.__rand__,
|
|
dtypes=integral_types_and(torch.bool),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
supports_forward_ad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
)),
|
|
BinaryUfuncInfo('__ror__',
|
|
op=torch.Tensor.__ror__,
|
|
dtypes=integral_types_and(torch.bool),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
supports_forward_ad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
)),
|
|
BinaryUfuncInfo('__rxor__',
|
|
op=torch.Tensor.__rxor__,
|
|
dtypes=integral_types_and(torch.bool),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
supports_forward_ad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
)),
|
|
OpInfo('__rmatmul__',
|
|
op=torch.Tensor.__rmatmul__,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16,
|
|
*[torch.bfloat16]
|
|
if SM53OrLater or TEST_WITH_ROCM else []),
|
|
assert_autodiffed=True,
|
|
sample_inputs_func=partial(sample_inputs_matmul, is_rmatmul=True),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
decorators=(
|
|
# NVIDIA only assures that bfloat16 is supported by bmm if SM >= 5.3
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes', device_type='cuda', active_if=not SM53OrLater),
|
|
DecorateInfo(toleranceOverride({torch.complex64: tol(atol=1e-05, rtol=1.2e-03)}),
|
|
'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-05, rtol=1.2e-03)}),
|
|
'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(toleranceOverride({torch.complex64: tol(atol=1e-05, rtol=1e-05)}),
|
|
"TestDecomp", "test_comprehensive", device_type="cuda",
|
|
active_if=TEST_WITH_ROCM),
|
|
),
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
# https://github.com/pytorch/pytorch/issues/67470
|
|
DecorateInfo(unittest.skip("67470!"),
|
|
'TestCommon', 'test_noncontiguous_samples',
|
|
device_type='cpu', dtypes=(torch.long,)),
|
|
# Fails on XLA.
|
|
# AssertionError: False is not true : Tensors failed to compare as equal
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOpInfo', device_type='xla', dtypes=(torch.long,)),
|
|
# https://github.com/pytorch/pytorch/issues/71774
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestNNCOpInfo', 'test_nnc_correctness',
|
|
device_type='cpu', dtypes=(torch.long,)),
|
|
)),
|
|
BinaryUfuncInfo('__rmod__',
|
|
op=torch.Tensor.__rmod__,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half,),
|
|
dtypesIfCUDA=all_types_and(torch.bfloat16, torch.half),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
),
|
|
# Support autograd after torch.remainder(Tensor, Tensor) supports
|
|
# autograd of the second argument.
|
|
# https://github.com/pytorch/pytorch/pull/58476/files#r637167630
|
|
# supports_autograd=False,
|
|
assert_autodiffed=True,
|
|
autodiff_nonfusible_nodes=['aten::remainder'],),
|
|
BinaryUfuncInfo('__rpow__',
|
|
op=torch.Tensor.__rpow__,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/54774
|
|
# "log2" "_vml_cpu" not implemented for Half
|
|
backward_dtypes=all_types_and_complex_and(torch.bfloat16, torch.half),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
# TODO: FIXME tolerance is too high
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBwdGradients'),
|
|
),
|
|
assert_autodiffed=True,
|
|
autodiff_nonfusible_nodes=['aten::pow'],),
|
|
BinaryUfuncInfo('__rsub__',
|
|
op=torch.Tensor.__rsub__,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',),
|
|
),
|
|
assert_autodiffed=True,
|
|
autodiff_nonfusible_nodes=['aten::rsub'],),
|
|
BinaryUfuncInfo('rsub',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
supports_inplace_autograd=False,
|
|
assert_autodiffed=None,
|
|
sample_inputs_func=sample_inputs_add_sub),
|
|
OpInfo('select',
|
|
aten_backward_name='select_backward',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool, torch.chalf),
|
|
sample_inputs_func=sample_inputs_select,
|
|
assert_jit_shape_analysis=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('select_scatter',
|
|
dtypes=all_types_and(torch.bfloat16, torch.half, torch.bool),
|
|
sample_inputs_func=sample_inputs_select_scatter,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False),
|
|
OpInfo('slice',
|
|
op=torch.ops.aten.slice.Tensor,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.half, torch.bool, torch.chalf),
|
|
sample_inputs_func=sample_inputs_slice,
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_scripting=False,
|
|
supports_inplace_autograd=False,
|
|
supports_out=False),
|
|
OpInfo('slice_scatter',
|
|
dtypes=all_types_and(torch.bfloat16, torch.half, torch.bool),
|
|
sample_inputs_func=sample_inputs_slice_scatter,
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=True),
|
|
UnaryUfuncInfo('signbit',
|
|
ref=np.signbit,
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.half),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_autograd=False,),
|
|
UnaryUfuncInfo('tan',
|
|
ref=np.tan,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
decorators=(DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-04, rtol=1e-05)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda'),),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
# FIXME:
|
|
# Mismatched elements: 2 / 400 (0.5%)
|
|
# Greatest absolute difference: inf at index (7, 16) (up to 1e-05 allowed)
|
|
# Greatest relative difference: nan at index (7, 16) (up to 0.001 allowed)
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
dtypes=(torch.float16,),
|
|
device_type="cuda",
|
|
),
|
|
),
|
|
# tan(pi/2 * odd_number) is nan
|
|
reference_numerics_filter=NumericsFilter(
|
|
condition=lambda x: close_to_int(x / (math.pi * 0.5)), safe_val=math.pi)),
|
|
UnaryUfuncInfo('tanh',
|
|
ref=np.tanh,
|
|
aten_backward_name='tanh_backward',
|
|
aliases=('nn.functional.tanh',),
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-04, rtol=2e-05)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda'),),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
assert_jit_shape_analysis=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
),
|
|
# tan(j * pi/2 * odd_number) is nan
|
|
reference_numerics_filter=NumericsFilter(
|
|
condition=lambda x: (close_to_int(x / (math.pi * 0.5j))
|
|
if x.is_complex() else x.new_tensor(False, dtype=torch.bool)),
|
|
safe_val=0)),
|
|
OpInfo('tensor_split',
|
|
ref=np.array_split,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Pre-existing condition; Needs to be fixed
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_operator'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_backward'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_forward_ad'),
|
|
),
|
|
sample_inputs_func=sample_inputs_tensor_split,),
|
|
OpInfo('hsplit',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_hsplit,
|
|
error_inputs_func=error_inputs_hsplit,),
|
|
OpInfo('vsplit',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_vsplit,
|
|
error_inputs_func=error_inputs_vsplit,),
|
|
OpInfo('dsplit',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_dsplit,
|
|
error_inputs_func=error_inputs_dsplit,),
|
|
OpInfo('triangular_solve',
|
|
op=torch.triangular_solve,
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_legacy_solve,
|
|
check_batched_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_wrapper=lambda *args, **kwargs: gradcheck_wrapper_triangular_input(*args, idx=1, **kwargs),
|
|
decorators=[
|
|
skipCUDAIfNoMagma,
|
|
skipCPUIfNoLapack,
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=3e-5, rtol=3e-6)}),
|
|
'TestConsistency', 'test_output_match', device_type='cpu',
|
|
),
|
|
],
|
|
skips=(
|
|
# AssertionError: Scalars are not equal!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# Gradcheck fails
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_fn_fwgrad_bwgrad',
|
|
dtypes=floating_and_complex_types()),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
)),
|
|
UnaryUfuncInfo('trunc',
|
|
aliases=('fix', ),
|
|
ref=np.trunc,
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=tuple(t for t in integral_types() if t != torch.uint8)),
|
|
),
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
assert_autodiffed=True),
|
|
UnaryUfuncInfo('exp2',
|
|
aliases=('special.exp2', ),
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(np.exp2),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.cdouble]),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48010
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
)),
|
|
UnaryUfuncInfo('expm1',
|
|
aliases=('special.expm1', ),
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(np.expm1),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
promotes_int_to_float=True,
|
|
assert_autodiffed=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.complex128]),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
UnaryUfuncInfo('nan_to_num',
|
|
ref=np.nan_to_num,
|
|
dtypes=all_types_and(torch.half, torch.bool, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.half, torch.bool, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
),
|
|
# Passing numpy_kwargs via sample_kwargs, as numpy does comparison
|
|
# with BFloat16 in float, since it currently doesn't support BFloat16.
|
|
# Ref: https://github.com/pytorch/pytorch/issues/57982#issuecomment-839150556
|
|
sample_kwargs=lambda device, dtype, input: ({},
|
|
{'posinf': torch.finfo(torch.bfloat16).max,
|
|
'neginf': torch.finfo(torch.bfloat16).min})
|
|
if dtype is torch.bfloat16 else ({}, {})),
|
|
UnaryUfuncInfo('reciprocal',
|
|
ref=np_unary_ufunc_integer_promotion_wrapper(np.reciprocal),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/45690
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
)),
|
|
UnaryUfuncInfo('rsqrt',
|
|
ref=lambda x: np.reciprocal(np.sqrt(x)),
|
|
domain=(0, None),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
decorators=(precisionOverride({torch.half: 5e-2}),),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=(torch.cfloat, torch.cdouble)),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: nan at index (700,) (up to 0.01 allowed)
|
|
# Greatest relative difference: nan at index (700,) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=(torch.chalf,)),
|
|
)),
|
|
UnaryUfuncInfo('sqrt',
|
|
ref=np.sqrt,
|
|
supports_sparse=True,
|
|
domain=(0, None),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(
|
|
precisionOverride({torch.bfloat16: 7e-2}),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=0)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_large'),
|
|
),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/47358
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=(torch.cfloat, torch.cdouble),
|
|
active_if=IS_MACOS),
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
)),
|
|
UnaryUfuncInfo('square',
|
|
ref=np.square,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
decorators=(precisionOverride({torch.complex64: 3e-4, torch.bfloat16: 3e-1}),),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/52549
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
# >>> t = torch.tensor(complex(-0.01, float("inf")))
|
|
# >>> np.square(t.numpy())
|
|
# (-inf-infj)
|
|
# >>> t.square()
|
|
# tensor(-inf-infj)
|
|
# >>> t.cuda().square()
|
|
# tensor(inf+nanj, device='cuda:0')
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_meta_inplace',
|
|
dtypes=[torch.bool]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_meta_inplace',
|
|
dtypes=[torch.bool]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_inplace',
|
|
dtypes=[torch.bool]),
|
|
),),
|
|
OpInfo('lerp',
|
|
dtypes=floating_and_complex_types_and(torch.bfloat16, torch.half),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.chalf, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_lerp,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True),
|
|
UnaryUfuncInfo('angle',
|
|
ref=np.angle,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool),
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.bfloat16: 1e-2}),),
|
|
backward_dtypes=floating_and_complex_types_and(torch.bfloat16, torch.float16),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_complex_to_float=True,
|
|
skips=(
|
|
# Ref: https://github.com/pytorch/pytorch/issues/78413
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
dtypes=(torch.bfloat16, torch.float16, torch.float32, torch.float64),),
|
|
)),
|
|
UnaryUfuncInfo('isfinite',
|
|
ref=np.isfinite,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=False,
|
|
supports_autograd=False),
|
|
UnaryUfuncInfo('isinf',
|
|
ref=np.isinf,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=False,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_autograd=False),
|
|
UnaryUfuncInfo('isposinf',
|
|
ref=np.isposinf,
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.float16),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_autograd=False),
|
|
UnaryUfuncInfo('isneginf',
|
|
ref=np.isneginf,
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16, torch.float16),
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_autograd=False),
|
|
UnaryUfuncInfo('isreal',
|
|
ref=np.isreal,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
supports_out=False,
|
|
supports_autograd=False),
|
|
UnaryUfuncInfo('isnan',
|
|
ref=np.isnan,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
supports_out=False,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_autograd=False),
|
|
OpInfo('einsum',
|
|
# we need this lambda because SampleInput expects tensor input as the first argument
|
|
# TODO(@heitorschueroff) update SampleInput to handle such cases
|
|
op=lambda tensors, equation: torch.einsum(equation, tensors),
|
|
dtypes=all_types_and_complex_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
sample_inputs_func=sample_inputs_einsum,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# test does not work with passing lambda for op
|
|
# there's a test `test_einsum` in `test_jit.py` to handle this case
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('svd',
|
|
op=torch.svd,
|
|
dtypes=floating_and_complex_types(),
|
|
sample_inputs_func=sample_inputs_svd,
|
|
# Runs very slowly on slow-gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
# We're using at::allclose, which does not have a batching rule
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
decorators=[skipCUDAIfNoMagmaAndNoCusolver, skipCPUIfNoLapack, with_tf32_off],
|
|
skips=(
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
)),
|
|
OpInfo('svd_lowrank',
|
|
op=lambda *args, **kwargs: wrapper_set_seed(
|
|
lambda a, b, **kwargs: torch.svd_lowrank(a @ b.mT, **kwargs),
|
|
*args, **kwargs
|
|
),
|
|
dtypes=floating_and_complex_types(),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
# Due to the use of randomness
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_forward_ad=True,
|
|
sample_inputs_func=sample_inputs_svd_lowrank,
|
|
decorators=[skipCUDAIfNoCusolver, skipCPUIfNoLapack, with_tf32_off,
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-03, rtol=1e-03),
|
|
torch.complex64: tol(atol=1e-02, rtol=1e-02)}),
|
|
'TestCommon', 'test_noncontiguous_samples'),
|
|
# FIXME This should be the following, but the toleranceOverride does not seem to do anything!
|
|
# DecorateInfo(toleranceOverride({torch.complex128: tol(atol=1e-04, rtol=1e-04)}),
|
|
# 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
DecorateInfo(unittest.skip("See comment above"),
|
|
'TestFwdGradients',
|
|
'test_fn_fwgrad_bwgrad',
|
|
dtypes=[torch.complex128]),
|
|
],
|
|
skips=(
|
|
# test does not work with passing lambda for op
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(unittest.expectedFailure, 'TestSchemaCheckModeOpInfo', 'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
DecorateInfo(slowTest, 'TestCompositeCompliance', 'test_forward_ad'),
|
|
)),
|
|
OpInfo('pca_lowrank',
|
|
op=lambda *args, **kwargs: wrapper_set_seed(
|
|
lambda a, b, **kwargs: torch.pca_lowrank(a @ b.mT, **kwargs),
|
|
*args, **kwargs
|
|
),
|
|
dtypes=floating_and_complex_types(),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
check_batched_forward_grad=False,
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_pca_lowrank,
|
|
decorators=[skipCUDAIfNoCusolver, skipCPUIfNoLapack, with_tf32_off,
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-03, rtol=1e-03),
|
|
torch.complex64: tol(atol=4e-02, rtol=4e-02)}),
|
|
'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-05, rtol=5e-05)}),
|
|
'TestOperators', 'test_grad'),
|
|
# FIXME This should be the following, but the toleranceOverride does not seem to do anything!
|
|
# DecorateInfo(toleranceOverride({torch.complex128: tol(atol=1e-04, rtol=1e-04)}),
|
|
# 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
DecorateInfo(unittest.skip("See comment above"),
|
|
'TestFwdGradients',
|
|
'test_fn_fwgrad_bwgrad',
|
|
dtypes=[torch.complex128]),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float32: tol(atol=3e-5, rtol=1e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda'),
|
|
],
|
|
skips=(
|
|
# test does not work with passing lambda for op
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(unittest.expectedFailure, 'TestSchemaCheckModeOpInfo', 'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
BinaryUfuncInfo('polar',
|
|
dtypes=floating_types(),
|
|
# this function is undefined if 'abs' values are <0
|
|
supports_forward_ad=True,
|
|
lhs_make_tensor_kwargs=dict(low=0),
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# RuntimeError: Expected object of scalar type Float but got scalar type Double for second argument
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
# GradcheckError: Jacobian computed with forward mode mismatch for output 0 with respect to input 0
|
|
# Numerical:
|
|
# tensor([[0.]], dtype=torch.float64)
|
|
# Analytical:
|
|
# tensor([[-0.0047]], dtype=torch.float64, grad_fn=<CopySlices>)
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
)),
|
|
# TODO(@kshitij12345): Refactor similar to `mvlgamma` entries.
|
|
# To test reference numerics against multiple values of argument `n`,
|
|
# we make multiple OpInfo entries with each entry corresponding to different value of n (currently 0 to 4).
|
|
# We run the op tests from test_ops.py only for `n=0` to avoid redundancy in testing.
|
|
UnaryUfuncInfo('polygamma',
|
|
op=lambda x, n, **kwargs: torch.polygamma(n, x, **kwargs),
|
|
variant_test_name='polygamma_n_0',
|
|
ref=reference_polygamma if TEST_SCIPY else None,
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
sample_inputs_func=sample_inputs_polygamma,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
),
|
|
sample_kwargs=lambda device, dtype, input: ({'n': 0}, {'n': 0}),
|
|
# polygamma functions have multiple singularities at x having non-positive integer value
|
|
reference_numerics_filter=NumericsFilter(condition=lambda x: (x < 0.1) & ((x - x.round()).abs() < 1e-4),
|
|
safe_val=1)),
|
|
*(UnaryUfuncInfo('polygamma',
|
|
op=lambda x, n, **kwargs: torch.polygamma(n, x, **kwargs),
|
|
variant_test_name=f'polygamma_n_{n_}',
|
|
ref=reference_polygamma if TEST_SCIPY else None,
|
|
dtypes=all_types_and(torch.bool, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
sample_inputs_func=sample_inputs_polygamma,
|
|
decorators=(
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=1e-4, rtol=1e-3)}), 'TestUnaryUfuncs'),
|
|
DecorateInfo(toleranceOverride({torch.bfloat16: tol(atol=1e1, rtol=1e-1),
|
|
torch.float32: tol(atol=1e-4, rtol=1e-2)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
skips=(
|
|
# Redundant tests
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNormalizeOperators'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon'),
|
|
# Mismatch: https://github.com/pytorch/pytorch/issues/55357
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large'),
|
|
),
|
|
sample_kwargs=lambda device, dtype, input: ({'n': n_}, {'n': n_}),
|
|
# polygamma functions have multiple singularities at x having non-positive integer value
|
|
reference_numerics_filter=NumericsFilter(condition=lambda x: (x < 0.1) & ((x - x.round()).abs() < 1e-4),
|
|
safe_val=1))
|
|
for n_ in (1, 2, 3, 4)),
|
|
OpInfo('ravel',
|
|
ref=np.ravel,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_ravel,
|
|
),
|
|
OpInfo('unravel_index',
|
|
ref=np.unravel_index,
|
|
dtypes=integral_types_and(),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
sample_inputs_func=sample_inputs_unravel_index,
|
|
),
|
|
OpInfo('reshape',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_view_reshape,
|
|
reference_inputs_func=reference_inputs_view_reshape,
|
|
error_inputs_func=error_inputs_view_reshape,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
),
|
|
OpInfo('reshape_as',
|
|
op=lambda x, other: x.reshape_as(other),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=partial(sample_inputs_view_reshape, tensor_arg=True),
|
|
reference_inputs_func=partial(reference_inputs_view_reshape, tensor_arg=True),
|
|
error_inputs_func=partial(error_inputs_view_reshape, tensor_arg=True),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
)),
|
|
OpInfo('view',
|
|
op=lambda x, shape: x.view(shape),
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
sample_inputs_func=sample_inputs_view_reshape,
|
|
reference_inputs_func=reference_inputs_view_reshape,
|
|
error_inputs_func=error_inputs_view_reshape,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: view size is not compatible with input tensor's size and stride
|
|
# (at least one dimension spans across two contiguous subspaces). Use .reshape(...) instead.
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"),
|
|
)),
|
|
OpInfo('view_as',
|
|
op=lambda x, other: x.view_as(other),
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=partial(sample_inputs_view_reshape, tensor_arg=True),
|
|
reference_inputs_func=partial(reference_inputs_view_reshape, tensor_arg=True),
|
|
error_inputs_func=partial(error_inputs_view_reshape, tensor_arg=True),
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: view size is not compatible with input tensor's size and stride
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides")
|
|
)),
|
|
OpInfo('atleast_1d',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_atleast1d2d3d,
|
|
skips=(
|
|
# JIT does not support variadic tensors.
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":252,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=[torch.float32]),
|
|
),
|
|
),
|
|
OpInfo('atleast_2d',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=[torch.float32]),
|
|
),
|
|
sample_inputs_func=sample_inputs_atleast1d2d3d,
|
|
),
|
|
OpInfo('atleast_3d',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit', dtypes=[torch.float32]),
|
|
),
|
|
sample_inputs_func=sample_inputs_atleast1d2d3d,
|
|
),
|
|
OpInfo('flatten',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
ref=reference_flatten,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_flatten,
|
|
reference_inputs_func=reference_inputs_flatten,
|
|
),
|
|
OpInfo('unflatten',
|
|
op=torch.unflatten,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_unflatten,
|
|
),
|
|
OpInfo('column_stack',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_column_stack,),
|
|
OpInfo('pinverse',
|
|
op=torch.pinverse,
|
|
dtypes=floating_and_complex_types(),
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_linalg_invertible,
|
|
decorators=[skipCUDAIfNoMagmaAndNoCusolver, skipCPUIfNoLapack],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit',
|
|
device_type='mps', dtypes=[torch.float32]),
|
|
)),
|
|
OpInfo('gather',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_gather,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
error_inputs_func=error_inputs_gather,
|
|
),
|
|
OpInfo('index_fill',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.complex32),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# RuntimeError: Mismatch on aten._unique.default: Shapes torch.Size([2]) and torch.Size([1]) are not equal!
|
|
DecorateInfo(unittest.expectedFailure, 'TestFakeTensor', 'test_fake_crossref_backward_no_amp'),
|
|
# RuntimeError: Mismatch on aten._unique.default: Shapes torch.Size([2]) and torch.Size([1]) are not equal!
|
|
DecorateInfo(unittest.expectedFailure, 'TestFakeTensor', 'test_fake_crossref_backward_amp'),
|
|
),
|
|
sample_inputs_func=sample_inputs_index,
|
|
reference_inputs_func=partial(sample_inputs_index, reference=True)),
|
|
OpInfo('index_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.complex32),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_index,
|
|
reference_inputs_func=partial(sample_inputs_index, reference=True),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL),
|
|
OpInfo('index_select',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_index,
|
|
reference_inputs_func=partial(sample_inputs_index, reference=True),
|
|
error_inputs_func=error_inputs_index_select,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL),
|
|
OpInfo('index_add',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_index,
|
|
reference_inputs_func=partial(sample_inputs_index, reference=True),
|
|
error_inputs_func=error_inputs_index_add,
|
|
skips=(
|
|
# boolean alpha not handled properly
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestNNCOpInfo',
|
|
'test_nnc_correctness',
|
|
dtypes=(torch.bool,)),
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL),
|
|
*(OpInfo('index_reduce',
|
|
variant_test_name=reduction_type,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=2e-3, rtol=3e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive'),
|
|
),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_index_reduce,
|
|
) for reduction_type in ('mean', 'prod', 'amin', 'amax')),
|
|
OpInfo('_unsafe_masked_index',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16, torch.bool),
|
|
supports_out=False,
|
|
supports_inplace_autograd=False,
|
|
supports_scripting=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs__unsafe_masked_index,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
DecorateInfo(slowTest, 'TestDecomp', 'test_quick_core_backward',
|
|
dtypes=(torch.float64,), active_if=IS_WINDOWS),
|
|
),),
|
|
OpInfo('_unsafe_masked_index_put_accumulate',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16, torch.bool),
|
|
supports_out=False,
|
|
supports_inplace_autograd=False,
|
|
supports_scripting=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=2e-3, rtol=3e-2)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cpu'
|
|
),
|
|
),
|
|
sample_inputs_func=sample_inputs__unsafe_masked_index_put_accumulate,
|
|
skips=(
|
|
DecorateInfo(slowTest, 'TestDecomp', 'test_quick_core_backward',
|
|
dtypes=(torch.float64,), active_if=IS_WINDOWS),
|
|
),),
|
|
OpInfo('__getitem__',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_inplace_autograd=False,
|
|
supports_scripting=False,
|
|
op=torch.Tensor.__getitem__,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# AssertionError: False is not true : Scalars failed to compare as equal! 0 != 104448
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit', device_type='cuda'),),
|
|
sample_inputs_func=sample_inputs_getitem),
|
|
OpInfo('index_put',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_inplace_autograd=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
test_neg_view=False,
|
|
sample_inputs_func=sample_inputs_index_put,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped"), 'TestBwdGradients', 'test_fn_grad', dtypes=[torch.float64],
|
|
device_type='cuda', active_if=(TEST_WITH_ROCM and TEST_WITH_TORCHINDUCTOR)),
|
|
)),
|
|
OpInfo('sort',
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_sort,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], device_type='cuda'),
|
|
)),
|
|
OpInfo('unique',
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16, torch.uint16, torch.uint32, torch.uint64),
|
|
sample_inputs_func=sample_inputs_unique,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Output order is undefined when sorted=False'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('unique_consecutive',
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_unique_consecutive,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('put',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
check_batched_gradgrad=False, # vmap complains of the sizes
|
|
sample_inputs_func=sample_inputs_put),
|
|
OpInfo('take',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
check_batched_grad=False, # vmap complains of the sizes
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_take,
|
|
error_inputs_func=error_inputs_take),
|
|
OpInfo('scatter',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_scatter,
|
|
error_inputs_func=error_inputs_scatter_and_scatter_add),
|
|
UnaryUfuncInfo(
|
|
'bfloat16',
|
|
op=lambda x, *args, **kwargs: x.bfloat16(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
skips=(
|
|
# autograd tests don't handle operators that change dtype
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'bool',
|
|
op=lambda x, *args, **kwargs: x.bool(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attributis not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'byte',
|
|
op=lambda x, *args, **kwargs: x.byte(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_byte,
|
|
# The autograd test runner cannot handle functions that change dtype
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'char',
|
|
op=lambda x, *args, **kwargs: x.char(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
# The autograd test runner cannot handle functions that change dtype
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'double',
|
|
op=lambda x, *args, **kwargs: x.double(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'float',
|
|
op=lambda x, *args, **kwargs: x.float(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
skips=(
|
|
# autograd tests don't handle operators that change dtype
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'half',
|
|
op=lambda x, *args, **kwargs: x.half(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_autograd=True,
|
|
skips=(
|
|
# autograd tests don't handle operators that change dtype
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'int',
|
|
op=lambda x, *args, **kwargs: x.int(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'long',
|
|
op=lambda x, *args, **kwargs: x.long(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'short',
|
|
op=lambda x, *args, **kwargs: x.short(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'cdouble',
|
|
op=torch.Tensor.cdouble,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'cfloat',
|
|
op=torch.Tensor.cfloat,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
skips=(
|
|
# autograd tests don't handle operators that change dtype
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# RuntimeError: attribute lookup is not defined on builtin
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'chalf',
|
|
op=lambda x, *args, **kwargs: x.chalf(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_conversion,
|
|
skips=(
|
|
# autograd tests don't handle operators that change dtype
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients'),
|
|
# use of lambda doesn't work with test_normalize_operator_exhaustive
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# RuntimeError: "sum_cpu" not implemented for 'ComplexHalf'
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager',
|
|
device_type='cpu'),
|
|
# TypeError: 'int' object is not iterable
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# RuntimeError: "sum_cpu" not implemented for 'ComplexHalf'
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view',
|
|
device_type='cpu'),
|
|
# RuntimeError: "sum_cpu" not implemented for 'ComplexHalf'
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view',
|
|
device_type='cpu'),
|
|
# RuntimeError: "sum_cpu" not implemented for 'ComplexHalf'
|
|
# RuntimeError: "neg_conj_cuda" not implemented for 'ComplexHalf'
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
)
|
|
),
|
|
OpInfo('empty_like',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_like_fns,
|
|
reference_inputs_func=reference_inputs_like_fns,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
"TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCudaFuserOpInfo'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_complex_half_reference_testing'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values'),
|
|
DecorateInfo(unittest.skip("Expected: empty_like is not comparable"), 'TestCompositeCompliance',
|
|
'test_operator'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('zeros_like',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_like_fns,
|
|
supports_autograd=False,
|
|
error_inputs_sparse_func=error_inputs_sparse_like_fns,
|
|
sample_inputs_sparse_coo_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_coo),
|
|
sample_inputs_sparse_csr_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_csr),
|
|
sample_inputs_sparse_csc_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_csc),
|
|
sample_inputs_sparse_bsr_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_bsr),
|
|
sample_inputs_sparse_bsc_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_bsc),
|
|
skips=(
|
|
)),
|
|
OpInfo('ones_like',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_like_fns,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('randn',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16, torch.complex32),
|
|
op=lambda *args, **kwargs: wrapper_set_seed(torch.randn, *args, **kwargs),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_randn,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestCommon", "test_noncontiguous_samples"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
# CPU randn generates different values based on the strides of out tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type='cpu'),
|
|
# randn fails to warn when resizing its out tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDecomp', 'test_quick'),
|
|
)),
|
|
OpInfo('randn_like',
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16, torch.complex32),
|
|
op=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.randn_like, inp, *args, **kwargs),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_like_fns,
|
|
supports_autograd=False,
|
|
error_inputs_sparse_func=error_inputs_sparse_like_fns,
|
|
sample_inputs_sparse_coo_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_coo),
|
|
sample_inputs_sparse_csr_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_csr),
|
|
sample_inputs_sparse_csc_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_csc),
|
|
sample_inputs_sparse_bsr_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_bsr),
|
|
sample_inputs_sparse_bsc_func=partial(sample_inputs_sparse_like_fns, layout=torch.sparse_bsc),
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Expected: randn_like is not comparable between dtypes"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('rand_like',
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16, torch.complex32, torch.complex64, torch.complex128),
|
|
op=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.randn_like, inp, *args, **kwargs),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_like_fns,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Expected: randn_like is not comparable between dtypes"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('randint',
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
op=lambda *args, **kwargs:
|
|
wrapper_set_seed(torch.randint, *args, **kwargs),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_randint,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestCommon", "test_noncontiguous_samples"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_vmap_exhaustive"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestVmapOperatorsOpInfo", "test_op_has_batch_rule"),
|
|
# CPU randint generates different values based on the strides of out tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# randint fails to warn when resizing its out tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Tests that assume input tensor has a meaningful effect on output tensor
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Might need to skip until ROCm5.5
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_multiple_devices',
|
|
dtypes=[torch.float32, torch.int64], active_if=TEST_WITH_ROCM),
|
|
)),
|
|
OpInfo('randint_like',
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
op=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.randint_like, inp, *args, **kwargs),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_randint_like,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('full_like',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_full_like,
|
|
supports_autograd=False,
|
|
skips=(
|
|
)),
|
|
OpInfo('new_zeros',
|
|
op=lambda x, *args, **kwargs: x.new_zeros(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_new_fns,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
),
|
|
supports_autograd=False),
|
|
OpInfo('new_ones',
|
|
op=lambda x, *args, **kwargs: x.new_ones(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_new_fns,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
),
|
|
supports_autograd=False),
|
|
OpInfo('ones',
|
|
op=torch.ones,
|
|
supports_autograd=False,
|
|
supports_varargs=True,
|
|
is_factory_function=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_ones_zeros,
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
)),
|
|
OpInfo('zeros',
|
|
op=torch.zeros,
|
|
supports_autograd=False,
|
|
is_factory_function=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_ones_zeros,
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
)),
|
|
OpInfo('full',
|
|
op=torch.full,
|
|
supports_autograd=False,
|
|
is_factory_function=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_full,
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Same failure as arange: cannot find linspace in captured graph
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# RuntimeError: UNSUPPORTED DTYPE: bool
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness', dtypes=(torch.bool,)),
|
|
)),
|
|
OpInfo('new_empty',
|
|
op=lambda x, *args, **kwargs: x.new_empty(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_new_fns,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCudaFuserOpInfo'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty is not comparable"), 'TestCompositeCompliance',
|
|
'test_operator'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty is not comparable"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
supports_autograd=False),
|
|
OpInfo('new_empty_strided',
|
|
op=lambda x, *args, **kwargs: x.new_empty_strided(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=partial(sample_inputs_new_fns, is_strided=True),
|
|
supports_autograd=False,
|
|
skips=(
|
|
# FX failed to normalize op
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Lazy tensor failures
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestLazyOpInfo', 'test_correctness'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestLazyOpInfo', 'test_correctness_with_reusing_ir'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestCommon', 'test_non_standard_bool_values'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestCompositeCompliance', 'test_operator'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestDecomp', 'test_comprehensive'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestDecomp', 'test_quick'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestProxyTensorOpInfo', 'test_make_fx_exhaustive'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestProxyTensorOpInfo', 'test_make_fx_fake_exhaustive'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestProxyTensorOpInfo', 'test_make_fx_symbolic_exhaustive'),
|
|
DecorateInfo(unittest.skip("Expected: new_empty_strided is not comparable"),
|
|
'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('empty_strided',
|
|
op=lambda inp, *args, **kwargs: wrapper_set_seed(torch.empty_strided, inp, *args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.bool, torch.half),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
sample_inputs_func=sample_inputs_empty_strided,
|
|
skips=(
|
|
# FX failed to normalize op - add the op to the op_skip list.
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"), 'TestCompositeCompliance', 'test_operator'),
|
|
# Lazy tensor failures
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"), 'TestLazyOpInfo'),
|
|
# RuntimeError: unsupported operation: more than one element of the written-to tensor refers to a single
|
|
# memory location. Please clone() the tensor before performing the operation.
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_meta_outplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_outplace'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_dispatch_symbolic_meta_outplace_all_strides'),
|
|
)),
|
|
OpInfo('empty',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_empty,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCudaFuserOpInfo'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"), 'TestCompositeCompliance',
|
|
'test_operator'),
|
|
# requires_grad doesn't exist in the jit schema
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestLazyOpInfo'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('eye',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_eye,
|
|
error_inputs_func=error_inputs_eye,
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# TODO: same as this?
|
|
# https://github.com/pytorch/pytorch/issues/81774
|
|
# also see: arange, new_full
|
|
# fails to match any schemas despite working in the interpreter
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
# fails to match any schemas despite working in the interpreter
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), "TestCommon", "test_noncontiguous_samples"),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
)),
|
|
OpInfo('empty_permuted',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_empty_permuted,
|
|
error_inputs_func=error_inputs_empty_permuted,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCudaFuserOpInfo'),
|
|
# Empty tensor data is garbage so it's hard to make comparisons with it.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values'),
|
|
DecorateInfo(unittest.skip("Expected: empty_permuted is not comparable"), 'TestCompositeCompliance',
|
|
'test_operator'),
|
|
# requires_grad doesn't exist in the jit schema
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
DecorateInfo(unittest.skip("Expected: empty_permuted is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: empty_permuted is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: empty_permuted is not comparable"),
|
|
'TestLazyOpInfo'),
|
|
DecorateInfo(unittest.skip("Expected: empty_permuted is not comparable"),
|
|
'TestCommon', 'test_complex_half_reference_testing'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)),
|
|
OpInfo('scalar_tensor',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_scalar_tensor,
|
|
supports_autograd=False,
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# fails to match any schemas despite working in the interpreter
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
# fails to match any schemas despite working in the interpreter
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), "TestCommon", "test_noncontiguous_samples"),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
OpInfo('new_full',
|
|
op=lambda x, *args, **kwargs: x.new_full(*args, **kwargs),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_new_full,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
),
|
|
supports_autograd=False),
|
|
OpInfo('multinomial',
|
|
op=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.multinomial, inp, *args, **kwargs),
|
|
method_variant=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.Tensor.multinomial, inp, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_multinomial,
|
|
error_inputs_func=error_inputs_multinomial,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Strides are not the same!
|
|
# This may not be reproducible in CI
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu')),
|
|
supports_autograd=False),
|
|
OpInfo('normal',
|
|
op=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.normal, inp, *args, **kwargs),
|
|
# The inplace variant (Tensor.normal_) is different from torch.normal
|
|
inplace_variant=None,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
dtypesIfCUDA=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_normal_tensor_first,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Tensor-likes are not close!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# Computed gradient is incorrect -- would be an exfail but gradgrad somehow passes
|
|
DecorateInfo(unittest.skip("Gradients are incorrect!"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Gradients are incorrect!"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
# RuntimeError: Difference from {dtype} is larger with decomposition
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_comprehensive'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_quick'),
|
|
# The inplace variant (Tensor.normal_) is different from torch.normal
|
|
# inplace varaint Tensor.normal_ is decomposed using randn_like()
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMeta', 'test_dispatch_symbolic_meta_outplace_all_strides'))),
|
|
OpInfo('normal',
|
|
# This has its own variant b/c OpInfos assume the first arg is a Tensor but it is not here
|
|
variant_test_name='number_mean',
|
|
op=lambda std, mean, *args, **kwargs:
|
|
wrapper_set_seed(torch.normal, mean, std, *args, **kwargs),
|
|
# The inplace variant (Tensor.normal_) is different from torch.normal
|
|
inplace_variant=None,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
dtypesIfCUDA=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_out=True,
|
|
sample_inputs_func=sample_inputs_normal_tensor_second,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_backward'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBwdGradients'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestEagerFusionOpInfo'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOperators'),
|
|
# AssertionError
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_comprehensive'),
|
|
# AssertionError
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDecomp', 'test_quick'),
|
|
# AssertionError in CUDA variant
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFakeTensor', device_type='cuda'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestDeviceUtils', 'test_device_mode_ops'))),
|
|
OpInfo('bernoulli',
|
|
op=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.bernoulli, inp, *args, **kwargs),
|
|
# The inplace variant (Tensor.bernoulli_) is different from torch.bernoulli
|
|
inplace_variant=None,
|
|
method_variant=lambda inp, *args, **kwargs:
|
|
wrapper_set_seed(torch.Tensor.bernoulli, inp, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_bernoulli,
|
|
error_inputs_func=error_inputs_bernoulli,
|
|
skips=(
|
|
# vmap: We do not yet support calling random operations inside of vmap
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Expected RuntimeError when doing an unsafe cast from a result of
|
|
# dtype torch.float32 into an out= with dtype torch.lon
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'))),
|
|
OpInfo('scatter_add',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_scatter_add,
|
|
error_inputs_func=error_inputs_scatter_and_scatter_add,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
),
|
|
OpInfo('stack',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_stack,
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/77046
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
),
|
|
),
|
|
OpInfo('_chunk_cat',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_chunk_cat,
|
|
error_inputs_func=error_inputs_chunk_cat,
|
|
supports_autograd=False,
|
|
supports_out=True,
|
|
),
|
|
OpInfo('hstack',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_hstack_dstack_vstack,
|
|
error_inputs_func=error_inputs_hstack_dstack_vstack,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
),
|
|
BinaryUfuncInfo('hypot',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.half),
|
|
dtypesIfCUDA=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_rhs_python_scalar=False),
|
|
OpInfo('histogram',
|
|
dtypes=floating_types(),
|
|
dtypesIfCUDA=_dispatch_dtypes(), # histogram is only implemented on CPU
|
|
sample_inputs_func=sample_inputs_histogram,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# JIT tests don't work with Tensor keyword arguments
|
|
# https://github.com/pytorch/pytorch/issues/58507
|
|
# RuntimeError:
|
|
# undefined value tensor:
|
|
# File "<string>", line 3
|
|
# def the_method(i0):
|
|
# return torch.histogram(i0, 1, weight=tensor(-0.5735, dtype=torch.float32), density=False)
|
|
# ~~~~~~ <--- HERE
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Not Implemented on XLA.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOpInfo', device_type='xla'),
|
|
)),
|
|
OpInfo('histogramdd',
|
|
dtypes=floating_types(),
|
|
dtypesIfCUDA=_dispatch_dtypes(), # histogramdd is only implemented on CPU
|
|
sample_inputs_func=sample_inputs_histogramdd,
|
|
error_inputs_func=error_inputs_histogramdd,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# Not implemented on CUDA
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_errors', device_type='cuda'),
|
|
# JIT tests don't work with Tensor keyword arguments
|
|
# https://github.com/pytorch/pytorch/issues/58507
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('histc',
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64),
|
|
sample_inputs_func=sample_inputs_histc,
|
|
supports_out=True,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# CUDA histc returns a float tensor but does not correctly warn when passed an integral out tensor
|
|
# "AssertionError: RuntimeError not raised : Expected RuntimeError when doing an unsafe cast
|
|
# from a result of dtype torch.float32 into an out= with dtype torch.long"
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out', device_type='cuda'),
|
|
)),
|
|
OpInfo('bincount',
|
|
dtypes=integral_types_and(),
|
|
sample_inputs_func=sample_inputs_bincount,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# JIT tests don't work with Tensor keyword arguments
|
|
# https://github.com/pytorch/pytorch/issues/58507
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('bucketize',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_bucketize,
|
|
reference_inputs_func=reference_inputs_bucketize,
|
|
error_inputs_func=error_inputs_bucketize,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# JIT tests don't work with Tensor keyword arguments
|
|
DecorateInfo(unittest.skip("Expected failure!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('searchsorted',
|
|
dtypes=all_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=all_types_and(torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_searchsorted,
|
|
supports_autograd=False,
|
|
ref=reference_searchsorted,
|
|
skips=(
|
|
# JIT tests don't work with Tensor keyword arguments
|
|
# https://github.com/pytorch/pytorch/issues/58507
|
|
DecorateInfo(unittest.skip("Expected failure!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
)),
|
|
OpInfo('cat',
|
|
ref=_cat_np,
|
|
aliases=('concat', 'concatenate'),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.complex32),
|
|
sample_inputs_func=sample_inputs_cat_concat,
|
|
reference_inputs_func=reference_inputs_cat,
|
|
error_inputs_func=error_inputs_cat,
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
assert_autodiffed=True,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/89353
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_numpy_ref_mps'),
|
|
# RuntimeError: Arguments for call not valid.
|
|
# Expected a value of type 'List[Tensor]' for argument
|
|
# 'tensors' but instead found type 'Tensor (inferred)'.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_jit_alias_remapping'),
|
|
# see https://github.com/pytorch/pytorch/issues/71286
|
|
DecorateInfo(unittest.expectedFailure, 'TestNNCOpInfo', 'test_nnc_correctness'),
|
|
# see https://github.com/pytorch/pytorch/issues/99806
|
|
# RuntimeError: The size of tensor a (25) must match the size of tensor b (0) at non-singleton dimension 0.
|
|
DecorateInfo(unittest.expectedFailure, 'TestBwdGradients', 'test_fn_gradgrad'),
|
|
)),
|
|
OpInfo('unbind',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
ref=reference_unbind,
|
|
sample_inputs_func=sample_inputs_unbind,
|
|
error_inputs_func=error_inputs_unbind,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_gradgrad=True,
|
|
supports_out=False,
|
|
),
|
|
OpInfo('vstack',
|
|
aliases=('row_stack',),
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_hstack_dstack_vstack,
|
|
error_inputs_func=error_inputs_hstack_dstack_vstack,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# RuntimeError: _fn() Expected a value of type
|
|
# 'Tensor (inferred)' for argument 't0' but instead found type 'tuple'.
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_jit_alias_remapping'),)),
|
|
OpInfo('dstack',
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_hstack_dstack_vstack,
|
|
error_inputs_func=error_inputs_hstack_dstack_vstack,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
),
|
|
OpInfo('unfold',
|
|
op=lambda x, *args: x.unfold(*args),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
backward_dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_gradgrad=False,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Skip operator schema test because this is a functional and not an operator
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
),
|
|
sample_inputs_func=sample_inputs_unfold),
|
|
OpInfo('unfold_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
backward_dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_gradgrad=False,
|
|
# See https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_unfold),
|
|
OpInfo('msort',
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
check_batched_gradgrad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_msort,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/139972
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], device_type='cuda', active_if=TEST_WITH_ROCM),
|
|
)),
|
|
OpInfo('movedim',
|
|
aliases=('moveaxis',),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_movedim_moveaxis,
|
|
reference_inputs_func=reference_movedim_moveaxis,
|
|
error_inputs_func=error_movedim_moveaxis),
|
|
OpInfo('renorm',
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_renorm,
|
|
error_inputs_func=error_inputs_renorm,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# RuntimeError: Difference from float64 is larger with decomposition
|
|
# linalg_vector_norm.default than original on output 0.
|
|
# Original max diff: 2.560596747969157e-07,
|
|
# Decomp max diff: 1.8187482915266173e-06
|
|
DecorateInfo(unittest.skip("Inconsistent accuracy"), 'TestDecomp', 'test_comprehensive',
|
|
device_type='cpu', dtypes=(torch.float16,)),
|
|
)),
|
|
ShapeFuncInfo('repeat',
|
|
op=lambda x, dims: x.repeat(dims),
|
|
ref=np.tile,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_repeat_tile,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
)),
|
|
OpInfo('squeeze',
|
|
ref=_squeeze_ref,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
assert_autodiffed=True,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
assert_jit_shape_analysis=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_squeeze),
|
|
OpInfo('squeeze',
|
|
ref=_squeeze_ref,
|
|
variant_test_name="multiple",
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
assert_autodiffed=True,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_squeeze_multiple),
|
|
OpInfo('squeeze_copy',
|
|
ref=_squeeze_ref,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_squeeze,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
'TestJit',
|
|
'test_variant_consistency_jit',
|
|
dtypes=(torch.float32,),
|
|
),
|
|
)),
|
|
UnaryUfuncInfo(
|
|
'fill',
|
|
ref=_fill_np,
|
|
method_variant=None,
|
|
sample_kwargs=_fill_sample_kwargs,
|
|
sample_inputs_func=partial(sample_inputs_elementwise_unary, op_kwargs={'value': True}),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
dtypes=all_types_and_complex_and(torch.complex32, torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
skips=(
|
|
# JIT has issue when op is passed as lambda
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip("No fill_ op"), 'TestCudaFuserOpInfo'),
|
|
DecorateInfo(unittest.skip("No fill_ op"), 'TestNNCOpInfo'),
|
|
)),
|
|
OpInfo('resize_',
|
|
op=lambda x, shape: x.clone().resize_(shape),
|
|
method_variant=None,
|
|
inplace_variant=torch.Tensor.resize_,
|
|
# the test fails because resize_ doesn't work with imag views as expected by the test
|
|
# https://github.com/pytorch/pytorch/issues/65945
|
|
test_neg_view=False,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# Cannot resize variables that require grad
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_dtypes'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.skip("Allowed exception"), 'TestCompositeCompliance', 'test_operator'),
|
|
),
|
|
sample_inputs_func=sample_inputs_resize_ops),
|
|
OpInfo('resize_as_',
|
|
op=lambda x, other: torch.resize_as_(x.clone(), other),
|
|
method_variant=None,
|
|
inplace_variant=torch.Tensor.resize_as_,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# Cannot resize variables that require grad
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_dtypes'),
|
|
DecorateInfo(unittest.skip('Allowed exemption'), 'TestCompositeCompliance', 'test_operator'),
|
|
),
|
|
sample_inputs_func=sample_inputs_resize_ops),
|
|
OpInfo('take_along_dim',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_take_along_dim,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
decorators=(
|
|
# RuntimeError: view size is not compatible with input tensor's size and stride
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"),
|
|
)),
|
|
ShapeFuncInfo('tile',
|
|
ref=np.tile,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_repeat_tile),
|
|
OpInfo('trapz', # TODO: in the future, 'trapz' should be made a proper alias of 'trapezoid'
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=9e-4, rtol=4.3e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda'
|
|
),
|
|
],
|
|
sample_inputs_func=sample_trapezoid),
|
|
OpInfo('trapezoid',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.half: tol(atol=9e-4, rtol=4.3e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda'
|
|
),
|
|
],
|
|
sample_inputs_func=sample_trapezoid),
|
|
OpInfo('cumulative_trapezoid',
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
supports_out=False,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=4e-3, rtol=4e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive',
|
|
),
|
|
),
|
|
sample_inputs_func=sample_cumulative_trapezoid,),
|
|
OpInfo('unsqueeze',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
assert_jit_shape_analysis=True,
|
|
assert_autodiffed=True,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
sample_inputs_func=sample_unsqueeze),
|
|
OpInfo('unsqueeze_copy',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
assert_jit_shape_analysis=True,
|
|
assert_autodiffed=True,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
sample_inputs_func=sample_unsqueeze,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestDTensorOps', 'test_dtensor_op_db'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
'TestJit',
|
|
'test_variant_consistency_jit',
|
|
dtypes=(torch.float32,),
|
|
),
|
|
)),
|
|
BinaryUfuncInfo('xlogy',
|
|
aliases=('special.xlogy',),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
promotes_int_to_float=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_one_python_scalar=True,
|
|
# We don't test 0 as the gradient will be NaN and it'll break
|
|
rhs_make_tensor_kwargs=dict(low=0.01)),
|
|
OpInfo('zero_',
|
|
op=lambda x: torch.zero_(x.clone()),
|
|
method_variant=None,
|
|
inplace_variant=torch.Tensor.zero_,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_gradgrad=True,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
sample_inputs_func=sample_inputs_zero_),
|
|
OpInfo('logsumexp',
|
|
aliases=('special.logsumexp',),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
gradcheck_fast_mode=False,
|
|
sample_inputs_func=sample_inputs_logsumexp,
|
|
reference_inputs_func=reference_inputs_logsumexp),
|
|
OpInfo('trace',
|
|
dtypes=all_types_and_complex(),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.chalf, torch.bool, torch.half, torch.bfloat16),
|
|
error_inputs_func=error_inputs_trace,
|
|
supports_inplace_autograd=False,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_trace),
|
|
OpInfo('transpose',
|
|
ref=_numpy_ref_transpose,
|
|
aliases=('swapdims', 'swapaxes'),
|
|
assert_jit_shape_analysis=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_transpose_swapdims),
|
|
OpInfo('transpose_copy',
|
|
assert_jit_shape_analysis=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_transpose_swapdims,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestDTensorOps', 'test_dtensor_op_db'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
'TestJit',
|
|
'test_variant_consistency_jit',
|
|
dtypes=(torch.float32,)
|
|
),
|
|
)),
|
|
OpInfo('T',
|
|
op=lambda x: x.T,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, "TestJit", "test_variant_consistency_jit"),),
|
|
sample_inputs_func=sample_inputs_T,
|
|
error_inputs_func=error_inputs_T),
|
|
OpInfo('H',
|
|
op=lambda x: x.H,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, "TestJit", "test_variant_consistency_jit"),),
|
|
sample_inputs_func=sample_inputs_T),
|
|
OpInfo('mT',
|
|
op=lambda x: x.mT,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, "TestJit", "test_variant_consistency_jit"),),
|
|
sample_inputs_func=sample_inputs_adjoint),
|
|
OpInfo('mH',
|
|
op=lambda x: x.mH,
|
|
aliases=('adjoint',),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.half, torch.chalf),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, "TestJit", "test_variant_consistency_jit"),),
|
|
sample_inputs_func=sample_inputs_adjoint),
|
|
OpInfo('tril',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
error_inputs_func=error_inputs_tril_triu,
|
|
sample_inputs_func=sample_inputs_tril_triu),
|
|
OpInfo('triu',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
error_inputs_func=error_inputs_tril_triu,
|
|
sample_inputs_func=sample_inputs_tril_triu),
|
|
OpInfo('triu_indices',
|
|
dtypes=_dispatch_dtypes((torch.int32, torch.int64)),
|
|
sample_inputs_func=sample_inputs_trilu_indices,
|
|
ref=lambda h, w, ofs=0, dtype=torch.long, device='cpu' : np.array(np.triu_indices(h, ofs, w), dtype=dtype),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
OpInfo('tril_indices',
|
|
dtypes=_dispatch_dtypes((torch.int32, torch.int64)),
|
|
sample_inputs_func=sample_inputs_trilu_indices,
|
|
ref=lambda h, w, ofs=0, dtype=torch.long, device='cpu' : np.array(np.tril_indices(h, ofs, w), dtype=dtype),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
OpInfo('kron',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_inplace_autograd=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_kron,
|
|
decorators=(
|
|
# RuntimeError: view size is not compatible with input tensor's size and stride
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"),
|
|
)),
|
|
OpInfo('inner',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfROCM=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_inner,
|
|
),
|
|
OpInfo('tensordot',
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfROCM=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
sample_inputs_func=sample_inputs_tensordot,
|
|
skips=(
|
|
# Skip operator schema test because this is a functional and not an operator.
|
|
# Reference: https://github.com/pytorch/pytorch/issues/54574
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
)
|
|
),
|
|
OpInfo('to_sparse',
|
|
op=lambda x, *args: x.to_sparse(*args),
|
|
sample_inputs_func=sample_inputs_to_sparse,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
backward_dtypes=floating_types(),
|
|
backward_dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
check_batched_grad=False,
|
|
check_batched_gradgrad=False,
|
|
skips=(
|
|
# NotImplementedError: Could not run 'aten::normal_' with arguments from the 'SparseCPU' backend
|
|
DecorateInfo(unittest.skip(""), 'TestCommon', 'test_noncontiguous_samples'),
|
|
# TODO: FIXME: complex inputs requiring grad error in forward
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_dtypes'),
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# Allowed exception: sparse tensors don't have strides
|
|
DecorateInfo(unittest.skip("Allowed exception"), 'TestCompositeCompliance', 'test_operator'),
|
|
DecorateInfo(unittest.skip("Allowed exception"), 'TestCompositeCompliance', 'test_backward'),
|
|
DecorateInfo(unittest.skip("Allowed exception"), 'TestTags', 'test_tags'),
|
|
# TODO: implement csr.to_sparse(sample_dim) where sampled_dim is 1.
|
|
DecorateInfo(unittest.skip("csr.to_sparse(1) not implemented. Skipped!"),
|
|
'TestSparseCSR', 'test_sparse_csr_consistency'),
|
|
# Compiler issue on ROCm. Might need to skip until ROCm5.5
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], active_if=TEST_WITH_ROCM),
|
|
)
|
|
),
|
|
OpInfo('logcumsumexp',
|
|
dtypes=floating_and_complex_types_and(torch.bfloat16, torch.half),
|
|
backward_dtypes=floating_and_complex_types_and(torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# AssertionError: UserWarning not triggered : Resized a non-empty tensor but did not warn about it.
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning', device_type='cuda'),
|
|
# RuntimeError: "max_values_cpu" not implemented for 'ComplexDouble'
|
|
# Falling back to non-numerically stablized exp, causing nan in the results.
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_forward_mode_AD', dtypes=[torch.complex128]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_fn_fwgrad_bwgrad', dtypes=[torch.complex128]),
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=7e-5, rtol=6e-3),
|
|
}),
|
|
"TestInductorOpInfo",
|
|
"test_comprehensive",
|
|
device_type="cuda"
|
|
),
|
|
),
|
|
sample_inputs_func=sample_inputs_logcumsumexp,
|
|
error_inputs_func=error_inputs_logcumsumexp),
|
|
UnaryUfuncInfo('sigmoid',
|
|
aliases=('special.expit', 'nn.functional.sigmoid'),
|
|
aten_backward_name='sigmoid_backward',
|
|
ref=reference_sigmoid if TEST_SCIPY else None,
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.complex64: 1e-1,
|
|
torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/56012
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.complex64, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.chalf, torch.complex64, torch.cdouble])),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.complex32, torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
assert_autodiffed=True,
|
|
# sigmoid(z) = 1 / (1 + exp(-z)), at z = j * pi * odd_number, the denominator is zero
|
|
reference_numerics_filter=NumericsFilter(
|
|
condition=lambda x: (close_to_int(x / (math.pi * 1j))
|
|
if x.is_complex() else x.new_tensor(False, dtype=torch.bool)),
|
|
safe_val=0)),
|
|
UnaryUfuncInfo('digamma',
|
|
ref=scipy.special.digamma if TEST_SCIPY else None,
|
|
aliases=('special.psi', 'special.digamma',),
|
|
decorators=(precisionOverride({torch.float16: 5e-1}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True),
|
|
UnaryUfuncInfo('erf',
|
|
ref=scipy.special.erf if TEST_SCIPY else None,
|
|
aliases=('special.erf', ),
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped! sparse backward not supported"),
|
|
'TestSparseUnaryUfuncs', 'test_sparse_fn_grad'),
|
|
|
|
),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
assert_jit_shape_analysis=True,
|
|
supports_sparse=True,
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True),
|
|
UnaryUfuncInfo('erfc',
|
|
ref=scipy.special.erfc if TEST_SCIPY else None,
|
|
aliases=('special.erfc', ),
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.bfloat16: 1e-2}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True),
|
|
UnaryUfuncInfo('erfinv',
|
|
ref=scipy.special.erfinv if TEST_SCIPY else None,
|
|
aliases=('special.erfinv', ),
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.bfloat16: 1e-2,
|
|
torch.float32: 1e-4}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_sparse_csr=True,
|
|
supports_sparse_csc=True,
|
|
supports_sparse_bsr=True,
|
|
supports_sparse_bsc=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
domain=(-1, 1),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/pull/49155#issuecomment-742664611
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
active_if=TEST_SCIPY and version.parse(scipy.__version__) < version.parse("1.4.0")),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
active_if=TEST_SCIPY and version.parse(scipy.__version__) < version.parse("1.4.0")),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_small',
|
|
active_if=TEST_SCIPY and version.parse(scipy.__version__) < version.parse("1.4.0")),
|
|
)),
|
|
OpInfo("nn.functional.smooth_l1_loss",
|
|
ref=reference_smooth_l1_loss,
|
|
sample_inputs_func=sample_inputs_smooth_l1_loss,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
backward_dtypes=floating_types_and(torch.bfloat16),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
backward_dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalTypeINTERNAL ASSERT FAILED
|
|
# at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270, please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, "TestJit", "test_variant_consistency_jit"),)),
|
|
OpInfo(
|
|
"nn.functional.l1_loss",
|
|
ref=loss_reference_reduction_wrapper(lambda input, target: np.abs(input - target)),
|
|
sample_inputs_func=sample_inputs_l1_loss,
|
|
error_inputs_func=error_inputs_l1_loss,
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalTypeINTERNAL ASSERT FAILED
|
|
# at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270, please report a bug to PyTorch.
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32,),
|
|
),
|
|
),
|
|
),
|
|
UnaryUfuncInfo('lgamma',
|
|
ref=reference_lgamma if TEST_SCIPY else None,
|
|
aliases=('special.gammaln', ),
|
|
decorators=(precisionOverride({torch.float16: 7e-1}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/pull/50140#issuecomment-756150214
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.float32, torch.float64], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.float32, torch.float64], active_if=IS_WINDOWS),
|
|
),
|
|
# lgamma have multiple singularities at x <= 0
|
|
reference_numerics_filter=NumericsFilter(condition=lambda x: x < 0.1, safe_val=1)),
|
|
OpInfo(
|
|
'logdet',
|
|
dtypes=floating_and_complex_types(),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_linalg_det_logdet_slogdet,
|
|
decorators=[skipCUDAIfNoMagma, skipCPUIfNoLapack]),
|
|
# `log_softmax` supports different dtypes based on whether `dtype` argument,
|
|
# is passed or not. Hence two OpInfo entries, one with dtype and other without.
|
|
OpInfo(
|
|
'log_softmax',
|
|
aliases=('special.log_softmax', 'nn.functional.log_softmax'),
|
|
supports_out=True,
|
|
aten_backward_name='_log_softmax_backward_data',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_softmax_variant,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True),
|
|
OpInfo(
|
|
'log_softmax',
|
|
variant_test_name='with_dtype',
|
|
aliases=('special.log_softmax', 'nn.functional.log_softmax'),
|
|
supports_out=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=partial(sample_inputs_softmax_variant, with_dtype=True),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True),
|
|
UnaryUfuncInfo('logit',
|
|
aten_backward_name='logit_backward',
|
|
ref=scipy.special.logit if TEST_SCIPY else None,
|
|
domain=(0, 1),
|
|
aliases=('special.logit', ),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_float=True,
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-1,
|
|
torch.float16: 5e-1}),),
|
|
dtypes=all_types_and(torch.bool, torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_logit),
|
|
OpInfo('where',
|
|
# Currently only the `input` is tested in gradcheck.
|
|
# If we pass `condition` first, none of the input which supports
|
|
# autograd will be tested. Hence the following lambda.
|
|
op=lambda self, condition, other, **kwargs: torch.where(condition, self, other, **kwargs),
|
|
ref=lambda self, condition, other: np.where(condition, self, other),
|
|
sample_inputs_func=sample_inputs_where,
|
|
reference_inputs_func=reference_inputs_where,
|
|
error_inputs_func=error_inputs_where,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=(
|
|
DecorateInfo(onlyCUDA, "TestCommon", 'test_errors'),),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
),
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.half, torch.bfloat16, torch.chalf)),
|
|
OpInfo('nonzero',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_nonzero,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# nonzero(): argument 'out' must be Tensor, not tuple
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# https://github.com/pytorch/pytorch/issues/67458
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# nonzero is not raising a warning when the out is resized
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
# Can't find schemas for this operator for some reason
|
|
DecorateInfo(unittest.expectedFailure, 'TestOperatorSignatures', 'test_get_torch_func_signature_exhaustive'),
|
|
# Compiler issue on ROCm. Might need to skip until ROCm5.5
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], active_if=TEST_WITH_ROCM),
|
|
)),
|
|
OpInfo('nonzero_static',
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_nonzero_static,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
decorators=[onlyCPU],
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out_warning'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDTensorOps', 'test_dtensor_op_db'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestInductorOpInfo', 'test_comprehensive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestVmapOperatorsOpInfo', 'test_op_has_batch_rule'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], active_if=TEST_WITH_ROCM),
|
|
)),
|
|
# Following tests are for jiterator's python interface
|
|
# Jiterator can be used to author elementwise CUDA kernel
|
|
# jiterator._create_jit_fn returns a callable that behaves like a regular pytorch op
|
|
# See create_jit_fn in jiterator.py for more information
|
|
UnaryUfuncInfo(
|
|
'jiterator_unary',
|
|
op=torch.cuda.jiterator._create_jit_fn("template <typename T> T unary(T x) { return x * x + x; }"),
|
|
ref=lambda x: x * x + x,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.bool),
|
|
supports_out=False,
|
|
supports_autograd=False, # jiterator ops doesn't have backward defined
|
|
decorators=[
|
|
onlyCUDA,
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-02, rtol=1e-02)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal'),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-02, rtol=1e-02)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_hard'),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-02, rtol=1e-02)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_normal'),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-02, rtol=1e-02)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_small'),
|
|
],
|
|
skips=(
|
|
# Jiterator ops doesn't support neg or conj view
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Jiterator ops doesn't support CompositeCompliantTensor
|
|
# Following test should expectedFailure, but it's causing cascading failures in CUDA, thus skipped
|
|
DecorateInfo(unittest.skip("skip"), 'TestCompositeCompliance', 'test_operator'),
|
|
# Skip reference_numerics tests for bool type, as the defined function doesn't work for bool
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
dtypes=[torch.bool]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_hard',
|
|
dtypes=[torch.bool]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_normal',
|
|
dtypes=[torch.bool]),
|
|
# ROCm generates -inf+infj instead of nan+infj for complex64 for some of the results
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_large',
|
|
dtypes=[torch.complex64], active_if=TEST_WITH_ROCM),
|
|
# Expected failure: torch.jiterator_unary is not a valid op
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Skip Nvfuser
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCudaFuserOpInfo'),
|
|
)
|
|
),
|
|
BinaryUfuncInfo(
|
|
'jiterator_binary',
|
|
op=torch.cuda.jiterator._create_jit_fn(
|
|
"template <typename T> T binary(T x, T y, T alpha) { return x + alpha * y; }", alpha=1),
|
|
ref=lambda input, other, *, alpha=1: np.add(input, other) if alpha == 1 \
|
|
else np.add(input, np.multiply(alpha, other)),
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.bool),
|
|
sample_inputs_func=partial(sample_inputs_jiterator, num_inputs=2, alpha=-3.14),
|
|
supports_out=False,
|
|
supports_autograd=False, # jiterator ops doesn't have backward defined
|
|
supports_rhs_python_scalar=False,
|
|
decorators=[onlyCUDA],
|
|
skips=(
|
|
# Jiterator ops doesn't support neg or conj view
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Jiterator ops doesn't support CompositeCompliantTensor
|
|
# Following test should expectedFailure, but it's causing cascading failures in CUDA, thus skipped
|
|
DecorateInfo(unittest.skip("skip"), 'TestCompositeCompliance', 'test_operator'),
|
|
# Expected failure: torch.jiterator_binary is not a valid op
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Skip Nvfuser
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCudaFuserOpInfo'),
|
|
)
|
|
),
|
|
OpInfo(
|
|
'jiterator_4inputs_with_extra_args',
|
|
op=torch.cuda.jiterator._create_jit_fn(
|
|
"template <typename T> T binary(T i0, T i1, T i2, T i3, T alpha, T beta) { return alpha * i0 + beta * i1 + i2 + i3; }",
|
|
alpha=1, beta=1),
|
|
ref=lambda i0, i1, i2, i3, *, alpha=1, beta=1: alpha * i0 + beta * i1 + i2 + i3,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.bool),
|
|
sample_inputs_func=partial(sample_inputs_jiterator, num_inputs=4, alpha=3.14, beta=-4.20),
|
|
supports_out=False,
|
|
supports_autograd=False, # jiterator ops doesn't have backward defined
|
|
decorators=[onlyCUDA],
|
|
skips=(
|
|
# Jiterator ops doesn't support neg or conj view
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Jiterator ops doesn't support CompositeCompliantTensor
|
|
# Following test should expectedFailure, but it's causing cascading failures in CUDA, thus skipped
|
|
DecorateInfo(unittest.skip("skip"), 'TestCompositeCompliance', 'test_operator'),
|
|
# Expected failure: torch.jiterator_4inputs_with_extra_args is not a valid op
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Skip Nvfuser
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCudaFuserOpInfo'),
|
|
)
|
|
),
|
|
BinaryUfuncInfo(
|
|
'jiterator_binary_return_by_ref',
|
|
op=torch.cuda.jiterator._create_multi_output_jit_fn(
|
|
"""
|
|
template <typename T>
|
|
void binary_return_by_ref(T i0, T i1, T& out0) {
|
|
out0 = i0 + i1;
|
|
}
|
|
""",
|
|
num_outputs=1),
|
|
ref=operator.add,
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.bool),
|
|
sample_inputs_func=partial(sample_inputs_jiterator, num_inputs=2, alpha=-0.42),
|
|
supports_out=False,
|
|
supports_autograd=False, # jiterator ops doesn't have backward defined
|
|
supports_rhs_python_scalar=False,
|
|
decorators=[onlyCUDA],
|
|
skips=(
|
|
# Jiterator ops doesn't support neg or conj view
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Jiterator ops doesn't support CompositeCompliantTensor
|
|
# Following test should expectedFailure, but it's causing cascading failures in CUDA, thus skipped
|
|
DecorateInfo(unittest.skip("skip"), 'TestCompositeCompliance', 'test_operator'),
|
|
# Expected failure: torch.jiterator_4inputs_with_extra_args is not a valid op
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Skip Nvfuser
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCudaFuserOpInfo'),
|
|
)
|
|
),
|
|
OpInfo(
|
|
'jiterator_2inputs_2outputs',
|
|
op=torch.cuda.jiterator._create_multi_output_jit_fn(
|
|
"""
|
|
template <typename T>
|
|
void binary_2outputs(T i0, T i1, T& out0, T& out1) {
|
|
out0 = i0 + i1;
|
|
out1 = i0 - i1;
|
|
}
|
|
""",
|
|
num_outputs=2),
|
|
ref=lambda i0, i1, *, alpha=1: (i0 + i1, i0 - i1),
|
|
dtypes=all_types_and_complex_and(torch.bfloat16, torch.float16, torch.bool),
|
|
sample_inputs_func=partial(sample_inputs_jiterator, num_inputs=2),
|
|
supports_out=False,
|
|
supports_autograd=False, # jiterator ops doesn't have backward defined
|
|
decorators=[onlyCUDA],
|
|
skips=(
|
|
# Jiterator ops doesn't support neg or conj view
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
# Jiterator ops doesn't support CompositeCompliantTensor
|
|
# Following test should expectedFailure, but it's causing cascading failures in CUDA, thus skipped
|
|
DecorateInfo(unittest.skip("skip"), 'TestCompositeCompliance', 'test_operator'),
|
|
# Expected failure: torch.jiterator_4inputs_with_extra_args is not a valid op
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# Skip Nvfuser
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCudaFuserOpInfo'),
|
|
)
|
|
),
|
|
# `torch.norm` has multiple code paths depending on the value of `p`.
|
|
# These paths have different dtype support. Also JIT supports,
|
|
# most variants but not all of them. So we split the OpInfo entries,
|
|
# for `norm` based on the code-paths and JIT support.
|
|
OpInfo(
|
|
"norm",
|
|
sample_inputs_func=sample_inputs_norm,
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16, torch.chalf),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
# TODO Benchmark again with the new implementation
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
check_batched_forward_grad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# Dispatches in Python to vector_norm. Not sure how to make this test happy
|
|
# Happens to pass on complex64. Also a mystery
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.float32,)),)
|
|
),
|
|
OpInfo('norm',
|
|
variant_test_name='nuc',
|
|
sample_inputs_func=sample_inputs_norm_nuc,
|
|
decorators=[skipCUDAIfNoMagmaAndNoCusolver, skipCPUIfNoLapack],
|
|
check_batched_gradgrad=False,
|
|
# torch.autograd.gradcheck.GradcheckError: While computing batched gradients
|
|
# got: Could not allocate memory to change Tensor SizesAndStrides!
|
|
check_batched_forward_grad=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_and_complex_types(),
|
|
dtypesIfCUDA=floating_and_complex_types(),
|
|
skips=(
|
|
# Dispatches in Python to matrix_norm. Not sure how to make this test happy
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.complex64, torch.float32,)),)
|
|
),
|
|
OpInfo('norm',
|
|
variant_test_name='fro',
|
|
sample_inputs_func=sample_inputs_norm_fro,
|
|
dtypes=floating_and_complex_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
# torch.autograd.gradcheck.GradcheckError: While computing batched gradients
|
|
# got: Could not allocate memory to change Tensor SizesAndStrides!
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# MPS has some mild accuracy issues for float16. We divide the tolerances by 10
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-4, rtol=0.01)}),
|
|
'TestConsistency',
|
|
'test_output_match',
|
|
|
|
),
|
|
# Issue with conj and torch dispatch, see https://github.com/pytorch/pytorch/issues/82479
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
'TestSchemaCheckModeOpInfo',
|
|
'test_schema_correctness',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
# Dispatches in Python to vector_norm. Not sure how to make this test happy
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.complex64, torch.float32,)),)
|
|
),
|
|
OpInfo(
|
|
"norm",
|
|
variant_test_name="inf",
|
|
sample_inputs_func=sample_inputs_norm_inf,
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16, torch.chalf),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
# fast gradcheck produces NaNs
|
|
gradcheck_fast_mode=False,
|
|
skips=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=2e-3, rtol=1e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type='cuda',
|
|
),
|
|
# Dispatches in Python to vector_norm. Not sure how to make this test happy
|
|
# Happens to pass on complex64. Also a mystery
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit',
|
|
dtypes=(torch.float32,))
|
|
),
|
|
),
|
|
OpInfo('t',
|
|
sample_inputs_func=sample_inputs_t,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
error_inputs_func=error_inputs_t),
|
|
OpInfo('t_copy',
|
|
sample_inputs_func=sample_inputs_t,
|
|
supports_out=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
# vmap does not support inplace views
|
|
check_inplace_batched_forward_grad=False,
|
|
autodiff_fusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
autodiff_nonfusible_nodes=[], # aliases inputs, shouldn't be fused
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
assert_autodiffed=True,
|
|
error_inputs_func=error_inputs_t),
|
|
OpInfo(
|
|
"nn.functional.dropout",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.dropout, input, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Probably because we have used lambda for the op here
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# inplace variant dispatches to dropout kernel, while on CUDA
|
|
# the op dispatches to _fused_dropout (with a few more conditions)
|
|
# hence, different values and this skip here
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view', device_type='cuda'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu')),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# https://github.com/pytorch/pytorch/issues/66357
|
|
check_batched_forward_grad=False,
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_dropout,
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.dropout, input, *args, **kwargs, inplace=True)),
|
|
OpInfo(
|
|
"native_dropout_backward",
|
|
op=torch.ops.aten.native_dropout_backward.default,
|
|
aten_name="native_dropout_backward",
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfCUDA=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_dropout_backward,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
# Lazy tensor failures
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestLazyOpInfo', 'test_dispatched_to_lazy'),
|
|
# These tests fail only when built with ASAN
|
|
DecorateInfo(unittest.skip("Fails with ASAN"), 'TestLazyOpInfo', 'test_correctness', active_if=TEST_WITH_ASAN),
|
|
DecorateInfo(
|
|
unittest.skip("Fails with ASAN"),
|
|
'TestLazyOpInfo',
|
|
'test_correctness_with_reusing_ir',
|
|
active_if=TEST_WITH_ASAN
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.dropout2d",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.dropout2d, input, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu')),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
check_batched_forward_grad=False,
|
|
# As per the docs, valid input dims are (3, 4)
|
|
sample_inputs_func=partial(sample_inputs_dropout, valid_input_dim=(3, 4)),
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.dropout2d, input, *args, **kwargs, inplace=True)),
|
|
OpInfo(
|
|
"nn.functional.dropout3d",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.dropout3d, input, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu')),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
check_batched_forward_grad=False,
|
|
# As per the docs, valid input dims are (4, 5)
|
|
sample_inputs_func=partial(sample_inputs_dropout, valid_input_dim=(4, 5)),
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.dropout3d, input, *args, **kwargs, inplace=True)),
|
|
OpInfo(
|
|
"nn.functional.alpha_dropout",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.alpha_dropout, input, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
gradcheck_wrapper=wrapper_set_seed,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_dropout,
|
|
check_batched_forward_grad=False,
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.alpha_dropout, input, *args, **kwargs, inplace=True),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Fails in cuda11.7
|
|
# Error Log: https://github.com/pytorch/pytorch/actions/runs/3440108478/jobs/5738475757
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_compare_cpu', device_type='cuda'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),),),
|
|
# In training mode, feature_alpha_dropout currently doesn't support inputs of complex dtype
|
|
# unlike when `train=False`, it supports complex inputs, hence 2 OpInfos to cover all cases
|
|
OpInfo(
|
|
"nn.functional.feature_alpha_dropout",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.feature_alpha_dropout, input, *args, **kwargs),
|
|
variant_test_name="with_train",
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
# torch.autograd.gradcheck.GradcheckError: While computing batched gradients, got:
|
|
# vmap: We do not yet support calling random operations inside of vmap.
|
|
# Please perform random operations outside of vmap as a workaround
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', "test_forward_mode_AD"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', "test_inplace_forward_mode_AD"),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu')),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
# As per the docs, valid input dims are (4, 5)
|
|
sample_inputs_func=partial(sample_inputs_dropout, train=True, valid_input_dim=(4, 5)),
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.feature_alpha_dropout, input, *args, **kwargs, inplace=True)),
|
|
OpInfo(
|
|
"nn.functional.feature_alpha_dropout",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.feature_alpha_dropout, input, *args, **kwargs),
|
|
variant_test_name="without_train",
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),),
|
|
gradcheck_wrapper=wrapper_set_seed,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
supports_out=False,
|
|
sample_inputs_func=partial(sample_inputs_dropout, train=False),
|
|
inplace_variant=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.feature_alpha_dropout, input, *args, **kwargs, inplace=True)),
|
|
OpInfo(
|
|
"nn.functional.one_hot",
|
|
ref=reference_one_hot,
|
|
supports_out=False,
|
|
dtypes=_dispatch_dtypes((torch.int64,)),
|
|
sample_inputs_func=sample_inputs_one_hot,
|
|
),
|
|
OpInfo(
|
|
"nn.functional.embedding",
|
|
aten_backward_name="embedding_dense_backward",
|
|
# We use lambda to reshuffle the positional arguments.
|
|
# This is because currently only the `input` field of SampleInput
|
|
# is tested in gradient tests.
|
|
op=lambda weight, idx, **kwargs: torch.nn.functional.embedding(idx, weight, **kwargs),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_embedding,
|
|
allow_cow_input_materialize_forward=[0],
|
|
error_inputs_func=error_inputs_embedding,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Fails on CI https://github.com/pytorch/pytorch/issues/85377
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_compare_cpu'),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/67084
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view', device_type='cuda'),
|
|
# Not a problem: embedding does weird stuff to its input (it renormalizes)
|
|
DecorateInfo(unittest.skip('Allowed exemption'), 'TestCompositeCompliance', 'test_operator'),
|
|
# Fails due to non-determinism (see issue #74679)
|
|
# TODO: Investigate why more granular skips in the test don't work in CI
|
|
DecorateInfo(unittest.skip('Skipped!'),
|
|
'TestExpandedWeightFunctional',
|
|
'test_expanded_weight_forward'),
|
|
),
|
|
supports_expanded_weight=True,
|
|
supports_out=False,
|
|
),
|
|
OpInfo(
|
|
"nn.functional.embedding_bag",
|
|
# We use lambda to reshuffle the positional arguments.
|
|
# This is because currently only the `input` field of SampleInput
|
|
# is tested in gradient tests.
|
|
op=lambda weight, idx, **kwargs: torch.nn.functional.embedding_bag(idx, weight, **kwargs),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=floating_types_and(torch.bfloat16, torch.float16),
|
|
# backward is not supported for mode `max` and dtype `bfloat16`
|
|
backward_dtypesIfCUDA=floating_types_and(torch.float16),
|
|
sample_inputs_func=sample_inputs_embedding_bag,
|
|
skips=(
|
|
# lambda impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestNormalizeOperators', 'test_normalize_operator_exhaustive'),
|
|
# Not a problem: embedding_bag does weird stuff to its input (it renormalizes)
|
|
DecorateInfo(unittest.skip('Allowed exemption'), 'TestCompositeCompliance', 'test_operator'),
|
|
),
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
allow_cow_input_materialize_forward=[0],
|
|
),
|
|
OpInfo(
|
|
"nn.functional.multi_head_attention_forward",
|
|
op=lambda input, *args, **kwargs:
|
|
wrapper_set_seed(torch.nn.functional.multi_head_attention_forward, input, *args, **kwargs),
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
sample_inputs_func=sample_inputs_multi_head_attention_forward,
|
|
skips=(
|
|
# Tensor-likes are not close
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_noncontiguous_samples', dtypes=(torch.float32,)),
|
|
DecorateInfo(toleranceOverride({torch.float32: tol(atol=5e-3, rtol=0)}), 'TestDecomp', 'test_comprehensive'),
|
|
|
|
# TODO skip this for now since we can't skip on runtime arch support (taken from scaled_dot_product_attention)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestInductorOpInfo', 'test_comprehensive'),
|
|
# randomness
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
# lambda impl
|
|
# AssertionError: JIT Test does not execute any logic
|
|
DecorateInfo(unittest.expectedFailure, 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.expectedFailure, "TestNormalizeOperators", "test_normalize_operator_exhaustive"),
|
|
# tests running very slowly break slow tests, so we skip them instead of using `slowTest`.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_forward_ad'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCompositeCompliance', 'test_operator'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped - baddbmm decomp does not have enough precision for 16-bit float"),
|
|
'TestDecomp',
|
|
'test_comprehensive',
|
|
dtypes=(torch.bfloat16, torch.float16),
|
|
),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped - baddbmm decomp does not have enough precision for 16-bit float"),
|
|
'TestDecomp',
|
|
'test_quick',
|
|
dtypes=(torch.bfloat16, torch.float16))),
|
|
supports_out=False,
|
|
supports_gradgrad=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
),
|
|
UnaryUfuncInfo(
|
|
"nn.functional.softplus",
|
|
aten_backward_name='softplus_backward',
|
|
ref=reference_softplus,
|
|
sample_kwargs=lambda device, dtype, input: ({'beta': 3, 'threshold': .2}, {'beta': 3, 'threshold': .2}),
|
|
sample_inputs_func=partial(sample_inputs_elementwise_unary, op_kwargs={'beta': 3, 'threshold': .2}),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.bfloat16, torch.float16),
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride
|
|
({
|
|
torch.half: tol(atol=1e-2, rtol=1e-2),
|
|
torch.bfloat16: tol(atol=1e-2, rtol=1e-2),
|
|
}),
|
|
'TestUnaryUfuncs'),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.mse_loss",
|
|
aten_backward_name='mse_loss_backward',
|
|
ref=loss_reference_reduction_wrapper(lambda input, target: (input - target) ** 2),
|
|
sample_inputs_func=sample_inputs_loss,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":252,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.expectedFailure, "TestJit", "test_variant_consistency_jit", dtypes=(torch.float32,),),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.grid_sample",
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_grid_sample,
|
|
reference_inputs_func=reference_inputs_grid_sample,
|
|
supports_gradgrad=False,
|
|
gradcheck_nondet_tol=1e-15),
|
|
# TODO: delete this OpInfo once we add meta support for grid_sampler_3d
|
|
OpInfo(
|
|
"grid_sampler_2d",
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_grid_sampler_2d,
|
|
supports_gradgrad=False,
|
|
gradcheck_nondet_tol=1e-15,
|
|
skips=(
|
|
DecorateInfo(slowTest, 'TestDecomp', 'test_comprehensive', dtypes=(torch.float32, torch.float64),
|
|
active_if=IS_WINDOWS),
|
|
),),
|
|
OpInfo(
|
|
"argwhere",
|
|
ref=np.argwhere,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
sample_inputs_func=sample_inputs_argwhere,
|
|
skips=(
|
|
# Compiler issue on ROCm. Might need to skip until ROCm5.5
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_non_standard_bool_values',
|
|
dtypes=[torch.bool], active_if=TEST_WITH_ROCM),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'all',
|
|
identity=True,
|
|
supports_autograd=False,
|
|
result_dtype=torch.bool,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
ref=reference_reduction_numpy(np.all),
|
|
skips=(
|
|
# FIXME: uint8 input returns uint8 instead of bool
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_result_dtype', dtypes=[torch.uint8]),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'any',
|
|
identity=False,
|
|
supports_autograd=False,
|
|
result_dtype=torch.bool,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
ref=reference_reduction_numpy(np.any),
|
|
skips=(
|
|
# FIXME: uint8 input returns uint8 instead of bool
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_result_dtype', dtypes=[torch.uint8]),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'amax',
|
|
nan_policy='propagate',
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
ref=reference_reduction_numpy(np.amax),
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
error_inputs_func=error_inputs_aminmax_amax_amin,
|
|
),
|
|
ReductionOpInfo(
|
|
'amin',
|
|
nan_policy='propagate',
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
ref=reference_reduction_numpy(np.amin),
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
error_inputs_func=error_inputs_aminmax_amax_amin,
|
|
),
|
|
ReductionOpInfo(
|
|
'argmax',
|
|
supports_multiple_dims=False,
|
|
supports_autograd=False,
|
|
assert_jit_shape_analysis=True,
|
|
result_dtype=torch.int64,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
ref=reference_reduction_numpy(np.argmax, supports_keepdims=False),
|
|
),
|
|
ReductionOpInfo(
|
|
'argmin',
|
|
supports_multiple_dims=False,
|
|
supports_autograd=False,
|
|
result_dtype=torch.int64,
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
ref=reference_reduction_numpy(np.argmin, supports_keepdims=False),
|
|
),
|
|
ReductionOpInfo(
|
|
'count_nonzero',
|
|
identity=0,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
result_dtype=torch.int64,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_reduction_count_nonzero,
|
|
ref=reference_reduction_numpy(np.count_nonzero),
|
|
skips=(
|
|
# FIXME: count_nonzero does not accept keepdim kwarg
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_default_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_none_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_single_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_multi_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_multi_unsorted_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_offbounds_keepdim'),
|
|
# FIXME: dim=[] reduces all dimensions
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'mean',
|
|
nan_policy='propagate',
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# FIXME: mean needs 'dim' parameter when using the 'out' overload.
|
|
# Adding it with 'generate_args_kwargs' does not work, since these also get passed
|
|
# onto the reference implementations.
|
|
supports_out=True,
|
|
assert_autodiffed=True,
|
|
assert_jit_shape_analysis=True,
|
|
promotes_int_to_float=True,
|
|
dtypes=floating_and_complex_types_and(torch.float16, torch.bfloat16),
|
|
ref=reference_reduction_numpy(np.mean),
|
|
error_inputs_func=error_inputs_mean,
|
|
skips=(
|
|
# AssertionError: RuntimeError not raised : Expected RuntimeError when doing an unsafe cast from a result
|
|
# of dtype torch.float32 into an out= with dtype torch.long
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_out', device_type='cuda', dtypes=[torch.float32]),
|
|
# FIXME: mean does not support passing keepdim without passing dim
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_default_keepdim'),
|
|
# FIXME: mean reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_extremal_values',
|
|
device_type='cuda', dtypes=[torch.complex64]),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'nanmean',
|
|
nan_policy='omit',
|
|
assert_autodiffed=True,
|
|
promotes_int_to_float=True,
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_nan_reduction(supports_multiple_dims=True),
|
|
ref=reference_reduction_numpy(np.nanmean),
|
|
skips=(
|
|
# AssertionError: False is not true :
|
|
# Failure in testing nodes' autodifferentiation.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# FIXME: prod reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_duplicate_values',
|
|
device_type='cuda', dtypes=[torch.float16]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_extremal_values',
|
|
device_type='cuda', dtypes=[torch.complex64]),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'std',
|
|
nan_policy='propagate',
|
|
supports_out=True,
|
|
complex_to_real=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
promotes_int_to_float=True,
|
|
check_batched_forward_grad=False,
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var,
|
|
ref=reference_std_var(np.std),
|
|
generate_args_kwargs=generate_std_var_kwargs,
|
|
skips=(
|
|
# FIXME: cannot specify keepdim without dim
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_default_keepdim'),
|
|
# FIXME: dim=[] reduces all dimensions
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=(torch.float16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_duplicate_values',
|
|
dtypes=(torch.float16,)),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'std',
|
|
variant_test_name='unbiased',
|
|
nan_policy='propagate',
|
|
supports_out=False,
|
|
complex_to_real=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
promotes_int_to_float=True,
|
|
check_batched_forward_grad=False,
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var_unbiased,
|
|
skips=(
|
|
# FIXME: dim=[] reduces all dimensions
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'var',
|
|
nan_policy='propagate',
|
|
supports_out=True,
|
|
assert_autodiffed=True,
|
|
promotes_int_to_float=True,
|
|
complex_to_real=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
check_batched_forward_grad=False,
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var,
|
|
ref=reference_std_var(np.var),
|
|
generate_args_kwargs=generate_std_var_kwargs,
|
|
skips=(
|
|
# FIXME: cannot specify keepdim without dim
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_default_keepdim'),
|
|
# FIXME: dim=[] reduces all dimensions
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_duplicate_values'),
|
|
# NumPy is giving NaN for this
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_large_input'),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'var',
|
|
variant_test_name='unbiased',
|
|
nan_policy='propagate',
|
|
supports_out=False,
|
|
complex_to_real=True,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_autodiffed=True,
|
|
promotes_int_to_float=True,
|
|
check_batched_forward_grad=False,
|
|
dtypes=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
dtypesIfCUDA=floating_and_complex_types_and(torch.half, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_std_var_unbiased,
|
|
skips=(
|
|
# FIXME: dim=[] reduces all dimensions
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'prod',
|
|
identity=1,
|
|
nan_policy='propagate',
|
|
supports_multiple_dims=False,
|
|
# https://github.com/pytorch/pytorch/issues/80411
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_int64=True,
|
|
gradcheck_nondet_tol=GRADCHECK_NONDET_TOL,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_prod,
|
|
ref=prod_numpy,
|
|
skips=(
|
|
# FIXME: prod does not support passing keepdim without passing dim
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_default_keepdim'),
|
|
# FIXME: prod reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: prod does not support passing None to dim
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_none'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_none_keepdim'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16, torch.complex64]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_duplicate_values',
|
|
dtypes=[torch.uint8, torch.float16, torch.complex64]),
|
|
# FIXME: ValueError: The data in MaskedTensor a and Tensor b do not match
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOperators', 'test_reduction_all',
|
|
dtypes=[torch.float16]),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'sum',
|
|
identity=0,
|
|
nan_policy='propagate',
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
promotes_int_to_int64=True,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
ref=reference_reduction_numpy(np.sum),
|
|
error_inputs_sparse_func=error_inputs_sparse_reduction_sum,
|
|
sample_inputs_sparse_coo_func=partial(sample_inputs_sparse_reduction_sum, layout=torch.sparse_coo),
|
|
sample_inputs_sparse_csr_func=partial(sample_inputs_sparse_reduction_sum, layout=torch.sparse_csr),
|
|
sample_inputs_sparse_csc_func=partial(sample_inputs_sparse_reduction_sum, layout=torch.sparse_csc),
|
|
sample_inputs_sparse_bsr_func=partial(sample_inputs_sparse_reduction_sum, layout=torch.sparse_bsr),
|
|
sample_inputs_sparse_bsc_func=partial(sample_inputs_sparse_reduction_sum, layout=torch.sparse_bsc),
|
|
skips=(
|
|
# FIXME: sum does not support passing keepdim without passing dim
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_default_keepdim'),
|
|
# FIXME: sum reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_duplicate_values',
|
|
dtypes=[torch.float16]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestOperators', 'test_reduction_all',
|
|
dtypes=[torch.float32]),
|
|
),
|
|
),
|
|
ReductionOpInfo(
|
|
'nansum',
|
|
identity=0,
|
|
nan_policy='omit',
|
|
supports_out=True,
|
|
promotes_int_to_int64=True,
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_nan_reduction(supports_multiple_dims=True),
|
|
ref=reference_reduction_numpy(np.nansum),
|
|
skips=(
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestJit', 'test_variant_consistency_jit'),
|
|
# FIXME: nansum reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: flaky test so skipped instead of xfailed
|
|
# possibly bad low precision reference in numpy
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16]),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.ctc_loss",
|
|
dtypes=floating_types(),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_ctc_loss,
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/67462
|
|
# torch.autograd.gradcheck.GradcheckError: Jacobian mismatch for output 0 with respect to input 0
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestBwdGradients",
|
|
"test_fn_grad",
|
|
dtypes=(torch.float64,),
|
|
),
|
|
# RuntimeError: derivative for aten::_ctc_loss_backward is not implemented
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestBwdGradients",
|
|
"test_fn_gradgrad",
|
|
dtypes=(torch.float64,),
|
|
),
|
|
# RuntimeError: derivative for aten::_ctc_loss_backward is not implemented
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32,),
|
|
),
|
|
# Ref: https://github.com/pytorch/pytorch/issues/85231
|
|
DecorateInfo(unittest.skip("Fails with ASAN"),
|
|
'TestProxyTensorOpInfo',
|
|
'test_make_fx_fake_exhaustive', active_if=TEST_WITH_ASAN),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.cosine_embedding_loss",
|
|
dtypes=all_types_and(torch.half, torch.bfloat16, torch.bool),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-4, rtol=2e-3)}),
|
|
'TestInductorOpInfo', 'test_comprehensive', device_type="cuda",
|
|
),
|
|
],
|
|
sample_inputs_func=sample_inputs_cosine_embedding_loss,
|
|
),
|
|
OpInfo(
|
|
"nn.functional.nll_loss",
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
sample_inputs_func=sample_inputs_nll_loss,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
assert_jit_shape_analysis=True,
|
|
skips=(
|
|
# RuntimeError:
|
|
# undefined value tensor:
|
|
# File "<string>", line 3
|
|
# def the_method(i0, i1):
|
|
# return torch.nn.functional.nll_loss(i0, i1, weight=tensor([8.4784, 1.7658, 4.3228], dtype=torch.float32))
|
|
# ~~~~~~ <--- HERE
|
|
DecorateInfo(unittest.skip("Skipped!"), "TestJit", "test_variant_consistency_jit", dtypes=(torch.float32,),),
|
|
# Fails for unknown reason: https://github.com/pytorch/pytorch/issues/120782
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestCompositeCompliance",
|
|
"test_cow_input",
|
|
device_type='cuda',
|
|
),
|
|
DecorateInfo(unittest.skip("FP16 nll_loss cases have not been enabled on MPS yet"),
|
|
dtypes=(torch.half,), device_type="mps"),
|
|
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.gaussian_nll_loss",
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
# Runs very slowly on slow gradcheck - alternatively reduce input sizes
|
|
gradcheck_fast_mode=True,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_gaussian_nll_loss,
|
|
error_inputs_func=error_inputs_gaussian_nll_loss,
|
|
skips=(
|
|
# Pre-existing condition (calls .item); needs to be fixed
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_backward'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_forward_ad'),
|
|
# Pre-existing condition (calls .item); needs to be fixed
|
|
DecorateInfo(unittest.expectedFailure, 'TestCompositeCompliance', 'test_operator'),
|
|
# JIT does not support variadic tensors.
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), "TestJit", "test_variant_consistency_jit", dtypes=(torch.float32,),),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.hinge_embedding_loss",
|
|
dtypes=floating_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_hinge_embedding_loss,
|
|
error_inputs_func=error_inputs_hinge_embedding_loss,
|
|
reference_inputs_func=reference_inputs_hinge_embedding_loss,
|
|
),
|
|
OpInfo(
|
|
"nn.functional.huber_loss",
|
|
aten_backward_name='huber_loss_backward',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
sample_inputs_func=sample_inputs_huber_loss,
|
|
error_inputs_func=error_inputs_huber_loss,
|
|
skips=(
|
|
# JIT does not support variadic tensors.
|
|
# RuntimeError: input->type()->kind() == TypeKind::OptionalType
|
|
# INTERNAL ASSERT FAILED at "../torch/csrc/jit/passes/utils/check_alias_annotation.cpp":270,
|
|
# please report a bug to PyTorch.
|
|
DecorateInfo(unittest.skip("Skipped!"), "TestJit", "test_variant_consistency_jit", dtypes=(torch.float32,),),
|
|
)
|
|
),
|
|
OpInfo(
|
|
"nn.functional.pdist",
|
|
ref=reference_pdist,
|
|
sample_inputs_func=sample_inputs_pdist,
|
|
dtypes=floating_types(),
|
|
supports_out=False,
|
|
supports_gradgrad=False,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Unsupported on MPS for now"), 'TestCommon', 'test_numpy_ref_mps'),
|
|
)
|
|
),
|
|
OpInfo(
|
|
"nn.functional.poisson_nll_loss",
|
|
dtypes=all_types_and(torch.half, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_poisson_nll_loss,
|
|
error_inputs_func=error_inputs_poisson_nll_loss,
|
|
),
|
|
OpInfo(
|
|
"argsort",
|
|
dtypes=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.bool, torch.float16, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_sort,
|
|
supports_out=False,
|
|
supports_autograd=False,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32,),
|
|
),
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestCommon",
|
|
"test_non_standard_bool_values",
|
|
dtypes=[torch.bool],
|
|
device_type='cuda',
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"repeat_interleave",
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16, torch.chalf),
|
|
backward_dtypesIfCUDA=floating_and_complex_types_and(torch.float16, torch.bfloat16, torch.chalf),
|
|
sample_inputs_func=sample_inputs_repeat_interleave,
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32, torch.complex64),
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.pairwise_distance",
|
|
ref=lambda a, b, p=2.0, eps=1e-6, keepdim=False: (
|
|
np.sum(np.abs(a - b + eps) ** p, axis=-1, keepdims=keepdim) ** (1 / p)
|
|
),
|
|
sample_inputs_func=sample_inputs_pairwise_distance,
|
|
dtypes=all_types_and_complex_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32, torch.complex64),
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.pixel_shuffle",
|
|
sample_inputs_func=sample_inputs_pixel_shuffle,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32, torch.complex64),
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.pixel_unshuffle",
|
|
sample_inputs_func=sample_inputs_pixel_unshuffle,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
dtypes=(torch.float32, torch.complex64),
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.channel_shuffle",
|
|
sample_inputs_func=sample_inputs_channel_shuffle,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
allow_cow_input_materialize_forward=[0],
|
|
allow_cow_input_materialize_backward=[0, 'output grad 0'],
|
|
skips=(
|
|
# Skip due to NotImplementedError for MPS device.
|
|
DecorateInfo(unittest.expectedFailure, 'TestConsistency'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestDTensorOps', 'test_dtensor_op_db'),
|
|
DecorateInfo(unittest.expectedFailure, "TestMeta", "test_dispatch_symbolic_meta_outplace_all_strides"),
|
|
),
|
|
),
|
|
OpInfo(
|
|
"nn.functional.kl_div",
|
|
sample_inputs_func=sample_inputs_kl_div,
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
),
|
|
OpInfo(
|
|
"diagflat",
|
|
ref=lambda input, offset=0: np.diagflat(input, k=offset),
|
|
sample_inputs_func=sample_inputs_diagflat,
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.bfloat16, torch.float16),
|
|
dtypesIfCUDA=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
# See https://github.com/pytorch/pytorch/pull/78358
|
|
check_batched_forward_grad=False,
|
|
),
|
|
OpInfo(
|
|
'scatter_reduce',
|
|
variant_test_name='sum',
|
|
# complex not added to dtypes as complex gradients are not properly handled
|
|
# and scatter_reduce hasn't been added to the whitelist in gen_variable_type yet
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_scatter_reduce,
|
|
),
|
|
OpInfo(
|
|
'scatter_reduce',
|
|
variant_test_name='prod',
|
|
# complex not added to dtypes as complex gradients are not properly handled
|
|
# and scatter_reduce hasn't been added to the whitelist in gen_variable_type yet
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
sample_inputs_func=sample_inputs_scatter_reduce,
|
|
skips=(
|
|
# Not implemented
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_forward_mode_AD'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_inplace_forward_mode_AD'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestFwdGradients', 'test_fn_fwgrad_bwgrad'),
|
|
),
|
|
),
|
|
OpInfo(
|
|
'scatter_reduce',
|
|
variant_test_name='mean',
|
|
# complex not added to dtypes as complex gradients are not properly handled
|
|
# and scatter_reduce hasn't been added to the whitelist in gen_variable_type yet
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_scatter_reduce,
|
|
),
|
|
OpInfo(
|
|
'scatter_reduce',
|
|
variant_test_name='amin',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_scatter_reduce,
|
|
),
|
|
OpInfo(
|
|
'scatter_reduce',
|
|
variant_test_name='amax',
|
|
dtypes=all_types_and(torch.float16, torch.bfloat16, torch.bool),
|
|
dtypesIfCUDA=all_types_and(torch.float16, torch.bfloat16),
|
|
dtypesIfHpu=custom_types(torch.float32, torch.bfloat16),
|
|
supports_forward_ad=True,
|
|
check_batched_forward_grad=False,
|
|
supports_fwgrad_bwgrad=True,
|
|
sample_inputs_func=sample_inputs_scatter_reduce,
|
|
),
|
|
OpInfo(
|
|
'_segment_reduce',
|
|
aten_name='segment_reduce',
|
|
variant_test_name='lengths',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
# RuntimeError: derivative for aten::_segment_reduce_backward is not implemented
|
|
supports_gradgrad=False,
|
|
sample_inputs_func=sample_inputs_segment_reduce,
|
|
skips=(
|
|
# FIXME: CUDA driver API confirmed a leak in
|
|
# __main__.TestJitCUDA.test_variant_consistency_jit_segment_reduce_cuda_float32
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
device_type="cuda",
|
|
),
|
|
),
|
|
),
|
|
OpInfo(
|
|
'_segment_reduce',
|
|
aten_name='segment_reduce',
|
|
variant_test_name='offsets',
|
|
dtypes=floating_types_and(torch.float16, torch.bfloat16),
|
|
supports_out=False,
|
|
# RuntimeError: derivative for aten::_segment_reduce_backward is not implemented
|
|
supports_gradgrad=False,
|
|
sample_inputs_func=partial(sample_inputs_segment_reduce, mode='offsets'),
|
|
skips=(
|
|
# FIXME: CUDA driver API confirmed a leak in
|
|
# __main__.TestJitCUDA.test_variant_consistency_jit_segment_reduce_cuda_float32
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"),
|
|
"TestJit",
|
|
"test_variant_consistency_jit",
|
|
device_type="cuda",
|
|
),
|
|
),
|
|
),
|
|
]
|
|
op_db += opinfo.definitions.op_db
|
|
|
|
|
|
# Separate registry for experimental Python Reference OpInfos.
|
|
python_ref_db = [
|
|
#
|
|
# Elementwise Unary OpInfos
|
|
#
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.abs",
|
|
torch_opinfo_name="abs",
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/49224
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
dtypes=[torch.int8], active_if=TEST_WITH_ASAN),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.acos",
|
|
torch_opinfo_name="acos",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_normal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
# Failing with wrong imaginary sign on at least some Windows jobs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
# Failing with wrong imaginary sign on at least some Windows jobs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.acosh",
|
|
torch_opinfo_name="acosh",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_normal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
# Failing with wrong imaginary sign on at least some Windows jobs
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.asin",
|
|
torch_opinfo_name="asin",
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-05, rtol=1e-03)}),
|
|
'TestUnaryUfuncs', device_type='cuda'),
|
|
precisionOverride({torch.bfloat16: 1e-2}),
|
|
],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.asinh",
|
|
torch_opinfo_name="asinh",
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_normal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.lerp",
|
|
torch_opinfo_name="lerp",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.ones",
|
|
torch_opinfo_name="ones",
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.zeros",
|
|
torch_opinfo_name="zeros",
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.cauchy",
|
|
torch_opinfo_name="cauchy",
|
|
decorators=(
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: cauchy is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: cauchy is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip("Expected: cauchy is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.exponential",
|
|
torch_opinfo_name="exponential",
|
|
supports_out=True,
|
|
decorators=(
|
|
# dtypes that do not support check_uniform_bounds of rand_like
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_meta',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64)),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_dtypes'),
|
|
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: exponential is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: exponential is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip("Expected: exponential is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.geometric",
|
|
torch_opinfo_name="geometric",
|
|
supports_out=True,
|
|
decorators=(
|
|
# dtypes that do not support check_uniform_bounds of rand_like
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_dtypes'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_meta',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64)),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64)),
|
|
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: geometric is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_executor', device_type='cuda'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: geometric is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: geometric is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: geometric is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.log_normal",
|
|
torch_opinfo_name="log_normal",
|
|
supports_out=True,
|
|
decorators=(
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: log_normal is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_executor', device_type='cuda'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: log_normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: log_normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: log_normal is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.normal",
|
|
torch_opinfo_name="normal",
|
|
supports_out=True,
|
|
decorators=(
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"), 'TestDecomp', 'test_comprehensive'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.skip("make_traced() doesn't set seed properly!"), 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.normal",
|
|
torch_opinfo_name="normal",
|
|
torch_opinfo_variant_name="number_mean",
|
|
supports_out=True,
|
|
decorators=(
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"), 'TestDecomp', 'test_comprehensive'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.skip("make_traced() doesn't set seed properly!"), 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.normal_",
|
|
op=torch.Tensor.normal_,
|
|
torch_opinfo_name="normal",
|
|
torch_opinfo_variant_name="in_place",
|
|
supports_out=False,
|
|
decorators=(
|
|
# TODO: RuntimeError: no _refs support for torch.rand_like
|
|
DecorateInfo(unittest.skip("TODO: RuntimeError: no _refs support for torch.rand_like"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: normal is not comparable"), 'TestDecomp', 'test_comprehensive'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
DecorateInfo(unittest.skip("make_traced() doesn't set seed properly!"), 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.arange",
|
|
torch_opinfo_name="arange",
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.linspace",
|
|
torch_opinfo_name="linspace",
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
|
|
# cpu implementation is wrong on some integral types
|
|
# https://github.com/pytorch/pytorch/issues/81996
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64), device_type="cpu"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64), device_type="cpu"),
|
|
|
|
# cuda implementation is off-by-one on some inputs due to precision issues
|
|
# https://github.com/pytorch/pytorch/issues/82230
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.linspace",
|
|
torch_opinfo_name="linspace",
|
|
torch_opinfo_variant_name="tensor_overload",
|
|
skips=(
|
|
# TypeError: 'int' object is not subscriptable
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
|
|
# cpu implementation is wrong on some integral types
|
|
# https://github.com/pytorch/pytorch/issues/81996
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64), device_type="cpu"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.int8, torch.uint8, torch.int16, torch.int32, torch.int64), device_type="cpu"),
|
|
|
|
# cuda implementation is off-by-one on some inputs due to precision issues
|
|
# https://github.com/pytorch/pytorch/issues/82230
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.uint8, torch.int8, torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.logspace",
|
|
torch_opinfo_name="logspace",
|
|
skips=(
|
|
# Tests that assume input is a tensor or sequence of tensors
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_conj_view'),
|
|
|
|
# Off-by-one issue when casting floats to ints
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.logspace",
|
|
torch_opinfo_name="logspace",
|
|
torch_opinfo_variant_name="tensor_overload",
|
|
skips=(
|
|
# TypeError: 'int' object is not subscriptable
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMathBits', 'test_conj_view'),
|
|
|
|
# Off-by-one issue when casting floats to ints
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.int16, torch.int32, torch.int64),
|
|
device_type="cuda"),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.meshgrid",
|
|
torch_opinfo_name="meshgrid",
|
|
torch_opinfo_variant_name="variadic_tensors",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.take_along_dim",
|
|
torch_opinfo_name="take_along_dim",
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.to",
|
|
torch_opinfo_name="to",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.triu",
|
|
torch_opinfo_name="triu",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.tril",
|
|
torch_opinfo_name="tril",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.triu_indices",
|
|
torch_opinfo_name="triu_indices",
|
|
# the implementation uses torch.stack that violates view consistency
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
PythonRefInfo(
|
|
"_refs.tril_indices",
|
|
torch_opinfo_name="tril_indices",
|
|
# the implementation uses torch.stack that violates view consistency
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_noncontiguous_samples'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestCommon', 'test_variant_consistency_eager'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestJit', 'test_variant_consistency_jit'),
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestMathBits', 'test_neg_view'),
|
|
)),
|
|
PythonRefInfo(
|
|
"_refs.meshgrid",
|
|
torch_opinfo_name="meshgrid",
|
|
torch_opinfo_variant_name="list_of_tensors",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.movedim",
|
|
aliases=('moveaxis',),
|
|
torch_opinfo_name="movedim",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.bucketize",
|
|
torch_opinfo_name="bucketize",
|
|
skips=(
|
|
# RuntimeError: It appears that you're trying to get value out of a tracing tensor with
|
|
# aten._local_scalar_dense.default - erroring out! [...]
|
|
# triggered by mid_val = boundaries[mid]
|
|
DecorateInfo(unittest.expectedFailure, "TestCommon", "test_python_ref_executor"),
|
|
)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.equal",
|
|
torch_opinfo_name="equal",
|
|
skips=(
|
|
# RuntimeError: Cannot cast FakeTensor to number
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_meta',),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.atan",
|
|
torch_opinfo_name="atan",
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.atanh",
|
|
torch_opinfo_name="atanh",
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda', dtypes=[torch.cfloat],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.bitwise_not",
|
|
torch_opinfo_name="bitwise_not",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.ceil",
|
|
torch_opinfo_name="ceil",
|
|
# Fails on int32
|
|
# https://github.com/pytorch/pytorch/issues/85258
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.item",
|
|
torch_opinfo_name="item",
|
|
skips=(
|
|
# RuntimeError: Cannot cast FakeTensor(FakeTensor(..., device='meta', size=()), cpu) to number
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_meta'),
|
|
# ValueError: Can't convert a tensor with 10 elements to a number!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.conj_physical",
|
|
torch_opinfo_name="conj_physical",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.cos",
|
|
torch_opinfo_name="cos",
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.cfloat, torch.cdouble,), device_type='cpu',
|
|
active_if=IS_WINDOWS),
|
|
# This fails on CUDA but passes on ROCm
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.cdouble,), device_type='cuda'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_MACOS),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: nan at index (700,) (up to 1e-05 allowed)
|
|
# Greatest relative difference: nan at index (700,) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda',
|
|
dtypes=(torch.chalf,), active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.cosh",
|
|
torch_opinfo_name="cosh",
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48641
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.int8]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=[torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_MACOS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu',
|
|
dtypes=[torch.cfloat, torch.cdouble], active_if=IS_MACOS),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: nan at index (6000,) (up to 1e-05 allowed)
|
|
# Greatest relative difference: nan at index (6000,) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cuda',
|
|
dtypes=(torch.chalf,), active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.digamma",
|
|
torch_opinfo_name="digamma",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.erf",
|
|
torch_opinfo_name="erf",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.erfinv",
|
|
torch_opinfo_name="erfinv",
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.bfloat16: 1e-2,
|
|
torch.float32: 1e-4}),),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/pull/49155#issuecomment-742664611
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
active_if=TEST_SCIPY and version.parse(scipy.__version__) < version.parse("1.4.0")),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
active_if=TEST_SCIPY and version.parse(scipy.__version__) < version.parse("1.4.0")),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
active_if=TEST_SCIPY and version.parse(scipy.__version__) < version.parse("1.4.0")),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.erfc",
|
|
torch_opinfo_name="erfc",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.exp",
|
|
torch_opinfo_name="exp",
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48010
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.expm1",
|
|
torch_opinfo_name="expm1",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.exp2",
|
|
torch_opinfo_name="exp2",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=[torch.cdouble]),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48010
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.fill",
|
|
torch_opinfo_name="fill",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.floor",
|
|
torch_opinfo_name="floor",
|
|
# Fails on int32
|
|
# https://github.com/pytorch/pytorch/issues/85258
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.frexp",
|
|
torch_opinfo_name="frexp",
|
|
# Skipped due to numerical failures on Windows CI.
|
|
# This is also skipped in frexp earlier in the file.
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs', 'test_reference_numerics_extremal',
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.frac",
|
|
torch_opinfo_name="frac",
|
|
skips=(
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=(torch.bfloat16, torch.float16, torch.float32, torch.float64)),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.imag",
|
|
torch_opinfo_name="imag",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.isfinite",
|
|
torch_opinfo_name="isfinite",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.isinf",
|
|
torch_opinfo_name="isinf",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.isposinf",
|
|
torch_opinfo_name="isposinf",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.isneginf",
|
|
torch_opinfo_name="isneginf",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.isnan",
|
|
torch_opinfo_name="isnan",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.isreal",
|
|
torch_opinfo_name="isreal",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.i0",
|
|
torch_opinfo_name="i0",
|
|
decorators=(precisionOverride({torch.bfloat16: 3e-1,
|
|
torch.float16: 5e-1}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.int8,)),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.lgamma",
|
|
torch_opinfo_name="lgamma",
|
|
decorators=(precisionOverride({torch.float16: 7e-1}),),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/pull/50140#issuecomment-756150214
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.float32, torch.float64], active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=[torch.float32, torch.float64], active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.special.multigammaln",
|
|
torch_opinfo_name="mvlgamma",
|
|
torch_opinfo_variant_name="mvlgamma_p_1",
|
|
skips=skips_mvlgamma(),
|
|
decorators=(
|
|
DecorateInfo(torch.testing._internal.common_utils.markDynamoStrictTest, 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large'),
|
|
DecorateInfo(torch.testing._internal.common_utils.xfailIfTorchDynamo, 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large'),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.special.multigammaln",
|
|
torch_opinfo_name="mvlgamma",
|
|
torch_opinfo_variant_name="mvlgamma_p_3",
|
|
skips=skips_mvlgamma(),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.special.multigammaln",
|
|
torch_opinfo_name="mvlgamma",
|
|
torch_opinfo_variant_name="mvlgamma_p_5",
|
|
skips=skips_mvlgamma(),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.log",
|
|
torch_opinfo_name="log",
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.log1p",
|
|
torch_opinfo_name="log1p",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.log10",
|
|
torch_opinfo_name="log10",
|
|
decorators=(precisionOverride({torch.bfloat16: 5e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.log2",
|
|
torch_opinfo_name="log2",
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-1}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.logsumexp",
|
|
torch_opinfo_name="logsumexp",
|
|
# When keepdim=False logsumexp function uses squeeze operation
|
|
# that is not yet exposed in nvFuser's Python API.
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.log_softmax",
|
|
torch_opinfo_name="log_softmax",
|
|
torch_opinfo_variant_name="with_dtype",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nan_to_num",
|
|
torch_opinfo_name="nan_to_num",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.neg",
|
|
torch_opinfo_name="neg",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.positive",
|
|
torch_opinfo_name="positive",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.real",
|
|
torch_opinfo_name="real",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.reciprocal",
|
|
torch_opinfo_name="reciprocal",
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/45690
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.round",
|
|
torch_opinfo_name="round",
|
|
# Fails on int32
|
|
# https://github.com/pytorch/pytorch/issues/85258
|
|
skips=(
|
|
DecorateInfo(toleranceOverride({torch.bfloat16: tol(atol=1e-3, rtol=0.016)}),
|
|
"TestUnaryUfuncs", "test_reference_numerics_extremal",
|
|
device_type="cuda"),
|
|
DecorateInfo(toleranceOverride({torch.bfloat16: tol(atol=1e-3, rtol=0.016)}),
|
|
"TestUnaryUfuncs", "test_reference_numerics_normal",
|
|
device_type="cuda"),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.rsqrt",
|
|
torch_opinfo_name="rsqrt",
|
|
decorators=(precisionOverride({torch.half: 5e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=(torch.cfloat, torch.cdouble)),
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: nan at index (700,) (up to 0.01 allowed)
|
|
# Greatest relative difference: nan at index (700,) (up to 0.001 allowed)
|
|
DecorateInfo(unittest.expectedFailure, 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.chalf,)),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sigmoid",
|
|
torch_opinfo_name="sigmoid",
|
|
aliases=('_refs.special.expit',),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/56012
|
|
handles_complex_extremal_values=False,
|
|
handles_large_floats=False,
|
|
decorators=(precisionOverride({torch.float16: 1e-2,
|
|
torch.complex64: 1e-1,
|
|
torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/56012
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.complex64, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=[torch.chalf, torch.complex64, torch.cdouble])
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sign",
|
|
torch_opinfo_name="sign",
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/41245
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.bfloat16, torch.float16, torch.float32,
|
|
torch.float64]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sgn",
|
|
torch_opinfo_name="sgn",
|
|
# This is an issue with the vectorised abs on CPU
|
|
handles_complex_extremal_values=False,
|
|
handles_large_floats=False,
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/41245
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=[torch.bfloat16, torch.float16, torch.float32,
|
|
torch.float64]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.signbit",
|
|
torch_opinfo_name="signbit",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sin",
|
|
torch_opinfo_name="sin",
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2}),),
|
|
skips=(
|
|
# Fails on CUDA but passes on ROCm
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.cdouble,), device_type='cuda'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
dtypes=(torch.cfloat, torch.cdouble,), device_type='cpu',
|
|
active_if=IS_WINDOWS),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.cfloat, torch.cdouble,), device_type='cpu',
|
|
active_if=IS_WINDOWS),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sinc",
|
|
torch_opinfo_name="sinc",
|
|
decorators=(precisionOverride({torch.bfloat16: 1e-2,
|
|
torch.float16: 1e-2}),),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/49133
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_small',
|
|
dtypes=[torch.cfloat]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sinh",
|
|
torch_opinfo_name="sinh",
|
|
decorators=(precisionOverride({torch.float16: 1e-2}),),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.cdouble,)),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/48641
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.int8]),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.softmax",
|
|
torch_opinfo_name="softmax",
|
|
torch_opinfo_variant_name="with_dtype",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.sqrt",
|
|
torch_opinfo_name="sqrt",
|
|
decorators=(
|
|
precisionOverride({torch.bfloat16: 7e-2}),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=0)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_large'),
|
|
),
|
|
skips=(
|
|
# Reference: https://github.com/pytorch/pytorch/issues/47358
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=(torch.cfloat, torch.cdouble),
|
|
active_if=IS_MACOS),
|
|
# Reference: https://github.com/pytorch/pytorch/pull/47293#issuecomment-721774436
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=(torch.bfloat16,)),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.square",
|
|
torch_opinfo_name="square",
|
|
decorators=(precisionOverride({torch.complex64: 3e-4, torch.bfloat16: 3e-1}),),
|
|
skips=(
|
|
# AssertionError: Reference result was farther (2.2417024338305655e-07) from the precise computation
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref_executor', dtypes=(torch.complex64,)),
|
|
# Reference: https://github.com/pytorch/pytorch/issues/52549
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cuda', dtypes=[torch.cfloat, torch.cdouble]),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.tan",
|
|
torch_opinfo_name="tan",
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-04, rtol=1e-05)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal', device_type='cuda'),
|
|
],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.tanh",
|
|
torch_opinfo_name="tanh",
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-04, rtol=2e-05)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal', device_type='cuda'),
|
|
],
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_extremal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_large',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble],
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.trunc",
|
|
torch_opinfo_name="trunc",
|
|
# Fails on int32
|
|
# https://github.com/pytorch/pytorch/issues/85258
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.special.log_softmax",
|
|
torch_opinfo_name="log_softmax", # alias
|
|
torch_opinfo_variant_name="with_dtype",
|
|
supports_out=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.special.softmax",
|
|
torch_opinfo_name="softmax", # alias
|
|
torch_opinfo_variant_name="with_dtype",
|
|
supports_out=False,
|
|
),
|
|
#
|
|
# Elementwise Unary Special OpInfos
|
|
#
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.special.logit",
|
|
torch_opinfo_name="logit",
|
|
),
|
|
#
|
|
# Elementwise Unary nn.functional OpInfos
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.alpha_dropout",
|
|
torch_opinfo_name="nn.functional.alpha_dropout",
|
|
decorators=(
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_executor', device_type='cuda'),
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
# AssertionError: Tensor-likes are not close!
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.celu",
|
|
torch_opinfo_name="nn.functional.celu",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.channel_shuffle",
|
|
torch_opinfo_name="nn.functional.channel_shuffle",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.threshold",
|
|
torch_opinfo_name="nn.functional.threshold",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.dropout",
|
|
torch_opinfo_name="nn.functional.dropout",
|
|
decorators=(
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestMathBits',
|
|
'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: dropout is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
# dropout is not comparable
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.elu",
|
|
torch_opinfo_name="nn.functional.elu",
|
|
supports_out=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-03, rtol=1.2e-03),
|
|
torch.bfloat16: tol(atol=1e-03, rtol=1.2e-03)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.hardtanh",
|
|
torch_opinfo_name="nn.functional.hardtanh",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo( # TODO: Port this to an UnaryOpInfo
|
|
"_refs.nn.functional.gelu",
|
|
torch_opinfo_name="nn.functional.gelu",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.layer_norm",
|
|
torch_opinfo_name="nn.functional.layer_norm",
|
|
skips=(
|
|
# Reference result was farther (3.5762786809723224e-07) from the precise computation
|
|
# than the torch result was (2.5068410824946596e-07)!
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.float32,), device_type='cpu'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.glu",
|
|
torch_opinfo_name="nn.functional.glu",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.pairwise_distance",
|
|
torch_opinfo_name="nn.functional.pairwise_distance",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.pdist",
|
|
torch_opinfo_name="nn.functional.pdist",
|
|
supports_out=True,
|
|
skips=(
|
|
# RunTimeError: no _refs support for torch.Tensor.index_select
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),
|
|
# Reference result was farther (1.946091651916504e-05) from the precise
|
|
# computation than the torch result was (1.1920928955078125e-06)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback',
|
|
dtypes=(torch.float32,),
|
|
device_type='cpu',
|
|
),
|
|
)),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.leaky_relu",
|
|
torch_opinfo_name="nn.functional.leaky_relu",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.log_softmax",
|
|
torch_opinfo_name="log_softmax", # alias
|
|
torch_opinfo_variant_name="with_dtype",
|
|
supports_out=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.pixel_shuffle",
|
|
torch_opinfo_name="nn.functional.pixel_shuffle",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.pixel_unshuffle",
|
|
torch_opinfo_name="nn.functional.pixel_unshuffle",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.poisson_nll_loss",
|
|
torch_opinfo_name="nn.functional.poisson_nll_loss",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.prelu",
|
|
torch_opinfo_name="nn.functional.prelu",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.relu",
|
|
torch_opinfo_name="nn.functional.relu",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.relu6",
|
|
torch_opinfo_name="nn.functional.relu6",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.mish",
|
|
torch_opinfo_name="nn.functional.mish",
|
|
supports_out=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-02, rtol=1e-03)}),
|
|
'TestUnaryUfuncs',), ],
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.selu",
|
|
torch_opinfo_name="nn.functional.selu",
|
|
supports_out=True,
|
|
decorators=[
|
|
DecorateInfo(
|
|
toleranceOverride({
|
|
torch.float16: tol(atol=1e-2, rtol=1.8e-2),
|
|
torch.bfloat16: tol(atol=1e-2, rtol=1.8e-2)
|
|
}),
|
|
'TestUnaryUfuncs', device_type='cuda',
|
|
), ],
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.softmax",
|
|
torch_opinfo_name="softmax", # alias
|
|
torch_opinfo_variant_name="with_dtype",
|
|
supports_out=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.softmin",
|
|
torch_opinfo_name="nn.functional.softmin",
|
|
torch_opinfo_variant_name="with_dtype",
|
|
supports_out=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.softplus",
|
|
torch_opinfo_name="nn.functional.softplus",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.l1_loss",
|
|
torch_opinfo_name="nn.functional.l1_loss",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.margin_ranking_loss",
|
|
torch_opinfo_name="nn.functional.margin_ranking_loss",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.mse_loss",
|
|
torch_opinfo_name="nn.functional.mse_loss",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.smooth_l1_loss",
|
|
torch_opinfo_name="nn.functional.smooth_l1_loss",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.hinge_embedding_loss",
|
|
torch_opinfo_name="nn.functional.hinge_embedding_loss",
|
|
skips=(
|
|
# Reference result was farther (0.29562714856322714) from the precise
|
|
# computation than the torch result was (0.20437285143677286)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.bfloat16,), device_type="cpu"
|
|
),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.nll_loss",
|
|
torch_opinfo_name="nn.functional.nll_loss",
|
|
# The corresponding PyTorch op doesn't support out. But the ref is
|
|
# registered as a decomp and ATen has an out variant.
|
|
supports_out=True,
|
|
# For simpler indexing, we flatten target indices, then reshape the result tensor.
|
|
# This creates inconsistent view state with reference impl.
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
# RuntimeError: It appears that you're trying to get value out of a tracing tensor - erroring out!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor', device_type="cuda"
|
|
),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.huber_loss",
|
|
torch_opinfo_name="nn.functional.huber_loss",
|
|
# The corresponding PyTorch op doesn't support out. But the ref is
|
|
# registered as a decomp and ATen has an out variant.
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.tanhshrink",
|
|
torch_opinfo_name="nn.functional.tanhshrink",
|
|
decorators=[
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestUnaryUfuncs',
|
|
'test_reference_numerics_normal',
|
|
device_type='cpu', dtypes=[torch.cfloat, torch.cdouble]),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.bfloat16: tol(atol=1e-02, rtol=1.6e-02),
|
|
torch.complex64: tol(atol=6e-04, rtol=1e-05)}),
|
|
'TestUnaryUfuncs', 'test_reference_numerics_extremal', device_type='cuda'),
|
|
],
|
|
skips=(
|
|
# in each case, pytorch will produce a nan while numpy will not
|
|
DecorateInfo(unittest.skip("Fails on some jobs works on others!"),
|
|
'TestUnaryUfuncs', "test_reference_numerics_large",
|
|
dtypes=(torch.complex64, torch.complex128),
|
|
active_if=(IS_MACOS)),
|
|
DecorateInfo(unittest.skip("Fails on some jobs works on others!"),
|
|
'TestUnaryUfuncs', "test_reference_numerics_extremal",
|
|
dtypes=(torch.complex64, torch.complex128),
|
|
device_type='cpu',
|
|
active_if=(IS_MACOS or IS_WINDOWS)),
|
|
),
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.hardshrink",
|
|
torch_opinfo_name="nn.functional.hardshrink",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.nn.functional.softshrink",
|
|
torch_opinfo_name="nn.functional.softshrink",
|
|
),
|
|
#
|
|
# Elementwise Binary Reference OpInfos
|
|
#
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.add",
|
|
torch_opinfo_name="add",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=0)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.atan2",
|
|
torch_opinfo_name="atan2",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.bitwise_and",
|
|
torch_opinfo_name="bitwise_and",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.bitwise_left_shift",
|
|
torch_opinfo_name="bitwise_left_shift",
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/70904
|
|
DecorateInfo(unittest.skip("Some inputs produce undefined outputs"), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.bitwise_right_shift",
|
|
torch_opinfo_name="bitwise_right_shift",
|
|
skips=(
|
|
# # https://github.com/pytorch/pytorch/issues/70904
|
|
DecorateInfo(unittest.skip("Skipped some inputs produce undefined outputs"), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.bitwise_or",
|
|
torch_opinfo_name="bitwise_or",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.bitwise_xor",
|
|
torch_opinfo_name="bitwise_xor",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.copysign",
|
|
torch_opinfo_name="copysign",
|
|
skips=(
|
|
# RuntimeError: Expected divisor (b) to be on the same device (cuda:0) as dividend (a), but it is found on cpu!
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
# FIXME output 0: meta disagrees with real impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
)
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.div",
|
|
torch_opinfo_name="div",
|
|
torch_opinfo_variant_name="no_rounding_mode",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
# NotImplementedError: argument of type: <class 'complex'>
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128,)
|
|
),
|
|
# Reference result was farther (0.7433461727239705) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.complex32,), device_type="cuda"
|
|
),
|
|
# Reference result was farther (0.7433461727239705) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.complex32,), device_type="cuda"
|
|
),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.div",
|
|
torch_opinfo_name="div",
|
|
torch_opinfo_variant_name="trunc_rounding",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
decorators=(
|
|
# See https://github.com/pytorch/pytorch/issues/111126
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.div",
|
|
torch_opinfo_name="div",
|
|
torch_opinfo_variant_name="floor_rounding",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
decorators=(
|
|
# See https://github.com/pytorch/pytorch/issues/111126
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
# Reference result was farther (nan) from the precise computation than the
|
|
# torch result was (inf)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure,
|
|
"TestCommon",
|
|
"test_python_ref",
|
|
dtypes=(torch.bfloat16,),
|
|
device_type="cpu",
|
|
),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.eq",
|
|
torch_opinfo_name="eq",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.float_power",
|
|
torch_opinfo_name="float_power",
|
|
skips=(
|
|
# Test doesn't account for float -> double type promotion
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
# Complex values error with: Greatest absolute difference: nan at index
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=[torch.complex64, torch.complex128]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_large_values',
|
|
dtypes=[torch.complex64, torch.complex128]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values',
|
|
dtypes=[torch.complex64, torch.complex128]),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.logaddexp",
|
|
torch_opinfo_name="logaddexp",
|
|
skips=(
|
|
# failure due to mismatch in edge cases, which boils down to what torch.exp(inf + infj) should be
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref', device_type='cpu',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback', device_type='cpu',
|
|
dtypes=(torch.complex64, torch.complex128)),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.logaddexp2",
|
|
torch_opinfo_name="logaddexp2",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.floor_divide",
|
|
torch_opinfo_name="floor_divide",
|
|
rhs_make_tensor_kwargs=dict(exclude_zero=True),
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
# bfloat16 floor_divide compared with a float32 reference works inconsistently
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.bfloat16,)),
|
|
# bfloat16 floor_divide compared with a float32 reference works inconsistently
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs',
|
|
dtypes=(torch.bfloat16,)),
|
|
# int8 floor divide has different results for -128 // -1 vs. NumPy
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.int8,)),
|
|
# The following tests fails on some jobs
|
|
DecorateInfo(unittest.skip('Skipped!'), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values',
|
|
dtypes=(torch.float16,)),
|
|
DecorateInfo(toleranceOverride({torch.float16: tol(atol=1e-3, rtol=5e-3)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
# FIXME output 0: meta disagrees with real impl
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.fmax",
|
|
torch_opinfo_name="fmax",
|
|
supports_rhs_python_scalar=False,
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.fmin",
|
|
torch_opinfo_name="fmin",
|
|
supports_rhs_python_scalar=False,
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.fmod",
|
|
torch_opinfo_name="fmod",
|
|
rhs_make_tensor_kwargs={'exclude_zero': True},
|
|
supports_rhs_python_scalar=True,
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.bfloat16,), device_type='cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.bfloat16,), device_type='cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_contig_vs_every_other',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_non_contig',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.uint8,)),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.gcd",
|
|
torch_opinfo_name="gcd",
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure,
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.int8,)),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.ge",
|
|
torch_opinfo_name="ge",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.gt",
|
|
torch_opinfo_name="gt",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.heaviside",
|
|
torch_opinfo_name="heaviside",
|
|
supports_rhs_python_scalar=False,
|
|
skips=(
|
|
# PyTorch's heaviside does not appear to propagate NaNs
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.hypot",
|
|
torch_opinfo_name="hypot",
|
|
supports_rhs_python_scalar=False,
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.igamma",
|
|
torch_opinfo_name="igamma",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.igammac",
|
|
torch_opinfo_name="igammac",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.isclose",
|
|
torch_opinfo_name="isclose",
|
|
skips=(
|
|
# Intentional xfail -- isclose does not type promote
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.lcm",
|
|
torch_opinfo_name="lcm",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.le",
|
|
torch_opinfo_name="le",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.logical_and",
|
|
torch_opinfo_name="logical_and",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.logical_not",
|
|
torch_opinfo_name="logical_not",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.logical_or",
|
|
torch_opinfo_name="logical_or",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.logical_xor",
|
|
torch_opinfo_name="logical_xor",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.lt",
|
|
torch_opinfo_name="lt",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.maximum",
|
|
torch_opinfo_name="maximum",
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.minimum",
|
|
torch_opinfo_name="minimum",
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.mul",
|
|
torch_opinfo_name="mul",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
# Reference result was farther (0.0) from the precise computation
|
|
# than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.complex32,),
|
|
),
|
|
# Reference result was farther (0.0) from the precise computation
|
|
# than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.complex32,), device_type='cuda'
|
|
),
|
|
# Reference result was farther (0.0) from the precise computation
|
|
# than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.complex32,), device_type='cuda'
|
|
),
|
|
)
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.ne",
|
|
torch_opinfo_name="ne",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.nextafter",
|
|
torch_opinfo_name="nextafter",
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.pow",
|
|
torch_opinfo_name="pow",
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-4, rtol=1.3e-05)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.complex64: tol(atol=1e-4, rtol=1.3e-05),
|
|
torch.complex128: tol(atol=1e-4, rtol=1.3e-05)}),
|
|
'TestBinaryUfuncs', 'test_scalar_support'),
|
|
),
|
|
skips=(
|
|
# Reference result was farther (inf) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.complex32,),
|
|
),
|
|
# Reference result was farther (inf) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.complex32,), device_type="cuda"
|
|
),
|
|
# Reference result was farther (inf) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.complex32,), device_type="cuda"
|
|
),
|
|
# Skipping integers because they are being raised to negative powers causing an error
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=[torch.int8, torch.int16, torch.int32, torch.int64]),
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs',
|
|
'test_reference_numerics_large_values',
|
|
dtypes=[torch.int16, torch.int32, torch.int64]),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.complex32,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_large_values',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_extremal_values',
|
|
dtypes=(torch.complex32, torch.complex64, torch.complex128)),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.remainder",
|
|
torch_opinfo_name="remainder",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.bfloat16,), device_type='cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.bfloat16,), device_type='cpu'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.bfloat16,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.uint8,)),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.rsub",
|
|
torch_opinfo_name="rsub",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
skips=(
|
|
# Reference result was farther (nan) from the precise computation than
|
|
# the torch result was (nan)!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.chalf,), device_type='cpu'),
|
|
# Reference result was farther (nan) from the precise computation than
|
|
# the torch result was (nan)!
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.chalf,), device_type='cpu'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.sub",
|
|
torch_opinfo_name="sub",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
decorators=(
|
|
DecorateInfo(
|
|
toleranceOverride({torch.float16: tol(atol=1e-2, rtol=0),
|
|
torch.bfloat16: tol(atol=1e-5, rtol=5e-3),
|
|
torch.complex32: tol(atol=1e-5, rtol=1e-3)}),
|
|
'TestBinaryUfuncs', 'test_reference_numerics'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=1e-2, rtol=0)}),
|
|
'TestCommon', 'test_complex_half_reference_testing', device_type='cpu'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=5e-3, rtol=0)}),
|
|
'TestDecomp', 'test_comprehensive', device_type='cpu'),
|
|
DecorateInfo(
|
|
toleranceOverride({torch.chalf: tol(atol=5e-3, rtol=0)}),
|
|
'TestDecomp', 'test_quick', device_type='cpu'),
|
|
),
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics',
|
|
dtypes=(torch.uint8,)),
|
|
DecorateInfo(unittest.skip("Skipped!"),
|
|
'TestBinaryUfuncs',
|
|
'test_reference_numerics_small_values',
|
|
dtypes=(torch.uint8,)),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.true_divide",
|
|
torch_opinfo_name="true_divide",
|
|
# https://github.com/pytorch/pytorch/issues/76944
|
|
supports_two_python_scalars=True,
|
|
supports_one_python_scalar=True,
|
|
skips=(
|
|
# Reference result was farther (0.7433461727239705) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_executor',
|
|
dtypes=(torch.complex32,),
|
|
),
|
|
# Reference result was farther (0.7433461727239705) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.complex32,), device_type="cuda"
|
|
),
|
|
# Reference result was farther (0.7433461727239705) from the precise
|
|
# computation than the torch result was (nan)!
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.complex32,), device_type="cuda"
|
|
),
|
|
),
|
|
),
|
|
#
|
|
# Elementwise Ternary Reference OpInfos
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.addcdiv",
|
|
torch_opinfo_name="addcdiv",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.addcmul",
|
|
torch_opinfo_name="addcmul",
|
|
skips=(
|
|
# Reference result was farther (1.3343989849090576e-05)
|
|
# from the precise computation than the torch result
|
|
# was (9.592622518539429e-06)!
|
|
# FIXME: enable dtype-based tolerances in test_ops.py:TestCommon._ref_test_helper
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.float16,), device_type="cpu"),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref_torch_fallback',
|
|
dtypes=(torch.float16,), device_type="cpu"),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.clamp_min",
|
|
torch_opinfo_name="clamp_min",
|
|
skips=(
|
|
# test error disabled since rhs non-tensor python scalar is supported
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.clamp_max",
|
|
torch_opinfo_name="clamp_max",
|
|
skips=(
|
|
# test error disabled since rhs non-tensor python scalar is supported
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.clamp",
|
|
torch_opinfo_name="clamp",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.triplet_margin_loss",
|
|
torch_opinfo_name="nn.functional.triplet_margin_loss",
|
|
supports_out=False,
|
|
# TODO: Uses minimum and clamp
|
|
skips=(
|
|
# AssertionError: Tensor-likes are not close!
|
|
# Greatest absolute difference: 6.103515625e-05 at index (4,) (up to 1e-05 allowed)
|
|
# Greatest relative difference: 8.519846983548175e-06 at index (4,) (up to 1.3e-06 allowed)
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestCommon', 'test_python_ref',
|
|
dtypes=(torch.uint8,), device_type="cpu"),
|
|
)
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.xlogy",
|
|
torch_opinfo_name="xlogy",
|
|
supports_one_python_scalar=True,
|
|
),
|
|
#
|
|
# Elementwise Binary Special OpInfos
|
|
#
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs.special.xlog1py",
|
|
torch_opinfo_name="special.xlog1py",
|
|
supports_one_python_scalar=True,
|
|
),
|
|
#
|
|
# Data Conversion & Data Movement Opinfos
|
|
#
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.bfloat16",
|
|
torch_opinfo_name="bfloat16",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.bool",
|
|
torch_opinfo_name="bool",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.byte",
|
|
torch_opinfo_name="byte",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.char",
|
|
torch_opinfo_name="char",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs._conversions.complex",
|
|
torch_opinfo_name="complex",
|
|
error_inputs_func=partial(error_inputs_complex, is_ref=True),
|
|
skips=(
|
|
# Tests don't account for complex's type promotion semantics
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
)
|
|
),
|
|
ElementwiseBinaryPythonRefInfo(
|
|
"_refs._conversions.polar",
|
|
torch_opinfo_name="polar",
|
|
skips=(
|
|
# Tests don't account for complex's type promotion semantics
|
|
DecorateInfo(unittest.expectedFailure, 'TestBinaryUfuncs', 'test_type_promotion'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestMeta', 'test_binary_ufuncs_mixed_dtype'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.double",
|
|
torch_opinfo_name="double",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.float",
|
|
torch_opinfo_name="float",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.half",
|
|
torch_opinfo_name="half",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.int",
|
|
torch_opinfo_name="int",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.long",
|
|
torch_opinfo_name="long",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.short",
|
|
torch_opinfo_name="short",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
DecorateInfo(unittest.skip('Overflow when downcasting signed type is undefined'), 'TestCommon', 'test_compare_cpu'),
|
|
)
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.chalf",
|
|
torch_opinfo_name="chalf",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.cfloat",
|
|
torch_opinfo_name="cfloat",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs._conversions.cdouble",
|
|
torch_opinfo_name="cdouble",
|
|
# TODO: If self already has the correct dtype and device, then self is
|
|
# returned ignoring memory_format.
|
|
# https://github.com/pytorch/pytorch/issues/86558
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.clone",
|
|
torch_opinfo_name="clone",
|
|
),
|
|
#
|
|
# View & Shape OpInfos
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.alias_copy",
|
|
torch_opinfo_name="alias_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.atleast_1d",
|
|
torch_opinfo_name="atleast_1d",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.atleast_2d",
|
|
torch_opinfo_name="atleast_2d",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.atleast_3d",
|
|
torch_opinfo_name="atleast_3d",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.as_strided",
|
|
torch_opinfo_name="as_strided",
|
|
# FIXME: doesn't support chalf
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# cloned_mutable_input.is_same(returned_output) INTERNAL ASSERT FAILED
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_conj_view'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.as_strided_copy",
|
|
torch_opinfo_name="as_strided_copy",
|
|
supports_out=True,
|
|
# FIXME: doesn't support chalf
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# cloned_mutable_input.is_same(returned_output) INTERNAL ASSERT FAILED
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_conj_view'),
|
|
# The view function this decompose into does not have a ref
|
|
DecorateInfo(unittest.expectedFailure, "TestCommon", "test_python_ref"),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.as_strided",
|
|
torch_opinfo_name="as_strided",
|
|
torch_opinfo_variant_name="partial_views",
|
|
# FIXME: doesn't support chalf
|
|
dtypes=all_types_and_complex_and(torch.bool, torch.float16, torch.bfloat16),
|
|
skips=(
|
|
# cloned_mutable_input.is_same(returned_output) INTERNAL ASSERT FAILED
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Errors when storage_offset is included"), 'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.as_strided_scatter",
|
|
torch_opinfo_name="as_strided_scatter",
|
|
# returns a view of an intermediate tensor (as_strided)
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.block_diag",
|
|
torch_opinfo_name="block_diag",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.broadcast_shapes",
|
|
torch_opinfo_name="broadcast_shapes",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.broadcast_tensors",
|
|
torch_opinfo_name="broadcast_tensors",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.broadcast_to",
|
|
torch_opinfo_name="broadcast_to",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.cat",
|
|
torch_opinfo_name="cat",
|
|
skips=(
|
|
# FIXME: AssertionError: RuntimeError not raised
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.chunk",
|
|
torch_opinfo_name="chunk",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.column_stack",
|
|
torch_opinfo_name="column_stack",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.conj",
|
|
torch_opinfo_name="conj",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.constant_pad_nd",
|
|
torch_opinfo_name="constant_pad_nd",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.contiguous",
|
|
torch_opinfo_name="contiguous",
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.deg2rad",
|
|
torch_opinfo_name="deg2rad",
|
|
decorators=(precisionOverride({torch.bfloat16: 7e-1,
|
|
torch.float16: 7e-1}),),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.dsplit",
|
|
torch_opinfo_name="dsplit",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.diag",
|
|
torch_opinfo_name="diag",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.diagonal",
|
|
torch_opinfo_name="diagonal",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.diagonal_copy",
|
|
torch_opinfo_name="diagonal_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.diagonal_scatter",
|
|
torch_opinfo_name="diagonal_scatter",
|
|
supports_out=True,
|
|
# returns a view of an intermediate tensor (as_strided)
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.diag_embed",
|
|
torch_opinfo_name="diag_embed",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.dstack",
|
|
torch_opinfo_name="dstack",
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.expand",
|
|
torch_opinfo_name="expand",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.expand_as",
|
|
torch_opinfo_name="expand_as",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.expand_copy",
|
|
torch_opinfo_name="expand_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.flatten",
|
|
torch_opinfo_name="flatten",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.flip",
|
|
torch_opinfo_name="flip",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.fliplr",
|
|
torch_opinfo_name="fliplr",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.flipud",
|
|
torch_opinfo_name="flipud",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.hstack",
|
|
torch_opinfo_name="hstack",
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/78613
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.narrow",
|
|
torch_opinfo_name="narrow",
|
|
error_inputs_func=partial(error_inputs_narrow_narrow_copy, is_narrow=True, is_ref=True),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.narrow_copy",
|
|
torch_opinfo_name="narrow_copy",
|
|
supports_out=True,
|
|
error_inputs_func=partial(error_inputs_narrow_narrow_copy, is_narrow=False, is_ref=True),
|
|
skips=(
|
|
# The view function this decompose into does not have a ref
|
|
DecorateInfo(unittest.expectedFailure, "TestCommon", "test_python_ref"),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.nn.functional.group_norm",
|
|
torch_opinfo_name="nn.functional.group_norm",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.native_layer_norm",
|
|
torch_opinfo_name="native_layer_norm",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Skipped!"), "TestCommon", "test_python_ref",
|
|
device_type="cpu", dtypes=(torch.float32,)),
|
|
DecorateInfo(unittest.skip("Skipped!"), "TestCommon", "test_python_ref_torch_fallback",
|
|
device_type="cpu", dtypes=(torch.float32,)),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.permute",
|
|
torch_opinfo_name="permute",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.permute_copy",
|
|
torch_opinfo_name="permute_copy",
|
|
supports_out=True,
|
|
),
|
|
ElementwiseUnaryPythonRefInfo(
|
|
"_refs.rad2deg",
|
|
torch_opinfo_name="rad2deg",
|
|
decorators=(precisionOverride({torch.bfloat16: 7e-1,
|
|
torch.float16: 7e-1}),),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.ravel",
|
|
torch_opinfo_name="ravel",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.renorm",
|
|
torch_opinfo_name="renorm",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.repeat",
|
|
torch_opinfo_name="repeat",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.reshape",
|
|
torch_opinfo_name="reshape",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.reshape_as",
|
|
torch_opinfo_name="reshape_as",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.roll",
|
|
torch_opinfo_name="roll",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.rot90",
|
|
torch_opinfo_name="rot90",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.select_scatter",
|
|
torch_opinfo_name="select_scatter",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.stack",
|
|
torch_opinfo_name="stack",
|
|
validate_view_consistency=False,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.squeeze",
|
|
torch_opinfo_name="squeeze",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.squeeze_copy",
|
|
torch_opinfo_name="squeeze_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.squeeze",
|
|
torch_opinfo_name="squeeze",
|
|
torch_opinfo_variant_name="multiple",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.tensor_split",
|
|
torch_opinfo_name="tensor_split",
|
|
skips=(
|
|
# RuntimeError: no _refs support for torch.Tensor.tolist
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.hsplit",
|
|
torch_opinfo_name="hsplit",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.vsplit",
|
|
torch_opinfo_name="vsplit",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.dot",
|
|
torch_opinfo_name="dot",
|
|
error_inputs_func=partial(error_inputs_dot_vdot, is_ref=True),
|
|
# .conj() does not set ._is_view() correctly in ATen
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
# RuntimeError: no _refs support for torch.Tensor.is_conj
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref', dtypes=[torch.complex64, torch.complex128]),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.vdot",
|
|
torch_opinfo_name="vdot",
|
|
error_inputs_func=partial(error_inputs_dot_vdot, is_ref=True),
|
|
# .conj() does not set ._is_view() correctly in ATen
|
|
validate_view_consistency=False,
|
|
skips=(
|
|
# RuntimeError: no _refs support for torch.Tensor.is_conj
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref', dtypes=[torch.complex64, torch.complex128]),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.transpose",
|
|
torch_opinfo_name="transpose",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.transpose_copy",
|
|
torch_opinfo_name="transpose_copy",
|
|
skips=(
|
|
# RuntimeError: no _refs support for torch.Tensor.is_conj
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),
|
|
),
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.t",
|
|
torch_opinfo_name="t",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.t_copy",
|
|
torch_opinfo_name="t_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.T",
|
|
torch_opinfo_name="T",
|
|
error_inputs_func=partial(error_inputs_T, has_ndims_error=True),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.unfold",
|
|
torch_opinfo_name="unfold",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.unfold_copy",
|
|
torch_opinfo_name="unfold_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.unsqueeze",
|
|
torch_opinfo_name="unsqueeze",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.unsqueeze_copy",
|
|
torch_opinfo_name="unsqueeze_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.view",
|
|
torch_opinfo_name="view",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.view_as",
|
|
torch_opinfo_name="view_as",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.view_copy",
|
|
torch_opinfo_name="view_copy",
|
|
supports_out=True,
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.vstack",
|
|
torch_opinfo_name="vstack",
|
|
skips=(
|
|
# https://github.com/pytorch/pytorch/issues/78613
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.unflatten",
|
|
torch_opinfo_name="unflatten",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.unbind",
|
|
torch_opinfo_name="unbind",
|
|
),
|
|
#
|
|
# Reduction Reference OpInfos
|
|
#
|
|
ReductionPythonRefInfo(
|
|
"_refs.all",
|
|
torch_opinfo_name="all",
|
|
skips=(
|
|
# FIXME: uint8 input returns uint8 instead of bool
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_result_dtype',
|
|
dtypes=[torch.uint8]),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.amax",
|
|
torch_opinfo_name="amax",
|
|
error_inputs_func=partial(error_inputs_aminmax_amax_amin, is_ref=True),
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.amin",
|
|
torch_opinfo_name="amin",
|
|
error_inputs_func=partial(error_inputs_aminmax_amax_amin, is_ref=True),
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.any",
|
|
torch_opinfo_name="any",
|
|
skips=(
|
|
# FIXME: uint8 input returns uint8 instead of bool
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_result_dtype',
|
|
dtypes=[torch.uint8]),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.count_nonzero",
|
|
torch_opinfo_name="count_nonzero",
|
|
skips=(
|
|
# FIXME: count_nonzero does not accept keepdim kwarg
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions',
|
|
'test_dim_default_keepdim'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_dim_none_keepdim'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_dim_single_keepdim'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_dim_multi_keepdim'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions',
|
|
'test_dim_multi_unsorted_keepdim'),
|
|
# FIXME: dim=[] reduces all dimensions
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.mean",
|
|
torch_opinfo_name="mean",
|
|
supports_out=True,
|
|
error_inputs_func=partial(error_inputs_mean, is_ref=True),
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.std",
|
|
torch_opinfo_name="std",
|
|
supports_out=True,
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=(torch.float16,)),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions',
|
|
'test_ref_duplicate_values',
|
|
dtypes=(torch.float16,)),
|
|
),
|
|
),
|
|
# std_mean and var_mean are not ReductionInfos
|
|
PythonRefInfo(
|
|
"_refs.std_mean",
|
|
torch_opinfo_name="std_mean",
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.sum",
|
|
torch_opinfo_name="sum",
|
|
supports_out=True,
|
|
skips=(
|
|
# FIXME: doesn't test out behavior properly for this operator
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# FIXME: mean reduces all dimensions when dim=[]
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16]),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions',
|
|
'test_ref_duplicate_values',
|
|
dtypes=[torch.float16]),
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestOperators', 'test_reduction_all',
|
|
dtypes=[torch.float32]),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.cumsum",
|
|
torch_opinfo_name="cumsum",
|
|
supports_out=True,
|
|
skips=(
|
|
# doesn't test out behavior properly for this operator
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.cumprod",
|
|
torch_opinfo_name="cumprod",
|
|
supports_out=True,
|
|
skips=(
|
|
# doesn't test out behavior properly for this operator
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.sum_to_size",
|
|
torch_opinfo_name="sum_to_size",
|
|
validate_view_consistency=False,
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.prod",
|
|
torch_opinfo_name="prod",
|
|
supports_out=True,
|
|
supports_multiple_dims=True,
|
|
skips=(
|
|
# FIXME: doesn't test out behavior properly for this operator
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_out'),
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input',
|
|
dtypes=[torch.float16, torch.complex64]),
|
|
),
|
|
),
|
|
ReductionPythonRefInfo(
|
|
"_refs.var",
|
|
torch_opinfo_name="var",
|
|
supports_out=True,
|
|
skips=(
|
|
# FIXME: reduces all dimensions when dim=[]
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty'),
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestReductions', 'test_dim_empty_keepdim'),
|
|
# FIXME: improve precision
|
|
DecorateInfo(
|
|
unittest.skip("Skipped!"), 'TestReductions', 'test_ref_small_input'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.var_mean",
|
|
torch_opinfo_name="var_mean",
|
|
validate_view_consistency=False,
|
|
),
|
|
#
|
|
# Linear Algebra Operators
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.addr",
|
|
torch_opinfo_name="addr",
|
|
decorators=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref',),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.trace",
|
|
torch_opinfo_name="trace",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.norm",
|
|
torch_opinfo_name="norm",
|
|
supports_out=True,
|
|
# Uses vector_norm inside and vector_norm is affected by
|
|
# https://github.com/pytorch/pytorch/issues/77216
|
|
validate_view_consistency=False,
|
|
),
|
|
#
|
|
# Tensor Creation Reference OpInfos
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.empty",
|
|
torch_opinfo_name="empty",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
# FIXME: shouldn't check empty results
|
|
DecorateInfo(unittest.skip("Can't check result for empty"), 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.empty_like",
|
|
torch_opinfo_name="empty_like",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
# FIXME: should not compare results of empty_like
|
|
DecorateInfo(unittest.skip("Can't check result for empty_like"), 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.randn",
|
|
torch_opinfo_name="randn",
|
|
op=lambda *args, **kwargs: wrapper_set_seed(refs.randn, *args, **kwargs),
|
|
skips=(
|
|
# see https://github.com/pytorch/pytorch/issues/85121
|
|
DecorateInfo(unittest.skip("make_traced() doesn't set seed properly!"),
|
|
'TestCommon',
|
|
'test_python_ref_executor'),
|
|
# These tests expect the input to be a tensor or a sequence of tensors
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), "TestCommon", "test_noncontiguous_samples"),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), 'TestMathBits', 'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Test expects tensor input"), 'TestMathBits', 'test_neg_conj_view'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.eye",
|
|
torch_opinfo_name="eye",
|
|
skips=(
|
|
# skip these tests since we have non tensor input
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Skipped!"), 'TestMathBits', 'test_neg_view'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.new_empty",
|
|
torch_opinfo_name="new_empty",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestCommon',
|
|
'test_out_warning'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
# FIXME: should not compare results of empty_like
|
|
DecorateInfo(unittest.skip("Can't check result for new_empty"), 'TestCommon', 'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.new_empty_strided",
|
|
torch_opinfo_name="new_empty_strided",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestMathBits',
|
|
'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.empty_strided",
|
|
torch_opinfo_name="empty_strided",
|
|
skips=(
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_torch_fallback'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestMathBits',
|
|
'test_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_conj_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestMathBits',
|
|
'test_neg_view'),
|
|
DecorateInfo(unittest.skip("Expected: empty_strided is not comparable"),
|
|
'TestCommon',
|
|
'test_python_ref_executor'),
|
|
DecorateInfo(unittest.skip('output is non-deterministic'), 'TestCommon', 'test_compare_cpu'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.new_full",
|
|
torch_opinfo_name="new_full",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.new_ones",
|
|
torch_opinfo_name="new_ones",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.new_zeros",
|
|
torch_opinfo_name="new_zeros",
|
|
),
|
|
#
|
|
# Conditional Reference OpInfos
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.masked_fill",
|
|
torch_opinfo_name="masked_fill",
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.where",
|
|
torch_opinfo_name="where",
|
|
op=lambda self, condition, other: refs.where(condition, self, other),
|
|
supports_out=False,
|
|
skips=(
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors', device_type='cuda'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.index_select",
|
|
torch_opinfo_name="index_select",
|
|
# empty_strided
|
|
skips=(
|
|
# no _refs support for Tensor.__setitem__
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),
|
|
# Sample out= with a stride of zero. This _out operation checks that the input has no
|
|
# inner overlap
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),)
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.index_copy",
|
|
torch_opinfo_name="index_copy",
|
|
# empty_strided
|
|
skips=(
|
|
# no _refs support for Tensor.__setitem__
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.index_add",
|
|
torch_opinfo_name="index_add",
|
|
# empty_strided
|
|
skips=(
|
|
# no _refs support for Tensor.__setitem__
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref_errors'),
|
|
),
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.index_fill",
|
|
torch_opinfo_name="index_fill",
|
|
# empty_strided
|
|
skips=(
|
|
# no _refs support for Tensor.__setitem__
|
|
DecorateInfo(unittest.expectedFailure, 'TestCommon', 'test_python_ref'),)
|
|
),
|
|
#
|
|
# Test-related functions
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.allclose",
|
|
torch_opinfo_name="allclose",
|
|
),
|
|
#
|
|
# Misc functions
|
|
#
|
|
PythonRefInfo(
|
|
"_refs.stft",
|
|
torch_opinfo_name="stft",
|
|
skips=[
|
|
# RuntimeError: no _refs support for aten.pad
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref'
|
|
),
|
|
],
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.istft",
|
|
torch_opinfo_name="istft",
|
|
skips=[
|
|
# RuntimeError: no _refs support for aten.unfold_backward
|
|
DecorateInfo(
|
|
unittest.expectedFailure, 'TestCommon', 'test_python_ref'
|
|
),
|
|
DecorateInfo(
|
|
unittest.skip("Expected: unfold_backward() got an unexpected keyword argument 'input_sizes'"),
|
|
'TestCommon',
|
|
'test_python_ref_executor',
|
|
dtypes=(torch.complex64, torch.complex128),
|
|
),
|
|
],
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.view_as_complex",
|
|
torch_opinfo_name="view_as_complex",
|
|
),
|
|
PythonRefInfo(
|
|
"_refs.split_with_sizes",
|
|
torch_opinfo_name="split_with_sizes",
|
|
),
|
|
]
|
|
python_ref_db += opinfo.definitions.python_ref_db
|
|
|
|
# Common operator groupings
|
|
ops_and_refs = op_db + python_ref_db
|
|
unary_ufuncs = [op for op in ops_and_refs if isinstance(op, UnaryUfuncInfo)]
|
|
binary_ufuncs = [op for op in ops_and_refs if isinstance(op, BinaryUfuncInfo)]
|
|
binary_ufuncs_and_refs = tuple(op for op in ops_and_refs if isinstance(op, BinaryUfuncInfo))
|
|
spectral_funcs = [op for op in ops_and_refs if isinstance(op, SpectralFuncInfo)]
|
|
sparse_unary_ufuncs = [op for op in op_db if isinstance(op, UnaryUfuncInfo) and op.supports_sparse]
|
|
sparse_csr_unary_ufuncs = [op for op in op_db if isinstance(op, UnaryUfuncInfo) and op.supports_sparse_csr]
|
|
sparse_reduction_ops = [op for op in op_db if isinstance(op, ReductionOpInfo) and op.supports_sparse]
|
|
shape_funcs = [op for op in ops_and_refs if isinstance(op, ShapeFuncInfo)]
|
|
reduction_ops = [op for op in ops_and_refs if isinstance(op, ReductionOpInfo)]
|
|
reference_filtered_ops = [op for op in reduction_ops if op.ref is not None]
|
|
reference_masked_ops = [op for op in reference_filtered_ops if op.name.startswith('masked.')]
|
|
sparse_masked_reduction_ops = [op for op in sparse_reduction_ops if op.name.startswith('masked.')]
|
|
|
|
# TODO: review porting these to make_tensor
|
|
def index_variable(shape, max_indices, device=torch.device('cpu')):
|
|
if not isinstance(shape, tuple):
|
|
shape = (shape,)
|
|
index = torch.rand(*shape, dtype=torch.double, device=device).mul_(max_indices).floor_().long()
|
|
return index
|
|
|
|
def gather_variable(shape, index_dim, max_indices, duplicate=False, device=torch.device('cpu')):
|
|
assert len(shape) == 2
|
|
assert index_dim < 2
|
|
batch_dim = 1 - index_dim
|
|
index = torch.zeros(*shape, dtype=torch.long, device=device)
|
|
for i in range(shape[index_dim]):
|
|
index.select(index_dim, i).copy_(
|
|
torch.randperm(max_indices, device=device)[:shape[batch_dim]])
|
|
if duplicate:
|
|
index.select(batch_dim, 0).copy_(index.select(batch_dim, 1))
|
|
return index
|
|
|
|
def bernoulli_scalar():
|
|
return torch.tensor(0, dtype=torch.bool).bernoulli_()
|
|
|
|
def mask_not_all_zeros(shape):
|
|
assert len(shape) > 0
|
|
while True:
|
|
result = torch.randn(shape).gt(0)
|
|
if result.sum() > 0:
|
|
return result
|
|
|
|
# Copied from functorch
|
|
def xfail(op_name, variant_name='', *, device_type=None, dtypes=None):
|
|
return (op_name, variant_name, device_type, dtypes, True)
|
|
|
|
|
|
def skip(op_name, variant_name='', *, device_type=None, dtypes=None):
|
|
return (op_name, variant_name, device_type, dtypes, False)
|
|
|
|
|
|
def skipOps(test_case_name, base_test_name, to_skip):
|
|
all_opinfos = op_db
|
|
for xfail in to_skip:
|
|
op_name, variant_name, device_type, dtypes, expected_failure = xfail
|
|
matching_opinfos = [o for o in all_opinfos
|
|
if o.name == op_name and o.variant_test_name == variant_name]
|
|
assert len(matching_opinfos) >= 1, f"Couldn't find OpInfo for {xfail}"
|
|
for op in matching_opinfos:
|
|
decorators = list(op.decorators)
|
|
if expected_failure:
|
|
decorator = DecorateInfo(unittest.expectedFailure,
|
|
test_case_name, base_test_name,
|
|
device_type=device_type, dtypes=dtypes)
|
|
decorators.append(decorator)
|
|
else:
|
|
decorator = DecorateInfo(unittest.skip("Skipped!"),
|
|
test_case_name, base_test_name,
|
|
device_type=device_type, dtypes=dtypes)
|
|
decorators.append(decorator)
|
|
op.decorators = tuple(decorators)
|
|
|
|
# This decorator doesn't modify fn in any way
|
|
def wrapped(fn):
|
|
return fn
|
|
return wrapped
|