Repository: cupy/cupy

Issue:
Detect wrong installation (duplicate wheels) and warn 
Refs: #3541

https://github.com/chainer/chainer/blob/e8283065bc706447bf4f721122fc3e49f0a06ea1/chainer/_environment_check.py#L44


Discussion:
Is it possible to also detect if a source-build and a wheel coexist?
> Is it possible to also detect if a source-build and a wheel coexist?

Yes, packages are named `cupy`  for source build and `cupy-cudaXXX` for wheels.
I think if a user does `pip install cupy` and then `pip install cupy-cudaXXX` (or vice versa), the second attempt should error out. I've been stumbled by this possible coexistence of wheel + source build several times...
I understand that, but wheel installation is basically just a unzip and cannot run code. `pip install cupy` can run any code but unable to display a message to users because stdout/stderr is captured and discarded if the installation succeeds.

Resolving patch:
diff --git a/cupy/__init__.py b/cupy/__init__.py
--- a/cupy/__init__.py
+++ b/cupy/__init__.py
@@ -8,6 +8,7 @@
 from cupy import _version
 
 
+_environment._detect_duplicate_installation()  # NOQA
 _environment._setup_win32_dll_directory()  # NOQA
 _environment._preload_libraries()  # NOQA
 
diff --git a/cupy/_environment.py b/cupy/_environment.py
--- a/cupy/_environment.py
+++ b/cupy/_environment.py
@@ -380,3 +380,60 @@ def _preload_warning(lib, exc):
             lib=lib, exc_type=type(exc).__name__, exc=str(exc),
             cuda=config['cuda'])
         warnings.warn(msg)
+
+
+def _detect_duplicate_installation():
+    # importlib.metadata only available in Python 3.8+.
+    if sys.version_info < (3, 8):
+        return
+    import importlib.metadata
+
+    # List of all CuPy packages, including out-dated ones.
+    known = [
+        'cupy',
+        'cupy-cuda80',
+        'cupy-cuda90',
+        'cupy-cuda91',
+        'cupy-cuda92',
+        'cupy-cuda100',
+        'cupy-cuda101',
+        'cupy-cuda102',
+        'cupy-cuda110',
+        'cupy-cuda111',
+        'cupy-cuda112',
+        'cupy-cuda113',
+        'cupy-rocm-4-0',
+        'cupy-rocm-4-1',
+        'cupy-rocm-4-2',
+    ]
+    cupy_installed = [
+        name for name in known
+        if list(importlib.metadata.distributions(name=name))]
+    if 1 < len(cupy_installed):
+        cupy_packages_list = ', '.join(sorted(cupy_installed))
+        warnings.warn(f'''
+--------------------------------------------------------------------------------
+
+  CuPy may not function correctly because multiple CuPy packages are installed
+  in your environment:
+
+    {cupy_packages_list}
+
+  Follow these steps to resolve this issue:
+
+    1. For all packages listed above, run the following command to remove all
+       existing CuPy installations:
+
+         $ pip uninstall <package_name>
+
+      If you previously installed CuPy via conda, also run the following:
+
+         $ conda uninstall cupy
+
+    2. Install the appropriate CuPy package.
+       Refer to the Installation Guide for detailed instructions.
+
+         https://docs.cupy.dev/en/stable/install.html
+
+--------------------------------------------------------------------------------
+''')


Test patch: