Skip to content

[RFC] handling CUDA-suffixed dependencies needed at setuptools.setup() time #39

Closed
@jameslamb

Description

Description

Consider a project with the following characteristics:

  • uses a setup.py running setuptools.setup()
  • needs to import {library} in that setup.py, prior to setup() being called
  • {library} is only distributed via CUDA-suffixed wheels (e.g. {library}-cu11)

How should such cases be handled? Is it possible to make them work with rapids-build-backend?

Details

Consider the specific case of ucx-py.

Its setup.py includes stuff like this that runs before setuptools.setup() is executed:

def _find_libucx_libs_and_headers():
    import libucx
    module_dir = os.path.dirname(libucx.__file__)
    libs = glob.glob(f"{module_dir}/**/lib*.so*", recursive=True)
    ...
    return list(lib_dirs), list(header_dirs)

libucx_lib_dirs, libucx_header_dirs = _find_libucx_libs_and_headers()

ext_modules = [
    Extension(
        ...
        include_dirs=[libucx_header_dirs],
        library_dirs=[libucx_lib_dirs],
    ),
    ...
]

setup(
    ext_modules=ext_modules,
    cmdclass={"build_ext": new_build_ext},
    ...
)

(ucx-wheels/setup.py)

The key line is that import libucx.

By the time that line runs, libucx-cu11 or libucx-cu12 needs to have been installed. It that seems pip wheel ends up running setup.py before rapids-build-backend has had a chance to replace the contents of pyproject.toml.

With libucx==1.15.0 (unsuffixed) in [build-system], like this:

[build-system]
build-backend = "rapids_build_backend.build"
requires = [
    "cython>=3.0.0",
    "libucx==1.15.0",
    "rapids-build-backend>=0.3.0,<0.4.0dev0",
    "setuptools>=64.0.0",
]

Wheel-building fails like this:

ERROR: Could not find a version that satisfies the requirement libucx==1.15.0 (from versions: none)
ERROR: No matching distribution found for libucx==1.15.0

(example build link)

With it omitted from that table and moved down into [tool.rapids-build-backend], wheel building fails like this:

ModuleNotFoundError: No module named 'libucx'

(example build link)

Options I can think of

(in no particular order)

  1. still use rapids-build-backend, but preserve the sed-replacing of just libucx in wheel-building scripts
    • in other words... solve this case-by-case and not generally
  2. run rapids-dependency-file-generator --matrix "cuda=${RAPIDS_CUDA_VERSION%.*}" in build scripts prior to pip wheel
    to update pyproject.toml in place
  3. install libucx at build time by some other mechanism, omit it from [build-system] table, run pip wheel --no-build-isolation
  4. in setup.py, customize the command run by python setup.py build_ext
    • such that it does all the import libucx stuff when it's called to build extensions (instead of when setuptools.setup() is called)
    • for example, I think we could subclass Cython.build_ext and just override the build_extension() method (Cython/distutils/build_ext.py#L82)
    • more details in "Extending or Customizing Setuptools" (setuptools docs)

Request for comment

Other options?

Any of these that definitely won't work?

How should we proceed?

References

Created after starting rapidsai/ucx-py#1044.

Metadata

Assignees

Labels

questionFurther information is requested

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions