Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Basic support for Python Optional Dependencies #5940

Open
wants to merge 7 commits into
base: main
Choose a base branch
from

Conversation

samypr100
Copy link
Contributor

@samypr100 samypr100 commented Feb 21, 2023

Type

  • Bug fix (non-breaking change which fixes an issue): Fixes #
  • New feature (non-breaking change which adds functionality). Resolves #
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) Resolves Make dash an optional dependency #5740

Motivation and Context

This PR is a more conservative approach to what's described in #5853. Using only [standard] came up as an option in the discussion so I've decided to adopt it in this alternate PR.

I've only included the gui dependencies as part of standard, but we can include the ML dependencies (from open3d-ml) as well as discussed in #5853 (comment) if we desire to.

Note, Including the ml dependencies would help close #2991 in addition to #5740.

Checklist:

  • I have run python util/check_style.py --apply to apply Open3D code style
    to my code.
  • This PR changes Open3D behavior or adds new functionality.
    • Both C++ (Doxygen) and Python (Sphinx / Google style) documentation is
      updated accordingly.
    • I have added or updated C++ and / or Python unit tests OR included test
      results
      (e.g. screenshots or numbers) here.
  • I will follow up and update the code if CI fails.
  • For fork PRs, I have selected Allow edits from maintainers.

Description

As discussed in #5853, below is a table of the changes:

Optional Dependency Contents
standard Includes new (this PR) requirements_gui.txt file from https://github.com/isl-org/Open3D

Strictly speaking from a python dependencies size, below are the sizes with the new optional dependencies calculated on OSX (transitive sizes may vary between platforms).

Package Transitive Dependencies Size (MB)
open3d 350.13
open3d[standard] 459.13

If we decide to include ml as part of standard, the above table becomes

Package Transitive Dependencies Size (MB)
open3d 107.69
open3d[standard] 459.13

Total Savings

For table #1, the total savings would be about 109mb.

For table #2, the total savings would be about 351mb.


This change is Reviewable

@samypr100 samypr100 force-pushed the optional-dependencies-gui-only branch from b1aab0a to 5ca0f74 Compare April 5, 2023 14:40
@theNded theNded self-requested a review August 11, 2023 04:44
@theNded
Copy link
Contributor

theNded commented Aug 16, 2023

I am not an expert on CI. I had a conversation with the CI expert on our team, and we think your solution would be viable as long as we keep

  • workflows stable
  • artifacts correctly uploaded
  • docs consistent

I think we can start with this minimal PR first and check those items one by one until reach somewhere that looks promising. It's my pleasure to work with you!

fix: add missing new line to requirements_gui.txt
@samypr100
Copy link
Contributor Author

samypr100 commented Aug 16, 2023

@theNded 👍 Can you re-run the CI on both PR's again with the latest commit? Thanks

docs consistent

For this, what do you have in mind? I believe I updated the docs unless I missed something? 😅

@theNded
Copy link
Contributor

theNded commented Aug 16, 2023

Nah, it is just a general comment for future reference. Docs look great now, although I haven't gone through them thoroughly.

@samypr100
Copy link
Contributor Author

@theNded Thanks! Looks like CI is passing on both PR's 🙂

@theNded
Copy link
Contributor

theNded commented Aug 17, 2023

@samypr100 thanks for the update!
Here are two of my thoughts before a thorough review:

  1. Would it be possible that we keep the original installation behavior, i.e. pip install open3d installs the complete package, and pip install open3d[nogui] installs the partial package? That will probably make the transition smoother.
  2. Would you be able to upgrade the workflows as well, such that both wheels are produced in the CI? For instance, right now, only one artifact is produced. We will need to upload both to github, upload both to gcloud, and distribute them with pypi correspondingly. This should involve modifications here.

Please correct me if I'm wrong in those comments; otherwise, I will be glad to help with the workflows.

@samypr100
Copy link
Contributor Author

@theNded In regards to the artifact question, only one artifact is needed to use optional dependencies. Extras is just metadata for the package that declares what to install in adition to the core required dependencies, giving more control to the end user. Hence luckily, there wouldn't be more than one artifact needed. Both open3d and open3d-cpu should get this functionality automatically without the need for a new artifact.

For your question about nogui, python spec doesn't support it since extras is only additive. There was a in-depth discussion on that on the other PR #5853 (review) with @johnthagen

@johnthagen
Copy link
Contributor

