Skip to content

Move some imports to make GPU optional#346

Open
MoritzWM wants to merge 6 commits into
SBC-Utrecht:mainfrom
MoritzWM:optional_cuda
Open

Move some imports to make GPU optional#346
MoritzWM wants to merge 6 commits into
SBC-Utrecht:mainfrom
MoritzWM:optional_cuda

Conversation

@MoritzWM

Copy link
Copy Markdown

Hello,
I'm using pytom-match-pick on a HPC cluster and love it. Though one issue I'm having is that I sometimes play with the false positive rate or cutoff and I don't want to submit that as GPU-bound jobs. The same applies to merging star files.

I figured I could just move around some imports to make it not fail when there's no GPU. It still requires Cuda for installation though.

@sroet

sroet commented Mar 26, 2026

Copy link
Copy Markdown
Collaborator

Hey @MoritzWM,

Thanks for the PR! I understand your use case, did you test that this is all it takes for your jobs to run?

Could you tell me:

  1. Which of our entry points you normally try to run without a gpu?
  2. What is the error you get when you try to run on a non-gpu node with current main
  3. What is the error you get when you try to run gpu code on a non-gpu node with your PR

First option is so I can think about what tests to add to make sure this doesn't break in the future
2 and 3 is just to make sure the error message doesn't get significantly more confusing than before.

@sroet

sroet commented Mar 26, 2026

Copy link
Copy Markdown
Collaborator

seems like our pre-commit checks are failing, do you mind:

  1. running the steps under developer install, up to and including pre-commit install
  2. run ruff format (after updating ruff in your conda install if that hasn't happened in a while)
  3. commit and push the result

@MoritzWM

Copy link
Copy Markdown
Author

Hello @sroet,

sorry forgot to do the most basic things. Fixed the formatting.

Yes it seems that this is all that is required. I didn't test all options though, only a basic set. I will test a little more tomorrow to really make sure.

  1. Which of our entry points you normally try to run without a gpu?

Only pytom_extract_candidates.py and pytom_merge_stars.py.

  1. What is the error you get when you try to run on a non-gpu node with current main
pytom_create_template.py
Traceback (most recent call last):
  File "/gpfs/lsdf02/sd18g002/.helix/envs/pytom_dev/bin/pytom_create_template.py", line 6, in <module>
    sys.exit(pytom_create_template())
             ~~~~~~~~~~~~~~~~~~~~~^^
  File "/gpfs/lsdf02/sd18g002/Moritz/git/pytom-match-pick/src/pytom_tm/entry_points.py", line 148, in pytom_create_template
    from pytom_tm.template import generate_template_from_map
  File "/gpfs/lsdf02/sd18g002/Moritz/git/pytom-match-pick/src/pytom_tm/template.py", line 3, in <module>
    import voltools as vt
  File "/gpfs/lsdf02/sd18g002/.helix/envs/pytom_dev/lib/python3.14/site-packages/voltools/__init__.py", line 3, in <module>
    from .transforms import AVAILABLE_INTERPOLATIONS, AVAILABLE_DEVICES, scale, shear, rotate, translate, transform, affine
  File "/gpfs/lsdf02/sd18g002/.helix/envs/pytom_dev/lib/python3.14/site-packages/voltools/transforms.py", line 19, in <module>
    AVAILABLE_DEVICES = utils.get_available_devices()
  File "/gpfs/lsdf02/sd18g002/.helix/envs/pytom_dev/lib/python3.14/site-packages/voltools/utils/general.py", line 73, in get_available_devices
    for i in range(cupy.cuda.runtime.getDeviceCount()):
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "cupy_backends/cuda/api/runtime.pyx", line 420, in cupy_backends.cuda.api.runtime.getDeviceCount
  File "cupy_backends/cuda/api/runtime.pyx", line 423, in cupy_backends.cuda.api.runtime.getDeviceCount
  File "cupy_backends/cuda/api/runtime.pyx", line 146, in cupy_backends.cuda.api.runtime.check_status
cupy_backends.cuda.api.runtime.CUDARuntimeError: cudaErrorInsufficientDriver: CUDA driver version is insufficient for CUDA runtime version
  1. What is the error you get when you try to run gpu code on a non-gpu node with your PR

Same error.

First option is so I can think about what tests to add to make sure this doesn't break in the future 2 and 3 is just to make sure the error message doesn't get significantly more confusing than before.

I personally think the error message is fine. It says CUDA, it shows where the error is coming from and hiding the line where it is thrown will only make it harder to debug.

@github-actions

github-actions Bot commented Mar 26, 2026

Copy link
Copy Markdown

File Coverage Missing
All files 95%
src/pytom_tm/extract.py 98% 315-319
src/pytom_tm/io.py 89% 26 46 62 98 130-136 157-161 168 187 224 229 276-278 348 524-532 557
src/pytom_tm/parallel.py 97% 15-16
src/pytom_tm/plotting.py 33% 35-43 47-50 53-69 76-77 97-102 118-126 132-149 164-172 176-193 197-205 209-216 222 228 233 280 303-385 393 396
src/pytom_tm/weights.py 96% 59 299-303 552 557 562

Minimum allowed coverage is 94%

Generated by 🐒 cobertura-action against b592e30

@sroet

sroet commented Mar 30, 2026

Copy link
Copy Markdown
Collaborator

Thanks for dealing with the feedback!

Yes it seems that this is all that is required. I didn't test all options though, only a basic set. I will test a little more tomorrow to really make sure.

Please let me know if you still wanted to do this, or if I should go ahead and see if I can implement some tests for this?

I personally think the error message is fine. It says CUDA, it shows where the error is coming from and hiding the line where it is thrown will only make it harder to debug.

Yeah, as long as it is failing hard inside the cuda backends it is fine, just wanted to make sure it doesn't lead to weird importerrors.

@MoritzWM

Copy link
Copy Markdown
Author

I tested on our HPC login node and it seems to work just fine. I just wanted to make sure I didn't make some stupid mistake.

One could maybe test that voltools and cupy are not loaded as modules when calling merge_stars and extract_particles?

@sroet

sroet commented Apr 1, 2026

Copy link
Copy Markdown
Collaborator

Hey @MoritzWM,

Thanks for checking! I am trying to design the tests. My idea is to mock out GPU availability somehow (probably setting CUDA_VISIBLE_DEVICES to an empty string) or by somehow mocking cupy (as both pytom_tm and voltools use that to interface with the gpus)

I am getting somewhere, but not quite there yet. Will push to your branch once I have figured out a test that fails on main, but works on your branch.

It is surprisingly hard to pretend to run on a machine without gpus even if the machine has them for one test and then have the GPU enabled for other tests. (Specifically struggling with python's import caching atm)😅.

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.

2 participants