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

using physical threads #641

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions include/finufft/finufft_utils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
// using chrono since the interface is portable between linux and windows

namespace finufft::utils {

template<typename T>
FINUFFT_EXPORT FINUFFT_ALWAYS_INLINE void FINUFFT_CDECL arrayrange(BIGINT n, const T *a,

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 16 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once
T *lo, T *hi)
// With a a length-n array, writes out min(a) to lo and max(a) to hi,
// so that all a values lie in [lo,hi].
Expand All @@ -28,7 +27,7 @@
}
}
template<typename T>
FINUFFT_EXPORT FINUFFT_ALWAYS_INLINE void FINUFFT_CDECL arraywidcen(BIGINT n, const T *a,

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 30 in include/finufft/finufft_utils.hpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once
T *w, T *c)
// Writes out w = half-width and c = center of an interval enclosing all a[n]'s
// Only chooses a nonzero center if this increases w by less than fraction
Expand Down Expand Up @@ -59,8 +58,9 @@
double initial;
};

// openmp helpers
int get_num_threads_parallel_block();
FINUFFT_NEVER_INLINE int getPhysicalCoreCount();

FINUFFT_NEVER_INLINE int get_num_threads_parallel_block();

} // namespace finufft::utils

Expand Down
7 changes: 5 additions & 2 deletions src/finufft_core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@
Outputs:
phihat - real Fourier transform evaluated at freq k
*/
FINUFFT_ALWAYS_INLINE T operator()(T k) {

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, On)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, On)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:SSE2, On, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, native, Off, Release, cl, cl, Off)

'inline': used more than once

Check warning on line 268 in src/finufft_core.cpp

View workflow job for this annotation

GitHub Actions / cmake-ci (windows-2022, msvc, /arch:AVX2, Off, Release, cl, cl, Off)

'inline': used more than once
T x = 0;
for (size_t n = 0; n < z.size(); ++n)
x += f[n] * 2 * cos(k * z[n]); // pos & neg freq pair. use T cos!
Expand Down Expand Up @@ -590,8 +590,8 @@

#ifdef _OPENMP
// choose overall # threads...
int ompmaxnthr = MY_OMP_GET_MAX_THREADS();
int nthr = ompmaxnthr; // default: use as many as OMP gives us
int ompmaxnthr = getPhysicalCoreCount();
int nthr = ompmaxnthr; // default: use as many physical cores as possible
// (the above could be set, or suggested set, to 1 for small enough problems...)
if (opts.nthreads > 0) {
nthr = opts.nthreads; // user override, now without limit
Expand All @@ -609,6 +609,9 @@
__func__, opts.nthreads);
#endif
opts.nthreads = nthr; // store actual # thr planned for
if (opts.debug > 1) {
printf("[%s] opts.nthreads=%d\n", __func__, nthr);
}
// (this sets/limits all downstream spread/interp, 1dkernel, and FFT thread counts...)

// choose batchSize for types 1,2 or 3... (uses int ceil(b/a)=1+(b-1)/a trick)
Expand Down
109 changes: 109 additions & 0 deletions src/finufft_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@
// For self-test see ../test/testutils.cpp. Barnett 2017-2020.

#include <cstdint>
#include <iostream>
#include <string>

#if defined(_WIN32)
#include <vector>
#include <windows.h>
#elif defined(__APPLE__)
#include <sys/sysctl.h>
#include <sys/types.h>
#elif defined(__linux__)
#include <fstream>
#include <set>
#endif

#include <finufft/finufft_utils.hpp>

Expand Down Expand Up @@ -57,6 +70,102 @@ double CNTime::elapsedsec() const
return nowsec - initial;
}

