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

switch pyenv to uv #253

Closed
wants to merge 43 commits into from
Closed

switch pyenv to uv #253

wants to merge 43 commits into from

Conversation

coder351
Copy link
Contributor

The PR is follow up of #248 and resolves #240

The DockerFile also needed to be switched to uv. The pyqt5 library uses pyqt5-qt5 which only has wheels for macos. pyqt6 has wheels for linux (arm64 and x86-64). so switched to pyqt6 and pyqt6-sip.
The dbus-python library also had missing dependencies libdbus-glib-1-dev , libgirepository1.0-dev. The pkg-config also was failing due to missing pc files for python 311. Package python3-dev and python3.12-dev installs pc files python-3.12.pc and python-3.11-embed.pc. The python-3.12.pc files can also be used for building python 3.11. Full build is passing without errors.

@coder351 coder351 mentioned this pull request Jul 22, 2024
@robin-reckmann
Copy link
Contributor

With your changes python and all packages from the pyproject.toml are installed to either /tmp/agnos or the home folder of the root user. These places are not accessible when you boot the image. Also userspace/files/profiles should be adapted accordingly.

Dockerfile.agnos Outdated
pyenv rehash
source .venv/bin/activate && \
.venv/bin/python --version && \
uv pip install pyqt6-sip==13.8.0 && \
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
uv pip install pyqt6-sip==13.8.0 && \
uv pip install pyqt5-sip==12.12.1 && \

Copy link
Contributor Author

@coder351 coder351 Jul 24, 2024

Choose a reason for hiding this comment

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

I have reverted to pyqt5-sip.

Copy link
Contributor

Choose a reason for hiding this comment

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

Did the installation with uv like suggested above not work?

Dockerfile.agnos Outdated
source .venv/bin/activate && \
.venv/bin/python --version && \
uv pip install pyqt6-sip==13.8.0 && \
uv pip install pyqt6==6.7.1 --verbose --config-settings="--confirm-license="
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
uv pip install pyqt6==6.7.1 --verbose --config-settings="--confirm-license="
uv pip install pyqt5==5.15.9 --verbose --config-settings="--confirm-license=" --no-deps

Copy link
Contributor

Choose a reason for hiding this comment

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

pyqt5 can be installed from sources. I guess we should stay with pyqt5 for now.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have reverted to pyqt5.

@adeebshihadeh
Copy link
Contributor

Also needs to be PyQt5 since openpilot is on Qt5.

@coder351
Copy link
Contributor Author

coder351 commented Jul 24, 2024

With your changes python and all packages from the pyproject.toml are installed to either /tmp/agnos or the home folder of the root user. These places are not accessible when you boot the image. Also userspace/files/profiles should be adapted accordingly.

@robin-reckmann I checked using ./scripts/check-space.sh and anything installed using uv pip including packages from pyproject.toml are stored in /.venv/lib/. I have also adapted the various services and userspace/files/profile to use uv python installation (/.venv/bin/python).

I also noticed gabrielfalcao/pyenv-action@2f49ca7 is used by build_kernel.sh and is installing python2. Removing the github action causes the github build to fail. uv python does not have python version < 3.7, perhaps the necessary thing to do would be to also switch from python2 to python3. Also if possible, the generated system.img should be booted to test and confirm if the services are able to load correctly using uv based python.

@andiradulescu
Copy link
Collaborator

@coder351 - python2 in CI for build_kernel.sh has no connection with what happens inside Dockerfile.agnos. Just ignore it, the current kernel needs python2 to build.

Also, with #247 python2 is removed from CI.

I might be able to try out what you did here, after I get my PR merged.

@coder351
Copy link
Contributor Author

@adeebshihadeh The PR also resolves the #30 (build python with optimizations). After installing UV, I can check the build flags and uv python is installed using --enable-optimizations

