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

Feature/core binding report #110

Merged
merged 3 commits into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/allvars.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@
#include <unordered_set>
#include <unistd.h>
#include <vector>
#include <sys/types.h>
#include <sys/sysctl.h>
#include <sched.h>

#include <gsl/gsl_heapsort.h>
#include <gsl/gsl_errno.h>
Expand Down
2 changes: 2 additions & 0 deletions src/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ void show_version_info(int argc, char *argv[])
#else
<< "no";
#endif
// report binding
report_binding();
}

int run(int argc,char **argv)
Expand Down
15 changes: 15 additions & 0 deletions src/proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -890,6 +890,21 @@ namespace vr {
std::string GetMemUsage(const std::string &function);
#define MEMORY_USAGE_REPORT(lvl) { if(LOG_ENABLED(lvl)) LOG(lvl) << GetMemUsage(__FUNCTION__); }

/// Core binding
//@{
#ifdef __APPLE__

#define SYSCTL_CORE_COUNT "machdep.cpu.core_count"
#define CPU_SETSIZE 1024
typedef struct cpu_set {
uint32_t count;
} cpu_set_t;
int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set);
#endif
void cpuset_to_cstr(cpu_set_t *mask, char *str);
void report_binding();
//@}

namespace vr {
/// Get the basename of `filename`
std::string basename(const std::string &filename);
Expand Down
106 changes: 106 additions & 0 deletions src/utilities.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,112 @@ std::string GetMemUsage(const std::string &function)
return memory_report.str();
}

/* Borrowed from util-linux-2.13-pre7/schedutils/taskset.c */
#ifdef __APPLE__

static inline void
CPU_ZERO(cpu_set_t *cs) { cs->count = 0; }

static inline void
CPU_SET(int num, cpu_set_t *cs) { cs->count |= (1 << num); }

static inline int
CPU_ISSET(int num, cpu_set_t *cs) { return (cs->count & (1 << num)); }

int sched_getaffinity(pid_t pid, size_t cpu_size, cpu_set_t *cpu_set)
{
int32_t core_count = 0;
size_t len = sizeof(core_count);
int ret = sysctlbyname(SYSCTL_CORE_COUNT, &core_count, &len, 0, 0);
if (ret) {
printf("error while get core count %d\n", ret);
return -1;
}
cpu_set->count = 0;
for (int i = 0; i < core_count; i++) {
cpu_set->count |= (1 << i);
}

return 0;
}
#endif

void cpuset_to_cstr(cpu_set_t *mask, char *str)
{
char *ptr = str;
int i, j, entry_made = 0;
for (i = 0; i < CPU_SETSIZE; i++) {
if (CPU_ISSET(i, mask)) {
int run = 0;
entry_made = 1;
for (j = i + 1; j < CPU_SETSIZE; j++) {
if (CPU_ISSET(j, mask)) run++;
else break;
}
if (!run)
sprintf(ptr, "%d ", i);
else if (run == 1) {
sprintf(ptr, "%d,%d ", i, i + 1);
i++;
} else {
sprintf(ptr, "%d-%d ", i, i + run);
i += run;
}
while (*ptr != 0) ptr++;
}
}
ptr -= entry_made;
ptr = nullptr;
}

void report_binding()
{
// if there is no MPI do not report any binding
#if !defined(USEMPI) && !defined(USEOPENMP)
return;
#endif
#ifdef USEMPI
MPI_Barrier(MPI_COMM_WORLD);
#else
int ThisTask=0, NProcs=1;
#endif
string binding_report = "Core binding \n ";
cpu_set_t coremask;
char clbuf[7 * CPU_SETSIZE], hnbuf[64];
memset(clbuf, 0, sizeof(clbuf));
memset(hnbuf, 0, sizeof(hnbuf));
(void)gethostname(hnbuf, sizeof(hnbuf));
#ifdef USEOPENMP
#pragma omp parallel shared (binding_report) private(coremask, clbuf)
#endif
{
string result;
(void)sched_getaffinity(0, sizeof(coremask), &coremask);
cpuset_to_cstr(&coremask, clbuf);
result = "\t On node " + string(hnbuf) + " : ";
#ifdef USEMPI
result += "MPI Rank " + to_string(ThisTask) + " : ";
#endif
#ifdef USEOPENMP
auto thread = omp_get_thread_num();
result +=" OMP Thread " + to_string(thread) + " : ";
#endif
result += " Core affinity = " + string(clbuf) + " \n ";
#ifdef USEOPENMP
#pragma omp critical
#endif
{
binding_report +=result;

}
}
LOG(info)<<binding_report;
#ifdef USEMPI
MPI_Barrier(MPI_COMM_WORLD);
#endif
}


#ifdef NOMASS
void VR_NOMASS(){};
#endif
Expand Down