// Returns the number of physical CPU cores (excluding hyper-threaded logical cores)
int getPhysicalCoreCount() {
int physicalCoreCount = 0;

#if defined(_WIN32)
// Determine the size of the buffer.
DWORD bufferSize = 0;
if (GetLogicalProcessorInformation(nullptr, &bufferSize) == FALSE &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
// Leave physicalCoreCount as 0 if the call fails.
return physicalCoreCount;
}

// Calculate the number of entries and allocate a vector.
size_t entryCount = bufferSize / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
std::vector<SYSTEM_LOGICAL_PROCESSOR_INFORMATION> procInfo(entryCount);
if (GetLogicalProcessorInformation(procInfo.data(), &bufferSize) != FALSE) {
for (const auto &info : procInfo) {
if (info.Relationship == RelationProcessorCore) ++physicalCoreCount;
}
}

#elif defined(__APPLE__)
// Retrieve the number of physical cores using sysctl.
int cores = 0;
size_t size = sizeof(cores);
if (sysctlbyname("hw.physicalcpu", &cores, &size, nullptr, 0) == 0)
physicalCoreCount = static_cast<unsigned int>(cores);

#elif defined(__linux__)
Copy link
Collaborator

@mreineck mreineck Feb 27, 2025

Choose a reason for hiding this comment

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

Just a small word of caution: this will always report the full number of physical cores on the system, independent of possible restrictions on the executable itself. On computing center nodes, the system may limit a job to a part of the available hardware (e.g. via taskset); if this happens, the code here will overestimate the number of usable cores.
On systems with power and efficiency cores the code will probably (this is just speculation, I haven't tested it) return the sum of both core counts, which may also be larger than the amount of cores that should actually be used.

I'm not saying that the code should be changed (I wouldn't know how...), but this could be worth remembering in case there are reports about weird behaviour in the future.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yeah, this emerged from some discussions with @blackwer yesterday. I'll see if I find a way to figure out the active cores.

Copy link
Member

Choose a reason for hiding this comment

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

I was going to suggest looking at hwloc for inspiration, and it looks like you've found a very similar solution that they did. For posterity:
https://github.com/open-mpi/hwloc/blob/1779eae26f2f55a510e9d73cb648b68e71d9e6d4/hwloc/topology-linux.c#L1036

Copy link
Collaborator

Choose a reason for hiding this comment

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

I was going to suggest libpthreads ... it seems this functionality is available everywhere these days :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Where is the functionality in pthread? I didn't go the route of hwloc because I read somewhere that is an issue on maybe freebsd? This seemed more portable to me

Copy link
Collaborator

@mreineck mreineck Feb 28, 2025

Choose a reason for hiding this comment

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

In ducc I'm using

size_t available_hardware_threads()
  {
  static const size_t available_hardware_threads_ = []()
    {
#if __has_include(<pthread.h>) && defined(__linux__) && defined(_GNU_SOURCE)
    cpu_set_t cpuset;
    CPU_ZERO(&cpuset);
    pthread_getaffinity_np(pthread_self(), sizeof(cpuset), &cpuset);
    size_t res=0;
    for (size_t i=0; i<CPU_SETSIZE; ++i)
      if (CPU_ISSET(i, &cpuset)) ++res;
#else
    size_t res = std::max<size_t>(1, std::thread::hardware_concurrency());
#endif
    return res;
    }();
  return available_hardware_threads_;
  }

which is very close to your getAllowedCoreCount function, but it gets the affinity masks from libpthreads instead of the GNU libc. It might be more portable, but I'm not sure.

// Parse /proc/cpuinfo to count unique (physical id, core id) pairs.
std::ifstream cpuinfo("/proc/cpuinfo");
if (!cpuinfo.is_open()) return physicalCoreCount;

std::set<std::string> coreSet;
std::string line;
int physicalId = -1, coreId = -1;
bool foundPhysical = false, foundCore = false;

while (std::getline(cpuinfo, line)) {
// An empty line indicates the end of a processor block.
if (line.empty()) {
if (foundPhysical && foundCore)
coreSet.insert(std::to_string(physicalId) + "-" + std::to_string(coreId));
// Reset for the next processor block.
foundPhysical = foundCore = false;
physicalId = coreId = -1;
} else {
auto colonPos = line.find(':');
if (colonPos == std::string::npos) continue;
std::string key = line.substr(0, colonPos);
std::string value = line.substr(colonPos + 1);
// Trim whitespace.
key.erase(key.find_last_not_of(" \t") + 1);
value.erase(0, value.find_first_not_of(" \t"));

if (key == "physical id") {
physicalId = std::stoi(value);
foundPhysical = true;
} else if (key == "core id") {
coreId = std::stoi(value);
foundCore = true;
}
}
}
// In case the file doesn't end with an empty line.
if (foundPhysical && foundCore)
coreSet.insert(std::to_string(physicalId) + "-" + std::to_string(coreId));

if (!coreSet.empty()) {
physicalCoreCount = static_cast<unsigned int>(coreSet.size());
} else {
// Fallback: try reading "cpu cores" from the first processor block.
cpuinfo.clear();
cpuinfo.seekg(0, std::ios::beg);
while (std::getline(cpuinfo, line)) {
auto colonPos = line.find(':');
if (colonPos != std::string::npos) {
std::string key = line.substr(0, colonPos);
std::string value = line.substr(colonPos + 1);
key.erase(key.find_last_not_of(" \t") + 1);
value.erase(0, value.find_first_not_of(" \t"));
if (key == "cpu cores") {
physicalCoreCount = static_cast<unsigned int>(std::stoi(value));
break;
}
}
}
}
#endif
if (physicalCoreCount == 0) {
return MY_OMP_GET_MAX_THREADS();
}
return physicalCoreCount;
}

// -------------------------- openmp helpers -------------------------------
int get_num_threads_parallel_block()
// return how many threads an omp parallel block would use.
Expand Down
3 changes: 1 addition & 2 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,10 @@ target_compile_features(testutils PRIVATE cxx_std_17)
finufft_link_test(testutils)
add_test(NAME run_testutils COMMAND testutils WORKING_DIRECTORY ${CMAKE_BINARY_DIR})

if(NOT FINUFFT_USE_DUCC0)
if(NOT FINUFFT_USE_DUCC0 AND FINUFFT_USE_OPENMP)
add_executable(fftw_lock_test fftw_lock_test.cpp)
target_compile_features(fftw_lock_test PRIVATE cxx_std_17)
finufft_link_test(fftw_lock_test)

add_test(NAME run_fftw_lock_test COMMAND fftw_lock_test WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endif()

Expand Down
Loading