CONFIG_ARGS = "'--build=x86_64-unknown-linux-gnu' '--host=x86_64-unknown-linux-gnu' '--prefix=/install' '--with-openssl=/tools/deps' '--with-system-expat' '--with-system-libmpdec' '--without-ensurepip' '--with-readline=editline' '--enable-shared' '--enable-optimizations' '--with-lto`

For claiming the bounty I am also posting before and after benchmark for python, before took 5:14 and after took 2:51.

Before using --enable-optimizations ===================================================================== slowest 10 durations ===================================================================== 17.09s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_025_FORD_EXPLORER_MK6 16.01s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_026_FORD_FOCUS_MK4 15.92s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_027_FORD_F_150_LIGHTNING_MK1 15.88s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_028_FORD_F_150_MK14 15.44s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_024_FORD_ESCAPE_MK4 15.43s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_029_FORD_MAVERICK_MK1 15.38s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_023_FORD_BRONCO_SPORT_MK1 15.14s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_030_FORD_MUSTANG_MACH_E_MK1 14.91s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_034_GENESIS_G80 14.59s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_099_KIA_FORTE =============================================================== 208 passed in 314.95s (0:05:14) ================================================================
After using --enable-optimizations using uv python '--enable-optimizations' '--with-lto' ===================================================================== slowest 10 durations ===================================================================== 8.26s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_192_VOLKSWAGEN_ATLAS_MK1 8.20s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_150_SKODA_OCTAVIA_MK3 8.15s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_112_KIA_OPTIMA_H_G4_FL 8.14s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_198_VOLKSWAGEN_PASSAT_NMS 8.13s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_191_VOLKSWAGEN_ARTEON_MK1 8.11s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_195_VOLKSWAGEN_GOLF_MK7 8.06s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_149_SKODA_KODIAQ_MK1 7.97s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_199_VOLKSWAGEN_POLO_MK6 7.89s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_197_VOLKSWAGEN_PASSAT_MK8 7.88s call selfdrive/car/tests/test_car_interfaces.py::TestCarInterfaces::test_car_interfaces_151_SKODA_SUPERB_MK3 =============================================================== 208 passed in 171.89s (0:02:51) ================================================================

@coder351
Copy link
Contributor Author

coder351 commented Jul 25, 2024

@andiradulescu Thanks for helping test in the mean time, I suppose if anybody has instructions if possible on how to test booting the image without the actual hardware would be helpful.

@adeebshihadeh
Copy link
Contributor

@andiradulescu Thanks for helping test in the mean time, I suppose if anybody has instructions if possible on how to test booting the image without the actual hardware would be helpful.

I'd recommend preparing an openpilot branch and reaching out on Discord for someone to give it a quick test.

@coder351
Copy link
Contributor Author