@theNded Like @samypr100 said, the reasons for why extras can only be additive are explained in the link @samypr100 posted above.

But at the same time, many popular Python packages have gone through this transition due to how useful it is for end users to be able to better control/trim transitive dependencies. This can speed up development workflows, CI workflows, container image sizes, etc for all downstream users of Open3D who only need a subset of Open3D's functionality.

@theNded
Copy link
Contributor

theNded commented Aug 19, 2023

@samypr100 @johnthagen Thanks for the update, I have read the explanation and it looks very reasonable. I have a heavy workload right now at my full-time job, but hopefully I will be back to review this PR at the end of next week.

# Conflicts:
#	docs/getting_started.in.rst
@@ -109,7 +109,14 @@ def _insert_pybind_names(skip_names=()):
sys.modules.update(submodules)


import open3d.visualization
try:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should implement systematic unit tests starting from this point.
For example, in the pytest files, expect this exception conditioned on the extra package (open3d or open3d[standard]). This can help us make sure that the core behavior is preserved without the gui requirements. Might need to tweak some of the CIs, but a summary of some local tests would be also helpful.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may not be quite critical for this PR, but if we plan on more advanced dependency management I think it would be required.

@@ -98,7 +98,7 @@ Open3D is designed to make use of the SYCL GPU devices.

## List of oneAPI Python packages

To make `pip install open3d` works out-of-the box on SYCL-enabled platforms,
To make `pip install open3d[standard]` works out-of-the box on SYCL-enabled platforms,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally, also add doc for the behavior of pip install open3d. Same below.

@@ -399,7 +400,7 @@ jobs:
$PIP_PKG_NAME=(Get-ChildItem open3d*-$py_tag-*.whl).Name
}
echo "Installing Open3D wheel $PIP_PKG_NAME in virtual environment..."
python -m pip install "$PIP_PKG_NAME"
python -m pip install "$PIP_PKG_NAME[standard]"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like [all], [full], [complete], or even [gui] might be more informative. Standard gives me the impression that it is a standard minimal set. But this is possibly subjective. @ssheorey what's your opinion?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pip install open3d # or
pip install open3d-cpu # Smaller CPU only wheel on x86_64 Linux (v0.17+)
pip install open3d[standard] # or
pip install open3d-cpu[standard] # Smaller CPU only wheel on x86_64 Linux (v0.17+)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, please add the behavior of pip install open3d and pip install open3d-cpu. Ideally, elaborate on the design choice and the expected usage of both options.

@@ -5,4 +5,4 @@
# it is guaranteed that there is only one wheel in ${PYTHON_PACKAGE_DST_DIR}/pip_package/*.whl
file(GLOB WHEEL_FILE "${PYTHON_PACKAGE_DST_DIR}/pip_package/*.whl")
execute_process(COMMAND ${Python3_EXECUTABLE} -m pip uninstall open3d open3d-cpu --yes)
execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install ${WHEEL_FILE} -U)
execute_process(COMMAND ${Python3_EXECUTABLE} -m pip install "${WHEEL_FILE}[standard]" -U)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we expose this extra option to cmake/make as well?

@@ -35,9 +35,12 @@ Pip (PyPI)

.. code-block:: bash

pip install open3d # or
pip install open3d-cpu # Smaller CPU only wheel on x86_64 Linux (since v0.17+)
pip install open3d[standard] # or
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same, could use some explanation.

@@ -83,6 +83,7 @@ install_python_dependencies() {

# TODO: modify other locations to use requirements.txt
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements.txt"
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_gui.txt"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make this requirement optional (controlled by the script input flags).

# For extra requirements
extra_requires = defaultdict(list)

# Standard Extras
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could also put a link to the relevant PEP docs for reference.

import open3d.visualization
except ModuleNotFoundError:
warnings.warn(
"Open3D Python GUI Libraries not found. "
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

NIT: GUI libraries

@@ -276,6 +276,7 @@ jobs:
run: |
$ErrorActionPreference = 'Stop'
python -m pip install -r python/requirements.txt
python -m pip install -r python/requirements_gui.txt
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In practice the difference between open3d and open3d[standard] is gui packages, so naming feels fine.
But semantically this feels a bit inconsistent: open3d + gui = open3d[standard].

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make dash an optional dependency pip: Why does Open3D pull in Open3D-ML/requirements.txt?
3 participants