From 8dfe38e06c86205e388924ceeeccb42a16fdfac9 Mon Sep 17 00:00:00 2001 From: Gregor Sturm Date: Fri, 17 May 2024 08:41:15 +0200 Subject: [PATCH] Fix #517 (#518) * Fix #517 * Update CHANGELOG --- CHANGELOG.md | 8 +++++++- src/scirpy/ir_dist/_clonotype_neighbors.py | 5 ++--- src/scirpy/util/__init__.py | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96ba991df..17362dd22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,10 +8,16 @@ and this project adheres to [Semantic Versioning][]. [keep a changelog]: https://keepachangelog.com/en/1.0.0/ [semantic versioning]: https://semver.org/spec/v2.0.0.html -## Unreleased +## v0.17.0 + +### Additions - Add "TCRdist" as new metric ([#502](https://github.com/scverse/scirpy/pull/502)) +### Fixes + +- Fix issue with detecting the number of available CPUs on MacOD ([#518](https://github.com/scverse/scirpy/pull/502)) + ## v0.16.1 ### Fixes diff --git a/src/scirpy/ir_dist/_clonotype_neighbors.py b/src/scirpy/ir_dist/_clonotype_neighbors.py index b70c39e6d..a7e24a06e 100644 --- a/src/scirpy/ir_dist/_clonotype_neighbors.py +++ b/src/scirpy/ir_dist/_clonotype_neighbors.py @@ -1,5 +1,4 @@ import itertools -import os from collections.abc import Mapping, Sequence from typing import Literal, Optional, Union @@ -11,7 +10,7 @@ from scirpy.get import _has_ir from scirpy.get import airr as get_airr -from scirpy.util import DataHandler, tqdm +from scirpy.util import DataHandler, _get_usable_cpus, tqdm from ._util import DoubleLookupNeighborFinder, merge_coo_matrices, reduce_and, reduce_or @@ -225,7 +224,7 @@ def compute_distances(self) -> sp.csr_matrix: dist_rows = process_map( self._dist_for_clonotype, range(n_clonotypes), - max_workers=self.n_jobs if self.n_jobs > 0 else len(os.sched_getaffinity(0)), + max_workers=_get_usable_cpus(self.n_jobs), chunksize=2000, tqdm_class=tqdm, ) diff --git a/src/scirpy/util/__init__.py b/src/scirpy/util/__init__.py index caf79577c..01283b43e 100644 --- a/src/scirpy/util/__init__.py +++ b/src/scirpy/util/__init__.py @@ -1,4 +1,5 @@ import contextlib +import os import warnings from collections.abc import Mapping, Sequence from textwrap import dedent @@ -582,3 +583,21 @@ def _parallelize_with_joblib(delayed_objects, *, total=None, **kwargs): "Consider setting verbosity in joblib.parallel_config" ) return Parallel(return_as="list", **kwargs)(delayed_objects) + + +def _get_usable_cpus(n_jobs: int = 0): + """Get the number of CPUs available to the process + + If `n_jobs` is specified and > 0 that value will be returned unaltered. + Otherwise will try to determine the number of CPUs available to the process which + is not necessarily the number of CPUs available on the system. + + On MacOS, `os.sched_getaffinity` is not implemented, therefore we just return the cpu count there. + """ + if n_jobs > 0: + return n_jobs + + try: + return os.sched_getaffinity(0) + except AttributeError: + return os.cpu_count()