Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/NVIDIA/cuda-quantum into br…
Browse files Browse the repository at this point in the history
…aket-pipeline-3

Signed-off-by: Anna Gringauze <[email protected]>
  • Loading branch information
annagrin committed Nov 27, 2024
2 parents 797ea89 + a4660c9 commit e92e5f1
Show file tree
Hide file tree
Showing 2 changed files with 94 additions and 19 deletions.
32 changes: 26 additions & 6 deletions .github/workflows/python_metapackages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:
echo "Creating README.md for cuda-quantum package"
echo "# Welcome to the CUDA-Q Python API" > README.md
echo "This package is deprecated and new versions are published under the name `cudaq` instead." >> README.md
echo "This package is deprecated and new versions are published under the name \`cudaq\` instead." >> README.md
echo "For more information, please see [CUDA-Q on PyPI](https://pypi.org/project/cudaq)." >> README.md
echo "Building cuda-quantum metapackage ..."
Expand Down Expand Up @@ -195,8 +195,6 @@ jobs:
fi
- name: Test installation error
# FIXME: We actually don't give a proper install error if there are conflicting packages on the system...
if: matrix.cuda_version == ''
run: |
python=python${{ matrix.python_version }}
$python -m pip install pypiserver
Expand All @@ -211,11 +209,13 @@ jobs:
set -e && check_package=cuda-quantum
;;
12.*)
test_conflicting=cuda-quantum-cu11
$python -m pip install cuda-quantum-cu11==${{ inputs.cudaq_version }} \
--extra-index-url http://localhost:8080
set +e # continue on error
$python -m pip install cudaq==${{ inputs.cudaq_version }} -v \
--extra-index-url http://localhost:8080
--extra-index-url http://localhost:8080 \
2>&1 | tee /tmp/install.out
set -e && check_package=cudaq
;;
*)
Expand All @@ -225,17 +225,37 @@ jobs:
set -e
if [ -z "$($python -m pip list | grep cuda-quantum)" ]; then
# if we don't have a 0.8.0 version for this python version, test other conflict
test_conflicting=cuda-quantum-cu12
$python -m pip install cuda-quantum-cu12==${{ inputs.cudaq_version }} \
--extra-index-url http://localhost:8080
else
test_conflicting=cuda-quantum
fi
set +e # continue on error
$python -m pip install cudaq==${{ inputs.cudaq_version }} -v \
--extra-index-url http://localhost:8080
--extra-index-url http://localhost:8080 \
2>&1 | tee /tmp/install.out
set -e && check_package=cudaq
;;
esac
if [ -n "$($python -m pip list | grep ${check_package})" ]; then
# The autodetection will fail if the runner does not have a GPU.
# In that case, we will only check if the install failed, if the
# package we want to test the conflict detection for is not the
# default package that is installed when there is no GPU.
if [ -f /tmp/install.out ] && [ -z "$(cat /tmp/install.out | grep -o 'Autodetection succeeded')" ]; then
# Autodetection failed - a default choice of the binary distribution will be installed.
echo "::warning::Autodetection to determine cudaq binary distribution failed."
# Take the first Identified best package because the logs print multiple lines.
# They should all be the same, if they differ in the build environment then there is probably issues.
installed_default=$(cat /tmp/install.out | sed -nE 's/.*Identified (\S*) as the best package.*/\1/p' | head -n 1)
echo "::warning::The installed default is ${installed_default}, the potential conflicting package is ${test_conflicting}"
if [ "$installed_default" == "$test_conflicting" ]; then
check_package=none
fi
fi
if [ "$check_package" != "none" ] && [ -n "$($python -m pip list | grep ${check_package})" ]; then
echo "::error file=python_metapackages.yml::Unexpected installation of ${check_package} package."
exit 1
fi
Expand Down
81 changes: 68 additions & 13 deletions python/metapackages/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import ctypes, os, sys
import importlib.util
import site, glob
from setuptools import setup
from typing import Optional

Expand Down Expand Up @@ -116,22 +117,76 @@ def _get_cuda_version() -> Optional[int]:
return None


def _infer_best_package() -> str:
def _check_package_installed(package_name) -> bool:
"""
Checks if a python package is installed globally or in user packages.
"""

# ideally you would use `importlib.util.find_spec` to check for the file.
# For some reason, that does not work during pip install, which I'm
# not clear about for now. This is worked around by getting the site
# packages and searching for the files manually.

def _check_in_directory(directory, package_name):
"""
Helper function to check if a package exists in a given directory.
"""
search_pattern = os.path.join(directory, f"{package_name}-*.dist-info")
matches = glob.glob(search_pattern)
if matches:
_log(
f"Found the following matches for '{package_name}*' in {directory}:"
)
for match in matches:
_log(match)
return True
return False

def _replace_hyphens_with_underscores(input_string):
return input_string.replace("-", "_")

# ```
# Normalize because package name hyphens replaced with underscores
# ex:
# # ls /usr/local/lib/python3.10/dist-packages | grep cuda
# cuda_quantum_cu11-0.9.0.dist-info
# cuda_quantum_cu11.libs
# cuda_quantum_cu12-0.9.0.dist-info
# cuda_quantum_cu12.libs
# ```
normalized_package_name = _replace_hyphens_with_underscores(package_name)

# Check in user site-packages
user_site_packages = site.getusersitepackages()
if os.path.exists(user_site_packages):
_log(f"User site-packages directory: {user_site_packages}")
return _check_in_directory(user_site_packages, normalized_package_name)
else:
_log("User site-packages directory does not exist.")

# Check in global site-packages
site_packages_dirs = site.getsitepackages()
_log(f"Global site-packages directories: {site_packages_dirs}")
for directory in site_packages_dirs:
if _check_in_directory(directory, normalized_package_name):
return True

_log(
f"No matches found for '{normalized_package_name}' in any site-packages directory."
)
return False


def _infer_best_package() -> str:
"""
Checks what packages should be installed, and handles potential conflicts.
"""
# Find the existing wheel installation
installed = []
for pkg_suffix in ['', '-cu11', '-cu12']:
_log(f"Looking for existing installation of cuda-quantum{pkg_suffix}.")
try:
package_spec = importlib.util.find_spec(f"cuda-quantum{pkg_suffix}")
if package_spec is None:
_log("No installation found.")
else:
installed.append(f"cuda-quantum{pkg_suffix}")
_log("Installation found.")
except:
_log("No installation found.")
pass
for pkg in ['cuda-quantum', 'cuda-quantum-cu11', 'cuda-quantum-cu12']:
_log(f"Looking for existing installation of {pkg}.")
if _check_package_installed(pkg):
installed.append(pkg)

cuda_version = _get_cuda_version()
if cuda_version is None:
Expand Down

0 comments on commit e92e5f1

Please sign in to comment.