Repository: pytorch/vision

Issue:
AttributeError: '_OpNamespace' 'torchvision' object has no attribute 'roi_align' 
Hi, I'm getting the following error while running the e2e tests in Torch-MLIR. I'm trying to get a small reproducible for the issue. Meanwhile, if someone is familiar with the error or knows what could be the probable reason behind this, it would be helpful to know. Some changes have been made here: https://github.com/pytorch/vision/commit/8f2e5c90ce0f55877eddb1f7fee8f8b48004849b, but I'm not sure how this relates to the below error.

```
Traceback (most recent call last): 

38535 File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torch/_ops.py", line 705, in __getattr__ 

38536 op, overload_names = torch._C._jit_get_operation(qualified_op_name) 

38537RuntimeError: No such operator torchvision::roi_align 

38538 

38539The above exception was the direct cause of the following exception: 

38540 

38541Traceback (most recent call last): 

38542 File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main 

38543 return _run_code(code, main_globals, None, 

38544 File "/usr/lib/python3.10/runpy.py", line 86, in _run_code 

38545 exec(code, run_globals) 

38546 File "/main_checkout/torch-mlir/e2e_testing/main.py", line 34, in <module> 

38547 register_all_tests() 

38548 File "/main_checkout/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/test_suite/__init__.py", line 18, in register_all_tests 

38549 from . import vision_models 

38550 File "/main_checkout/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/test_suite/vision_models.py", line 7, in <module> 

38551 import torchvision.models as models 

38552 File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torchvision/__init__.py", line 6, in <module> 

38553 from torchvision import _meta_registrations, datasets, io, models, ops, transforms, utils 

38554 File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torchvision/_meta_registrations.py", line 22, in <module> 

38555 @register_meta(vision.roi_align.default) 

38556 File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torch/_ops.py", line 709, in __getattr__ 

38557 raise AttributeError( 

38558AttributeError: '_OpNamespace' 'torchvision' object has no attribute 'roi_align' 

38559Error: Process completed with exit code 1.
```


Discussion:
@ezyang Do you have any idea about this since I think the changes made by you here:https://github.com/pytorch/vision/commit/8f2e5c90ce0f55877eddb1f7fee8f8b48004849b are somehow related to this error?
Do you have any warnings, like unable to load C++ extension?
> Do you have any warnings, like unable to load C++ extension?

No. You can see the failure log here: https://github.com/llvm/torch-mlir/actions/runs/4543405704/jobs/8008048515
A reproducer would be best then. I can manually patch out the problem by testing if the ops are defined or not before attempting to register things to them, but a non-broken torchvision install really should have them all available.
you can check the version here


pip uninstall torchvision
Found existing installation: torchvision 0.16.0.dev20230329
Uninstalling torchvision-0.16.0.dev20230329:
  Would remove:
    /home/oem/miniconda3/envs/torch2/lib/python3.10/site-packages/torchvision
    /home/oem/miniconda3/envs/torch2/lib/python3.10/site-packages/torchvision-0.16.0.dev20230329-py3.10.egg-info
Proceed (Y/n)? n


I suspect its specific to 0.16 nightly build? did they make this obsolete? 
When I install the nightlies on my Linux box, I am able to import without trouble

```
(base) [ezyang@devgpu020.ftw1 ~]$ python -c "import torchvision._meta_registrations"
(base) [ezyang@devgpu020.ftw1 ~]$ pip list | grep vision
torchvision            0.16.0.dev20230403+cpu
```

So it seems like some problem with the CI environment specifically.

Maybe we can help debug by running inside the CI environment that torch-mlir is doing? Is there a way to lobotomize the CI so all it does is install torchvision nightly, and then tries to import it?
The CI tries to build from the corresponding PyTorch nightly SHA (vs just using the binary) so we can validate building Pytorch from source and linking to it. Could there be some new requirement or flag required when we build PyTorch from source so that  prevents `_meta_registrations` from working ?  

This is how we build Pytorch for the test: https://github.com/llvm/torch-mlir/blob/f83c516b1587679ce76a65e4fcd9be4b9d411200/build_tools/build_libtorch.sh#L69-L117 

The issue is easy to recreate locally since it is a docker script. You just need to git checkout / update submodules for torch-mlir and run the docker script. 

```
git clone http://github.com/llvm/torch-mlir 
git submodule update --init

TM_PACKAGES="in-tree" TM_USE_PYTORCH_BINARY="OFF" \
        TORCH_MLIR_SRC_PYTORCH_BRANCH="3b8052d979c7658064feed6b462908383c9243ca" \
        TORCH_MLIR_SRC_PYTORCH_RELEASE="2.1.0.dev20230403" \
        TM_UPDATE_ODS_AND_ABSTRACT_INTERP_LIB="ON" \
        TM_PYTHON_VERSIONS="cp311-cp311" \
        ./build_tools/python_deploy/build_linux_packages.sh

```

perhaps use this to run a sanity check on versions 
 
