Skip to content

Commit 8900263

Browse files
committed
dedicated uenv-venv section
1 parent e0188d8 commit 8900263

File tree

3 files changed

+112
-55
lines changed

3 files changed

+112
-55
lines changed

docs/guides/storage.md

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ At first it can seem strange that a "high-performance" file system is significan
173173
Meta data lookups on Lustre are expensive compared to your laptop, where the local file system is able to aggressively cache meta data.
174174

175175
[](){#ref-guides-storage-venv}
176-
### Python virtual environments with uenv
176+
### Squash Python virtual environments with uenv
177177

178178
Python virtual environments can be very slow on Lustre, for example a simple `import numpy` command run on Lustre might take seconds, compared to milliseconds on your laptop.
179179

@@ -191,7 +191,7 @@ This file can be mounted as a read-only [Squashfs](https://en.wikipedia.org/wiki
191191

192192
#### Step 1: create the virtual environment
193193

194-
The first step is to create the virtual environment using the usual workflow.
194+
The first step is to create the virtual environment using the usual workflow described in the [uenv documentation][ref-uenv-venv].
195195

196196
=== "uv"
197197

@@ -205,13 +205,11 @@ The first step is to create the virtual environment using the usual workflow.
205205

206206
# unset PYTHONPATH and set PYTHONUSERBASE to avoid conflicts
207207
unset PYTHONPATH
208-
export PYTHONUSERBASE=/user-environment/env/default
208+
export PYTHONUSERBASE="$(dirname "$(dirname "$(which python)")")"
209209

210210
# create and activate a new relocatable venv using uv
211211
# in this case we explicitly select the python interpreter from the uenv view
212-
uv venv -p /user-environment/env/default/bin/python --system-site-packages --relocatable --link-mode=copy /dev/shm/sqfs-demo/.venv
213-
# You can also point to the uenv python with `uv venv -p $(which python) ...`
214-
# which, among other things, enables user portability of the venv
212+
uv venv --python $(which python) --system-site-packages --seed --relocatable --link-mode=copy /dev/shm/sqfs-demo/.venv
215213
cd /dev/shm/sqfs-demo
216214
source .venv/bin/activate
217215

docs/software/ml/pytorch.md

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -779,55 +779,11 @@ There are two ways to access the software provided by the uenv, once it has been
779779
[](){#ref-uenv-pytorch-venv}
780780
### Adding Python packages on top of the uenv
781781

782-
Uenvs are read-only, and cannot be modified. However, it is possible to add Python packages on top of the uenv using virtual environments analogous to the setup with containers.
783-
784-
```console title="Creating a virtual environment on top of the uenv"
785-
$ uenv start pytorch/v2.8.0:v1 --view=default # (1)!
786-
787-
$ python -m venv --system-site-packages venv-uenv-pt2.8-v1 # (2)!
788-
789-
$ source venv-uenv-pt2.8-v1/bin/activate # (3)!
790-
791-
(venv-uenv-pt2.8-v1) $ pip install <package> # (4)!
792-
793-
(venv-uenv-pt2.8-v1) $ deactivate # (5)!
794-
795-
$ exit # (6)!
796-
```
797-
798-
1. The `default` view is recommended, as it loads all the packages provided by the uenv.
799-
This is important for PyTorch to work correctly, as it relies on the CUDA and NCCL libraries provided by the uenv.
800-
2. The virtual environment is created in the current working directory, and can be activated and deactivated like any other Python virtual environment.
801-
3. Activating the virtual environment will override the Python executable provided by the uenv, and use the one from the virtual environment instead.
802-
This is important to ensure that the packages installed in the virtual environment are used.
803-
4. The virtual environment can be used to install any Python package.
804-
5. The virtual environment can be deactivated using the `deactivate` command.
805-
This will restore the original Python executable provided by the uenv.
806-
6. The uenv can be exited using the `exit` command or by typing `ctrl-d`.
807-
808-
809-
!!! note "Squashing the virtual environment"
810-
Python virtual environments can be slow on the parallel Lustre file system due to the amount of small files and potentially many processes accessing it.
811-
If this becomes a bottleneck, consider [squashing the venv][ref-guides-storage-venv] into its own memory-mapped, read-only file system to enhance scalability and reduce load times.
812-
813-
??? bug "Python packages from uenv view shadowing those in a virtual environment"
814-
Some uenv views set the `PYTHONPATH` environment variable and/or do not set the `PYTHONUSERBASE` environment variable.
815-
This can lead to unexpected behavior when using Python virtual environments on top of the uenv, as the packages installed in the uenv view may take precedence over those in the virtual environment.
816-
A possible workaround is to unset the `PYTHONPATH` and set the `PYTHONUSERBASE` environment variables, as described in the [Python virtual environments with uenv guide][ref-guides-storage-venv]:
817-
```bash
818-
unset PYTHONPATH
819-
export PYTHONUSERBASE=/user-environment/env/default
820-
```
821-
It is recommended to apply this workaround if you are constrained by a Python package version installed in the uenv view that you need to change for your application.
822-
823-
!!! note
824-
Keep in mind that
825-
826-
* this virtual environment is _specific_ to this particular uenv and won't actually work unless you are using it from inside this uenv - it relies on the resources packaged inside the uenv.
827-
* every Slurm job making use of this virtual environment will need to activate it first (_inside_ the `srun` command).
828-
829-
Alternatively one can use the uenv as [upstream Spack instance][ref-build-uenv-spack] to to add both Python and non-Python packages.
830-
However, this workflow is more involved and intended for advanced Spack users.
782+
Python virtual environments can be created on top of the uenv to install additional Python packages not provided by the uenv itself, or to override existing packages.
783+
Please refer to the [Python virtual environments with uenv documentation][ref-uenv-venv] and the [guide on performance][ref-guides-storage-venv] for more details on
784+
- creating and managing virtual environments on top of uenvs
785+
- best practices and caveats when using virtual environments with uenvs
786+
- troubleshooting common issues
831787

832788
### Running PyTorch jobs with Slurm
833789

docs/software/uenv/index.md

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,5 +775,108 @@ $ which uenv
775775
/usr/bin/uenv
776776
```
777777

778+
[](){#ref-uenv-venv}
779+
## Python virtual environments on top of uenv views
778780

781+
When stacking a Python virtual environment on top of a _uenv view_, keep Python’s import resolution predictable with the following:
779782

783+
- **Unset `PYTHONPATH`**. Anything there is *prepended* to Python's `sys.path`, which can lead to surprising imports.
784+
- **Set `PYTHONUSERBASE` to the view's root directory** (e.g., `/user-environment/env/default`) so the interpreter’s _user site_ resolves inside the view.
785+
- You can derive this automatically from the interpreter you’re about to use: take the parent of `which python`:
786+
```bash
787+
export PYTHONUSERBASE=$(dirname $(dirname $(which python)))
788+
```
789+
- Do not use tools that resolve symlinks (such as `readlink -f` or Python's `Path.resolve()`), as the Python interpreter in the _uenv view_ is a symlink - following it would point outside the view.
790+
- **Create the venv with `--system-site-packages`**.
791+
`venv` disables the user site by default; enabling system site restores both the system site and the user site, so packages provided by the _uenv view_ become visible inside the venv.
792+
793+
=== "uv"
794+
795+
```console title="Creating a Python virtual environment on top of a uenv view"
796+
# start the uenv with the default view
797+
$ uenv start --view=default prgenv-gnu/25.6:v2
798+
799+
# unset PYTHONPATH to avoid surprises
800+
$ unset PYTHONPATH
801+
802+
# set PYTHONUSERBASE to the root of the view
803+
$ export PYTHONUSERBASE="$(dirname "$(dirname "$(which python)")")"
804+
805+
# create the virtual environment with access to system site packages
806+
# - optionally seed it with pip, setuptools and wheel
807+
# - optionally make it relocatable and copy linked files (useful for moving venvs)
808+
$ uv venv --python $(which python) --system-site-packages --seed --relocatable --link-mode=copy path/to/my-venv
809+
810+
# activate the virtual environment
811+
$ source path/to/my-venv/bin/activate
812+
813+
# verify that packages from the uenv are visible (note Locations)
814+
(my-venv) $ python -m pip list -v
815+
Package Version Location Installer
816+
------- ------- ---------------------------------------------------------- ---------
817+
meson 1.7.0 /user-environment/env/default/lib/python3.13/site-packages pip
818+
pip 25.3 /path/to/my-venv/lib/python3.13/site-packages uv
819+
820+
# upgrade a package into the venv (overrides the view's version)
821+
(my-venv) $ uv pip install --upgrade meson
822+
823+
# verify that the upgraded package is now coming from the venv
824+
(my-venv) $ python -m pip list -v
825+
Package Version Location Installer
826+
------- ------- ------------------------------------------------ ---------
827+
meson 1.9.1 /path/to/my-venv-uv/lib/python3.13/site-packages uv
828+
pip 25.3 /path/to/my-venv-uv/lib/python3.13/site-packages uv
829+
```
830+
831+
=== "venv"
832+
833+
```console title="Creating a Python virtual environment on top of a uenv view"
834+
# start the uenv with the default view
835+
$ uenv start --view=default prgenv-gnu/25.6:v2
836+
837+
# unset PYTHONPATH to avoid surprises
838+
$ unset PYTHONPATH
839+
840+
# set PYTHONUSERBASE to the root of the view
841+
$ export PYTHONUSERBASE="$(dirname "$(dirname "$(which python)")")"
842+
843+
# create the virtual environment with access to system site packages
844+
$ python -m venv --system-site-packages path/to/my-venv
845+
846+
# activate the virtual environment
847+
$ source path/to/my-venv/bin/activate
848+
849+
# verify that packages from the uenv are visible (note Locations)
850+
(my-venv) $ python -m pip list -v
851+
python -m pip list -v
852+
Package Version Location Installer
853+
------- ------- ---------------------------------------------------------- ---------
854+
meson 1.7.0 /user-environment/env/default/lib/python3.13/site-packages pip
855+
pip 25.1.1 /path/to/my-venv/lib/python3.13/site-packages pip
856+
857+
# upgrade a package into the venv (overrides the view's version)
858+
(my-venv) $ pip install --upgrade meson
859+
860+
# verify that the upgraded package is now coming from the venv
861+
(my-venv) $ pip list
862+
Package Version Location Installer
863+
------- ------- --------------------------------------------- ---------
864+
meson 1.9.1 /path/to/my-venv/lib/python3.13/site-packages pip
865+
pip 25.1.1 /path/to/my-venv/lib/python3.13/site-packages pip
866+
```
867+
868+
!!! note "Listing only the packages that live in the uenv’s user-site"
869+
To see _just_ what's in the uenv view (not what's installed into the venv), list by the user-site path that your interpreter is using:
870+
```console
871+
(my-venv) $ python -m pip list -v --path "$(python -c 'import site; print(site.getusersitepackages())')"
872+
```
873+
874+
!!! note "Troubleshooting & Gotchas"
875+
- `pip install --user` will fail here.
876+
The uenv is a read-only squashfs; a `--user` install would try to write into `PYTHONUSERBASE` (the uenv), which is not possible.
877+
- Some uenv views already set `PYTHONUSERBASE`. If you start a uenv view that does this, you can skip setting `PYTHONUSERBASE` yourself.
878+
- The virtual environment is _specific_ to a particular uenv and won't work unless used from inside this excact uenv - it relies on the resources packaged inside the uenv.
879+
880+
!!! note "Performance considerations"
881+
On our Lustre parallel file system, large venvs can be slow due to many small files.
882+
See [How to squash virtual environments][ref-guides-storage-venv] for turning a venv into a compact image to improve startup and import performance.

0 commit comments

Comments
 (0)