@andiradulescu since PR (#247) is merged, please do help test booting the image on physical device. Thanks.

@andiradulescu
Copy link
Collaborator

The PR looks good, will boot it and let you know how it goes.

@andiradulescu
Copy link
Collaborator

andiradulescu commented Jul 31, 2024

@coder351 can you push another commit that has [upload] inside the commit message - the commit can be empty - so it uploads the artifact for me to download and flash?

if you don't want to overthink it, just do:

git commit --allow-empty -m "[upload]"
git push

@coder351
Copy link
Contributor Author

coder351 commented Aug 3, 2024

@robin-reckmann I wanted to request to put PR #278 on hold while the pyenvtouv PR is merged because PRs like #277 are duplicating the effort. The pyenv PR already handled the FromAsCasing warning. Thanks.

@coder351
Copy link
Contributor Author

coder351 commented Aug 3, 2024

@adeebshihadeh The script openpilot_dependencies.sh, is duplicated and run on agnos-compiler and agnos-base.

RUN /tmp/agnos/openpilot_dependencies.sh

RUN /tmp/agnos/openpilot_dependencies.sh

The duplication is basically installing 71 libraries in agnos-base. The openpilot_dependencies.sh should only run on agnos-compiler and only necessary packages should be installed in agnos-base. After some testing I found out of 71 packages only 3 packages are necessary to build pyproject.toml and the rest of the DockerFile. I have placed the 3 packages namely portaudio19-dev, opencl-headers, gcc-arm-none-eabi in openpilot_python_dependencies.sh.
By removing the duplication, the build size is also reduced. In regards to removing build time dependencies i.e packages ending with -dev, I ran some tests and found the command apt-get purge lib*-dev is able to remove -dev packages and conserve about 0.5 gb of disk space from the final image. The command fails when run in github runner due to frontend-lock. I have also put back shims/pip, pointing PIP_PATH to uv based pip in venv. The PR can be merged and the removal of dev packages would reduce the agnos system image size which can be discussed in #225.

Copy link
Contributor

Choose a reason for hiding this comment

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

Permission are not the same anymore. Should be 755

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

Dockerfile.agnos Outdated
RUN rm -rf /usr/share/icons/* && \
rm -rf /var/lib/apt/lists/* && \
rm -rf /home/$USERNAME/.cache && \
rm -rf /root/.cache && \
apt-get clean
apt-get clean
Copy link
Contributor

Choose a reason for hiding this comment

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

Also the newline should probably be preserved. (I guess its a setting of your IDE/text editor). Same for the other files where this happened.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done.

ENV XDG_DATA_HOME="/usr/local"
ENV PATH="$XDG_DATA_HOME/.cargo/bin:$PATH"

COPY ./userspace/files/PyQt5-5.15.9-cp38-abi3-manylinux_2_17_aarch64.whl /tmp/agnos/
Copy link
Contributor

Choose a reason for hiding this comment

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

From this comment the way to go is to still build PyQt5 for now but make sure its somewhere in the build where other changes to the dockerfile dont break the cache. Also its unrelated to the uv introduction, so could we do this in another PR and remove it here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

according to docker build cache invalidation general rules,
"During cache lookup, cache is invalidated if the file metadata has changed for any of the files involved."
the docker cache should not bust as long as the wheel file metadata is not modified. I have already built the wheel and setup in dockerfile and using the pre-built PyQt5 wheel also provides the much needed build time optimization. Unless updating to pyqt6, I suggest to keep using the pre-built wheel.


export PATH="/usr/local/.cargo/bin:$PATH"
export XDG_DATA_HOME="/usr/local"
source $XDG_DATA_HOME/venv/bin/activate
Copy link
Contributor

Choose a reason for hiding this comment

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

@adeebshihadeh This will activate the venv for all sessions on the device. It is a different behavior compared to now, where you have to use pyenv exec. Is this ok?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@robin-reckmann pyenv exec would still use python "3.11.4", when run using pyenv exec

export PYENV_VERSION="3.11.4"

unless the idea is to use different python versions across sessions, then activating venv ensures the python version 3.11.4 is consistent across sessions.

@adeebshihadeh
Copy link
Contributor

With 24.04, we will no longer need to install a custom python (#262).

Gonna close this since 24.04 will be merged soon, but you're good to claim the bounty since the work was done.

@coder351
Copy link
Contributor Author

coder351 commented Aug 8, 2024

@adeebshihadeh Thanks, regarding the bounty, please highlight exactly how much I should be claiming, also please note regarding issue #30, I had posted before and after benchmarks, the uv based python is already using optimized python. So if the issue is still valid, perhaps the python portion of the bounty can also be factored in.

@adeebshihadeh
Copy link
Contributor

@coder351 bounty is locked to you, but let's open a new PR since this one has gotten pretty messy. Looking over this, the remaining TODOs are:

  • I see uv has the optimizations enabled by default, but can we explicitly enable them so we're not relying on defaults?
  • PyQt5: either need a script to build/pull the wheel or build/install in the Docker build again
  • final test on device
    • openpilot runs
    • python, python3, pip, pip3, scons all work in a shell logged in as comma

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.

Switch from pyenv to uv
4 participants