Open surfaceowl opened 8 months ago
I had an issue on Windows 11 which prevented me running kmeans. ...Could not find the number of physical cores for the following reason: [WinError 2] The system cannot find the file specified... Using the absolute path of wmic in context.py helped: C:/Windows/System32/wbem/WMIC.exe instead of wmic
Thanks for the reports. I think both problems should be tackled:
implement some of the fallback mechanisms proposed above in case lscpu
fails to detect physical cores;
try to see if the C:/Windows/System32/wbem/WMIC.exe
file exists in case shutil.which("WMIC") is False
.
Those two problems should be addressed in separate pull requests to make the review independent.
Any taker?
Note: I did not know that nproc
was cgroup
-aware. If this is always the case, we can probably use it to simplify _cpu_count_cgroup
. Still we need to be able to find about hyper-threaded cores in case not cgroups quotas are undefined or larger than the number of physical cores detected by reading /proc/cpuinfo
or using lscpu
.
I tried the docker commands above with an old image of ubuntu (ubuntu:18.04
) and nproc
already behaved that way at the time.
Issue: The loky context manager relies only on the
lscpu
util to get physical and logical cpu for the_count_physical_cores
method, and raises a ValueError offound
{cpu_count_physical} physical cores < 1` when lscpu is missing or fails. This makes loky less cross-platform friendly than it could be.Impact: On systems where
lscpu
is missing or fails, a ValueError is raised as the stringfound 0 physical cores < 1
trigging a failure when creating multiprocessing Pools on these systems. This happens both when the env var LOKY_MAX_CPU_COUNT is set and when it is missing or unset.Example containers where it is missing include Heroku and Alpine. Docker containers your team is building are easy to fix, but some platform providers make it more difficult (cough, cough Heroku), and would be nice to reduce Docker build noise for missing libraries.
Suggested solutions for consideration:
lscpu
that are more cross-platform friendly. This could be methods like os.cpu_count(), or cat proc/cpuinfo or some other *nix utility. This may have some downsides on accuracy on logical vs. physical cores, or cores not actually available to the process I'm not aware of... and I am not fully conversant on which utils are available on what platforms._count_physical_cores
did not work correctly. A users multiprocessing pool would surely be slow, but it would at least run rather than fail. Picking the wrong number of cpu would slow down multiprocessing, but that may be preferred to not running at all.Additional Context: Other commands exist may give sufficiently accurate CPU info and be more broadly cross-platform:
siblings for number of logical CPU and
cpu cores` for number of physical CPU.nproc
though I don't know how many of these are out there, and given the number of different platforms out there it may not be possible to find the silver bullet.Separately - on Heroku I was able to install
lscpu
but due to some backend magic by Heroku maintainers,lscpu
still failed from the cli returning the errorlscpu: failed to determine number of CPUs: /sys/devices/system/cpu/possible: No such file or **directory
.**In discussion with Heroku maintainers, they suggested using 'nproc': """ ...just to follow up on my colleague's response: on Linux, please use nproc (available on Heroku's base images, from GNU coreutils) to determine the number if available processor cores.
Unlike lscpu, nproc will correctly represent the number of CPU cores that are available to the current process after any cgroup restrictions are applied, which might be the case e.g. in a local Docker environment, and could be employed by Heroku in the future on shared dynos.
In contrast, lscpu will always report the number of online cores, even if a process may not have access to all of them.
Observe the following differences in output for a container restricted to CPU cores 1 and 2:
~ % docker run --rm -ti --cgroupns host --cpuset-cpus 1-2 heroku/heroku:22 bash
root@5d5abb8e0108:/# lscpu Architecture: x86_64 CPU op-mode(s): 32-bit Byte Order: Little Endian CPU(s): 6 On-line CPU(s) list: 0-5 Vendor ID: Apple Model: 0 Thread(s) per core: 1 Core(s) per socket: 6 Socket(s): 1 …
root@5d5abb8e0108:/# nproc 2
root@5d5abb8e0108:/# nproc --all 6 """