Repository: pytorch
Issue: __torch_function__ is hitting private functions in some cases
Labels: triaged,enhancement,module: __torch_function__

### 🐛 Describe the bug

I ran this script to generate `__torch_function__` operator coverage per OpInfos:

```
1	
import argparse
import torch
from torch.utils._python_dispatch import enable_python_mode
from torch.testing._internal.common_methods_invocations import op_db
from torch.utils._pytree import tree_map
import math
import warnings
import types
import torch.overrides
import torch.fx.node
import functools
import __future__

warnings.filterwarnings("ignore")

COVERAGE = {}

class DispatchCoverageMode(torch.Tensor):
    @staticmethod
    def __new__(cls, elem):
        raise RuntimeError("this is mode only")

    @classmethod
    def __torch_dispatch__(cls, func, types, args=(), kwargs=None):
        return super().__torch_dispatch__(func, types, args, kwargs)

def fullname(o):
    module = o.__module__
    if module is None:
        return o.__qualname__
    return module + '.' + o.__qualname__


# copied from torch.overrides
@functools.lru_cache(None)
def get_overridable_functions_index():
    """List functions that are overridable via __torch_function__

    Returns
    -------
    Dict[Any, List[Callable]]
        A dictionary that maps namespaces that contain overridable functions
        to functions in that namespace that can be overridden.
    """
    index = {}
    tested_namespaces = [
        ("torch._C._VariableFunctions", dir(torch._C._VariableFunctions)),
        ("torch", torch.__all__ + dir(torch._C._VariableFunctions)),
        ("torch.functional", torch.functional.__all__),
        ("torch.nn.functional", dir(torch.nn.functional)),
        ("torch.Tensor", dir(torch.Tensor)),
        ("torch.linalg", dir(torch.linalg)),
        ("torch.fft", dir(torch.fft)),
        ("torch.special", dir(torch.special)),
    ]
    for namespace_str, ns_funcs in tested_namespaces:
        namespace = eval(namespace_str)
        for func_name in ns_funcs:
            # ignore private functions or functions that are deleted in torch.__init__
            if namespace is not torch.Tensor:
                # TODO: I deleted the private stuff, this is bad news, it
                # means we are hitting private API here
                if func_name.startswith('__'):
                    continue
                if func_name == 'unique_dim':
                    continue
            else:
                func = getattr(namespace, func_name)
                if getattr(object, func_name, None) == func:
                    continue
                if func_name == '__weakref__':
                    continue
            func = getattr(namespace, func_name)
            if namespace is torch.Tensor and getattr(object, func_name, None) == func:
                continue
            # ignore re-exported modules
            if isinstance(func, types.ModuleType):
                continue
            # ignore __future__ imports
            if isinstance(func, __future__._Feature):
                continue

            if not callable(func) and hasattr(func, "__get__"):
                index[func.__get__] = f"{namespace_str}.{func_name}"
                continue

            if not callable(func):
                continue

            index[func] = f"{namespace_str}.{func_name}"
    return index


COVERAGE = set()
class FunctionCoverageProxy(torch.Tensor):
    @classmethod
    def __torch_function__(cls, func, types, args=(), kwargs=None):
        # print(get_overridable_functions_index()[func])
        COVERAGE.add(get_overridable_functions_index()[func])
        return super().__torch_function__(func, types, args, kwargs)


parser = argparse.ArgumentParser(description='Generate operator sheet.')
parser.add_argument('--dispatch-coverage', action='store_true')
parser.add_argument('--function-coverage', action='store_true')
options = parser.parse_args()

device = 'cpu'
for op in op_db:
    try:
        dtypes = op.supported_dtypes(device)
        if not dtypes:
            continue
        for t in [torch.float, torch.int, torch.bool]:
            if t in dtypes:
                dtype = t
        else:
            dtype = next(iter(dtypes))
        # Hypothetically you can run on all dtypes but empirically this
        # does not help
        try:
            for input in op.sample_inputs(
                device, dtype, requires_grad=False
            ):
                args = (input.input,) + input.args
                kwargs = input.kwargs

                if options.dispatch_coverage:
                    with enable_python_mode(DispatchCoverageMode):
                        op.op(*(input.input,) + input.args, **input.kwargs)

                if options.function_coverage:
                    if op.name not in ['to_sparse']:
                        def wrap(t):
                            if isinstance(t, torch.Tensor):
                                return torch.Tensor._make_subclass(FunctionCoverageProxy, t)
                            else:
                                return t
                        op.op(*tree_map(wrap, args), **tree_map(wrap, kwargs))
        except Exception:
            print(dtype)
            print(dtypes)
            raise
    except Exception:
        print(op.name)
        raise

print("\n".join(sorted(list(COVERAGE))))
```

A few private functions showed up:

```
torch._C._VariableFunctions.atleast_1d
torch._C._VariableFunctions.atleast_2d
torch._C._VariableFunctions.atleast_3d
torch._C._VariableFunctions.meshgrid
torch._histogramdd_bin_edges
torch._histogramdd_from_bin_cts
torch._histogramdd_from_bin_tensors
```

`__torch_functions__` overrides should only be for public API, so there is something fishy going on here; probably missing "has torch function" at a higher level.

Relevant backtraces

```

  File "/data/users/ezyang/pytorch-tmp/torch/functional.py", line 584, in meshgrid
    return _meshgrid(*tensors, indexing=indexing)
  File "/data/users/ezyang/pytorch-tmp/torch/functional.py", line 599, in _meshgrid
    return _VF.meshgrid(tensors, **kwargs)  # type: ignore[attr-defined]


  File "/data/users/ezyang/pytorch-tmp/torch/functional.py", line 1427, in atleast_3d
    return _VF.atleast_3d(tensors)  # type: ignore[attr-defined]



  File "/data/users/ezyang/pytorch-tmp/torch/functional.py", line 471, in histogramdd
    bin_edges = _VF._histogramdd_bin_edges(input, bins, range=range, weight=weight, density=density)

```

### Versions

master

cc @hameerabbasi @rgommers @peterbell10