`python -c 'import torch;import gradio;import torchvision;print(f"gradio {gradio.__version__},\ntorch {torch.__version__},\ntorchvision {torchvision.__version__},  \ncuda {torch.version.cuda}, \ncudnn {torch.backends.cudnn.version()}")'`


**gradio 3.23.0,
torch 2.0.0+cu117,
torchvision 0.15.1+cu117,  
cuda 11.7, 
cudnn 8500**

I think I downgraded torchvision to the above version and it resolved problem
I think the problem only happens in the nightly builds -- all builds before https://github.com/pytorch/vision/commit/8f2e5c90ce0f55877eddb1f7fee8f8b48004849b work well
I'm going to try reproducing with the listed docker instructions
Thank you. Please let me know if you have any trouble. I verified I ran into the issue with my local docker build

```
:::: Run Linalg e2e integration tests
Traceback (most recent call last):
  File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torch/_ops.py", line 705, in __getattr__
    op, overload_names = torch._C._jit_get_operation(qualified_op_name)
RuntimeError: No such operator torchvision::roi_align

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.10/runpy.py", line 196, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.10/runpy.py", line 86, in _run_code
    exec(code, run_globals)
  File "/main_checkout/torch-mlir/e2e_testing/main.py", line 34, in <module>
    register_all_tests()
  File "/main_checkout/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/test_suite/__init__.py", line 18, in register_all_tests
    from . import vision_models
  File "/main_checkout/torch-mlir/build/tools/torch-mlir/python_packages/torch_mlir/torch_mlir_e2e_test/test_suite/vision_models.py", line 7, in <module>
    import torchvision.models as models
  File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torchvision/__init__.py", line 6, in <module>
    from torchvision import _meta_registrations, datasets, io, models, ops, transforms, utils
  File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torchvision/_meta_registrations.py", line 22, in <module>
    @register_meta(vision.roi_align.default)
  File "/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torch/_ops.py", line 709, in __getattr__
    raise AttributeError(AttributeError: '_OpNamespace' 'torchvision' object has no attribute 'roi_align'
```
It appears to be taking its sweet time and building all of LLVM, I hope that I can get at the docker image when it inevitably fails lol
uff yeah this is the full source build -- so all of llvm, and pytorch from source.  BTW the docker cleans up when it is done [here](https://github.com/llvm/torch-mlir/blob/e90ea3d7ab66c1b5e858818630261721b3c53d82/build_tools/python_deploy/build_linux_packages.sh#L112)

If you want maybe we can echo the command there and use it manually so you can run docker with `-it`  so you get a shell ? 
It did reproduce and the docker went poof, time to reverse engineer how to get into the docker
OK, I got into the Docker, and there is indeed a warning saying that we failed to load the C extension:

```
3: UserWarning: Failed to load image Python extension: '/main_checkout/torch-mlir/docker_venv/lib/python3.10/site-packages/torchvision/image.so: undefined symbol: _ZN3c106detail23torchInternalAssertFailEPKcS2_jS2_RKSs'If you don't plan on using image functionality from `torchvision.io`, you can ignore this warning. Otherwise, there might be something wrong with your environment. Did you have `libjpeg` or `libpng` installed before building `torchvision` from source?
```

So what I will do is fix these registrations to no-op if torchvision is not loading the C extension. However, there is probably something wrong with your setup: probably that you are building PyTorch from source and then not building torchvision from source.

Resolving patch:
diff --git a/torchvision/_meta_registrations.py b/torchvision/_meta_registrations.py
--- a/torchvision/_meta_registrations.py
+++ b/torchvision/_meta_registrations.py
@@ -1,3 +1,5 @@
+import functools
+
 import torch
 import torch.library
 
@@ -6,20 +8,22 @@
 
 from torch._prims_common import check
 
-_meta_lib = torch.library.Library("torchvision", "IMPL", "Meta")
 
-vision = torch.ops.torchvision
+@functools.lru_cache(None)
+def get_meta_lib():
+    return torch.library.Library("torchvision", "IMPL", "Meta")
 
 
-def register_meta(op):
+def register_meta(op_name, overload_name="default"):
     def wrapper(fn):
-        _meta_lib.impl(op, fn)
+        if torchvision.extension._has_ops():
+            get_meta_lib().impl(getattr(getattr(torch.ops.torchvision, op_name), overload_name), fn)
         return fn
 
     return wrapper
 
 
-@register_meta(vision.roi_align.default)
+@register_meta("roi_align")
 def meta_roi_align(input, rois, spatial_scale, pooled_height, pooled_width, sampling_ratio, aligned):
     check(rois.size(1) == 5, lambda: "rois must have shape as Tensor[K, 5]")
     check(
@@ -34,7 +38,7 @@ def meta_roi_align(input, rois, spatial_scale, pooled_height, pooled_width, samp
     return input.new_empty((num_rois, channels, pooled_height, pooled_width))
 
 
-@register_meta(vision._roi_align_backward.default)
+@register_meta("_roi_align_backward")
 def meta_roi_align_backward(
     grad, rois, spatial_scale, pooled_height, pooled_width, batch_size, channels, height, width, sampling_ratio, aligned
 ):


Test patch: