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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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].

python -m pip install -r python/requirements_jupyter_build.txt

- name: Config
Expand Down Expand Up @@ -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

@johnthagen johnthagen Aug 28, 2023

Choose a reason for hiding this comment

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

python -c "import open3d; print('Imported:', open3d)"
python -c "import open3d; print('CUDA enabled: ', open3d.core.cuda.is_available())"

Expand Down
2 changes: 1 addition & 1 deletion 3rdparty/README_SYCL.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

we can utilize runtime libraries released via PyPI. This feature needs to be
implemented.

Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
* Fix Python bindings for CUDA device synchronization, voxel grid saving (PR #5425)
* Support msgpack versions without cmake
* Fix some bad triangle generation in TriangleMesh::SimplifyQuadricDecimation
* Introduce new optional dependencies support, allowing you to do `pip install open3d[standard]`

## 0.13

Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ Pre-built pip packages support Ubuntu 18.04+, macOS 10.15+ and Windows 10+

```bash
# Install
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.


# Verify installation
python -c "import open3d as o3d; print(o3d.__version__)"
Expand Down
2 changes: 1 addition & 1 deletion cpp/pybind/make_install_pip_package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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?

1 change: 1 addition & 0 deletions cpp/pybind/make_python_package.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ if (BUILD_JUPYTER_EXTENSION)
# These will be installed when `pip install open3d`.
execute_process(COMMAND ${CMAKE_COMMAND} -E cat
${PYTHON_PACKAGE_SRC_DIR}/requirements.txt
${PYTHON_PACKAGE_SRC_DIR}/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.

Same, can we expose this extra option to cmake/make as well?

${PYTHON_PACKAGE_SRC_DIR}/requirements_jupyter_install.txt
OUTPUT_VARIABLE ALL_REQUIREMENTS
)
Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile.openblas
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ COPY ./python/requirements*.txt /root/Open3D/python/
RUN which python \
&& python --version \
&& python -m pip install -U -r /root/Open3D/python/requirements.txt \
-r /root/Open3D/python/requirements_gui.txt \
-r /root/Open3D/python/requirements_build.txt \
-r /root/Open3D/python/requirements_test.txt

Expand Down
1 change: 1 addition & 0 deletions docker/Dockerfile.wheel
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ RUN /root/Open3D/util/install_deps_ubuntu.sh assume-yes \
# Open3D Python dependencies
COPY ./util/ci_utils.sh /root/Open3D/util/
COPY ./python/requirements.txt /root/Open3D/python/
COPY ./python/requirements_gui.txt /root/Open3D/python/
COPY ./python/requirements_jupyter_build.txt /root/Open3D/python/
COPY ./python/requirements_jupyter_install.txt /root/Open3D/python/
RUN source /root/Open3D/util/ci_utils.sh \
Expand Down
34 changes: 17 additions & 17 deletions docs/arm.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ we provide pre-compiled ARM64 wheels for Linux and macOS. Install the wheel by:

.. code-block:: bash
pip install open3d
pip install open3d[standard]
Copy link
Contributor

Choose a reason for hiding this comment

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

Same, explain how pip install open3d would work.

python -c "import open3d; print(open3d.__version__)"
# Test the legacy visualizer
Expand All @@ -18,21 +18,21 @@ we provide pre-compiled ARM64 wheels for Linux and macOS. Install the wheel by:
# Test the new GUI visualizer
python -c "import open3d as o3d; c = o3d.geometry.TriangleMesh.create_box(); o3d.visualization.draw(c)"
+------------------------+----------------+---------------------+------------+----------------+
| | Linux (OpenGL) | Linux (OpenGL ES) | macOS | Windows on ARM |
+========================+================+=====================+============+================+
| ``pip install open3d`` | Yes | Yes | Yes | No |
+------------------------+----------------+---------------------+------------+----------------+
| Compile from source | Yes | Yes | Yes | No |
+------------------------+----------------+---------------------+------------+----------------+
| Visualizer and GUI | Yes | No | Yes | No |
+------------------------+----------------+---------------------+------------+----------------+
| Non-GUI features | Yes | Yes | Yes | No |
+------------------------+----------------+---------------------+------------+----------------+
| Special build flags | Not needed | ``-DBUILD_GUI=OFF`` | Not needed | N/A |
+------------------------+----------------+---------------------+------------+----------------+
| Example device | Nvidia Jetson | Raspberry Pi 4 | M1 MacBook | Surface Pro X |
+------------------------+----------------+---------------------+------------+----------------+
+----------------------------------+----------------+---------------------+------------+----------------+
| | Linux (OpenGL) | Linux (OpenGL ES) | macOS | Windows on ARM |
+==================================+================+=====================+============+================+
| ``pip install open3d[standard]`` | Yes | Yes | Yes | No |
+----------------------------------+----------------+---------------------+------------+----------------+
| Compile from source | Yes | Yes | Yes | No |
+----------------------------------+----------------+---------------------+------------+----------------+
| Visualizer and GUI | Yes | No | Yes | No |
+----------------------------------+----------------+---------------------+------------+----------------+
| Non-GUI features | Yes | Yes | Yes | No |
+----------------------------------+----------------+---------------------+------------+----------------+
| Special build flags | Not needed | ``-DBUILD_GUI=OFF`` | Not needed | N/A |
+----------------------------------+----------------+---------------------+------------+----------------+
| Example device | Nvidia Jetson | Raspberry Pi 4 | M1 MacBook | Surface Pro X |
+----------------------------------+----------------+---------------------+------------+----------------+

Additional notes:

Expand Down Expand Up @@ -107,7 +107,7 @@ TBB, Parallel STL, BLAS, LAPACK) may cause compatibility issues if they are not
the same version as the one used by Open3D.

If you only need the Python wheel, consider using the Docker build method or
install Open3D via ``pip install open3d`` directly.
install Open3D via ``pip install open3d[standard]`` directly.
Copy link
Contributor

Choose a reason for hiding this comment

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

Same, try to provide something like "if you only need the core functionalities and do not need visualization, you may install the minimal wheel via pip install open3d".


Install dependencies
````````````````````
Expand Down
2 changes: 1 addition & 1 deletion docs/docker.in.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Python applications looks like this:

# Install Open3D from the PyPI repositories
RUN python3 -m pip install --no-cache-dir --upgrade pip && \
python3 -m pip install --no-cache-dir --upgrade open3d
python3 -m pip install --no-cache-dir --upgrade open3d[standard]

If you have an NVIDIA GPU and want to use it for computation (``CUDA``) or
visualization, follow these `directions.
Expand Down
15 changes: 9 additions & 6 deletions docs/getting_started.in.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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.

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

.. note::
Above will work for most purposes and aligns with behavior seen in `v0.17` and below.
Using anything under :mod:`open3d.visualization` will require ``[standard]``.

.. note::
Please upgrade your ``pip`` to a version >=20.3 to install Open3D in Linux,
Expand All @@ -54,11 +57,11 @@ Pip (PyPI)

.. code-block:: bash

pip3 install open3d
pip3 install open3d[standard]
# or
pip install --user open3d
pip install --user open3d[standard]
# or
python3 -m pip install --user open3d
python3 -m pip install --user open3d[standard]

Development version (pip)
-------------------------
Expand Down Expand Up @@ -100,7 +103,7 @@ install the latest development version directly with pip:

.. code-block:: bash

pip install -U --trusted-host www.open3d.org -f http://www.open3d.org/docs/latest/getting_started.html open3d
pip install -U --trusted-host www.open3d.org -f http://www.open3d.org/docs/latest/getting_started.html open3d[standard]

.. note::
The development wheels for Linux are named according to PEP600. Please
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/sensor/realsense.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Install Open3D from PyPI (a virtual environment is recommended):

.. code-block:: sh
pip install open3d
pip install open3d[standard]
Compile from source (C++)
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
9 changes: 8 additions & 1 deletion python/open3d/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.

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

"Please make sure to install open3d[standard] if you wish to use "
"the open3d.visualization module.", RuntimeWarning)

_insert_pybind_names(skip_names=("ml",))

__version__ = "@PROJECT_VERSION@"
Expand Down
2 changes: 0 additions & 2 deletions python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
numpy>=1.18.0
dash>=2.6.0
werkzeug>=2.2.3
nbformat>=5.7.0
configargparse
2 changes: 2 additions & 0 deletions python/requirements_gui.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
dash>=2.6.0
werkzeug>=2.2.3
11 changes: 11 additions & 0 deletions python/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import sys
import platform
import ctypes
from collections import defaultdict
from setuptools import setup, find_packages
from setuptools.command.install import install as _install
from wheel.bdist_wheel import bdist_wheel as _bdist_wheel
Expand Down Expand Up @@ -93,6 +94,15 @@ def finalize_options(self):
with open("requirements.txt", "r") as f:
install_requires = [line.strip() for line in f.readlines() if line]

# 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.

with open("requirements_gui.txt", "r") as f:
extra_requires["standard"] += [
line.strip() for line in f.readlines() if line
]

# Read requirements for ML.
if "@BUNDLE_OPEN3D_ML@" == "ON":
with open("@OPEN3D_ML_ROOT@/requirements.txt", "r") as f:
Expand Down Expand Up @@ -160,6 +170,7 @@ def finalize_options(self):
python_requires=">=3.6",
include_package_data=True,
install_requires=install_requires,
extras_require=extra_requires,
packages=find_packages(),
entry_points=entry_points,
zip_safe=False,
Expand Down
4 changes: 3 additions & 1 deletion util/ci_utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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).

if [[ "with-jupyter" =~ ^($options)$ ]]; then
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_jupyter_build.txt"
fi
Expand Down Expand Up @@ -262,7 +263,7 @@ test_wheel() {
echo -n "Using pip: "
python -m pip --version
echo "Installing Open3D wheel $wheel_path in virtual environment..."
python -m pip install "$wheel_path"
python -m pip install "${wheel_path}[standard]"
python -c "import open3d; print('Installed:', open3d); print('BUILD_CUDA_MODULE: ', open3d._build_config['BUILD_CUDA_MODULE'])"
python -c "import open3d; print('CUDA available: ', open3d.core.cuda.is_available())"
echo
Expand Down Expand Up @@ -392,6 +393,7 @@ install_docs_dependencies() {
fi
echo
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements.txt"
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_gui.txt"
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/python/requirements_jupyter_build.txt"
python -m pip install -r "${OPEN3D_SOURCE_ROOT}/docs/requirements.txt"
}
Expand Down